summaryrefslogtreecommitdiffstats
path: root/libck-connector
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2007-02-28 13:52:17 -0500
committerWilliam Jon McCann <mccann@jhu.edu>2007-02-28 13:52:17 -0500
commitfed7e94f76c4279015354ff210bc72f1ac68af70 (patch)
tree9ffb075579693cf2a2000fd8a0dcb3ad1c6ac367 /libck-connector
parent8b33f57e8cd5f451d55fbb0f9bcc3c119a076326 (diff)
add a connector library and (reluctantly) a PAM module
Here are some patches to add one library and one PAM module so other programs (apart from gdm) can easily interact with ConsoleKit. It's mainly going to be used, I think, by login(1) and xinit(1). I'm not super happy about doing a PAM module but the Fedora util-linux package maintainer seems to be insist on this instead of just patching login(1). The PAM module isn't built by default. Both pieces of code are licensed under the MIT license as god knows what might want to use them. Sounds good to you?
Diffstat (limited to 'libck-connector')
-rw-r--r--libck-connector/Makefile.am22
-rw-r--r--libck-connector/ck-connector.c381
-rw-r--r--libck-connector/ck-connector.h122
-rw-r--r--libck-connector/ck-connector.pc.in9
4 files changed, 534 insertions, 0 deletions
diff --git a/libck-connector/Makefile.am b/libck-connector/Makefile.am
new file mode 100644
index 0000000..80a4e2b
--- /dev/null
+++ b/libck-connector/Makefile.am
@@ -0,0 +1,22 @@
+
+INCLUDES = $(LIBDBUS_CFLAGS)
+
+slib_LTLIBRARIES=libck-connector.la
+slibdir=/lib
+libck_connectorincludedir=$(includedir)/ConsoleKit/ck-connector
+libck_connectorinclude_HEADERS = ck-connector.h
+libck_connector_la_SOURCES = ck-connector.c ck-connector.h
+
+# soname management for libck-connector
+LIBCKCON_LT_CURRENT=0
+LIBCKCON_LT_REVISION=0
+LIBCKCON_LT_AGE=0
+
+libck_connector_la_LIBADD = $(LIBDBUS_LIBS)
+libck_connector_la_LDFLAGS = -version-info $(LIBCKCON_LT_CURRENT):$(LIBCKCON_LT_REVISION):$(LIBCKCON_LT_AGE)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ck-connector.pc
+
+clean-local :
+ rm -f *~
diff --git a/libck-connector/ck-connector.c b/libck-connector/ck-connector.c
new file mode 100644
index 0000000..b22f76c
--- /dev/null
+++ b/libck-connector/ck-connector.c
@@ -0,0 +1,381 @@
+/*
+ * ck-connector.c : Code for login managers to register with ConsoleKit.
+ *
+ * Copyright (c) 2007 David Zeuthen <davidz@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dbus/dbus.h>
+
+#include "ck-connector.h"
+
+static dbus_bool_t
+add_param_int32 (DBusMessageIter *iter_array, const char *key, dbus_int32_t value)
+{
+ DBusMessageIter iter_struct;
+ DBusMessageIter iter_variant;
+
+ if (!dbus_message_iter_open_container (iter_array,
+ DBUS_TYPE_STRUCT,
+ NULL,
+ &iter_struct))
+ goto oom;
+ if (!dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &key))
+ goto oom;
+ if (!dbus_message_iter_open_container (&iter_struct,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_INT32_AS_STRING,
+ &iter_variant))
+ goto oom;
+ if (!dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_INT32, &value))
+ goto oom;
+ if (!dbus_message_iter_close_container (&iter_struct, &iter_variant))
+ goto oom;
+ if (!dbus_message_iter_close_container (iter_array, &iter_struct))
+ goto oom;
+
+ return TRUE;
+oom:
+ return FALSE;
+}
+
+static dbus_bool_t
+add_param_string (DBusMessageIter *iter_array, const char *key, const char *value)
+{
+ DBusMessageIter iter_struct;
+ DBusMessageIter iter_variant;
+
+ if (!dbus_message_iter_open_container (iter_array,
+ DBUS_TYPE_STRUCT,
+ NULL,
+ &iter_struct))
+ goto oom;
+ if (!dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &key))
+ goto oom;
+ if (!dbus_message_iter_open_container (&iter_struct,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_STRING_AS_STRING,
+ &iter_variant))
+ goto oom;
+ if (!dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_STRING, &value))
+ goto oom;
+ if (!dbus_message_iter_close_container (&iter_struct, &iter_variant))
+ goto oom;
+ if (!dbus_message_iter_close_container (iter_array, &iter_struct))
+ goto oom;
+
+ return TRUE;
+oom:
+ return FALSE;
+}
+
+static dbus_bool_t
+add_param_bool (DBusMessageIter *iter_array, const char *key, dbus_bool_t value)
+{
+ DBusMessageIter iter_struct;
+ DBusMessageIter iter_variant;
+
+ if (!dbus_message_iter_open_container (iter_array,
+ DBUS_TYPE_STRUCT,
+ NULL,
+ &iter_struct))
+ goto oom;
+ if (!dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &key))
+ goto oom;
+ if (!dbus_message_iter_open_container (&iter_struct,
+ DBUS_TYPE_VARIANT,
+ DBUS_TYPE_BOOLEAN_AS_STRING,
+ &iter_variant))
+ goto oom;
+ if (!dbus_message_iter_append_basic (&iter_variant, DBUS_TYPE_BOOLEAN, &value))
+ goto oom;
+ if (!dbus_message_iter_close_container (&iter_struct, &iter_variant))
+ goto oom;
+ if (!dbus_message_iter_close_container (iter_array, &iter_struct))
+ goto oom;
+
+ return TRUE;
+oom:
+ return FALSE;
+}
+
+
+struct CKConnector_s
+{
+ char *cookie;
+ dbus_bool_t session_created;
+ DBusConnection *con;
+};
+
+CKConnector*
+ckc_new (void)
+{
+ CKConnector *ckc;
+
+ ckc = calloc (1, sizeof (CKConnector));
+ if (ckc == NULL)
+ goto oom;
+ ckc->con = NULL;
+ ckc->cookie = NULL;
+ ckc->session_created = FALSE;
+oom:
+ return ckc;
+};
+
+dbus_bool_t
+ckc_create_local_session2 (CKConnector *ckc)
+{
+ DBusError error;
+ DBusMessage *message;
+ DBusMessage *reply;
+ dbus_bool_t ret;
+ char *cookie;
+
+ reply = NULL;
+ message = NULL;
+ ret = FALSE;
+
+ dbus_error_init (&error);
+ ckc->con = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);
+ if (ckc->con == NULL) {
+ goto out;
+ }
+ dbus_connection_set_exit_on_disconnect (ckc->con, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager",
+ "OpenSession");
+ if (message == NULL)
+ goto out;
+
+ reply = dbus_connection_send_with_reply_and_block (ckc->con, message, -1, &error);
+ if (reply == NULL) {
+ if (dbus_error_is_set (&error)) {
+ dbus_error_free (&error);
+ goto out;
+ }
+ }
+
+ if (!dbus_message_get_args (reply,
+ &error,
+ DBUS_TYPE_STRING, &cookie,
+ DBUS_TYPE_INVALID)) {
+ if (dbus_error_is_set (&error)) {
+ dbus_error_free (&error);
+ goto out;
+ }
+ }
+
+ ckc->cookie = strdup (cookie);
+ if (ckc->cookie == NULL)
+ goto out;
+
+ ckc->session_created = TRUE;
+ ret = TRUE;
+
+out:
+ if (reply != NULL)
+ dbus_message_unref (reply);
+
+ if (message != NULL)
+ dbus_message_unref (message);
+
+ return ret;
+}
+
+dbus_bool_t
+ckc_create_local_session (CKConnector *ckc, uid_t user, const char *tty, const char *x11_display)
+{
+ DBusError error;
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+ dbus_bool_t ret;
+ char *cookie;
+
+ reply = NULL;
+ message = NULL;
+ ret = FALSE;
+
+ dbus_error_init (&error);
+ ckc->con = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error);
+ if (ckc->con == NULL) {
+ goto out;
+ }
+ dbus_connection_set_exit_on_disconnect (ckc->con, FALSE);
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager",
+ "OpenSessionWithParameters");
+ if (message == NULL)
+ goto out;
+
+ dbus_message_iter_init_append (message, &iter);
+ if (!dbus_message_iter_open_container (&iter,
+ DBUS_TYPE_ARRAY,
+ "(sv)",
+ &iter_array))
+ goto out;
+
+ if (!add_param_string (&iter_array, "host-name", "localhost"))
+ goto out;
+ if (!add_param_string (&iter_array, "display-device", tty))
+ goto out;
+ if (x11_display != NULL)
+ if (!add_param_string (&iter_array, "x11-display", x11_display))
+ goto out;
+ if (!add_param_int32 (&iter_array, "user", user))
+ goto out;
+ if (!add_param_bool (&iter_array, "is-local", TRUE))
+ goto out;
+
+ if (!dbus_message_iter_close_container (&iter, &iter_array))
+ goto out;
+
+ reply = dbus_connection_send_with_reply_and_block (ckc->con, message, -1, &error);
+ if (reply == NULL) {
+ if (dbus_error_is_set (&error)) {
+ dbus_error_free (&error);
+ goto out;
+ }
+ }
+
+ if (!dbus_message_get_args (reply,
+ &error,
+ DBUS_TYPE_STRING, &cookie,
+ DBUS_TYPE_INVALID)) {
+ if (dbus_error_is_set (&error)) {
+ dbus_error_free (&error);
+ goto out;
+ }
+ }
+
+ ckc->cookie = strdup (cookie);
+ if (ckc->cookie == NULL)
+ goto out;
+
+ ckc->session_created = TRUE;
+ ret = TRUE;
+
+out:
+ if (reply != NULL)
+ dbus_message_unref (reply);
+
+ if (message != NULL)
+ dbus_message_unref (message);
+
+ return ret;
+}
+
+char *
+ckc_get_cookie (CKConnector *ckc)
+{
+ if (!ckc->session_created)
+ return NULL;
+ else
+ return ckc->cookie;
+}
+
+dbus_bool_t
+ckc_close_session (CKConnector *ckc)
+{
+ DBusError error;
+ DBusMessage *message;
+ DBusMessage *reply;
+ dbus_bool_t ret;
+ dbus_bool_t session_closed;
+
+ reply = NULL;
+ message = NULL;
+ ret = FALSE;
+ if (!ckc->session_created || ckc->cookie == NULL)
+ goto out;
+
+ dbus_error_init (&error);
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager",
+ "CloseSession");
+ if (message == NULL)
+ goto out;
+
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_STRING, &(ckc->cookie),
+ DBUS_TYPE_INVALID))
+ goto out;
+
+ reply = dbus_connection_send_with_reply_and_block (ckc->con, message, -1, &error);
+ if (reply == NULL) {
+ if (dbus_error_is_set (&error)) {
+ dbus_error_free (&error);
+ goto out;
+ }
+ }
+
+ if (!dbus_message_get_args (reply,
+ &error,
+ DBUS_TYPE_BOOLEAN, &session_closed,
+ DBUS_TYPE_INVALID)) {
+ if (dbus_error_is_set (&error)) {
+ dbus_error_free (&error);
+ goto out;
+ }
+ }
+
+ if (!session_closed)
+ goto out;
+
+ ckc->session_created = FALSE;
+ ret = TRUE;
+
+out:
+ if (reply != NULL)
+ dbus_message_unref (reply);
+
+ if (message != NULL)
+ dbus_message_unref (message);
+
+ return ret;
+
+}
+
+void
+ckc_free (CKConnector *ckc)
+{
+ if (ckc->con != NULL) {
+ /* it's a private connection so it's all good */
+ dbus_connection_close (ckc->con);
+ }
+ if (ckc->cookie != NULL) {
+ free (ckc->cookie);
+ }
+ free (ckc);
+}
diff --git a/libck-connector/ck-connector.h b/libck-connector/ck-connector.h
new file mode 100644
index 0000000..e92712d
--- /dev/null
+++ b/libck-connector/ck-connector.h
@@ -0,0 +1,122 @@
+/*
+ * ck-connector.h : Code for login managers to register with ConsoleKit.
+ *
+ * Copyright (c) 2007 David Zeuthen <davidz@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef CK_CONNECTOR_H
+#define CK_CONNECTOR_H
+
+#include <sys/types.h>
+#include <dbus/dbus.h>
+
+struct CKConnecter_s;
+typedef struct CKConnector_s CKConnector;
+
+/* Allocates a new CKConnector instance.
+ *
+ * Returns NULL on OOM */
+CKConnector *ckc_new (void);
+
+/* Connects to the D-Bus system bus daemon and issues the method call
+ * OpenSessionWithParameters on the ConsoleKit manager interface. The
+ * connection to the bus is private.
+ *
+ * The only parameter that is optional is x11_display - it may be set
+ * to NULL if there is no X11 server associated with the session.
+ *
+ * Returns FALSE on OOM, if the system bus daemon is not running, if
+ * the ConsoleKit daemon is not running or if the caller doesn't have
+ * sufficient privileges.
+ */
+dbus_bool_t ckc_create_local_session (CKConnector *ckc, uid_t user, const char *tty, const char *x11_display);
+
+dbus_bool_t ckc_create_local_session2 (CKConnector *ckc);
+
+/* Gets the cookie that should be set as XDG_SESSION_COOKIE in the
+ * users environment.
+ *
+ * Returns NULL unless ckc_create_local_session() succeeded
+ */
+char *ckc_get_cookie (CKConnector *ckc);
+
+/* Issues the CloseSession method call on the ConsoleKit manager
+ * interface.
+ *
+ * Returns FALSE on OOM, if the system bus daemon is not running, if
+ * the ConsoleKit daemon is not running, if the caller doesn't have
+ * sufficient privilege or if ckc_create_local_session() wasn't
+ * successfully invoked.
+ */
+dbus_bool_t ckc_close_session (CKConnector *ckc);
+
+/* Frees all resources allocated and disconnects from the system
+ * message bus.
+ */
+void ckc_free (CKConnector *ckc);
+
+/* example code:
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ck-connector.h"
+
+int
+main (int argc, char *argv[])
+{
+ CKConnector *ckc;
+
+ ckc = ckc_new ();
+ if (ckc == NULL) {
+ printf ("OOM creating CKConnector\n");
+ goto out;
+ }
+
+ if (!ckc_create_local_session (ckc, 500, "/dev/tty2", ":1")) {
+ printf ("cannot create CK session: OOM, D-Bus system bus not available,\n"
+ "ConsoleKit not available or insufficient privileges.\n");
+ goto out;
+ }
+
+ printf ("Session cookie is '%s'\n", ckc_get_cookie (ckc));
+ sleep (20);
+
+ if (!ckc_close_session (ckc)) {
+ printf ("Cannot close CK session: OOM, D-Bus system bus not available,\n"
+ "ConsoleKit not available or insufficient privileges.\n");
+ goto out;
+ }
+
+out:
+ if (ckc != NULL) {
+ ckc_free (ckc);
+ }
+}
+
+*/
+
+#endif /* CK_CONNECTOR_H */
+
+
+
diff --git a/libck-connector/ck-connector.pc.in b/libck-connector/ck-connector.pc.in
new file mode 100644
index 0000000..e3f00cd
--- /dev/null
+++ b/libck-connector/ck-connector.pc.in
@@ -0,0 +1,9 @@
+libdir=/lib
+includedir=@prefix@/include
+
+Name: ck-connector
+Description: Library for connecting new sessions to ConsoleKit
+Version: @VERSION@
+Requires: dbus-1
+Libs: -L${libdir} -lck-connector
+Cflags: -I${includedir}/ConsoleKit/ck-connector