[gdm] worker: Copy environment from login session to reauth sessions



commit 6d5dd0936629d1d9754dfa93d4f4ac2738baaa84
Author: Ray Strode <rstrode redhat com>
Date:   Mon Sep 17 15:18:02 2012 -0400

    worker: Copy environment from login session to reauth sessions
    
    Reauthentication sessions depend on having the same environment
    as the session they were initiated from.  This is important to
    make sure login prompts are in the right language, to make sure
    the kerberos credentials cache is looked up, and for various
    other reasons.
    
    This commit copies the environment from the login session to
    any new reauthentication sessions that get started after login.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=684241

 daemon/gdm-launch-environment.c |    3 +-
 daemon/gdm-session-worker-job.c |   54 +++++++++++++++++++++++++++++---------
 daemon/gdm-session-worker-job.h |    2 +
 daemon/gdm-session-worker.c     |    7 ++++-
 daemon/gdm-session.c            |   51 ++++++++++++++++++++++++++++++++++++-
 daemon/gdm-session.h            |   17 +++++++-----
 daemon/gdm-simple-slave.c       |    3 +-
 7 files changed, 113 insertions(+), 24 deletions(-)
---
diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
index 10e9c32..de7ee4c 100644
--- a/daemon/gdm-launch-environment.c
+++ b/daemon/gdm-launch-environment.c
@@ -789,7 +789,8 @@ gdm_launch_environment_start (GdmLaunchEnvironment *launch_environment)
                                                              launch_environment->priv->x11_display_device,
                                                              launch_environment->priv->x11_display_seat_id,
                                                              launch_environment->priv->x11_authority_file,
-                                                             launch_environment->priv->x11_display_is_local);
+                                                             launch_environment->priv->x11_display_is_local,
+                                                             NULL);
 
         g_signal_connect (launch_environment->priv->session,
                           "conversation-started",
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
index 66268ad..557c452 100644
--- a/daemon/gdm-session-worker-job.c
+++ b/daemon/gdm-session-worker-job.c
@@ -57,11 +57,13 @@ struct GdmSessionWorkerJobPrivate
         guint           child_watch_id;
 
         char           *server_address;
+        char          **environment;
 };
 
 enum {
         PROP_0,
         PROP_SERVER_ADDRESS,
+        PROP_ENVIRONMENT,
         PROP_FOR_REAUTH,
 };
 
@@ -130,25 +132,30 @@ listify_hash (const char *key,
 }
 
 static void
-copy_environment_to_hash (GHashTable *hash)
+copy_environment_to_hash (GdmSessionWorkerJob *job,
+                          GHashTable          *hash)
 {
-        gchar **env_strv;
-        gint    i;
+        char **environment;
+        gint   i;
 
-        env_strv = g_listenv ();
+        if (job->priv->environment != NULL) {
+                environment = g_strdupv (job->priv->environment);
+        } else {
+                environment = g_get_environ ();
+        }
+        for (i = 0; environment[i]; i++) {
+                char **parts;
 
-        for (i = 0; env_strv [i]; i++) {
-                gchar *key = env_strv [i];
-                const gchar *value;
+                parts = g_strsplit (environment[i], "=", 2);
 
-                value = g_getenv (key);
-                if (!value)
-                        continue;
+                if (parts[0] != NULL && parts[1] != NULL) {
+                        g_hash_table_insert (hash, g_strdup (parts[0]), g_strdup (parts[1]));
+                }
 
-                g_hash_table_insert (hash, g_strdup (key), g_strdup (value));
+                g_strfreev (parts);
         }
 
-        g_strfreev (env_strv);
+        g_strfreev (environment);
 }
 
 static GPtrArray *
@@ -192,7 +199,7 @@ get_job_environment (GdmSessionWorkerJob *job)
 
         /* create a hash table of current environment, then update keys has necessary */
         hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-        copy_environment_to_hash (hash);
+        copy_environment_to_hash (job, hash);
 
         g_hash_table_insert (hash, g_strdup ("GDM_SESSION_DBUS_ADDRESS"), g_strdup (job->priv->server_address));
 
@@ -364,6 +371,15 @@ gdm_session_worker_job_set_for_reauth (GdmSessionWorkerJob *session_worker_job,
         session_worker_job->priv->for_reauth = for_reauth;
 }
 
+void
+gdm_session_worker_job_set_environment (GdmSessionWorkerJob *session_worker_job,
+                                        const char * const  *environment)
+{
+        g_return_if_fail (GDM_IS_SESSION_WORKER_JOB (session_worker_job));
+
+        session_worker_job->priv->environment = g_strdupv ((char **) environment);
+}
+
 static void
 gdm_session_worker_job_set_property (GObject      *object,
                                      guint         prop_id,
@@ -381,6 +397,9 @@ gdm_session_worker_job_set_property (GObject      *object,
         case PROP_FOR_REAUTH:
                 gdm_session_worker_job_set_for_reauth (self, g_value_get_boolean (value));
                 break;
+        case PROP_ENVIRONMENT:
+                gdm_session_worker_job_set_environment (self, g_value_get_pointer (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -404,6 +423,9 @@ gdm_session_worker_job_get_property (GObject    *object,
         case PROP_FOR_REAUTH:
                 g_value_set_boolean (value, self->priv->for_reauth);
                 break;
+        case PROP_ENVIRONMENT:
+                g_value_set_pointer (value, self->priv->environment);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -450,6 +472,12 @@ gdm_session_worker_job_class_init (GdmSessionWorkerJobClass *klass)
                                                                "for reauth",
                                                                FALSE,
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_ENVIRONMENT,
+                                         g_param_spec_pointer ("environment",
+                                                               "environment",
+                                                               "environment",
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         signals [STARTED] =
                 g_signal_new ("started",
                               G_OBJECT_CLASS_TYPE (object_class),
diff --git a/daemon/gdm-session-worker-job.h b/daemon/gdm-session-worker-job.h
index 2132ee1..8494ff4 100644
--- a/daemon/gdm-session-worker-job.h
+++ b/daemon/gdm-session-worker-job.h
@@ -59,6 +59,8 @@ void                    gdm_session_worker_job_set_server_address (GdmSessionWor
                                                                    const char          *server_address);
 void                    gdm_session_worker_job_set_for_reauth (GdmSessionWorkerJob *session_worker_job,
                                                                gboolean             for_reauth);
+void                    gdm_session_worker_job_set_environment    (GdmSessionWorkerJob *session_worker_job,
+                                                                   const char * const  *environment);
 gboolean                gdm_session_worker_job_start              (GdmSessionWorkerJob *session_worker_job,
                                                                    const char          *name);
 void                    gdm_session_worker_job_stop               (GdmSessionWorkerJob *session_worker_job);
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index d8a92b7..b1809f1 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2693,8 +2693,11 @@ reauthentication_request_new (GdmSessionWorker      *worker,
                               GDBusMethodInvocation *invocation)
 {
         ReauthenticationRequest *request;
+        char **environment;
         char *address;
 
+        environment = gdm_session_worker_get_environment (worker);
+
         request = g_slice_new (ReauthenticationRequest);
 
         request->worker = worker;
@@ -2707,7 +2710,8 @@ reauthentication_request_new (GdmSessionWorker      *worker,
                                             worker->priv->display_device,
                                             worker->priv->display_seat_id,
                                             worker->priv->x11_authority_file,
-                                            worker->priv->display_is_local);
+                                            worker->priv->display_is_local,
+                                            environment);
 
         g_signal_connect (request->session,
                           "client-connected",
@@ -2735,6 +2739,7 @@ reauthentication_request_new (GdmSessionWorker      *worker,
                           request);
 
         address = gdm_session_get_server_address (request->session);
+
         gdm_dbus_worker_complete_start_reauthentication (GDM_DBUS_WORKER (worker),
                                                          invocation,
                                                          address);
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 90b9045..22da76a 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -93,6 +93,8 @@ struct _GdmSessionPrivate
 
         GdmSessionConversation *session_conversation;
 
+        char                 **conversation_environment;
+
         GdmDBusUserVerifier   *user_verifier_interface;
         GdmDBusGreeter        *greeter_interface;
         GdmDBusRemoteGreeter  *remote_greeter_interface;
@@ -133,6 +135,7 @@ enum {
         PROP_DISPLAY_SEAT_ID,
         PROP_DISPLAY_X11_AUTHORITY_FILE,
         PROP_USER_X11_AUTHORITY_FILE,
+        PROP_CONVERSATION_ENVIRONMENT,
 };
 
 enum {
@@ -1761,6 +1764,13 @@ start_conversation (GdmSession *self,
         conversation->job = gdm_session_worker_job_new ();
         gdm_session_worker_job_set_server_address (conversation->job,
                                                    g_dbus_server_get_client_address (self->priv->worker_server));
+
+        if (self->priv->conversation_environment != NULL) {
+                gdm_session_worker_job_set_environment (conversation->job,
+                                                        (const char * const *)
+                                                        self->priv->conversation_environment);
+
+        }
         g_signal_connect (conversation->job,
                           "started",
                           G_CALLBACK (worker_started),
@@ -2200,6 +2210,20 @@ send_environment (GdmSession             *self,
                               conversation);
 }
 
+void
+gdm_session_send_environment (GdmSession *self,
+                              const char *service_name)
+{
+        GdmSessionConversation *conversation;
+
+        g_return_if_fail (GDM_IS_SESSION (self));
+
+        conversation = find_conversation_by_name (self, service_name);
+        if (conversation != NULL) {
+                send_environment (self, conversation);
+        }
+}
+
 static const char *
 get_language_name (GdmSession *self)
 {
@@ -2832,6 +2856,14 @@ set_allowed_user (GdmSession *self,
 }
 
 static void
+set_conversation_environment (GdmSession  *self,
+                              char       **environment)
+{
+        g_strfreev (self->priv->conversation_environment);
+        self->priv->conversation_environment = g_strdupv (environment);
+}
+
+static void
 gdm_session_set_property (GObject      *object,
                           guint         prop_id,
                           const GValue *value,
@@ -2869,6 +2901,9 @@ gdm_session_set_property (GObject      *object,
         case PROP_ALLOWED_USER:
                 set_allowed_user (self, g_value_get_uint (value));
                 break;
+        case PROP_CONVERSATION_ENVIRONMENT:
+                set_conversation_environment (self, g_value_get_pointer (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -2913,6 +2948,9 @@ gdm_session_get_property (GObject    *object,
         case PROP_ALLOWED_USER:
                 g_value_set_uint (value, self->priv->allowed_user);
                 break;
+        case PROP_CONVERSATION_ENVIRONMENT:
+                g_value_set_pointer (value, self->priv->environment);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -2949,6 +2987,9 @@ gdm_session_dispose (GObject *object)
         g_free (self->priv->display_x11_authority_file);
         self->priv->display_x11_authority_file = NULL;
 
+        g_strfreev (self->priv->conversation_environment);
+        self->priv->conversation_environment = NULL;
+
         if (self->priv->worker_server != NULL) {
                 g_dbus_server_stop (self->priv->worker_server);
                 g_clear_object (&self->priv->worker_server);
@@ -3223,6 +3264,12 @@ gdm_session_class_init (GdmSessionClass *session_class)
                                                             G_MAXUINT,
                                                             0,
                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_CONVERSATION_ENVIRONMENT,
+                                         g_param_spec_pointer ("conversation-environment",
+                                                               "conversation environment",
+                                                               "conversation environment",
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
         g_object_class_install_property (object_class,
                                          PROP_DISPLAY_NAME,
@@ -3285,7 +3332,8 @@ gdm_session_new (GdmSessionVerificationMode  verification_mode,
                  const char                 *display_device,
                  const char                 *display_seat_id,
                  const char                 *display_x11_authority_file,
-                 gboolean                    display_is_local)
+                 gboolean                    display_is_local,
+                 const char * const         *environment)
 {
         GdmSession *self;
 
@@ -3298,6 +3346,7 @@ gdm_session_new (GdmSessionVerificationMode  verification_mode,
                              "display-seat-id", display_seat_id,
                              "display-x11-authority-file", display_x11_authority_file,
                              "display-is-local", display_is_local,
+                             "conversation-environment", environment,
                              NULL);
 
         return self;
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index 2104a4c..2511eca 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -91,13 +91,14 @@ typedef struct
 GType            gdm_session_get_type                 (void);
 
 GdmSession      *gdm_session_new                      (GdmSessionVerificationMode verification_mode,
-                                                       uid_t       allowed_user,
-                                                       const char *display_name,
-                                                       const char *display_hostname,
-                                                       const char *display_device,
-                                                       const char *display_seat_id,
-                                                       const char *display_x11_authority_file,
-                                                       gboolean    display_is_local);
+                                                       uid_t         allowed_user,
+                                                       const char   *display_name,
+                                                       const char   *display_hostname,
+                                                       const char   *display_device,
+                                                       const char   *display_seat_id,
+                                                       const char   *display_x11_authority_file,
+                                                       gboolean      display_is_local,
+                                                       const char * const *environment);
 uid_t             gdm_session_get_allowed_user       (GdmSession     *session);
 void              gdm_session_start_reauthentication (GdmSession *session,
                                                       GPid        pid_of_caller,
@@ -126,6 +127,8 @@ void              gdm_session_setup_for_program           (GdmSession *session,
 void              gdm_session_set_environment_variable    (GdmSession *session,
                                                            const char *key,
                                                            const char *value);
+void              gdm_session_send_environment            (GdmSession *self,
+                                                           const char *service_name);
 void              gdm_session_reset                       (GdmSession *session);
 void              gdm_session_authenticate                (GdmSession *session,
                                                            const char *service_name);
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 563f6ed..632153b 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -754,7 +754,8 @@ create_new_session (GdmSimpleSlave  *slave)
                                                 display_device,
                                                 display_seat_id,
                                                 display_x11_authority_file,
-                                                display_is_local);
+                                                display_is_local,
+                                                NULL);
 
         g_free (display_id);
         g_free (display_name);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]