Blame SOURCES/fix-xdmcp.patch

f3033d
From 9b4d319e9bb89116ee883381912f53823d5b2234 Mon Sep 17 00:00:00 2001
f3033d
From: Ray Strode <rstrode@redhat.com>
f3033d
Date: Wed, 30 Oct 2013 13:30:40 -0400
f3033d
Subject: [PATCH 1/5] slave: don't run initial-setup on remote displays
f3033d
f3033d
GDM will run initial-setup if there are no configured user accounts
f3033d
on the system.  We correctly skip checking if there are configured user
f3033d
accounts on remote XDMCP displays, but incorrectly, still run initial-setup.
f3033d
f3033d
This commit makes sure we only every do any of the initial-setup logic
f3033d
in the local display code paths.
f3033d
---
f3033d
 daemon/gdm-simple-slave.c | 11 +++++++++++
f3033d
 1 file changed, 11 insertions(+)
f3033d
f3033d
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
f3033d
index 217c33b..bee6c37 100644
f3033d
--- a/daemon/gdm-simple-slave.c
f3033d
+++ b/daemon/gdm-simple-slave.c
f3033d
@@ -1285,60 +1285,71 @@ start_greeter (GdmSimpleSlave *slave)
f3033d
 {
f3033d
         start_launch_environment (slave, GDM_USERNAME, NULL);
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 start_initial_setup (GdmSimpleSlave *slave)
f3033d
 {
f3033d
         slave->priv->doing_initial_setup = TRUE;
f3033d
         start_launch_environment (slave, INITIAL_SETUP_USERNAME, "gnome-initial-setup");
f3033d
 }
f3033d
 
f3033d
 static gboolean
f3033d
 wants_autologin (GdmSimpleSlave *slave)
f3033d
 {
f3033d
         gboolean enabled = FALSE;
f3033d
         int delay = 0;
f3033d
         /* FIXME: handle wait-for-go */
f3033d
 
f3033d
         if (g_file_test (GDM_RAN_ONCE_MARKER_FILE, G_FILE_TEST_EXISTS)) {
f3033d
                 return FALSE;
f3033d
         }
f3033d
 
f3033d
         gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
f3033d
         return enabled && delay == 0;
f3033d
 }
f3033d
 
f3033d
 static gboolean
f3033d
 wants_initial_setup (GdmSimpleSlave *slave)
f3033d
 {
f3033d
         gboolean enabled = FALSE;
f3033d
+        gboolean display_is_local = FALSE;
f3033d
+
f3033d
+        g_object_get (G_OBJECT (slave),
f3033d
+                      "display-is-local", &display_is_local,
f3033d
+                      NULL);
f3033d
+
f3033d
+        /* don't run initial-setup on remote displays
f3033d
+         */
f3033d
+        if (!display_is_local) {
f3033d
+                return FALSE;
f3033d
+        }
f3033d
 
f3033d
         /* don't run if the system has existing users */
f3033d
         if (slave->priv->have_existing_user_accounts) {
f3033d
                 return FALSE;
f3033d
         }
f3033d
 
f3033d
         /* don't run if initial-setup is unavailable */
f3033d
         if (!can_create_environment ("gnome-initial-setup")) {
f3033d
                 return FALSE;
f3033d
         }
f3033d
 
f3033d
         if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) {
f3033d
                 return FALSE;
f3033d
         }
f3033d
 
f3033d
         return enabled;
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 setup_session (GdmSimpleSlave *slave)
f3033d
 {
f3033d
         if (wants_initial_setup (slave)) {
f3033d
                 start_initial_setup (slave);
f3033d
         } else if (wants_autologin (slave)) {
f3033d
                 /* Run the init script. gdmslave suspends until script has terminated */
f3033d
                 gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
f3033d
         } else {
f3033d
                 start_greeter (slave);
f3033d
         }
f3033d
         create_new_session (slave);
f3033d
-- 
f3033d
1.8.3.1
f3033d
f3033d
f3033d
From 29b3f4ea9c69deb3bac2edf76489fa42755d7cd2 Mon Sep 17 00:00:00 2001
f3033d
From: Ray Strode <rstrode@redhat.com>
f3033d
Date: Thu, 31 Oct 2013 14:57:04 -0400
f3033d
Subject: [PATCH 2/5] slave: don't kill slave when client disconnects
f3033d
f3033d
Right now we stop the slave if a greeter running on a remote
f3033d
X server exits. This is wrong, since the greeter will exit as
f3033d
part of the login screen process.  We already have mechanisms in
f3033d
place to reap the slave at the appropriate time, so stopping the
f3033d
slave on disconnection is totally unneeded and actively harmful.
f3033d
f3033d
This commit drops that code.
f3033d
---
f3033d
 daemon/gdm-simple-slave.c | 10 ----------
f3033d
 1 file changed, 10 deletions(-)
f3033d
f3033d
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
f3033d
index bee6c37..35951c7 100644
f3033d
--- a/daemon/gdm-simple-slave.c
f3033d
+++ b/daemon/gdm-simple-slave.c
f3033d
@@ -816,71 +816,61 @@ on_session_client_connected (GdmSession          *session,
f3033d
                                                          (GDestroyNotify)
f3033d
                                                          g_object_unref);
f3033d
                 g_cancellable_connect (cancellable,
f3033d
                                        G_CALLBACK (g_source_remove),
f3033d
                                        GINT_TO_POINTER (timeout_id),
f3033d
                                        NULL);
f3033d
 
f3033d
                 g_object_weak_ref (G_OBJECT (session),
f3033d
                                    (GWeakNotify)
f3033d
                                    g_cancellable_cancel,
f3033d
                                    cancellable);
f3033d
                 g_object_weak_ref (G_OBJECT (session),
f3033d
                                    (GWeakNotify)
f3033d
                                    g_object_unref,
f3033d
                                    cancellable);
f3033d
                 g_object_weak_ref (G_OBJECT (session),
f3033d
                                    (GWeakNotify)
f3033d
                                    g_free,
f3033d
                                    source_tag);
f3033d
         }
f3033d
 
f3033d
         g_free (username);
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 on_session_client_disconnected (GdmSession          *session,
f3033d
                                 GCredentials        *credentials,
f3033d
                                 GPid                 pid_of_client,
f3033d
                                 GdmSimpleSlave      *slave)
f3033d
 {
f3033d
-        gboolean display_is_local;
f3033d
-
f3033d
         g_debug ("GdmSimpleSlave: client disconnected");
f3033d
-
f3033d
-        g_object_get (slave,
f3033d
-                      "display-is-local", &display_is_local,
f3033d
-                      NULL);
f3033d
-
f3033d
-        if ( ! display_is_local && !slave->priv->session_is_running) {
f3033d
-                gdm_slave_stop (GDM_SLAVE (slave));
f3033d
-        }
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 on_session_cancelled (GdmSession      *session,
f3033d
                       GdmSimpleSlave  *slave)
f3033d
 {
f3033d
         g_debug ("GdmSimpleSlave: Session was cancelled");
f3033d
         queue_greeter_reset (slave);
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 touch_marker_file (GdmSimpleSlave *slave)
f3033d
 {
f3033d
         int fd;
f3033d
 
f3033d
         fd = g_creat (GDM_RAN_ONCE_MARKER_FILE, 0644);
f3033d
 
f3033d
         if (fd < 0 && errno != EEXIST) {
f3033d
                 g_warning ("could not create %s to mark run, this may cause auto login "
f3033d
                            "to repeat: %m", GDM_RAN_ONCE_MARKER_FILE);
f3033d
                 return;
f3033d
         }
f3033d
 
f3033d
         fsync (fd);
f3033d
         close (fd);
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 create_new_session (GdmSimpleSlave  *slave)
f3033d
 {
f3033d
-- 
f3033d
1.8.3.1
f3033d
f3033d
f3033d
From 0c6811cc358fa1e5ff22fe3ec656c351ab94a899 Mon Sep 17 00:00:00 2001
f3033d
From: Ray Strode <rstrode@redhat.com>
f3033d
Date: Thu, 31 Oct 2013 15:00:26 -0400
f3033d
Subject: [PATCH 3/5] manager: return ACCESS DENIED for most
f3033d
 open-reauth-channel failures
f3033d
f3033d
gnome-shell only falls back to opening a new session if the reauth
f3033d
channel fails to open because of denied access.  For XDMCP we currently
f3033d
fail for other reasons.
f3033d
f3033d
This commit returns ACCESS DENIED for those cases as well, so the
f3033d
intended fallback happens.
f3033d
---
f3033d
 daemon/gdm-manager.c | 34 ++++++++++++++++++++++++++++------
f3033d
 1 file changed, 28 insertions(+), 6 deletions(-)
f3033d
f3033d
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
f3033d
index 74c6888..eef7233 100644
f3033d
--- a/daemon/gdm-manager.c
f3033d
+++ b/daemon/gdm-manager.c
f3033d
@@ -698,90 +698,112 @@ gdm_manager_handle_open_session (GdmDBusManager        *manager,
f3033d
                                                 address);
f3033d
         g_free (address);
f3033d
 
f3033d
         return TRUE;
f3033d
 }
f3033d
 
f3033d
 static gboolean
f3033d
 gdm_manager_handle_open_reauthentication_channel (GdmDBusManager        *manager,
f3033d
                                                   GDBusMethodInvocation *invocation,
f3033d
                                                   const char            *username)
f3033d
 {
f3033d
         GdmManager       *self = GDM_MANAGER (manager);
f3033d
         GDBusConnection  *connection;
f3033d
         GdmDisplay       *display;
f3033d
         const char       *sender;
f3033d
         char             *seat_id;
f3033d
         char             *session_id = NULL;
f3033d
         GError           *error;
f3033d
         char             *address;
f3033d
         int               ret;
f3033d
         GPid              pid;
f3033d
         uid_t             caller_uid;
f3033d
 
f3033d
         g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
f3033d
 
f3033d
         sender = g_dbus_method_invocation_get_sender (invocation);
f3033d
         error = NULL;
f3033d
         ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
f3033d
 
f3033d
         if (!ret) {
f3033d
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
+                g_debug ("GdmManager: could not get pid of caller: %s",
f3033d
+                         error->message);
f3033d
                 g_error_free (error);
f3033d
+
f3033d
+                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
+                                                               G_DBUS_ERROR,
f3033d
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
+                                                               "Error getting process id of caller");
f3033d
                 return TRUE;
f3033d
 
f3033d
         }
f3033d
 
f3033d
         ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
f3033d
 
f3033d
         if (!ret) {
f3033d
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
+                g_debug ("GdmManager: could not get uid of caller: %s",
f3033d
+                         error->message);
f3033d
                 g_error_free (error);
f3033d
+
f3033d
+                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
+                                                               G_DBUS_ERROR,
f3033d
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
+                                                               "Error getting user id of caller");
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
         connection = g_dbus_method_invocation_get_connection (invocation);
f3033d
 
f3033d
         seat_id = get_seat_id_for_pid (connection, pid, &error);
f3033d
 
f3033d
         if (seat_id == NULL) {
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
+                g_debug ("GdmManager: could not get seat id of caller: %s",
f3033d
+                         error->message);
f3033d
                 g_error_free (error);
f3033d
+
f3033d
+                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
+                                                               G_DBUS_ERROR,
f3033d
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
+                                                               "Error getting seat id of caller");
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
         session_id = get_session_id_for_user_on_seat (connection, username, seat_id, &error);
f3033d
         if (session_id == NULL) {
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
+                g_debug ("GdmManager: could not get session id for caller: %s",
f3033d
+                         error->message);
f3033d
                 g_error_free (error);
f3033d
+
f3033d
+                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
+                                                               G_DBUS_ERROR,
f3033d
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
+                                                               "Error getting session id for caller");
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
         display = gdm_display_store_find (self->priv->display_store,
f3033d
                                           lookup_by_session_id,
f3033d
                                           (gpointer) session_id);
f3033d
         g_free (session_id);
f3033d
 
f3033d
         if (display == NULL) {
f3033d
                 g_dbus_method_invocation_return_error_literal (invocation,
f3033d
                                                                G_DBUS_ERROR,
f3033d
                                                                G_DBUS_ERROR_ACCESS_DENIED,
f3033d
                                                                _("No session available"));
f3033d
 
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
         address = gdm_display_open_reauthentication_channel_sync (display,
f3033d
                                                                   username,
f3033d
                                                                   pid,
f3033d
                                                                   caller_uid,
f3033d
                                                                   NULL,
f3033d
                                                                   &error);
f3033d
 
f3033d
         if (address == NULL) {
f3033d
                 g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
                 g_error_free (error);
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
-- 
f3033d
1.8.3.1
f3033d
f3033d
f3033d
From c4472c5e07b5d4e35a7a0c797ba96c882d97feb7 Mon Sep 17 00:00:00 2001
f3033d
From: Ray Strode <rstrode@redhat.com>
f3033d
Date: Fri, 1 Nov 2013 12:40:10 -0400
f3033d
Subject: [PATCH 4/5] daemon: don't require seat to locate reauth channel
f3033d
f3033d
With systemd, XDMCP sessions don't have associated seats.
f3033d
Currently, reauth channels find the session by first looking up
f3033d
the seat, which means unlocking fails for XDMCP.
f3033d
f3033d
This commit changes the code to determine session strictly from pid.
f3033d
---
f3033d
 daemon/gdm-manager.c | 503 +++++++--------------------------------------------
f3033d
 1 file changed, 61 insertions(+), 442 deletions(-)
f3033d
f3033d
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
f3033d
index eef7233..6c0fe1d 100644
f3033d
--- a/daemon/gdm-manager.c
f3033d
+++ b/daemon/gdm-manager.c
f3033d
@@ -226,605 +226,224 @@ get_uid_for_consolekit_session_id (GDBusConnection  *connection,
f3033d
         }
f3033d
 
f3033d
         g_variant_get (reply, "(u)", &uid);
f3033d
         g_variant_unref (reply);
f3033d
 
f3033d
         *out_uid = (uid_t) uid;
f3033d
 
f3033d
         return TRUE;
f3033d
 }
f3033d
 #endif
f3033d
 
f3033d
 static gboolean
f3033d
 get_uid_for_session_id (GDBusConnection  *connection,
f3033d
                         const char       *session_id,
f3033d
                         uid_t            *uid,
f3033d
                         GError          **error)
f3033d
 {
f3033d
 #ifdef WITH_SYSTEMD
f3033d
         if (LOGIND_RUNNING()) {
f3033d
                 return get_uid_for_systemd_session_id (session_id, uid, error);
f3033d
         }
f3033d
 #endif
f3033d
 
f3033d
 #ifdef WITH_CONSOLE_KIT
f3033d
         return get_uid_for_consolekit_session_id (connection, session_id, uid, error);
f3033d
 #endif
f3033d
 
f3033d
         return FALSE;
f3033d
 }
f3033d
 
f3033d
-#ifdef WITH_SYSTEMD
f3033d
-static char *
f3033d
-get_session_id_for_user_on_seat_systemd (const char  *username,
f3033d
-                                         const char  *seat,
f3033d
-                                         GError     **error)
f3033d
-{
f3033d
-        struct passwd  *pwent;
f3033d
-        uid_t           uid;
f3033d
-        int             i;
f3033d
-        char          **sessions;
f3033d
-        char           *session = NULL;
f3033d
-        int             ret;
f3033d
-
f3033d
-        pwent = NULL;
f3033d
-        gdm_get_pwent_for_name (username, &pwent);
f3033d
-
f3033d
-        if (pwent == NULL) {
f3033d
-                g_set_error (error,
f3033d
-                             G_DBUS_ERROR,
f3033d
-                             G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                             _("Unable to look up UID of user %s"),
f3033d
-                             username);
f3033d
-                return NULL;
f3033d
-        }
f3033d
-
f3033d
-        uid = pwent->pw_uid;
f3033d
-
f3033d
-        session = NULL;
f3033d
-        ret = sd_seat_get_sessions (seat, &sessions, NULL, NULL);
f3033d
-        if (ret < 0 || sessions == NULL) {
f3033d
-                g_set_error (error,
f3033d
-                             G_DBUS_ERROR,
f3033d
-                             G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                             "Error getting session ids from systemd: %s",
f3033d
-                             ret < 0? g_strerror (-ret) : _("no sessions available"));
f3033d
-                return NULL;
f3033d
-        }
f3033d
-
f3033d
-        for (i = 0; sessions[i] != NULL; i++) {
f3033d
-                char     *type;
f3033d
-                char     *state;
f3033d
-                gboolean  is_closing;
f3033d
-                gboolean  is_x11;
f3033d
-                uid_t     session_uid;
f3033d
-
f3033d
-                ret = sd_session_get_uid (sessions[i], &session_uid);
f3033d
-
f3033d
-                if (ret < 0) {
f3033d
-                        g_warning ("GdmManager: could not fetch uid of session '%s': %s",
f3033d
-                                   sessions[i], strerror (-ret));
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                if (uid != session_uid) {
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                ret = sd_session_get_type (sessions[i], &type);
f3033d
-
f3033d
-                if (ret < 0) {
f3033d
-                        g_warning ("GdmManager: could not fetch type of session '%s': %s",
f3033d
-                                   sessions[i], strerror (-ret));
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                is_x11 = g_strcmp0 (type, "x11") == 0;
f3033d
-                free (type);
f3033d
-
f3033d
-                if (!is_x11) {
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                ret = sd_session_get_state (sessions[i], &state);
f3033d
-                if (ret < 0) {
f3033d
-                        g_warning ("GdmManager: could not fetch state of session '%s': %s",
f3033d
-                                   sessions[i], strerror (-ret));
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                is_closing = g_strcmp0 (state, "closing") == 0;
f3033d
-
f3033d
-                if (is_closing) {
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                session = g_strdup (sessions[i]);
f3033d
-                break;
f3033d
-
f3033d
-        }
f3033d
-
f3033d
-        if (session == NULL) {
f3033d
-                g_debug ("GdmManager: There are no applicable sessions (%d looked at)", i);
f3033d
-                g_set_error (error,
f3033d
-                             G_DBUS_ERROR,
f3033d
-                             G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                             _("No sessions for %s available for reauthentication"),
f3033d
-                             username);
f3033d
-                return NULL;
f3033d
-        }
f3033d
-
f3033d
-        g_debug ("GdmManager: session %s is available for reauthentication", session);
f3033d
-
f3033d
-        return session;
f3033d
-}
f3033d
-#endif
f3033d
-
f3033d
-#ifdef WITH_CONSOLE_KIT
f3033d
-static char *
f3033d
-get_session_id_for_user_on_seat_consolekit (GDBusConnection  *connection,
f3033d
-                                            const char       *username,
f3033d
-                                            const char       *seat,
f3033d
-                                            GError          **error)
f3033d
-{
f3033d
-        GVariant       *reply;
f3033d
-        const gchar   **sessions;
f3033d
-        char           *session = NULL;
f3033d
-        struct passwd  *pwent;
f3033d
-        uid_t           uid;
f3033d
-        int             i;
f3033d
-
f3033d
-        pwent = NULL;
f3033d
-        gdm_get_pwent_for_name (username, &pwent);
f3033d
-
f3033d
-        if (pwent == NULL) {
f3033d
-                g_set_error (error,
f3033d
-                             G_DBUS_ERROR,
f3033d
-                             G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                             _("Unable to look up UID of user %s"),
f3033d
-                             username);
f3033d
-                return NULL;
f3033d
-        }
f3033d
-
f3033d
-        uid = pwent->pw_uid;
f3033d
-
f3033d
-        reply = g_dbus_connection_call_sync (connection,
f3033d
-                                             "org.freedesktop.ConsoleKit",
f3033d
-                                             "/org/freedesktop/ConsoleKit/Manager",
f3033d
-                                             "org.freedesktop.ConsoleKit.Manager",
f3033d
-                                             "GetSessionsForUnixUser",
f3033d
-                                             g_variant_new ("(u)", (guint32) uid),
f3033d
-                                             G_VARIANT_TYPE ("(ao)"),
f3033d
-                                             G_DBUS_CALL_FLAGS_NONE,
f3033d
-                                             -1,
f3033d
-                                             NULL,
f3033d
-                                             error);
f3033d
-        if (reply == NULL) {
f3033d
-                g_set_error (error,
f3033d
-                             G_DBUS_ERROR,
f3033d
-                             G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                             _("Unable to find session for user %s"),
f3033d
-                             username);
f3033d
-                return NULL;
f3033d
-        }
f3033d
-
f3033d
-        g_variant_get_child (reply, 0, "^a&o", &sessions);
f3033d
-        for (i = 0; sessions[i] != NULL; i++) {
f3033d
-                GVariant *reply2;
f3033d
-                GError   *error2 = NULL;
f3033d
-                gchar    *display;
f3033d
-                gchar    *session_seat_id;
f3033d
-
f3033d
-                reply2 = g_dbus_connection_call_sync (connection,
f3033d
-                                                     "org.freedesktop.ConsoleKit",
f3033d
-                                                     sessions[i],
f3033d
-                                                     "org.freedesktop.ConsoleKit.Session",
f3033d
-                                                     "GetSeatId",
f3033d
-                                                     NULL,
f3033d
-                                                     G_VARIANT_TYPE ("(o)"),
f3033d
-                                                     G_DBUS_CALL_FLAGS_NONE,
f3033d
-                                                     -1,
f3033d
-                                                     NULL,
f3033d
-                                                     &error2);
f3033d
-                if (reply2 == NULL) {
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                g_variant_get (reply2, "(o)", &session_seat_id);
f3033d
-                g_variant_unref (reply2);
f3033d
-
f3033d
-                if (g_strcmp0 (seat, session_seat_id) != 0) {
f3033d
-                        g_free (session_seat_id);
f3033d
-                        continue;
f3033d
-                }
f3033d
-                g_free (session_seat_id);
f3033d
-
f3033d
-                reply2 = g_dbus_connection_call_sync (connection,
f3033d
-                                                     "org.freedesktop.ConsoleKit",
f3033d
-                                                     sessions[i],
f3033d
-                                                     "org.freedesktop.ConsoleKit.Session",
f3033d
-                                                     "GetX11DisplayDevice",
f3033d
-                                                     NULL,
f3033d
-                                                     G_VARIANT_TYPE ("(s)"),
f3033d
-                                                     G_DBUS_CALL_FLAGS_NONE,
f3033d
-                                                     -1,
f3033d
-                                                     NULL,
f3033d
-                                                     &error2);
f3033d
-                if (reply2 == NULL) {
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                g_variant_get (reply2, "(s)", &display);
f3033d
-                g_variant_unref (reply2);
f3033d
-
f3033d
-                if (display[0] == '\0') {
f3033d
-                        g_free (display);
f3033d
-                        continue;
f3033d
-                }
f3033d
-
f3033d
-                session = g_strdup (sessions[i]);
f3033d
-                break;
f3033d
-
f3033d
-        }
f3033d
-        g_free (sessions);
f3033d
-        g_variant_unref (reply);
f3033d
-
f3033d
-        if (session == NULL) {
f3033d
-                g_set_error (error,
f3033d
-                             G_DBUS_ERROR,
f3033d
-                             G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                             _("Unable to find appropriate session for user %s"),
f3033d
-                             username);
f3033d
-        }
f3033d
-        return session;
f3033d
-}
f3033d
-#endif
f3033d
-
f3033d
-static char *
f3033d
-get_session_id_for_user_on_seat (GDBusConnection  *connection,
f3033d
-                                 const char       *username,
f3033d
-                                 const char       *seat,
f3033d
-                                 GError          **error)
f3033d
-{
f3033d
-#ifdef WITH_SYSTEMD
f3033d
-        if (LOGIND_RUNNING()) {
f3033d
-                return get_session_id_for_user_on_seat_systemd (username, seat, error);
f3033d
-        }
f3033d
-#endif
f3033d
-
f3033d
-#ifdef WITH_CONSOLE_KIT
f3033d
-        return get_session_id_for_user_on_seat_consolekit (connection, username, seat, error);
f3033d
-#endif
f3033d
-
f3033d
-        return NULL;
f3033d
-}
f3033d
-
f3033d
 static gboolean
f3033d
 lookup_by_session_id (const char *id,
f3033d
                       GdmDisplay *display,
f3033d
                       gpointer    user_data)
f3033d
 {
f3033d
         const char *looking_for = user_data;
f3033d
         char *current;
f3033d
         gboolean res;
f3033d
 
f3033d
         current = gdm_display_get_session_id (display);
f3033d
 
f3033d
         res = g_strcmp0 (current, looking_for) == 0;
f3033d
 
f3033d
         g_free (current);
f3033d
 
f3033d
         return res;
f3033d
 }
f3033d
 
f3033d
-#ifdef WITH_SYSTEMD
f3033d
-static char *
f3033d
-get_seat_id_for_pid_systemd (pid_t    pid,
f3033d
-                             GError **error)
f3033d
+static GdmDisplay *
f3033d
+get_display_and_details_for_bus_sender (GdmManager       *self,
f3033d
+                            GDBusConnection  *connection,
f3033d
+                            const char       *sender,
f3033d
+                            GPid             *out_pid,
f3033d
+                            uid_t            *out_uid)
f3033d
 {
f3033d
-        char *session;
f3033d
-        char *seat, *gseat;
f3033d
-        int ret;
f3033d
+        GdmDisplay *display = NULL;
f3033d
+        char       *session_id = NULL;
f3033d
+        GError     *error = NULL;
f3033d
+        int         ret;
f3033d
+        GPid        pid;
f3033d
+        uid_t       caller_uid, session_uid;
f3033d
 
f3033d
-        session = get_session_id_for_pid_systemd (pid, error);
f3033d
+        ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
f3033d
 
f3033d
-        if (session == NULL) {
f3033d
-                return NULL;
f3033d
+        if (!ret) {
f3033d
+                g_debug ("GdmManager: Error while retrieving pid for sender: %s",
f3033d
+                         error->message);
f3033d
+                g_error_free (error);
f3033d
+                goto out;
f3033d
         }
f3033d
 
f3033d
-        seat = NULL;
f3033d
-        ret = sd_session_get_seat (session, &seat;;
f3033d
-        free (session);
f3033d
+        ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
f3033d
 
f3033d
-        if (ret < 0) {
f3033d
-                g_set_error (error,
f3033d
-                             GDM_DISPLAY_ERROR,
f3033d
-                             GDM_DISPLAY_ERROR_GETTING_SESSION_INFO,
f3033d
-                             "Error getting seat id from systemd: %s",
f3033d
-                             g_strerror (-ret));
f3033d
-                return NULL;
f3033d
+        if (!ret) {
f3033d
+                g_debug ("GdmManager: Error while retrieving uid for sender: %s",
f3033d
+                         error->message);
f3033d
+                g_error_free (error);
f3033d
+                goto out;
f3033d
         }
f3033d
 
f3033d
-        if (seat != NULL) {
f3033d
-                gseat = g_strdup (seat);
f3033d
-                free (seat);
f3033d
+        session_id = get_session_id_for_pid (connection, pid, &error);
f3033d
 
f3033d
-                return gseat;
f3033d
-        } else {
f3033d
-                return NULL;
f3033d
+        if (session_id == NULL) {
f3033d
+                g_debug ("GdmManager: Error while retrieving session id for sender: %s",
f3033d
+                         error->message);
f3033d
+                g_error_free (error);
f3033d
+                goto out;
f3033d
         }
f3033d
-}
f3033d
-#endif
f3033d
-
f3033d
-#ifdef WITH_CONSOLE_KIT
f3033d
-static char *
f3033d
-get_seat_id_for_pid_consolekit (GDBusConnection  *connection,
f3033d
-                                pid_t             pid,
f3033d
-                                GError          **error)
f3033d
-{
f3033d
-        char *session;
f3033d
-        GVariant *reply;
f3033d
-        char *retval;
f3033d
 
f3033d
-        session = get_session_id_for_pid_consolekit (connection, pid, error);
f3033d
-
f3033d
-        if (session == NULL) {
f3033d
-                return NULL;
f3033d
+        if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
f3033d
+                g_debug ("GdmManager: Error while retrieving uid for session: %s",
f3033d
+                         error->message);
f3033d
+                g_error_free (error);
f3033d
+                goto out;
f3033d
         }
f3033d
 
f3033d
-        reply = g_dbus_connection_call_sync (connection,
f3033d
-                                             "org.freedesktop.ConsoleKit",
f3033d
-                                             session,
f3033d
-                                             "org.freedesktop.ConsoleKit.Session",
f3033d
-                                             "GetSeatId",
f3033d
-                                             NULL,
f3033d
-                                             G_VARIANT_TYPE ("(o)"),
f3033d
-                                             G_DBUS_CALL_FLAGS_NONE,
f3033d
-                                             -1,
f3033d
-                                             NULL, error);
f3033d
-        g_free (session);
f3033d
-
f3033d
-        if (reply == NULL) {
f3033d
-                return NULL;
f3033d
+        if (caller_uid != session_uid) {
f3033d
+                g_debug ("GdmManager: uid for sender and uid for session don't match");
f3033d
+                goto out;
f3033d
         }
f3033d
 
f3033d
-        g_variant_get (reply, "(o)", &retval);
f3033d
-        g_variant_unref (reply);
f3033d
+        display = gdm_display_store_find (self->priv->display_store,
f3033d
+                                          lookup_by_session_id,
f3033d
+                                          (gpointer) session_id);
f3033d
+out:
f3033d
+        g_free (session_id);
f3033d
 
f3033d
-        return retval;
f3033d
-}
f3033d
-#endif
f3033d
+        if (display != NULL) {
f3033d
+            if (out_pid != NULL)
f3033d
+                *out_pid = pid;
f3033d
 
f3033d
-static char *
f3033d
-get_seat_id_for_pid (GDBusConnection  *connection,
f3033d
-                     pid_t             pid,
f3033d
-                     GError          **error)
f3033d
-{
f3033d
-#ifdef WITH_SYSTEMD
f3033d
-        if (LOGIND_RUNNING()) {
f3033d
-                return get_seat_id_for_pid_systemd (pid, error);
f3033d
+            if (out_uid != NULL)
f3033d
+                *out_uid = session_uid;
f3033d
         }
f3033d
-#endif
f3033d
-
f3033d
-#ifdef WITH_CONSOLE_KIT
f3033d
-        return get_seat_id_for_pid_consolekit (connection, pid, error);
f3033d
-#endif
f3033d
-
f3033d
-        return NULL;
f3033d
+        return display;
f3033d
 }
f3033d
 
f3033d
 static gboolean
f3033d
 gdm_manager_handle_open_session (GdmDBusManager        *manager,
f3033d
                                  GDBusMethodInvocation *invocation)
f3033d
 {
f3033d
         GdmManager       *self = GDM_MANAGER (manager);
f3033d
+        const char       *sender = NULL;
f3033d
+        GError           *error = NULL;
f3033d
         GDBusConnection  *connection;
f3033d
         GdmDisplay       *display;
f3033d
-        const char       *sender;
f3033d
-        char             *session_id;
f3033d
-        GError           *error;
f3033d
         char             *address;
f3033d
-        int               ret;
f3033d
         GPid              pid;
f3033d
-        uid_t             caller_uid, session_uid;
f3033d
+        uid_t             uid;
f3033d
 
f3033d
-        sender = g_dbus_method_invocation_get_sender (invocation);
f3033d
-        error = NULL;
f3033d
-        ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
f3033d
-
f3033d
-        if (!ret) {
f3033d
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
-                g_error_free (error);
f3033d
-                return TRUE;
f3033d
-        }
f3033d
-
f3033d
-        ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
f3033d
-
f3033d
-        if (!ret) {
f3033d
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
-                g_error_free (error);
f3033d
-                return TRUE;
f3033d
-        }
f3033d
+        g_debug ("GdmManager: trying to open new session");
f3033d
 
f3033d
+        sender = g_dbus_method_invocation_get_sender (invocation);
f3033d
         connection = g_dbus_method_invocation_get_connection (invocation);
f3033d
-        session_id = get_session_id_for_pid (connection, pid, &error);
f3033d
-
f3033d
-        if (session_id == NULL) {
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
-                g_error_free (error);
f3033d
-                return TRUE;
f3033d
-        }
f3033d
-
f3033d
-        if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
f3033d
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
f3033d
-                g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
-                g_error_free (error);
f3033d
-                return TRUE;
f3033d
-        }
f3033d
-
f3033d
-        if (caller_uid != session_uid) {
f3033d
-                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
-                                                               G_DBUS_ERROR,
f3033d
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                                                               _("User doesn't own session"));
f3033d
-                return TRUE;
f3033d
-        }
f3033d
-
f3033d
-        display = gdm_display_store_find (self->priv->display_store,
f3033d
-                                          lookup_by_session_id,
f3033d
-                                          (gpointer) session_id);
f3033d
-        g_free (session_id);
f3033d
+        display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid);
f3033d
 
f3033d
         if (display == NULL) {
f3033d
                 g_dbus_method_invocation_return_error_literal (invocation,
f3033d
                                                                G_DBUS_ERROR,
f3033d
                                                                G_DBUS_ERROR_ACCESS_DENIED,
f3033d
                                                                _("No session available"));
f3033d
 
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
-        address = gdm_display_open_session_sync (display, pid, session_uid, NULL, &error);
f3033d
+        address = gdm_display_open_session_sync (display, pid, uid, NULL, &error);
f3033d
 
f3033d
         if (address == NULL) {
f3033d
                 g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
                 g_error_free (error);
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
         gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager),
f3033d
                                                 invocation,
f3033d
                                                 address);
f3033d
         g_free (address);
f3033d
 
f3033d
         return TRUE;
f3033d
 }
f3033d
 
f3033d
 static gboolean
f3033d
 gdm_manager_handle_open_reauthentication_channel (GdmDBusManager        *manager,
f3033d
                                                   GDBusMethodInvocation *invocation,
f3033d
                                                   const char            *username)
f3033d
 {
f3033d
         GdmManager       *self = GDM_MANAGER (manager);
f3033d
+        const char       *sender = NULL;
f3033d
+        GError           *error = NULL;
f3033d
         GDBusConnection  *connection;
f3033d
         GdmDisplay       *display;
f3033d
-        const char       *sender;
f3033d
-        char             *seat_id;
f3033d
-        char             *session_id = NULL;
f3033d
-        GError           *error;
f3033d
         char             *address;
f3033d
-        int               ret;
f3033d
         GPid              pid;
f3033d
-        uid_t             caller_uid;
f3033d
+        uid_t             uid;
f3033d
 
f3033d
         g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
f3033d
 
f3033d
         sender = g_dbus_method_invocation_get_sender (invocation);
f3033d
-        error = NULL;
f3033d
-        ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
f3033d
-
f3033d
-        if (!ret) {
f3033d
-                g_debug ("GdmManager: could not get pid of caller: %s",
f3033d
-                         error->message);
f3033d
-                g_error_free (error);
f3033d
-
f3033d
-                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
-                                                               G_DBUS_ERROR,
f3033d
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                                                               "Error getting process id of caller");
f3033d
-                return TRUE;
f3033d
-
f3033d
-        }
f3033d
-
f3033d
-        ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
f3033d
-
f3033d
-        if (!ret) {
f3033d
-                g_debug ("GdmManager: could not get uid of caller: %s",
f3033d
-                         error->message);
f3033d
-                g_error_free (error);
f3033d
-
f3033d
-                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
-                                                               G_DBUS_ERROR,
f3033d
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                                                               "Error getting user id of caller");
f3033d
-                return TRUE;
f3033d
-        }
f3033d
-
f3033d
         connection = g_dbus_method_invocation_get_connection (invocation);
f3033d
-
f3033d
-        seat_id = get_seat_id_for_pid (connection, pid, &error);
f3033d
-
f3033d
-        if (seat_id == NULL) {
f3033d
-                g_debug ("GdmManager: could not get seat id of caller: %s",
f3033d
-                         error->message);
f3033d
-                g_error_free (error);
f3033d
-
f3033d
-                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
-                                                               G_DBUS_ERROR,
f3033d
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                                                               "Error getting seat id of caller");
f3033d
-                return TRUE;
f3033d
-        }
f3033d
-
f3033d
-        session_id = get_session_id_for_user_on_seat (connection, username, seat_id, &error);
f3033d
-        if (session_id == NULL) {
f3033d
-                g_debug ("GdmManager: could not get session id for caller: %s",
f3033d
-                         error->message);
f3033d
-                g_error_free (error);
f3033d
-
f3033d
-                g_dbus_method_invocation_return_error_literal (invocation,
f3033d
-                                                               G_DBUS_ERROR,
f3033d
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
f3033d
-                                                               "Error getting session id for caller");
f3033d
-                return TRUE;
f3033d
-        }
f3033d
-
f3033d
-        display = gdm_display_store_find (self->priv->display_store,
f3033d
-                                          lookup_by_session_id,
f3033d
-                                          (gpointer) session_id);
f3033d
-        g_free (session_id);
f3033d
+        display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid);
f3033d
 
f3033d
         if (display == NULL) {
f3033d
                 g_dbus_method_invocation_return_error_literal (invocation,
f3033d
                                                                G_DBUS_ERROR,
f3033d
                                                                G_DBUS_ERROR_ACCESS_DENIED,
f3033d
                                                                _("No session available"));
f3033d
 
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
         address = gdm_display_open_reauthentication_channel_sync (display,
f3033d
                                                                   username,
f3033d
                                                                   pid,
f3033d
-                                                                  caller_uid,
f3033d
+                                                                  uid,
f3033d
                                                                   NULL,
f3033d
                                                                   &error);
f3033d
 
f3033d
         if (address == NULL) {
f3033d
                 g_dbus_method_invocation_return_gerror (invocation, error);
f3033d
                 g_error_free (error);
f3033d
                 return TRUE;
f3033d
         }
f3033d
 
f3033d
         gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
f3033d
                                                                  invocation,
f3033d
                                                                  address);
f3033d
         g_free (address);
f3033d
 
f3033d
         return TRUE;
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 manager_interface_init (GdmDBusManagerIface *interface)
f3033d
 {
f3033d
         interface->handle_open_session = gdm_manager_handle_open_session;
f3033d
         interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel;
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 on_display_removed (GdmDisplayStore *display_store,
f3033d
                     const char      *id,
f3033d
                     GdmManager      *manager)
f3033d
 {
f3033d
         GdmDisplay *display;
f3033d
-- 
f3033d
1.8.3.1
f3033d
f3033d
f3033d
From d70697ff1b6e987c7437fb1a9a8459626bc5358d Mon Sep 17 00:00:00 2001
f3033d
From: Ray Strode <rstrode@redhat.com>
f3033d
Date: Fri, 1 Nov 2013 15:27:14 -0400
f3033d
Subject: [PATCH 5/5] slave: Pass session id to unlocking code if we know it
f3033d
f3033d
We currently figure out which session to unlock on-the-fly based on
f3033d
the username that was just reauthenticated.  This doesn't work, for
f3033d
XDMCP sessions, under logind, since they don't have a seat. There's
f3033d
no reason to try to deduce the session, though.  We already know it,
f3033d
so we might as well pass it down.
f3033d
f3033d
This fixes unlocking for XDMCP.
f3033d
---
f3033d
 daemon/gdm-simple-slave.c |  5 ++++-
f3033d
 daemon/gdm-slave.c        | 13 +++++++++----
f3033d
 daemon/gdm-slave.h        |  1 +
f3033d
 3 files changed, 14 insertions(+), 5 deletions(-)
f3033d
f3033d
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
f3033d
index 35951c7..1fe58bc 100644
f3033d
--- a/daemon/gdm-simple-slave.c
f3033d
+++ b/daemon/gdm-simple-slave.c
f3033d
@@ -410,69 +410,72 @@ greeter_reset_timeout (GdmSimpleSlave  *slave)
f3033d
         return FALSE;
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 queue_greeter_reset (GdmSimpleSlave  *slave)
f3033d
 {
f3033d
         if (slave->priv->greeter_reset_id > 0) {
f3033d
                 return;
f3033d
         }
f3033d
 
f3033d
         slave->priv->greeter_reset_id = g_idle_add ((GSourceFunc)greeter_reset_timeout, slave);
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 gdm_simple_slave_start_session_when_ready (GdmSimpleSlave *slave,
f3033d
                                            const char     *service_name)
f3033d
 {
f3033d
         if (slave->priv->start_session_when_ready) {
f3033d
                 slave->priv->waiting_to_start_session = FALSE;
f3033d
                 queue_start_session (slave, service_name);
f3033d
         } else {
f3033d
                 slave->priv->waiting_to_start_session = TRUE;
f3033d
         }
f3033d
 }
f3033d
 
f3033d
 static gboolean
f3033d
 switch_to_and_unlock_session (GdmSimpleSlave  *slave,
f3033d
                               gboolean         fail_if_already_switched)
f3033d
 {
f3033d
         char    *username;
f3033d
+        char    *session_id;
f3033d
         gboolean res;
f3033d
 
f3033d
         username = gdm_session_get_username (slave->priv->session);
f3033d
+        session_id = gdm_session_get_session_id (slave->priv->session);
f3033d
 
f3033d
         g_debug ("GdmSimpleSlave: trying to switch to session for user %s", username);
f3033d
 
f3033d
         /* try to switch to an existing session */
f3033d
-        res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username, fail_if_already_switched);
f3033d
+        res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username, session_id, fail_if_already_switched);
f3033d
         g_free (username);
f3033d
+        g_free (session_id);
f3033d
 
f3033d
         return res;
f3033d
 }
f3033d
 
f3033d
 static void
f3033d
 stop_greeter (GdmSimpleSlave *slave)
f3033d
 {
f3033d
         char *username;
f3033d
         gboolean script_successful;
f3033d
 
f3033d
         g_debug ("GdmSimpleSlave: Stopping greeter");
f3033d
 
f3033d
         if (slave->priv->greeter_environment == NULL) {
f3033d
                 g_debug ("GdmSimpleSlave: No greeter running");
f3033d
                 return;
f3033d
         }
f3033d
 
f3033d
         /* Run the PostLogin script. gdmslave suspends until script has terminated */
f3033d
         username = NULL;
f3033d
         if (slave->priv->session != NULL) {
f3033d
                 username = gdm_session_get_username (slave->priv->session);
f3033d
         }
f3033d
 
f3033d
         if (username != NULL) {
f3033d
                 script_successful = gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PostLogin", username);
f3033d
         } else {
f3033d
                 script_successful = TRUE;
f3033d
         }
f3033d
         g_free (username);
f3033d
 
f3033d
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
f3033d
index ba292a3..e5c8be7 100644
f3033d
--- a/daemon/gdm-slave.c
f3033d
+++ b/daemon/gdm-slave.c
f3033d
@@ -1620,73 +1620,78 @@ session_unlock_for_ck (GdmSlave   *slave,
f3033d
 
f3033d
         g_variant_unref (reply);
f3033d
 
f3033d
         return TRUE;
f3033d
 }
f3033d
 #endif
f3033d
 
f3033d
 static gboolean
f3033d
 session_unlock (GdmSlave   *slave,
f3033d
                 const char *ssid)
f3033d
 {
f3033d
 
f3033d
         g_debug ("Unlocking session %s", ssid);
f3033d
 
f3033d
 #ifdef WITH_SYSTEMD
f3033d
         if (LOGIND_RUNNING()) {
f3033d
                 return session_unlock_for_systemd (slave, ssid);
f3033d
         }
f3033d
 #endif
f3033d
 
f3033d
 #ifdef WITH_CONSOLE_KIT
f3033d
         return session_unlock_for_ck (slave, ssid);
f3033d
 #else
f3033d
         return TRUE;
f3033d
 #endif
f3033d
 }
f3033d
 
f3033d
 gboolean
f3033d
 gdm_slave_switch_to_user_session (GdmSlave   *slave,
f3033d
                                   const char *username,
f3033d
+                                  const char *session_id,
f3033d
                                   gboolean    fail_if_already_switched)
f3033d
 {
f3033d
         gboolean    res;
f3033d
         gboolean    ret;
f3033d
         gboolean    session_already_switched;
f3033d
         char       *ssid_to_activate;
f3033d
 
f3033d
         ret = FALSE;
f3033d
 
f3033d
-        ssid_to_activate = gdm_slave_get_primary_session_id_for_user (slave, username);
f3033d
-        if (ssid_to_activate == NULL) {
f3033d
-                g_debug ("GdmSlave: unable to determine session to activate");
f3033d
-                goto out;
f3033d
+        if (session_id != NULL) {
f3033d
+                ssid_to_activate = g_strdup (session_id);
f3033d
+        } else {
f3033d
+                ssid_to_activate = gdm_slave_get_primary_session_id_for_user (slave, username);
f3033d
+                if (ssid_to_activate == NULL) {
f3033d
+                        g_debug ("GdmSlave: unable to determine session to activate");
f3033d
+                        goto out;
f3033d
+                }
f3033d
         }
f3033d
 
f3033d
         session_already_switched = session_is_active (slave, slave->priv->display_seat_id, ssid_to_activate);
f3033d
 
f3033d
         g_debug ("GdmSlave: Activating session: '%s'", ssid_to_activate);
f3033d
 
f3033d
         if (session_already_switched && fail_if_already_switched) {
f3033d
                 g_debug ("GdmSlave: unable to activate session since it's already active: %s", ssid_to_activate);
f3033d
                 goto out;
f3033d
         }
f3033d
 
f3033d
         if (!session_already_switched) {
f3033d
                 res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate);
f3033d
                 if (! res) {
f3033d
                         g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate);
f3033d
                         goto out;
f3033d
                 }
f3033d
         }
f3033d
 
f3033d
         res = session_unlock (slave, ssid_to_activate);
f3033d
         if (!res) {
f3033d
                 /* this isn't fatal */
f3033d
                 g_debug ("GdmSlave: unable to unlock session: %s", ssid_to_activate);
f3033d
         }
f3033d
 
f3033d
         ret = TRUE;
f3033d
 
f3033d
  out:
f3033d
         g_free (ssid_to_activate);
f3033d
 
f3033d
diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h
f3033d
index 902de21..9808433 100644
f3033d
--- a/daemon/gdm-slave.h
f3033d
+++ b/daemon/gdm-slave.h
f3033d
@@ -73,44 +73,45 @@ typedef struct
f3033d
 
f3033d
 typedef enum
f3033d
 {
f3033d
         GDM_SLAVE_ERROR_GENERIC,
f3033d
         GDM_SLAVE_ERROR_UNSUPPORTED,
f3033d
         GDM_SLAVE_ERROR_NOT_OPENED,
f3033d
         GDM_SLAVE_ERROR_WRONG_SESSION,
f3033d
 } GdmSlaveError;
f3033d
 
f3033d
 #define GDM_SLAVE_ERROR (gdm_slave_error_quark ())
f3033d
 
f3033d
 GQuark              gdm_slave_error_quark            (void);
f3033d
 GType               gdm_slave_get_type               (void);
f3033d
 gboolean            gdm_slave_start                  (GdmSlave   *slave);
f3033d
 gboolean            gdm_slave_stop                   (GdmSlave   *slave);
f3033d
 
f3033d
 char *              gdm_slave_get_primary_session_id_for_user (GdmSlave   *slave,
f3033d
                                                                const char *username);
f3033d
 
f3033d
 gboolean            gdm_slave_get_timed_login_details (GdmSlave  *slave,
f3033d
                                                        gboolean  *enabled,
f3033d
                                                        char     **username,
f3033d
                                                        int       *delay);
f3033d
 
f3033d
 gboolean            gdm_slave_add_user_authorization (GdmSlave   *slave,
f3033d
                                                       const char *username,
f3033d
                                                       char      **filename);
f3033d
 
f3033d
 gboolean            gdm_slave_switch_to_user_session (GdmSlave   *slave,
f3033d
                                                       const char *username,
f3033d
+                                                      const char *session_id,
f3033d
                                                       gboolean    fail_if_already_switched);
f3033d
 
f3033d
 gboolean            gdm_slave_connect_to_x11_display (GdmSlave   *slave);
f3033d
 
f3033d
 void                gdm_slave_set_initial_cursor_position (GdmSlave *slave);
f3033d
 
f3033d
 gboolean            gdm_slave_run_script             (GdmSlave   *slave,
f3033d
                                                       const char *dir,
f3033d
                                                       const char *username);
f3033d
 void                gdm_slave_export_interface       (GdmSlave               *slave,
f3033d
                                                       GDBusInterfaceSkeleton *interface);
f3033d
 G_END_DECLS
f3033d
 
f3033d
 #endif /* __GDM_SLAVE_H */
f3033d
-- 
f3033d
1.8.3.1
f3033d