summaryrefslogtreecommitdiffstats
path: root/libck-connector/ck-connector.c
diff options
context:
space:
mode:
Diffstat (limited to 'libck-connector/ck-connector.c')
-rw-r--r--libck-connector/ck-connector.c381
1 files changed, 381 insertions, 0 deletions
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);
+}