Blob Blame History Raw
From 8ce3d6268c5ff8f38062c62b487362ac728afa97 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 13 Nov 2014 10:57:05 -0500
Subject: [PATCH] worker: make sure SavedSessionNameRead is emitted for
 conversations without initial username

We emit SavedSessionNameRead when we know the session associated with a
user account. Unfortunately, we don't emit the signal in the case we
don't know the username up front (such as with a smartcard).

This commit fixes it to be emitted in that case.
---
 daemon/gdm-session-worker.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index eb81450..731fcf5 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2131,72 +2131,60 @@ on_saved_session_name_read (GdmSessionWorker *worker)
         g_debug ("GdmSessionWorker: Saved session is %s", session_name);
         gdm_dbus_worker_emit_saved_session_name_read (GDM_DBUS_WORKER (worker),
                                                       session_name);
         g_free (session_name);
 }

 static void
 do_setup (GdmSessionWorker *worker)
 {
         GError  *error;
         gboolean res;

         error = NULL;
         res = gdm_session_worker_initialize_pam (worker,
                                                  worker->priv->service,
                                                  worker->priv->username,
                                                  worker->priv->hostname,
                                                  worker->priv->display_is_local,
                                                  worker->priv->x11_display_name,
                                                  worker->priv->x11_authority_file,
                                                  worker->priv->display_device,
                                                  worker->priv->display_seat_id,
                                                  &error);

         if (res) {
                 g_dbus_method_invocation_return_value (worker->priv->pending_invocation, NULL);
         } else {
                 g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error);
         }
         worker->priv->pending_invocation = NULL;
-
-        /* These singal handlers should be disconnected after the loading,
-         * so that gdm_session_settings_set_* APIs don't cause the emitting
-         * of Saved*NameRead D-Bus signals any more.
-         */
-        g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
-                                              G_CALLBACK (on_saved_session_name_read),
-                                              worker);
-
-        g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
-                                              G_CALLBACK (on_saved_language_name_read),
-                                              worker);
 }

 static void
 do_authenticate (GdmSessionWorker *worker)
 {
         GError  *error;
         gboolean res;

         /* find out who the user is and ensure they are who they say they are
          */
         error = NULL;
         res = gdm_session_worker_authenticate_user (worker,
                                                     worker->priv->password_is_required,
                                                     &error);
         if (res) {
                 /* we're authenticated.  Let's make sure we've been given
                  * a valid username for the system
                  */
                 if (!worker->priv->is_program_session) {
                         g_debug ("GdmSessionWorker: trying to get updated username");
                         gdm_session_worker_update_username (worker);
                 }

                 gdm_dbus_worker_complete_authenticate (GDM_DBUS_WORKER (worker), worker->priv->pending_invocation);
         } else {
                 g_debug ("GdmSessionWorker: Unable to verify user");
                 g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error);
         }
         worker->priv->pending_invocation = NULL;
 }
@@ -2236,60 +2224,72 @@ do_accredit (GdmSessionWorker *worker)
                 gdm_dbus_worker_complete_establish_credentials (GDM_DBUS_WORKER (worker), worker->priv->pending_invocation);
         } else {
                 g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error);
         }
         worker->priv->pending_invocation = NULL;
 }

 static void
 save_account_details_now (GdmSessionWorker *worker)
 {
         g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED);

         g_debug ("GdmSessionWorker: saving account details for user %s", worker->priv->username);
         worker->priv->state = GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED;
         if (!gdm_session_settings_save (worker->priv->user_settings,
                                         worker->priv->username)) {
                 g_warning ("could not save session and language settings");
         }
         queue_state_change (worker);
 }

 static void
 on_settings_is_loaded_changed (GdmSessionSettings *user_settings,
                                GParamSpec         *pspec,
                                GdmSessionWorker   *worker)
 {
         if (!gdm_session_settings_is_loaded (worker->priv->user_settings)) {
                 return;
         }

+        /* These singal handlers should be disconnected after the loading,
+         * so that gdm_session_settings_set_* APIs don't cause the emitting
+         * of Saved*NameRead D-Bus signals any more.
+         */
+        g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
+                                              G_CALLBACK (on_saved_session_name_read),
+                                              worker);
+
+        g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
+                                              G_CALLBACK (on_saved_language_name_read),
+                                              worker);
+
         if (worker->priv->state == GDM_SESSION_WORKER_STATE_NONE) {
                 g_debug ("GdmSessionWorker: queuing setup for user: %s %s",
                          worker->priv->username, worker->priv->display_device);
                 queue_state_change (worker);
         } else if (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED) {
                 save_account_details_now (worker);
         } else {
                 return;
         }

         g_signal_handlers_disconnect_by_func (G_OBJECT (worker->priv->user_settings),
                                               G_CALLBACK (on_settings_is_loaded_changed),
                                               worker);
 }

 static void
 do_save_account_details_when_ready (GdmSessionWorker *worker)
 {
         g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED);

         if (!gdm_session_settings_is_loaded (worker->priv->user_settings)) {
                 g_signal_connect (G_OBJECT (worker->priv->user_settings),
                                   "notify::is-loaded",
                                   G_CALLBACK (on_settings_is_loaded_changed),
                                   worker);
                 g_debug ("GdmSessionWorker: user %s, not fully loaded yet, will save account details later",
                          worker->priv->username);
                 gdm_session_settings_load (worker->priv->user_settings,
                                            worker->priv->username);
                 return;
@@ -2505,60 +2505,69 @@ gdm_session_worker_handle_open (GdmDBusWorker         *object,
                                 GDBusMethodInvocation *invocation)
 {
         GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
         validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED);
         return TRUE;
 }

 static gboolean
 gdm_session_worker_handle_setup (GdmDBusWorker         *object,
                                  GDBusMethodInvocation *invocation,
                                  const char            *service,
                                  const char            *x11_display_name,
                                  const char            *x11_authority_file,
                                  const char            *console,
                                  const char            *seat_id,
                                  const char            *hostname,
                                  gboolean               display_is_local)
 {
         GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
         validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE);

         worker->priv->service = g_strdup (service);
         worker->priv->x11_display_name = g_strdup (x11_display_name);
         worker->priv->x11_authority_file = g_strdup (x11_authority_file);
         worker->priv->display_device = g_strdup (console);
         worker->priv->display_seat_id = g_strdup (seat_id);
         worker->priv->hostname = g_strdup (hostname);
         worker->priv->display_is_local = display_is_local;
         worker->priv->username = NULL;

+        g_signal_connect_swapped (worker->priv->user_settings,
+                                  "notify::language-name",
+                                  G_CALLBACK (on_saved_language_name_read),
+                                  worker);
+
+        g_signal_connect_swapped (worker->priv->user_settings,
+                                  "notify::session-name",
+                                  G_CALLBACK (on_saved_session_name_read),
+                                  worker);
         return TRUE;
 }

 static gboolean
 gdm_session_worker_handle_setup_for_user (GdmDBusWorker         *object,
                                           GDBusMethodInvocation *invocation,
                                           const char            *service,
                                           const char            *username,
                                           const char            *x11_display_name,
                                           const char            *x11_authority_file,
                                           const char            *console,
                                           const char            *seat_id,
                                           const char            *hostname,
                                           gboolean               display_is_local)
 {
         GdmSessionWorker *worker = GDM_SESSION_WORKER (object);

         if (!validate_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE))
                 return TRUE;

         worker->priv->service = g_strdup (service);
         worker->priv->x11_display_name = g_strdup (x11_display_name);
         worker->priv->x11_authority_file = g_strdup (x11_authority_file);
         worker->priv->display_device = g_strdup (console);
         worker->priv->display_seat_id = g_strdup (seat_id);
         worker->priv->hostname = g_strdup (hostname);
         worker->priv->display_is_local = display_is_local;
         worker->priv->username = g_strdup (username);

         g_signal_connect_swapped (worker->priv->user_settings,
--
2.1.0