Blob Blame History Raw
From 9b4d319e9bb89116ee883381912f53823d5b2234 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Wed, 30 Oct 2013 13:30:40 -0400
Subject: [PATCH 1/5] slave: don't run initial-setup on remote displays

GDM will run initial-setup if there are no configured user accounts
on the system.  We correctly skip checking if there are configured user
accounts on remote XDMCP displays, but incorrectly, still run initial-setup.

This commit makes sure we only every do any of the initial-setup logic
in the local display code paths.
---
 daemon/gdm-simple-slave.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 217c33b..bee6c37 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -1285,60 +1285,71 @@ start_greeter (GdmSimpleSlave *slave)
 {
         start_launch_environment (slave, GDM_USERNAME, NULL);
 }
 
 static void
 start_initial_setup (GdmSimpleSlave *slave)
 {
         slave->priv->doing_initial_setup = TRUE;
         start_launch_environment (slave, INITIAL_SETUP_USERNAME, "gnome-initial-setup");
 }
 
 static gboolean
 wants_autologin (GdmSimpleSlave *slave)
 {
         gboolean enabled = FALSE;
         int delay = 0;
         /* FIXME: handle wait-for-go */
 
         if (g_file_test (GDM_RAN_ONCE_MARKER_FILE, G_FILE_TEST_EXISTS)) {
                 return FALSE;
         }
 
         gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
         return enabled && delay == 0;
 }
 
 static gboolean
 wants_initial_setup (GdmSimpleSlave *slave)
 {
         gboolean enabled = FALSE;
+        gboolean display_is_local = FALSE;
+
+        g_object_get (G_OBJECT (slave),
+                      "display-is-local", &display_is_local,
+                      NULL);
+
+        /* don't run initial-setup on remote displays
+         */
+        if (!display_is_local) {
+                return FALSE;
+        }
 
         /* don't run if the system has existing users */
         if (slave->priv->have_existing_user_accounts) {
                 return FALSE;
         }
 
         /* don't run if initial-setup is unavailable */
         if (!can_create_environment ("gnome-initial-setup")) {
                 return FALSE;
         }
 
         if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) {
                 return FALSE;
         }
 
         return enabled;
 }
 
 static void
 setup_session (GdmSimpleSlave *slave)
 {
         if (wants_initial_setup (slave)) {
                 start_initial_setup (slave);
         } else if (wants_autologin (slave)) {
                 /* Run the init script. gdmslave suspends until script has terminated */
                 gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME);
         } else {
                 start_greeter (slave);
         }
         create_new_session (slave);
-- 
1.8.3.1


From 29b3f4ea9c69deb3bac2edf76489fa42755d7cd2 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 31 Oct 2013 14:57:04 -0400
Subject: [PATCH 2/5] slave: don't kill slave when client disconnects

Right now we stop the slave if a greeter running on a remote
X server exits. This is wrong, since the greeter will exit as
part of the login screen process.  We already have mechanisms in
place to reap the slave at the appropriate time, so stopping the
slave on disconnection is totally unneeded and actively harmful.

This commit drops that code.
---
 daemon/gdm-simple-slave.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index bee6c37..35951c7 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -816,71 +816,61 @@ on_session_client_connected (GdmSession          *session,
                                                          (GDestroyNotify)
                                                          g_object_unref);
                 g_cancellable_connect (cancellable,
                                        G_CALLBACK (g_source_remove),
                                        GINT_TO_POINTER (timeout_id),
                                        NULL);
 
                 g_object_weak_ref (G_OBJECT (session),
                                    (GWeakNotify)
                                    g_cancellable_cancel,
                                    cancellable);
                 g_object_weak_ref (G_OBJECT (session),
                                    (GWeakNotify)
                                    g_object_unref,
                                    cancellable);
                 g_object_weak_ref (G_OBJECT (session),
                                    (GWeakNotify)
                                    g_free,
                                    source_tag);
         }
 
         g_free (username);
 }
 
 static void
 on_session_client_disconnected (GdmSession          *session,
                                 GCredentials        *credentials,
                                 GPid                 pid_of_client,
                                 GdmSimpleSlave      *slave)
 {
-        gboolean display_is_local;
-
         g_debug ("GdmSimpleSlave: client disconnected");
-
-        g_object_get (slave,
-                      "display-is-local", &display_is_local,
-                      NULL);
-
-        if ( ! display_is_local && !slave->priv->session_is_running) {
-                gdm_slave_stop (GDM_SLAVE (slave));
-        }
 }
 
 static void
 on_session_cancelled (GdmSession      *session,
                       GdmSimpleSlave  *slave)
 {
         g_debug ("GdmSimpleSlave: Session was cancelled");
         queue_greeter_reset (slave);
 }
 
 static void
 touch_marker_file (GdmSimpleSlave *slave)
 {
         int fd;
 
         fd = g_creat (GDM_RAN_ONCE_MARKER_FILE, 0644);
 
         if (fd < 0 && errno != EEXIST) {
                 g_warning ("could not create %s to mark run, this may cause auto login "
                            "to repeat: %m", GDM_RAN_ONCE_MARKER_FILE);
                 return;
         }
 
         fsync (fd);
         close (fd);
 }
 
 static void
 create_new_session (GdmSimpleSlave  *slave)
 {
-- 
1.8.3.1


From 0c6811cc358fa1e5ff22fe3ec656c351ab94a899 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 31 Oct 2013 15:00:26 -0400
Subject: [PATCH 3/5] manager: return ACCESS DENIED for most
 open-reauth-channel failures

gnome-shell only falls back to opening a new session if the reauth
channel fails to open because of denied access.  For XDMCP we currently
fail for other reasons.

This commit returns ACCESS DENIED for those cases as well, so the
intended fallback happens.
---
 daemon/gdm-manager.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 74c6888..eef7233 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -698,90 +698,112 @@ gdm_manager_handle_open_session (GdmDBusManager        *manager,
                                                 address);
         g_free (address);
 
         return TRUE;
 }
 
 static gboolean
 gdm_manager_handle_open_reauthentication_channel (GdmDBusManager        *manager,
                                                   GDBusMethodInvocation *invocation,
                                                   const char            *username)
 {
         GdmManager       *self = GDM_MANAGER (manager);
         GDBusConnection  *connection;
         GdmDisplay       *display;
         const char       *sender;
         char             *seat_id;
         char             *session_id = NULL;
         GError           *error;
         char             *address;
         int               ret;
         GPid              pid;
         uid_t             caller_uid;
 
         g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
 
         sender = g_dbus_method_invocation_get_sender (invocation);
         error = NULL;
         ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
 
         if (!ret) {
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
-                g_dbus_method_invocation_return_gerror (invocation, error);
+                g_debug ("GdmManager: could not get pid of caller: %s",
+                         error->message);
                 g_error_free (error);
+
+                g_dbus_method_invocation_return_error_literal (invocation,
+                                                               G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
+                                                               "Error getting process id of caller");
                 return TRUE;
 
         }
 
         ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
 
         if (!ret) {
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
-                g_dbus_method_invocation_return_gerror (invocation, error);
+                g_debug ("GdmManager: could not get uid of caller: %s",
+                         error->message);
                 g_error_free (error);
+
+                g_dbus_method_invocation_return_error_literal (invocation,
+                                                               G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
+                                                               "Error getting user id of caller");
                 return TRUE;
         }
 
         connection = g_dbus_method_invocation_get_connection (invocation);
 
         seat_id = get_seat_id_for_pid (connection, pid, &error);
 
         if (seat_id == NULL) {
-                g_dbus_method_invocation_return_gerror (invocation, error);
+                g_debug ("GdmManager: could not get seat id of caller: %s",
+                         error->message);
                 g_error_free (error);
+
+                g_dbus_method_invocation_return_error_literal (invocation,
+                                                               G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
+                                                               "Error getting seat id of caller");
                 return TRUE;
         }
 
         session_id = get_session_id_for_user_on_seat (connection, username, seat_id, &error);
         if (session_id == NULL) {
-                g_dbus_method_invocation_return_gerror (invocation, error);
+                g_debug ("GdmManager: could not get session id for caller: %s",
+                         error->message);
                 g_error_free (error);
+
+                g_dbus_method_invocation_return_error_literal (invocation,
+                                                               G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_ACCESS_DENIED,
+                                                               "Error getting session id for caller");
                 return TRUE;
         }
 
         display = gdm_display_store_find (self->priv->display_store,
                                           lookup_by_session_id,
                                           (gpointer) session_id);
         g_free (session_id);
 
         if (display == NULL) {
                 g_dbus_method_invocation_return_error_literal (invocation,
                                                                G_DBUS_ERROR,
                                                                G_DBUS_ERROR_ACCESS_DENIED,
                                                                _("No session available"));
 
                 return TRUE;
         }
 
         address = gdm_display_open_reauthentication_channel_sync (display,
                                                                   username,
                                                                   pid,
                                                                   caller_uid,
                                                                   NULL,
                                                                   &error);
 
         if (address == NULL) {
                 g_dbus_method_invocation_return_gerror (invocation, error);
                 g_error_free (error);
                 return TRUE;
         }
 
-- 
1.8.3.1


From c4472c5e07b5d4e35a7a0c797ba96c882d97feb7 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 1 Nov 2013 12:40:10 -0400
Subject: [PATCH 4/5] daemon: don't require seat to locate reauth channel

With systemd, XDMCP sessions don't have associated seats.
Currently, reauth channels find the session by first looking up
the seat, which means unlocking fails for XDMCP.

This commit changes the code to determine session strictly from pid.
---
 daemon/gdm-manager.c | 503 +++++++--------------------------------------------
 1 file changed, 61 insertions(+), 442 deletions(-)

diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index eef7233..6c0fe1d 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -226,605 +226,224 @@ get_uid_for_consolekit_session_id (GDBusConnection  *connection,
         }
 
         g_variant_get (reply, "(u)", &uid);
         g_variant_unref (reply);
 
         *out_uid = (uid_t) uid;
 
         return TRUE;
 }
 #endif
 
 static gboolean
 get_uid_for_session_id (GDBusConnection  *connection,
                         const char       *session_id,
                         uid_t            *uid,
                         GError          **error)
 {
 #ifdef WITH_SYSTEMD
         if (LOGIND_RUNNING()) {
                 return get_uid_for_systemd_session_id (session_id, uid, error);
         }
 #endif
 
 #ifdef WITH_CONSOLE_KIT
         return get_uid_for_consolekit_session_id (connection, session_id, uid, error);
 #endif
 
         return FALSE;
 }
 
-#ifdef WITH_SYSTEMD
-static char *
-get_session_id_for_user_on_seat_systemd (const char  *username,
-                                         const char  *seat,
-                                         GError     **error)
-{
-        struct passwd  *pwent;
-        uid_t           uid;
-        int             i;
-        char          **sessions;
-        char           *session = NULL;
-        int             ret;
-
-        pwent = NULL;
-        gdm_get_pwent_for_name (username, &pwent);
-
-        if (pwent == NULL) {
-                g_set_error (error,
-                             G_DBUS_ERROR,
-                             G_DBUS_ERROR_ACCESS_DENIED,
-                             _("Unable to look up UID of user %s"),
-                             username);
-                return NULL;
-        }
-
-        uid = pwent->pw_uid;
-
-        session = NULL;
-        ret = sd_seat_get_sessions (seat, &sessions, NULL, NULL);
-        if (ret < 0 || sessions == NULL) {
-                g_set_error (error,
-                             G_DBUS_ERROR,
-                             G_DBUS_ERROR_ACCESS_DENIED,
-                             "Error getting session ids from systemd: %s",
-                             ret < 0? g_strerror (-ret) : _("no sessions available"));
-                return NULL;
-        }
-
-        for (i = 0; sessions[i] != NULL; i++) {
-                char     *type;
-                char     *state;
-                gboolean  is_closing;
-                gboolean  is_x11;
-                uid_t     session_uid;
-
-                ret = sd_session_get_uid (sessions[i], &session_uid);
-
-                if (ret < 0) {
-                        g_warning ("GdmManager: could not fetch uid of session '%s': %s",
-                                   sessions[i], strerror (-ret));
-                        continue;
-                }
-
-                if (uid != session_uid) {
-                        continue;
-                }
-
-                ret = sd_session_get_type (sessions[i], &type);
-
-                if (ret < 0) {
-                        g_warning ("GdmManager: could not fetch type of session '%s': %s",
-                                   sessions[i], strerror (-ret));
-                        continue;
-                }
-
-                is_x11 = g_strcmp0 (type, "x11") == 0;
-                free (type);
-
-                if (!is_x11) {
-                        continue;
-                }
-
-                ret = sd_session_get_state (sessions[i], &state);
-                if (ret < 0) {
-                        g_warning ("GdmManager: could not fetch state of session '%s': %s",
-                                   sessions[i], strerror (-ret));
-                        continue;
-                }
-
-                is_closing = g_strcmp0 (state, "closing") == 0;
-
-                if (is_closing) {
-                        continue;
-                }
-
-                session = g_strdup (sessions[i]);
-                break;
-
-        }
-
-        if (session == NULL) {
-                g_debug ("GdmManager: There are no applicable sessions (%d looked at)", i);
-                g_set_error (error,
-                             G_DBUS_ERROR,
-                             G_DBUS_ERROR_ACCESS_DENIED,
-                             _("No sessions for %s available for reauthentication"),
-                             username);
-                return NULL;
-        }
-
-        g_debug ("GdmManager: session %s is available for reauthentication", session);
-
-        return session;
-}
-#endif
-
-#ifdef WITH_CONSOLE_KIT
-static char *
-get_session_id_for_user_on_seat_consolekit (GDBusConnection  *connection,
-                                            const char       *username,
-                                            const char       *seat,
-                                            GError          **error)
-{
-        GVariant       *reply;
-        const gchar   **sessions;
-        char           *session = NULL;
-        struct passwd  *pwent;
-        uid_t           uid;
-        int             i;
-
-        pwent = NULL;
-        gdm_get_pwent_for_name (username, &pwent);
-
-        if (pwent == NULL) {
-                g_set_error (error,
-                             G_DBUS_ERROR,
-                             G_DBUS_ERROR_ACCESS_DENIED,
-                             _("Unable to look up UID of user %s"),
-                             username);
-                return NULL;
-        }
-
-        uid = pwent->pw_uid;
-
-        reply = g_dbus_connection_call_sync (connection,
-                                             "org.freedesktop.ConsoleKit",
-                                             "/org/freedesktop/ConsoleKit/Manager",
-                                             "org.freedesktop.ConsoleKit.Manager",
-                                             "GetSessionsForUnixUser",
-                                             g_variant_new ("(u)", (guint32) uid),
-                                             G_VARIANT_TYPE ("(ao)"),
-                                             G_DBUS_CALL_FLAGS_NONE,
-                                             -1,
-                                             NULL,
-                                             error);
-        if (reply == NULL) {
-                g_set_error (error,
-                             G_DBUS_ERROR,
-                             G_DBUS_ERROR_ACCESS_DENIED,
-                             _("Unable to find session for user %s"),
-                             username);
-                return NULL;
-        }
-
-        g_variant_get_child (reply, 0, "^a&o", &sessions);
-        for (i = 0; sessions[i] != NULL; i++) {
-                GVariant *reply2;
-                GError   *error2 = NULL;
-                gchar    *display;
-                gchar    *session_seat_id;
-
-                reply2 = g_dbus_connection_call_sync (connection,
-                                                     "org.freedesktop.ConsoleKit",
-                                                     sessions[i],
-                                                     "org.freedesktop.ConsoleKit.Session",
-                                                     "GetSeatId",
-                                                     NULL,
-                                                     G_VARIANT_TYPE ("(o)"),
-                                                     G_DBUS_CALL_FLAGS_NONE,
-                                                     -1,
-                                                     NULL,
-                                                     &error2);
-                if (reply2 == NULL) {
-                        continue;
-                }
-
-                g_variant_get (reply2, "(o)", &session_seat_id);
-                g_variant_unref (reply2);
-
-                if (g_strcmp0 (seat, session_seat_id) != 0) {
-                        g_free (session_seat_id);
-                        continue;
-                }
-                g_free (session_seat_id);
-
-                reply2 = g_dbus_connection_call_sync (connection,
-                                                     "org.freedesktop.ConsoleKit",
-                                                     sessions[i],
-                                                     "org.freedesktop.ConsoleKit.Session",
-                                                     "GetX11DisplayDevice",
-                                                     NULL,
-                                                     G_VARIANT_TYPE ("(s)"),
-                                                     G_DBUS_CALL_FLAGS_NONE,
-                                                     -1,
-                                                     NULL,
-                                                     &error2);
-                if (reply2 == NULL) {
-                        continue;
-                }
-
-                g_variant_get (reply2, "(s)", &display);
-                g_variant_unref (reply2);
-
-                if (display[0] == '\0') {
-                        g_free (display);
-                        continue;
-                }
-
-                session = g_strdup (sessions[i]);
-                break;
-
-        }
-        g_free (sessions);
-        g_variant_unref (reply);
-
-        if (session == NULL) {
-                g_set_error (error,
-                             G_DBUS_ERROR,
-                             G_DBUS_ERROR_ACCESS_DENIED,
-                             _("Unable to find appropriate session for user %s"),
-                             username);
-        }
-        return session;
-}
-#endif
-
-static char *
-get_session_id_for_user_on_seat (GDBusConnection  *connection,
-                                 const char       *username,
-                                 const char       *seat,
-                                 GError          **error)
-{
-#ifdef WITH_SYSTEMD
-        if (LOGIND_RUNNING()) {
-                return get_session_id_for_user_on_seat_systemd (username, seat, error);
-        }
-#endif
-
-#ifdef WITH_CONSOLE_KIT
-        return get_session_id_for_user_on_seat_consolekit (connection, username, seat, error);
-#endif
-
-        return NULL;
-}
-
 static gboolean
 lookup_by_session_id (const char *id,
                       GdmDisplay *display,
                       gpointer    user_data)
 {
         const char *looking_for = user_data;
         char *current;
         gboolean res;
 
         current = gdm_display_get_session_id (display);
 
         res = g_strcmp0 (current, looking_for) == 0;
 
         g_free (current);
 
         return res;
 }
 
-#ifdef WITH_SYSTEMD
-static char *
-get_seat_id_for_pid_systemd (pid_t    pid,
-                             GError **error)
+static GdmDisplay *
+get_display_and_details_for_bus_sender (GdmManager       *self,
+                            GDBusConnection  *connection,
+                            const char       *sender,
+                            GPid             *out_pid,
+                            uid_t            *out_uid)
 {
-        char *session;
-        char *seat, *gseat;
-        int ret;
+        GdmDisplay *display = NULL;
+        char       *session_id = NULL;
+        GError     *error = NULL;
+        int         ret;
+        GPid        pid;
+        uid_t       caller_uid, session_uid;
 
-        session = get_session_id_for_pid_systemd (pid, error);
+        ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
 
-        if (session == NULL) {
-                return NULL;
+        if (!ret) {
+                g_debug ("GdmManager: Error while retrieving pid for sender: %s",
+                         error->message);
+                g_error_free (error);
+                goto out;
         }
 
-        seat = NULL;
-        ret = sd_session_get_seat (session, &seat);
-        free (session);
+        ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
 
-        if (ret < 0) {
-                g_set_error (error,
-                             GDM_DISPLAY_ERROR,
-                             GDM_DISPLAY_ERROR_GETTING_SESSION_INFO,
-                             "Error getting seat id from systemd: %s",
-                             g_strerror (-ret));
-                return NULL;
+        if (!ret) {
+                g_debug ("GdmManager: Error while retrieving uid for sender: %s",
+                         error->message);
+                g_error_free (error);
+                goto out;
         }
 
-        if (seat != NULL) {
-                gseat = g_strdup (seat);
-                free (seat);
+        session_id = get_session_id_for_pid (connection, pid, &error);
 
-                return gseat;
-        } else {
-                return NULL;
+        if (session_id == NULL) {
+                g_debug ("GdmManager: Error while retrieving session id for sender: %s",
+                         error->message);
+                g_error_free (error);
+                goto out;
         }
-}
-#endif
-
-#ifdef WITH_CONSOLE_KIT
-static char *
-get_seat_id_for_pid_consolekit (GDBusConnection  *connection,
-                                pid_t             pid,
-                                GError          **error)
-{
-        char *session;
-        GVariant *reply;
-        char *retval;
 
-        session = get_session_id_for_pid_consolekit (connection, pid, error);
-
-        if (session == NULL) {
-                return NULL;
+        if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
+                g_debug ("GdmManager: Error while retrieving uid for session: %s",
+                         error->message);
+                g_error_free (error);
+                goto out;
         }
 
-        reply = g_dbus_connection_call_sync (connection,
-                                             "org.freedesktop.ConsoleKit",
-                                             session,
-                                             "org.freedesktop.ConsoleKit.Session",
-                                             "GetSeatId",
-                                             NULL,
-                                             G_VARIANT_TYPE ("(o)"),
-                                             G_DBUS_CALL_FLAGS_NONE,
-                                             -1,
-                                             NULL, error);
-        g_free (session);
-
-        if (reply == NULL) {
-                return NULL;
+        if (caller_uid != session_uid) {
+                g_debug ("GdmManager: uid for sender and uid for session don't match");
+                goto out;
         }
 
-        g_variant_get (reply, "(o)", &retval);
-        g_variant_unref (reply);
+        display = gdm_display_store_find (self->priv->display_store,
+                                          lookup_by_session_id,
+                                          (gpointer) session_id);
+out:
+        g_free (session_id);
 
-        return retval;
-}
-#endif
+        if (display != NULL) {
+            if (out_pid != NULL)
+                *out_pid = pid;
 
-static char *
-get_seat_id_for_pid (GDBusConnection  *connection,
-                     pid_t             pid,
-                     GError          **error)
-{
-#ifdef WITH_SYSTEMD
-        if (LOGIND_RUNNING()) {
-                return get_seat_id_for_pid_systemd (pid, error);
+            if (out_uid != NULL)
+                *out_uid = session_uid;
         }
-#endif
-
-#ifdef WITH_CONSOLE_KIT
-        return get_seat_id_for_pid_consolekit (connection, pid, error);
-#endif
-
-        return NULL;
+        return display;
 }
 
 static gboolean
 gdm_manager_handle_open_session (GdmDBusManager        *manager,
                                  GDBusMethodInvocation *invocation)
 {
         GdmManager       *self = GDM_MANAGER (manager);
+        const char       *sender = NULL;
+        GError           *error = NULL;
         GDBusConnection  *connection;
         GdmDisplay       *display;
-        const char       *sender;
-        char             *session_id;
-        GError           *error;
         char             *address;
-        int               ret;
         GPid              pid;
-        uid_t             caller_uid, session_uid;
+        uid_t             uid;
 
-        sender = g_dbus_method_invocation_get_sender (invocation);
-        error = NULL;
-        ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
-
-        if (!ret) {
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
-                g_dbus_method_invocation_return_gerror (invocation, error);
-                g_error_free (error);
-                return TRUE;
-        }
-
-        ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
-
-        if (!ret) {
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
-                g_dbus_method_invocation_return_gerror (invocation, error);
-                g_error_free (error);
-                return TRUE;
-        }
+        g_debug ("GdmManager: trying to open new session");
 
+        sender = g_dbus_method_invocation_get_sender (invocation);
         connection = g_dbus_method_invocation_get_connection (invocation);
-        session_id = get_session_id_for_pid (connection, pid, &error);
-
-        if (session_id == NULL) {
-                g_dbus_method_invocation_return_gerror (invocation, error);
-                g_error_free (error);
-                return TRUE;
-        }
-
-        if (!get_uid_for_session_id (connection, session_id, &session_uid, &error)) {
-                g_prefix_error (&error, "Error while retrieving caller session id: ");
-                g_dbus_method_invocation_return_gerror (invocation, error);
-                g_error_free (error);
-                return TRUE;
-        }
-
-        if (caller_uid != session_uid) {
-                g_dbus_method_invocation_return_error_literal (invocation,
-                                                               G_DBUS_ERROR,
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
-                                                               _("User doesn't own session"));
-                return TRUE;
-        }
-
-        display = gdm_display_store_find (self->priv->display_store,
-                                          lookup_by_session_id,
-                                          (gpointer) session_id);
-        g_free (session_id);
+        display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid);
 
         if (display == NULL) {
                 g_dbus_method_invocation_return_error_literal (invocation,
                                                                G_DBUS_ERROR,
                                                                G_DBUS_ERROR_ACCESS_DENIED,
                                                                _("No session available"));
 
                 return TRUE;
         }
 
-        address = gdm_display_open_session_sync (display, pid, session_uid, NULL, &error);
+        address = gdm_display_open_session_sync (display, pid, uid, NULL, &error);
 
         if (address == NULL) {
                 g_dbus_method_invocation_return_gerror (invocation, error);
                 g_error_free (error);
                 return TRUE;
         }
 
         gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager),
                                                 invocation,
                                                 address);
         g_free (address);
 
         return TRUE;
 }
 
 static gboolean
 gdm_manager_handle_open_reauthentication_channel (GdmDBusManager        *manager,
                                                   GDBusMethodInvocation *invocation,
                                                   const char            *username)
 {
         GdmManager       *self = GDM_MANAGER (manager);
+        const char       *sender = NULL;
+        GError           *error = NULL;
         GDBusConnection  *connection;
         GdmDisplay       *display;
-        const char       *sender;
-        char             *seat_id;
-        char             *session_id = NULL;
-        GError           *error;
         char             *address;
-        int               ret;
         GPid              pid;
-        uid_t             caller_uid;
+        uid_t             uid;
 
         g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
 
         sender = g_dbus_method_invocation_get_sender (invocation);
-        error = NULL;
-        ret = gdm_dbus_get_pid_for_name (sender, &pid, &error);
-
-        if (!ret) {
-                g_debug ("GdmManager: could not get pid of caller: %s",
-                         error->message);
-                g_error_free (error);
-
-                g_dbus_method_invocation_return_error_literal (invocation,
-                                                               G_DBUS_ERROR,
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
-                                                               "Error getting process id of caller");
-                return TRUE;
-
-        }
-
-        ret = gdm_dbus_get_uid_for_name (sender, &caller_uid, &error);
-
-        if (!ret) {
-                g_debug ("GdmManager: could not get uid of caller: %s",
-                         error->message);
-                g_error_free (error);
-
-                g_dbus_method_invocation_return_error_literal (invocation,
-                                                               G_DBUS_ERROR,
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
-                                                               "Error getting user id of caller");
-                return TRUE;
-        }
-
         connection = g_dbus_method_invocation_get_connection (invocation);
-
-        seat_id = get_seat_id_for_pid (connection, pid, &error);
-
-        if (seat_id == NULL) {
-                g_debug ("GdmManager: could not get seat id of caller: %s",
-                         error->message);
-                g_error_free (error);
-
-                g_dbus_method_invocation_return_error_literal (invocation,
-                                                               G_DBUS_ERROR,
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
-                                                               "Error getting seat id of caller");
-                return TRUE;
-        }
-
-        session_id = get_session_id_for_user_on_seat (connection, username, seat_id, &error);
-        if (session_id == NULL) {
-                g_debug ("GdmManager: could not get session id for caller: %s",
-                         error->message);
-                g_error_free (error);
-
-                g_dbus_method_invocation_return_error_literal (invocation,
-                                                               G_DBUS_ERROR,
-                                                               G_DBUS_ERROR_ACCESS_DENIED,
-                                                               "Error getting session id for caller");
-                return TRUE;
-        }
-
-        display = gdm_display_store_find (self->priv->display_store,
-                                          lookup_by_session_id,
-                                          (gpointer) session_id);
-        g_free (session_id);
+        display = get_display_and_details_for_bus_sender (self, connection, sender, &pid, &uid);
 
         if (display == NULL) {
                 g_dbus_method_invocation_return_error_literal (invocation,
                                                                G_DBUS_ERROR,
                                                                G_DBUS_ERROR_ACCESS_DENIED,
                                                                _("No session available"));
 
                 return TRUE;
         }
 
         address = gdm_display_open_reauthentication_channel_sync (display,
                                                                   username,
                                                                   pid,
-                                                                  caller_uid,
+                                                                  uid,
                                                                   NULL,
                                                                   &error);
 
         if (address == NULL) {
                 g_dbus_method_invocation_return_gerror (invocation, error);
                 g_error_free (error);
                 return TRUE;
         }
 
         gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
                                                                  invocation,
                                                                  address);
         g_free (address);
 
         return TRUE;
 }
 
 static void
 manager_interface_init (GdmDBusManagerIface *interface)
 {
         interface->handle_open_session = gdm_manager_handle_open_session;
         interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel;
 }
 
 static void
 on_display_removed (GdmDisplayStore *display_store,
                     const char      *id,
                     GdmManager      *manager)
 {
         GdmDisplay *display;
-- 
1.8.3.1


From d70697ff1b6e987c7437fb1a9a8459626bc5358d Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 1 Nov 2013 15:27:14 -0400
Subject: [PATCH 5/5] slave: Pass session id to unlocking code if we know it

We currently figure out which session to unlock on-the-fly based on
the username that was just reauthenticated.  This doesn't work, for
XDMCP sessions, under logind, since they don't have a seat. There's
no reason to try to deduce the session, though.  We already know it,
so we might as well pass it down.

This fixes unlocking for XDMCP.
---
 daemon/gdm-simple-slave.c |  5 ++++-
 daemon/gdm-slave.c        | 13 +++++++++----
 daemon/gdm-slave.h        |  1 +
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 35951c7..1fe58bc 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -410,69 +410,72 @@ greeter_reset_timeout (GdmSimpleSlave  *slave)
         return FALSE;
 }
 
 static void
 queue_greeter_reset (GdmSimpleSlave  *slave)
 {
         if (slave->priv->greeter_reset_id > 0) {
                 return;
         }
 
         slave->priv->greeter_reset_id = g_idle_add ((GSourceFunc)greeter_reset_timeout, slave);
 }
 
 static void
 gdm_simple_slave_start_session_when_ready (GdmSimpleSlave *slave,
                                            const char     *service_name)
 {
         if (slave->priv->start_session_when_ready) {
                 slave->priv->waiting_to_start_session = FALSE;
                 queue_start_session (slave, service_name);
         } else {
                 slave->priv->waiting_to_start_session = TRUE;
         }
 }
 
 static gboolean
 switch_to_and_unlock_session (GdmSimpleSlave  *slave,
                               gboolean         fail_if_already_switched)
 {
         char    *username;
+        char    *session_id;
         gboolean res;
 
         username = gdm_session_get_username (slave->priv->session);
+        session_id = gdm_session_get_session_id (slave->priv->session);
 
         g_debug ("GdmSimpleSlave: trying to switch to session for user %s", username);
 
         /* try to switch to an existing session */
-        res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username, fail_if_already_switched);
+        res = gdm_slave_switch_to_user_session (GDM_SLAVE (slave), username, session_id, fail_if_already_switched);
         g_free (username);
+        g_free (session_id);
 
         return res;
 }
 
 static void
 stop_greeter (GdmSimpleSlave *slave)
 {
         char *username;
         gboolean script_successful;
 
         g_debug ("GdmSimpleSlave: Stopping greeter");
 
         if (slave->priv->greeter_environment == NULL) {
                 g_debug ("GdmSimpleSlave: No greeter running");
                 return;
         }
 
         /* Run the PostLogin script. gdmslave suspends until script has terminated */
         username = NULL;
         if (slave->priv->session != NULL) {
                 username = gdm_session_get_username (slave->priv->session);
         }
 
         if (username != NULL) {
                 script_successful = gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/PostLogin", username);
         } else {
                 script_successful = TRUE;
         }
         g_free (username);
 
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
index ba292a3..e5c8be7 100644
--- a/daemon/gdm-slave.c
+++ b/daemon/gdm-slave.c
@@ -1620,73 +1620,78 @@ session_unlock_for_ck (GdmSlave   *slave,
 
         g_variant_unref (reply);
 
         return TRUE;
 }
 #endif
 
 static gboolean
 session_unlock (GdmSlave   *slave,
                 const char *ssid)
 {
 
         g_debug ("Unlocking session %s", ssid);
 
 #ifdef WITH_SYSTEMD
         if (LOGIND_RUNNING()) {
                 return session_unlock_for_systemd (slave, ssid);
         }
 #endif
 
 #ifdef WITH_CONSOLE_KIT
         return session_unlock_for_ck (slave, ssid);
 #else
         return TRUE;
 #endif
 }
 
 gboolean
 gdm_slave_switch_to_user_session (GdmSlave   *slave,
                                   const char *username,
+                                  const char *session_id,
                                   gboolean    fail_if_already_switched)
 {
         gboolean    res;
         gboolean    ret;
         gboolean    session_already_switched;
         char       *ssid_to_activate;
 
         ret = FALSE;
 
-        ssid_to_activate = gdm_slave_get_primary_session_id_for_user (slave, username);
-        if (ssid_to_activate == NULL) {
-                g_debug ("GdmSlave: unable to determine session to activate");
-                goto out;
+        if (session_id != NULL) {
+                ssid_to_activate = g_strdup (session_id);
+        } else {
+                ssid_to_activate = gdm_slave_get_primary_session_id_for_user (slave, username);
+                if (ssid_to_activate == NULL) {
+                        g_debug ("GdmSlave: unable to determine session to activate");
+                        goto out;
+                }
         }
 
         session_already_switched = session_is_active (slave, slave->priv->display_seat_id, ssid_to_activate);
 
         g_debug ("GdmSlave: Activating session: '%s'", ssid_to_activate);
 
         if (session_already_switched && fail_if_already_switched) {
                 g_debug ("GdmSlave: unable to activate session since it's already active: %s", ssid_to_activate);
                 goto out;
         }
 
         if (!session_already_switched) {
                 res = activate_session_id (slave, slave->priv->display_seat_id, ssid_to_activate);
                 if (! res) {
                         g_debug ("GdmSlave: unable to activate session: %s", ssid_to_activate);
                         goto out;
                 }
         }
 
         res = session_unlock (slave, ssid_to_activate);
         if (!res) {
                 /* this isn't fatal */
                 g_debug ("GdmSlave: unable to unlock session: %s", ssid_to_activate);
         }
 
         ret = TRUE;
 
  out:
         g_free (ssid_to_activate);
 
diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h
index 902de21..9808433 100644
--- a/daemon/gdm-slave.h
+++ b/daemon/gdm-slave.h
@@ -73,44 +73,45 @@ typedef struct
 
 typedef enum
 {
         GDM_SLAVE_ERROR_GENERIC,
         GDM_SLAVE_ERROR_UNSUPPORTED,
         GDM_SLAVE_ERROR_NOT_OPENED,
         GDM_SLAVE_ERROR_WRONG_SESSION,
 } GdmSlaveError;
 
 #define GDM_SLAVE_ERROR (gdm_slave_error_quark ())
 
 GQuark              gdm_slave_error_quark            (void);
 GType               gdm_slave_get_type               (void);
 gboolean            gdm_slave_start                  (GdmSlave   *slave);
 gboolean            gdm_slave_stop                   (GdmSlave   *slave);
 
 char *              gdm_slave_get_primary_session_id_for_user (GdmSlave   *slave,
                                                                const char *username);
 
 gboolean            gdm_slave_get_timed_login_details (GdmSlave  *slave,
                                                        gboolean  *enabled,
                                                        char     **username,
                                                        int       *delay);
 
 gboolean            gdm_slave_add_user_authorization (GdmSlave   *slave,
                                                       const char *username,
                                                       char      **filename);
 
 gboolean            gdm_slave_switch_to_user_session (GdmSlave   *slave,
                                                       const char *username,
+                                                      const char *session_id,
                                                       gboolean    fail_if_already_switched);
 
 gboolean            gdm_slave_connect_to_x11_display (GdmSlave   *slave);
 
 void                gdm_slave_set_initial_cursor_position (GdmSlave *slave);
 
 gboolean            gdm_slave_run_script             (GdmSlave   *slave,
                                                       const char *dir,
                                                       const char *username);
 void                gdm_slave_export_interface       (GdmSlave               *slave,
                                                       GDBusInterfaceSkeleton *interface);
 G_END_DECLS
 
 #endif /* __GDM_SLAVE_H */
-- 
1.8.3.1