diff --git a/gdm-2.17.6-consolekit.patch b/gdm-2.17.6-consolekit.patch new file mode 100644 index 0000000..1779a88 --- /dev/null +++ b/gdm-2.17.6-consolekit.patch @@ -0,0 +1,720 @@ +Index: daemon/gdmconsolekit.c +=================================================================== +--- daemon/gdmconsolekit.c (revision 4556) ++++ daemon/gdmconsolekit.c (working copy) +@@ -1,6 +1,6 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * +- * Copyright (C) 2006 William Jon McCann ++ * Copyright (C) 2006-2007 William Jon McCann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -20,11 +20,11 @@ + + #include "config.h" + ++#include + #include + + #define DBUS_API_SUBJECT_TO_CHANGE + #include +-#include + #include + + #include "misc.h" /* for gdm_debug */ +@@ -38,182 +38,360 @@ + #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" + #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" + +-#define CK_TYPE_PARAMETER_STRUCT (dbus_g_type_get_struct ("GValueArray", \ +- G_TYPE_STRING, \ +- G_TYPE_VALUE, \ +- G_TYPE_INVALID)) +-#define CK_TYPE_PARAMETER_LIST (dbus_g_type_get_collection ("GPtrArray", \ +- CK_TYPE_PARAMETER_STRUCT)) ++static DBusConnection *private_connection = NULL; ++ + static void +-add_param_int (GPtrArray *parameters, ++add_param_int (DBusMessageIter *iter_struct, + const char *key, + int value) + { +- GValue val = { 0, }; +- GValue param_val = { 0, }; ++ DBusMessageIter iter_struct_entry; ++ DBusMessageIter iter_var; ++ ++ dbus_message_iter_open_container (iter_struct, ++ DBUS_TYPE_STRUCT, ++ NULL, ++ &iter_struct_entry); ++ ++ dbus_message_iter_append_basic (&iter_struct_entry, ++ DBUS_TYPE_STRING, ++ &key); ++ ++ dbus_message_iter_open_container (&iter_struct_entry, ++ DBUS_TYPE_VARIANT, ++ DBUS_TYPE_INT32_AS_STRING, ++ &iter_var); ++ ++ dbus_message_iter_append_basic (&iter_var, ++ DBUS_TYPE_INT32, ++ &value); ++ ++ dbus_message_iter_close_container (&iter_struct_entry, ++ &iter_var); + +- g_value_init (&val, G_TYPE_INT); +- g_value_set_int (&val, value); +- g_value_init (¶m_val, CK_TYPE_PARAMETER_STRUCT); +- g_value_take_boxed (¶m_val, +- dbus_g_type_specialized_construct (CK_TYPE_PARAMETER_STRUCT)); +- dbus_g_type_struct_set (¶m_val, +- 0, key, +- 1, &val, +- G_MAXUINT); +- g_ptr_array_add (parameters, g_value_get_boxed (¶m_val)); ++ dbus_message_iter_close_container (iter_struct, &iter_struct_entry); + } + + static void +-add_param_boolean (GPtrArray *parameters, ++add_param_boolean (DBusMessageIter *iter_struct, + const char *key, + gboolean value) + { +- GValue val = { 0, }; +- GValue param_val = { 0, }; ++ DBusMessageIter iter_struct_entry; ++ DBusMessageIter iter_var; + +- g_value_init (&val, G_TYPE_BOOLEAN); +- g_value_set_boolean (&val, value); +- g_value_init (¶m_val, CK_TYPE_PARAMETER_STRUCT); +- g_value_take_boxed (¶m_val, +- dbus_g_type_specialized_construct (CK_TYPE_PARAMETER_STRUCT)); +- dbus_g_type_struct_set (¶m_val, +- 0, key, +- 1, &val, +- G_MAXUINT); +- g_ptr_array_add (parameters, g_value_get_boxed (¶m_val)); ++ dbus_message_iter_open_container (iter_struct, ++ DBUS_TYPE_STRUCT, ++ NULL, ++ &iter_struct_entry); ++ ++ dbus_message_iter_append_basic (&iter_struct_entry, ++ DBUS_TYPE_STRING, ++ &key); ++ ++ dbus_message_iter_open_container (&iter_struct_entry, ++ DBUS_TYPE_VARIANT, ++ DBUS_TYPE_BOOLEAN_AS_STRING, ++ &iter_var); ++ ++ dbus_message_iter_append_basic (&iter_var, ++ DBUS_TYPE_BOOLEAN, ++ &value); ++ ++ dbus_message_iter_close_container (&iter_struct_entry, ++ &iter_var); ++ ++ dbus_message_iter_close_container (iter_struct, &iter_struct_entry); + } + + static void +-add_param_string (GPtrArray *parameters, ++add_param_string (DBusMessageIter *iter_struct, + const char *key, + const char *value) + { +- GValue val = { 0, }; +- GValue param_val = { 0, }; ++ DBusMessageIter iter_struct_entry; ++ DBusMessageIter iter_var; ++ ++ dbus_message_iter_open_container (iter_struct, ++ DBUS_TYPE_STRUCT, ++ NULL, ++ &iter_struct_entry); ++ ++ dbus_message_iter_append_basic (&iter_struct_entry, ++ DBUS_TYPE_STRING, ++ &key); ++ ++ dbus_message_iter_open_container (&iter_struct_entry, ++ DBUS_TYPE_VARIANT, ++ DBUS_TYPE_STRING_AS_STRING, ++ &iter_var); ++ ++ dbus_message_iter_append_basic (&iter_var, ++ DBUS_TYPE_STRING, ++ &value); ++ ++ dbus_message_iter_close_container (&iter_struct_entry, ++ &iter_var); ++ ++ dbus_message_iter_close_container (iter_struct, &iter_struct_entry); ++} ++ ++static gboolean ++session_get_x11_display (DBusConnection *connection, ++ const char *ssid, ++ char **str) ++{ ++ DBusError error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ DBusMessageIter iter; ++ const char *value; ++ ++ if (str != NULL) { ++ *str = NULL; ++ } ++ ++ message = dbus_message_new_method_call (CK_NAME, ++ ssid, ++ CK_SESSION_INTERFACE, ++ "GetX11Display"); ++ if (message == NULL) { ++ gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message"); ++ return FALSE; ++ } ++ ++ dbus_error_init (&error); ++ reply = dbus_connection_send_with_reply_and_block (connection, ++ message, ++ -1, &error); ++ if (dbus_error_is_set (&error)) { ++ gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); ++ reply = NULL; ++ } ++ ++ dbus_connection_flush (connection); ++ dbus_message_unref (message); ++ ++ if (reply == NULL) { ++ return FALSE; ++ } + +- g_value_init (&val, G_TYPE_STRING); +- g_value_set_string (&val, value); ++ dbus_message_iter_init (reply, &iter); ++ dbus_message_iter_get_basic (&iter, &value); ++ if (str != NULL) { ++ *str = g_strdup (value); ++ } ++ dbus_message_unref (reply); + +- g_value_init (¶m_val, CK_TYPE_PARAMETER_STRUCT); +- g_value_take_boxed (¶m_val, +- dbus_g_type_specialized_construct (CK_TYPE_PARAMETER_STRUCT)); +- +- dbus_g_type_struct_set (¶m_val, +- 0, key, +- 1, &val, +- G_MAXUINT); +- g_ptr_array_add (parameters, g_value_get_boxed (¶m_val)); ++ return TRUE; + } + + static gboolean +-get_string (DBusGProxy *proxy, +- const char *method, +- char **str) ++session_unlock (DBusConnection *connection, ++ const char *ssid) ++{ ++ DBusError error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ ++ gdm_debug ("ConsoleKit: Unlocking session %s", ssid); ++ message = dbus_message_new_method_call (CK_NAME, ++ ssid, ++ CK_SESSION_INTERFACE, ++ "Unlock"); ++ if (message == NULL) { ++ gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message"); ++ return FALSE; ++ } ++ ++ dbus_error_init (&error); ++ reply = dbus_connection_send_with_reply_and_block (connection, ++ message, ++ -1, &error); ++ dbus_message_unref (message); ++ dbus_message_unref (reply); ++ dbus_connection_flush (connection); ++ ++ if (dbus_error_is_set (&error)) { ++ gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/* from libhal */ ++static char ** ++get_path_array_from_iter (DBusMessageIter *iter, ++ int *num_elements) ++{ ++ int count; ++ char **buffer; ++ ++ count = 0; ++ buffer = (char **)malloc (sizeof (char *) * 8); ++ ++ if (buffer == NULL) ++ goto oom; ++ ++ buffer[0] = NULL; ++ while (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_OBJECT_PATH) { ++ const char *value; ++ char *str; ++ ++ if ((count % 8) == 0 && count != 0) { ++ buffer = realloc (buffer, sizeof (char *) * (count + 8)); ++ if (buffer == NULL) ++ goto oom; ++ } ++ ++ dbus_message_iter_get_basic (iter, &value); ++ str = strdup (value); ++ if (str == NULL) ++ goto oom; ++ ++ buffer[count] = str; ++ ++ dbus_message_iter_next (iter); ++ count++; ++ } ++ ++ if ((count % 8) == 0) { ++ buffer = realloc (buffer, sizeof (char *) * (count + 1)); ++ if (buffer == NULL) ++ goto oom; ++ } ++ ++ buffer[count] = NULL; ++ if (num_elements != NULL) ++ *num_elements = count; ++ return buffer; ++ ++oom: ++ fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__); ++ return NULL; ++ ++} ++ ++static char ** ++get_sessions_for_user (DBusConnection *connection, ++ const char *user, ++ const char *x11_display) + { +- GError *error; +- gboolean res; ++ DBusError error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ DBusMessageIter iter; ++ DBusMessageIter iter_reply; ++ DBusMessageIter iter_array; ++ struct passwd *pwent; ++ char **sessions; ++ ++ sessions = NULL; ++ message = NULL; ++ reply = NULL; + +- error = NULL; +- res = dbus_g_proxy_call (proxy, +- method, +- &error, +- G_TYPE_INVALID, +- G_TYPE_STRING, str, +- G_TYPE_INVALID); +- if (! res) { +- g_warning ("%s failed: %s", method, error->message); +- g_error_free (error); ++ pwent = getpwnam (user); ++ ++ dbus_error_init (&error); ++ message = dbus_message_new_method_call (CK_NAME, ++ CK_MANAGER_PATH, ++ CK_MANAGER_INTERFACE, ++ "GetSessionsForUser"); ++ if (message == NULL) { ++ gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message"); ++ goto out; ++ } ++ ++ dbus_message_iter_init_append (message, &iter); ++ dbus_message_iter_append_basic (&iter, ++ DBUS_TYPE_UINT32, ++ &pwent->pw_uid); ++ ++ dbus_error_init (&error); ++ reply = dbus_connection_send_with_reply_and_block (connection, ++ message, ++ -1, &error); ++ dbus_connection_flush (connection); ++ ++ if (dbus_error_is_set (&error)) { ++ gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); ++ goto out; ++ } ++ ++ if (reply == NULL) { ++ gdm_debug ("ConsoleKit: No reply for GetSessionsForUser"); ++ goto out; ++ } ++ ++ dbus_message_iter_init (reply, &iter_reply); ++ if (dbus_message_iter_get_arg_type (&iter_reply) != DBUS_TYPE_ARRAY) { ++ gdm_debug ("ConsoleKit: Wrong reply for GetSessionsForUser - expecting an array."); ++ goto out; ++ } ++ ++ dbus_message_iter_recurse (&iter_reply, &iter_array); ++ sessions = get_path_array_from_iter (&iter_array, NULL); ++ ++ out: ++ if (message != NULL) { ++ dbus_message_unref (message); ++ } ++ if (reply != NULL) { ++ dbus_message_unref (reply); + } + +- return res; ++ return sessions; + } + + void + unlock_ck_session (const char *user, + const char *x11_display) + { +- DBusGConnection *connection; +- DBusGProxy *proxy; +- GError *error; +- gboolean res; +- struct passwd *pwent; +- GPtrArray *sessions; +- int i; ++ DBusError error; ++ DBusConnection *connection; ++ char **sessions; ++ int i; + +- gdm_debug ("Unlocking ConsoleKit session for %s on %s", user, x11_display); ++ gdm_debug ("ConsoleKit: Unlocking session for %s on %s", user, x11_display); + +- error = NULL; +- connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); ++ dbus_error_init (&error); ++ connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { +- gdm_debug ("Failed to connect to the D-Bus daemon: %s", error->message); +- g_error_free (error); ++ gdm_debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); ++ dbus_error_free (&error); + return; + } + +- proxy = dbus_g_proxy_new_for_name (connection, +- CK_NAME, +- CK_MANAGER_PATH, +- CK_MANAGER_INTERFACE); +- if (proxy == NULL) { ++ sessions = get_sessions_for_user (connection, user, x11_display); ++ if (sessions == NULL || sessions[0] == NULL) { ++ gdm_debug ("ConsoleKit: no sessions found"); + return; + } + +- pwent = getpwnam (user); +- +- error = NULL; +- res = dbus_g_proxy_call (proxy, +- "GetSessionsForUser", +- &error, +- G_TYPE_UINT, +- pwent->pw_uid, +- G_TYPE_INVALID, +- dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), +- &sessions, +- G_TYPE_INVALID); +- if (! res) { +- g_warning ("Failed to get list of sessions: %s", error->message); +- g_error_free (error); +- goto out; +- } +- +- for (i = 0; i < sessions->len; i++) { +- char *ssid; +- DBusGProxy *session_proxy; +- +- ssid = g_ptr_array_index (sessions, i); +- +- session_proxy = dbus_g_proxy_new_for_name (connection, +- CK_NAME, +- ssid, +- CK_SESSION_INTERFACE); +- if (session_proxy != NULL) { +- char *xdisplay; +- +- get_string (session_proxy, "GetX11Display", &xdisplay); +- if (xdisplay != NULL +- && x11_display != NULL +- && strcmp (xdisplay, x11_display) == 0) { +- res = dbus_g_proxy_call (session_proxy, +- "Unlock", +- &error, +- G_TYPE_INVALID, +- G_TYPE_INVALID); +- if (! res) { +- g_warning ("Unable to unlock %s: %s", ssid, error->message); +- g_error_free (error); +- } ++ for (i = 0; sessions[i] != NULL; i++) { ++ char *ssid; ++ char *xdisplay; ++ ++ ssid = sessions[i]; ++ session_get_x11_display (connection, ssid, &xdisplay); ++ gdm_debug ("ConsoleKit: session %s has DISPLAY %s", ssid, xdisplay); ++ ++ if (xdisplay != NULL ++ && x11_display != NULL ++ && strcmp (xdisplay, x11_display) == 0) { ++ gboolean res; ++ ++ res = session_unlock (connection, ssid); ++ if (! res) { ++ gdm_error ("ConsoleKit: Unable to unlock %s", ssid); + } + } + +- g_object_unref (session_proxy); +- g_free (ssid); ++ g_free (xdisplay); + } + +- g_ptr_array_free (sessions, TRUE); +- +- out: +- g_object_unref (proxy); ++ g_strfreev (sessions); + } + + char * +@@ -221,70 +399,89 @@ open_ck_session (struct passwd *pwent, + GdmDisplay *d, + const char *session) + { +- DBusGConnection *connection; +- DBusGProxy *proxy; +- GError *error; +- gboolean res; +- char *cookie; +- GPtrArray *parameters; ++ DBusConnection *connection; ++ DBusError error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ DBusMessageIter iter; ++ DBusMessageIter iter_struct; ++ char *cookie; + + cookie = NULL; + +- gdm_debug ("Opening ConsoleKit session for %s", pwent->pw_name); ++ gdm_debug ("ConsoleKit: Opening session for %s", pwent->pw_name); ++ ++ dbus_error_init (&error); ++ connection = dbus_bus_get_private (DBUS_BUS_SYSTEM, &error); ++ private_connection = connection; + +- error = NULL; +- connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { +- gdm_debug ("Failed to connect to the D-Bus daemon: %s", error->message); +- g_error_free (error); ++ gdm_debug ("ConsoleKit: Failed to connect to the D-Bus daemon: %s", error.message); ++ dbus_error_free (&error); + return NULL; + } + +- proxy = dbus_g_proxy_new_for_name (connection, +- CK_NAME, +- CK_MANAGER_PATH, +- CK_MANAGER_INTERFACE); +- if (proxy == NULL) { ++ dbus_connection_set_exit_on_disconnect (connection, FALSE); ++ dbus_connection_setup_with_g_main (connection, NULL); ++ ++ dbus_error_init (&error); ++ message = dbus_message_new_method_call (CK_NAME, ++ CK_MANAGER_PATH, ++ CK_MANAGER_INTERFACE, ++ "OpenSessionWithParameters"); ++ if (message == NULL) { ++ gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return NULL; + } + +- parameters = g_ptr_array_sized_new (10); +- +- add_param_int (parameters, "user", pwent->pw_uid); +- add_param_string (parameters, "x11-display", d->name); +- add_param_string (parameters, "host-name", d->hostname); +- add_param_boolean (parameters, "is-local", d->attached); +- ++ dbus_message_iter_init_append (message, &iter); ++ dbus_message_iter_open_container (&iter, ++ DBUS_TYPE_ARRAY, ++ DBUS_STRUCT_BEGIN_CHAR_AS_STRING ++ DBUS_TYPE_STRING_AS_STRING ++ DBUS_TYPE_VARIANT_AS_STRING ++ DBUS_STRUCT_END_CHAR_AS_STRING, ++ &iter_struct); ++ ++ add_param_int (&iter_struct, "user", pwent->pw_uid); ++ add_param_string (&iter_struct, "x11-display", d->name); ++ add_param_string (&iter_struct, "host-name", d->hostname); ++ add_param_boolean (&iter_struct, "is-local", d->attached); + /* FIXME: this isn't really a reliable value to use */ +- add_param_string (parameters, "session-type", session); ++ add_param_string (&iter_struct, "session-type", session); + + if (d->vt > 0) { + char *device; + + /* FIXME: how does xorg construct this */ + device = g_strdup_printf ("/dev/tty%d", d->vt); +- add_param_string (parameters, "display-device", device); ++ add_param_string (&iter_struct, "display-device", device); + g_free (device); + } + +- error = NULL; +- res = dbus_g_proxy_call (proxy, +- "OpenSessionWithParameters", +- &error, +- CK_TYPE_PARAMETER_LIST, +- parameters, +- G_TYPE_INVALID, +- G_TYPE_STRING, +- &cookie, +- G_TYPE_INVALID); +- if (! res) { +- g_warning ("OpenSession failed: %s", error->message); +- g_error_free (error); ++ dbus_message_iter_close_container (&iter, &iter_struct); ++ ++ reply = dbus_connection_send_with_reply_and_block (connection, ++ message, ++ -1, &error); ++ if (dbus_error_is_set (&error)) { ++ gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); ++ reply = NULL; + } + +- g_object_unref (proxy); ++ dbus_connection_flush (connection); ++ ++ dbus_message_unref (message); ++ dbus_error_free (&error); + +- g_ptr_array_free (parameters, TRUE); ++ if (reply != NULL) { ++ const char *value; ++ ++ dbus_message_iter_init (reply, &iter); ++ dbus_message_iter_get_basic (&iter, &value); ++ cookie = g_strdup (value); ++ dbus_message_unref (reply); ++ } + + return cookie; + } +@@ -292,41 +489,47 @@ open_ck_session (struct passwd *pwent, + void + close_ck_session (const char *cookie) + { +- DBusGConnection *connection; +- DBusGProxy *proxy; +- GError *error; +- gboolean res; ++ DBusError error; ++ DBusMessage *message; ++ DBusMessage *reply; ++ DBusMessageIter iter; + +- g_return_if_fail (cookie != NULL); ++ if (cookie == NULL) { ++ return; ++ } + +- error = NULL; +- connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); +- if (connection == NULL) { +- gdm_debug ("Failed to connect to the D-Bus daemon: %s", error->message); +- g_error_free (error); ++ if (private_connection == NULL) { + return; + } + +- proxy = dbus_g_proxy_new_for_name (connection, +- CK_NAME, +- CK_MANAGER_PATH, +- CK_MANAGER_INTERFACE); +- if (proxy == NULL) { ++ dbus_error_init (&error); ++ message = dbus_message_new_method_call (CK_NAME, ++ CK_MANAGER_PATH, ++ CK_MANAGER_INTERFACE, ++ "CloseSession"); ++ if (message == NULL) { ++ gdm_debug ("ConsoleKit: Couldn't allocate the D-Bus message"); + return; + } + +- error = NULL; +- res = dbus_g_proxy_call (proxy, +- "CloseSession", +- &error, +- G_TYPE_STRING, +- &cookie, +- G_TYPE_INVALID, +- G_TYPE_INVALID); +- if (! res) { +- g_warning ("CloseSession failed: %s", error->message); +- g_error_free (error); ++ dbus_message_iter_init_append (message, &iter); ++ dbus_message_iter_append_basic (&iter, ++ DBUS_TYPE_STRING, ++ &cookie); ++ ++ reply = dbus_connection_send_with_reply_and_block (private_connection, ++ message, ++ -1, &error); ++ if (dbus_error_is_set (&error)) { ++ gdm_debug ("ConsoleKit: %s raised:\n %s\n\n", error.name, error.message); ++ reply = NULL; + } + +- g_object_unref (proxy); ++ dbus_connection_flush (private_connection); ++ ++ dbus_message_unref (message); ++ dbus_error_free (&error); ++ ++ dbus_connection_close (private_connection); ++ private_connection = NULL; + } diff --git a/gdm.spec b/gdm.spec index 25cbc97..9192454 100644 --- a/gdm.spec +++ b/gdm.spec @@ -16,7 +16,7 @@ Summary: The GNOME Display Manager Name: gdm Version: 2.17.6 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 1 License: LGPL/GPL Group: User Interface/X @@ -54,6 +54,9 @@ Patch28: gdm-2.17.1-desensitize-entry.patch # http://bugzilla.gnome.org/show_bug.cgi?id=335786 Patch30: gdm-2.17.6-username.patch +# http://bugzilla.gnome.org/show_bug.cgi?id=400793 +Patch31: gdm-2.17.6-consolekit.patch + BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Prereq: /usr/sbin/useradd @@ -126,6 +129,7 @@ several different X sessions on your local machine at the same time. %patch25 -p1 -b .indic-langs %patch28 -p1 -b .desensitize-entry %patch30 -p1 -b .username +%patch31 -p0 -b .consolekit %build cp -f %{SOURCE1} config/gdm @@ -315,6 +319,9 @@ fi %attr(1770, root, gdm) %dir %{_localstatedir}/gdm %changelog +* Sat Feb 10 2007 Matthias Clasen - 1:2.17.6-3 +- Fix a problem with the ConsoleKit support + * Tue Feb 6 2007 Matthias Clasen - 1:2.17.6-2 - Apply a patch to improve fast user switching experience