612c0dc
From 692613bc996f5ab090a1fb605ae8dd50c6bb81bf Mon Sep 17 00:00:00 2001
612c0dc
From: Ray Strode <rstrode@redhat.com>
612c0dc
Date: Thu, 6 Sep 2018 19:31:50 -0400
612c0dc
Subject: [PATCH] manager: do initial-setup post work in manager code
612c0dc
612c0dc
Right now we do the initial-setup related post work
612c0dc
when stopping the greeter, but the problem is we delay
612c0dc
stopping the greeter now until after the user session
612c0dc
is started.
612c0dc
612c0dc
That post-work needs to be done before the user session
612c0dc
is started.
612c0dc
612c0dc
This commit moves the code to a more logical place.
612c0dc
---
612c0dc
 daemon/gdm-display.c | 132 -------------------------------------------
612c0dc
 daemon/gdm-manager.c | 132 +++++++++++++++++++++++++++++++++++++++++++
612c0dc
 2 files changed, 132 insertions(+), 132 deletions(-)
612c0dc
612c0dc
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
612c0dc
index 5e193f2f5..511a5ca3f 100644
612c0dc
--- a/daemon/gdm-display.c
612c0dc
+++ b/daemon/gdm-display.c
612c0dc
@@ -22,61 +22,60 @@
612c0dc
 
612c0dc
 #include <stdlib.h>
612c0dc
 #include <stdio.h>
612c0dc
 #include <stdint.h>
612c0dc
 #include <fcntl.h>
612c0dc
 #include <unistd.h>
612c0dc
 #include <string.h>
612c0dc
 #include <signal.h>
612c0dc
 #include <sys/stat.h>
612c0dc
 #include <sys/types.h>
612c0dc
 
612c0dc
 #include <glib.h>
612c0dc
 #include <glib/gi18n.h>
612c0dc
 #include <glib-object.h>
612c0dc
 
612c0dc
 #include <xcb/xcb.h>
612c0dc
 #include <X11/Xlib.h>
612c0dc
 
612c0dc
 #include "gdm-common.h"
612c0dc
 #include "gdm-display.h"
612c0dc
 #include "gdm-display-glue.h"
612c0dc
 #include "gdm-display-access-file.h"
612c0dc
 #include "gdm-launch-environment.h"
612c0dc
 
612c0dc
 #include "gdm-settings-direct.h"
612c0dc
 #include "gdm-settings-keys.h"
612c0dc
 
612c0dc
 #include "gdm-launch-environment.h"
612c0dc
 #include "gdm-dbus-util.h"
612c0dc
 
612c0dc
-#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
612c0dc
 #define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions"
612c0dc
 
612c0dc
 #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate))
612c0dc
 
612c0dc
 struct GdmDisplayPrivate
612c0dc
 {
612c0dc
         char                 *id;
612c0dc
         char                 *seat_id;
612c0dc
         char                 *session_id;
612c0dc
         char                 *session_class;
612c0dc
         char                 *session_type;
612c0dc
 
612c0dc
         char                 *remote_hostname;
612c0dc
         int                   x11_display_number;
612c0dc
         char                 *x11_display_name;
612c0dc
         int                   status;
612c0dc
         time_t                creation_time;
612c0dc
         GTimer               *server_timer;
612c0dc
 
612c0dc
         char                 *x11_cookie;
612c0dc
         gsize                 x11_cookie_size;
612c0dc
         GdmDisplayAccessFile *access_file;
612c0dc
 
612c0dc
         guint                 finish_idle_id;
612c0dc
 
612c0dc
         xcb_connection_t     *xcb_connection;
612c0dc
         int                   xcb_screen_number;
612c0dc
 
612c0dc
         GDBusConnection      *connection;
612c0dc
         GdmDisplayAccessFile *user_access_file;
612c0dc
@@ -100,131 +99,60 @@ enum {
612c0dc
         PROP_0,
612c0dc
         PROP_ID,
612c0dc
         PROP_STATUS,
612c0dc
         PROP_SEAT_ID,
612c0dc
         PROP_SESSION_ID,
612c0dc
         PROP_SESSION_CLASS,
612c0dc
         PROP_SESSION_TYPE,
612c0dc
         PROP_REMOTE_HOSTNAME,
612c0dc
         PROP_X11_DISPLAY_NUMBER,
612c0dc
         PROP_X11_DISPLAY_NAME,
612c0dc
         PROP_X11_COOKIE,
612c0dc
         PROP_X11_AUTHORITY_FILE,
612c0dc
         PROP_IS_CONNECTED,
612c0dc
         PROP_IS_LOCAL,
612c0dc
         PROP_LAUNCH_ENVIRONMENT,
612c0dc
         PROP_IS_INITIAL,
612c0dc
         PROP_ALLOW_TIMED_LOGIN,
612c0dc
         PROP_HAVE_EXISTING_USER_ACCOUNTS,
612c0dc
         PROP_DOING_INITIAL_SETUP,
612c0dc
 };
612c0dc
 
612c0dc
 static void     gdm_display_class_init  (GdmDisplayClass *klass);
612c0dc
 static void     gdm_display_init        (GdmDisplay      *self);
612c0dc
 static void     gdm_display_finalize    (GObject         *object);
612c0dc
 static void     queue_finish            (GdmDisplay      *self);
612c0dc
 static void     _gdm_display_set_status (GdmDisplay *self,
612c0dc
                                          int         status);
612c0dc
 static gboolean wants_initial_setup (GdmDisplay *self);
612c0dc
 G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT)
612c0dc
 
612c0dc
-static gboolean
612c0dc
-chown_file (GFile   *file,
612c0dc
-            uid_t    uid,
612c0dc
-            gid_t    gid,
612c0dc
-            GError **error)
612c0dc
-{
612c0dc
-        if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid,
612c0dc
-                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
612c0dc
-                                          NULL, error)) {
612c0dc
-                return FALSE;
612c0dc
-        }
612c0dc
-        if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid,
612c0dc
-                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
612c0dc
-                                          NULL, error)) {
612c0dc
-                return FALSE;
612c0dc
-        }
612c0dc
-        return TRUE;
612c0dc
-}
612c0dc
-
612c0dc
-static gboolean
612c0dc
-chown_recursively (GFile   *dir,
612c0dc
-                   uid_t    uid,
612c0dc
-                   gid_t    gid,
612c0dc
-                   GError **error)
612c0dc
-{
612c0dc
-        GFile *file = NULL;
612c0dc
-        GFileInfo *info = NULL;
612c0dc
-        GFileEnumerator *enumerator = NULL;
612c0dc
-        gboolean retval = FALSE;
612c0dc
-
612c0dc
-        if (chown_file (dir, uid, gid, error) == FALSE) {
612c0dc
-                goto out;
612c0dc
-        }
612c0dc
-
612c0dc
-        enumerator = g_file_enumerate_children (dir,
612c0dc
-                                                G_FILE_ATTRIBUTE_STANDARD_TYPE","
612c0dc
-                                                G_FILE_ATTRIBUTE_STANDARD_NAME,
612c0dc
-                                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
612c0dc
-                                                NULL, error);
612c0dc
-        if (!enumerator) {
612c0dc
-                goto out;
612c0dc
-        }
612c0dc
-
612c0dc
-        while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) {
612c0dc
-                file = g_file_get_child (dir, g_file_info_get_name (info));
612c0dc
-
612c0dc
-                if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
612c0dc
-                        if (chown_recursively (file, uid, gid, error) == FALSE) {
612c0dc
-                                goto out;
612c0dc
-                        }
612c0dc
-                } else if (chown_file (file, uid, gid, error) == FALSE) {
612c0dc
-                        goto out;
612c0dc
-                }
612c0dc
-
612c0dc
-                g_clear_object (&file;;
612c0dc
-                g_clear_object (&info;;
612c0dc
-        }
612c0dc
-
612c0dc
-        if (*error) {
612c0dc
-                goto out;
612c0dc
-        }
612c0dc
-
612c0dc
-        retval = TRUE;
612c0dc
-out:
612c0dc
-        g_clear_object (&file;;
612c0dc
-        g_clear_object (&info;;
612c0dc
-        g_clear_object (&enumerator);
612c0dc
-
612c0dc
-        return retval;
612c0dc
-}
612c0dc
-
612c0dc
 GQuark
612c0dc
 gdm_display_error_quark (void)
612c0dc
 {
612c0dc
         static GQuark ret = 0;
612c0dc
         if (ret == 0) {
612c0dc
                 ret = g_quark_from_static_string ("gdm_display_error");
612c0dc
         }
612c0dc
 
612c0dc
         return ret;
612c0dc
 }
612c0dc
 
612c0dc
 time_t
612c0dc
 gdm_display_get_creation_time (GdmDisplay *self)
612c0dc
 {
612c0dc
         g_return_val_if_fail (GDM_IS_DISPLAY (self), 0);
612c0dc
 
612c0dc
         return self->priv->creation_time;
612c0dc
 }
612c0dc
 
612c0dc
 int
612c0dc
 gdm_display_get_status (GdmDisplay *self)
612c0dc
 {
612c0dc
         g_return_val_if_fail (GDM_IS_DISPLAY (self), 0);
612c0dc
 
612c0dc
         return self->priv->status;
612c0dc
 }
612c0dc
 
612c0dc
 const char *
612c0dc
 gdm_display_get_session_id (GdmDisplay *self)
612c0dc
 {
612c0dc
@@ -1631,145 +1559,85 @@ gdm_display_start_greeter_session (GdmDisplay *self)
612c0dc
                                  G_CALLBACK (on_launch_environment_session_stopped),
612c0dc
                                  self, 0);
612c0dc
         g_signal_connect_object (self->priv->launch_environment,
612c0dc
                                  "exited",
612c0dc
                                  G_CALLBACK (on_launch_environment_session_exited),
612c0dc
                                  self, 0);
612c0dc
         g_signal_connect_object (self->priv->launch_environment,
612c0dc
                                  "died",
612c0dc
                                  G_CALLBACK (on_launch_environment_session_died),
612c0dc
                                  self, 0);
612c0dc
 
612c0dc
         if (auth_file != NULL) {
612c0dc
                 g_object_set (self->priv->launch_environment,
612c0dc
                               "x11-authority-file", auth_file,
612c0dc
                               NULL);
612c0dc
         }
612c0dc
 
612c0dc
         gdm_launch_environment_start (self->priv->launch_environment);
612c0dc
 
612c0dc
         session = gdm_launch_environment_get_session (self->priv->launch_environment);
612c0dc
         g_object_set (G_OBJECT (session),
612c0dc
                       "display-is-initial", self->priv->is_initial,
612c0dc
                       NULL);
612c0dc
 
612c0dc
         g_free (display_name);
612c0dc
         g_free (seat_id);
612c0dc
         g_free (hostname);
612c0dc
         g_free (auth_file);
612c0dc
 }
612c0dc
 
612c0dc
-static void
612c0dc
-chown_initial_setup_home_dir (void)
612c0dc
-{
612c0dc
-        GFile *dir;
612c0dc
-        GError *error;
612c0dc
-        char *gis_dir_path;
612c0dc
-        char *gis_uid_path;
612c0dc
-        char *gis_uid_contents;
612c0dc
-        struct passwd *pwe;
612c0dc
-        uid_t uid;
612c0dc
-
612c0dc
-        if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) {
612c0dc
-                g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME);
612c0dc
-                return;
612c0dc
-        }
612c0dc
-
612c0dc
-        gis_dir_path = g_strdup (pwe->pw_dir);
612c0dc
-
612c0dc
-        gis_uid_path = g_build_filename (gis_dir_path,
612c0dc
-                                         "gnome-initial-setup-uid",
612c0dc
-                                         NULL);
612c0dc
-        if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) {
612c0dc
-                g_warning ("Unable to read %s", gis_uid_path);
612c0dc
-                goto out;
612c0dc
-        }
612c0dc
-
612c0dc
-        uid = (uid_t) atoi (gis_uid_contents);
612c0dc
-        pwe = getpwuid (uid);
612c0dc
-        if (uid == 0 || pwe == NULL) {
612c0dc
-                g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path);
612c0dc
-                goto out;
612c0dc
-        }
612c0dc
-
612c0dc
-        error = NULL;
612c0dc
-        dir = g_file_new_for_path (gis_dir_path);
612c0dc
-        if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) {
612c0dc
-                g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message);
612c0dc
-                g_error_free (error);
612c0dc
-        }
612c0dc
-        g_object_unref (dir);
612c0dc
-out:
612c0dc
-        g_free (gis_uid_contents);
612c0dc
-        g_free (gis_uid_path);
612c0dc
-        g_free (gis_dir_path);
612c0dc
-}
612c0dc
-
612c0dc
 void
612c0dc
 gdm_display_stop_greeter_session (GdmDisplay *self)
612c0dc
 {
612c0dc
         GError *error = NULL;
612c0dc
 
612c0dc
         if (self->priv->launch_environment != NULL) {
612c0dc
 
612c0dc
                 g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
612c0dc
                                                       G_CALLBACK (on_launch_environment_session_opened),
612c0dc
                                                       self);
612c0dc
                 g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
612c0dc
                                                       G_CALLBACK (on_launch_environment_session_started),
612c0dc
                                                       self);
612c0dc
                 g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
612c0dc
                                                       G_CALLBACK (on_launch_environment_session_stopped),
612c0dc
                                                       self);
612c0dc
                 g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
612c0dc
                                                       G_CALLBACK (on_launch_environment_session_exited),
612c0dc
                                                       self);
612c0dc
                 g_signal_handlers_disconnect_by_func (self->priv->launch_environment,
612c0dc
                                                       G_CALLBACK (on_launch_environment_session_died),
612c0dc
                                                       self);
612c0dc
                 gdm_launch_environment_stop (self->priv->launch_environment);
612c0dc
                 g_clear_object (&self->priv->launch_environment);
612c0dc
         }
612c0dc
-
612c0dc
-        if (self->priv->doing_initial_setup) {
612c0dc
-                chown_initial_setup_home_dir ();
612c0dc
-
612c0dc
-                if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
612c0dc
-                                          "1",
612c0dc
-                                          1,
612c0dc
-                                          &error)) {
612c0dc
-                        g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s",
612c0dc
-                                   ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
612c0dc
-                                   error->message);
612c0dc
-                        g_clear_error (&error);
612c0dc
-                }
612c0dc
-        }
612c0dc
 }
612c0dc
 
612c0dc
 static xcb_window_t
612c0dc
 get_root_window (xcb_connection_t *connection,
612c0dc
                  int               screen_number)
612c0dc
 {
612c0dc
         xcb_screen_t *screen = NULL;
612c0dc
         xcb_screen_iterator_t iter;
612c0dc
 
612c0dc
         iter = xcb_setup_roots_iterator (xcb_get_setup (connection));
612c0dc
         while (iter.rem) {
612c0dc
                 if (screen_number == 0)
612c0dc
                         screen = iter.data;
612c0dc
                 screen_number--;
612c0dc
                 xcb_screen_next (&iter);
612c0dc
         }
612c0dc
 
612c0dc
         if (screen != NULL) {
612c0dc
                 return screen->root;
612c0dc
         }
612c0dc
 
612c0dc
         return XCB_WINDOW_NONE;
612c0dc
 }
612c0dc
 
612c0dc
 static void
612c0dc
 gdm_display_set_windowpath (GdmDisplay *self)
612c0dc
 {
612c0dc
         /* setting WINDOWPATH for clients */
612c0dc
         xcb_intern_atom_cookie_t atom_cookie;
612c0dc
         xcb_intern_atom_reply_t *atom_reply = NULL;
612c0dc
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
612c0dc
index 20a9ba7d7..c37135f44 100644
612c0dc
--- a/daemon/gdm-manager.c
612c0dc
+++ b/daemon/gdm-manager.c
612c0dc
@@ -35,60 +35,61 @@
612c0dc
 #include <glib-object.h>
612c0dc
 
612c0dc
 #include <act/act-user-manager.h>
612c0dc
 
612c0dc
 #include <systemd/sd-login.h>
612c0dc
 
612c0dc
 #include "gdm-common.h"
612c0dc
 
612c0dc
 #include "gdm-dbus-util.h"
612c0dc
 #include "gdm-manager.h"
612c0dc
 #include "gdm-manager-glue.h"
612c0dc
 #include "gdm-display-store.h"
612c0dc
 #include "gdm-display-factory.h"
612c0dc
 #include "gdm-launch-environment.h"
612c0dc
 #include "gdm-local-display.h"
612c0dc
 #include "gdm-local-display-factory.h"
612c0dc
 #include "gdm-session.h"
612c0dc
 #include "gdm-session-record.h"
612c0dc
 #include "gdm-settings-direct.h"
612c0dc
 #include "gdm-settings-keys.h"
612c0dc
 #include "gdm-xdmcp-display-factory.h"
612c0dc
 #include "gdm-xdmcp-chooser-display.h"
612c0dc
 
612c0dc
 #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate))
612c0dc
 
612c0dc
 #define GDM_DBUS_PATH             "/org/gnome/DisplayManager"
612c0dc
 #define GDM_MANAGER_PATH          GDM_DBUS_PATH "/Manager"
612c0dc
 #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
612c0dc
 
612c0dc
 #define INITIAL_SETUP_USERNAME "gnome-initial-setup"
612c0dc
+#define ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT GDM_RUN_DIR "/gdm.ran-initial-setup"
612c0dc
 
612c0dc
 typedef struct
612c0dc
 {
612c0dc
         GdmManager *manager;
612c0dc
         GdmSession *session;
612c0dc
         char *service_name;
612c0dc
         guint idle_id;
612c0dc
 } StartUserSessionOperation;
612c0dc
 
612c0dc
 struct GdmManagerPrivate
612c0dc
 {
612c0dc
         GdmDisplayStore        *display_store;
612c0dc
         GdmLocalDisplayFactory *local_factory;
612c0dc
 #ifdef HAVE_LIBXDMCP
612c0dc
         GdmXdmcpDisplayFactory *xdmcp_factory;
612c0dc
 #endif
612c0dc
         GList                  *user_sessions;
612c0dc
         GHashTable             *transient_sessions;
612c0dc
         GHashTable             *open_reauthentication_requests;
612c0dc
         gboolean                xdmcp_enabled;
612c0dc
 
612c0dc
         gboolean                started;
612c0dc
         gboolean                show_local_greeter;
612c0dc
 
612c0dc
         GDBusConnection          *connection;
612c0dc
         GDBusObjectManagerServer *object_manager;
612c0dc
 
612c0dc
 #ifdef  WITH_PLYMOUTH
612c0dc
         guint                     plymouth_is_running : 1;
612c0dc
 #endif
612c0dc
@@ -1552,130 +1553,261 @@ start_user_session (GdmManager *manager,
612c0dc
 
612c0dc
         destroy_start_user_session_operation (operation);
612c0dc
 }
612c0dc
 
612c0dc
 static void
612c0dc
 create_display_for_user_session (GdmManager *self,
612c0dc
                                  GdmSession *session,
612c0dc
                                  const char *session_id)
612c0dc
 {
612c0dc
         GdmDisplay *display;
612c0dc
         /* at the moment we only create GdmLocalDisplay objects on seat0 */
612c0dc
         const char *seat_id = "seat0";
612c0dc
 
612c0dc
         display = gdm_local_display_new ();
612c0dc
 
612c0dc
         g_object_set (G_OBJECT (display),
612c0dc
                       "session-class", "user",
612c0dc
                       "seat-id", seat_id,
612c0dc
                       "session-id", session_id,
612c0dc
                       NULL);
612c0dc
         gdm_display_store_add (self->priv->display_store,
612c0dc
                                display);
612c0dc
         g_object_set_data (G_OBJECT (session), "gdm-display", display);
612c0dc
         g_object_set_data_full (G_OBJECT (display),
612c0dc
                                 "gdm-user-session",
612c0dc
                                 g_object_ref (session),
612c0dc
                                 (GDestroyNotify)
612c0dc
                                 clean_user_session);
612c0dc
 }
612c0dc
 
612c0dc
+static gboolean
612c0dc
+chown_file (GFile   *file,
612c0dc
+            uid_t    uid,
612c0dc
+            gid_t    gid,
612c0dc
+            GError **error)
612c0dc
+{
612c0dc
+        if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid,
612c0dc
+                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
612c0dc
+                                          NULL, error)) {
612c0dc
+                return FALSE;
612c0dc
+        }
612c0dc
+        if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid,
612c0dc
+                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
612c0dc
+                                          NULL, error)) {
612c0dc
+                return FALSE;
612c0dc
+        }
612c0dc
+        return TRUE;
612c0dc
+}
612c0dc
+
612c0dc
+static gboolean
612c0dc
+chown_recursively (GFile   *dir,
612c0dc
+                   uid_t    uid,
612c0dc
+                   gid_t    gid,
612c0dc
+                   GError **error)
612c0dc
+{
612c0dc
+        GFile *file = NULL;
612c0dc
+        GFileInfo *info = NULL;
612c0dc
+        GFileEnumerator *enumerator = NULL;
612c0dc
+        gboolean retval = FALSE;
612c0dc
+
612c0dc
+        if (chown_file (dir, uid, gid, error) == FALSE) {
612c0dc
+                goto out;
612c0dc
+        }
612c0dc
+
612c0dc
+        enumerator = g_file_enumerate_children (dir,
612c0dc
+                                                G_FILE_ATTRIBUTE_STANDARD_TYPE","
612c0dc
+                                                G_FILE_ATTRIBUTE_STANDARD_NAME,
612c0dc
+                                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
612c0dc
+                                                NULL, error);
612c0dc
+        if (!enumerator) {
612c0dc
+                goto out;
612c0dc
+        }
612c0dc
+
612c0dc
+        while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) {
612c0dc
+                file = g_file_get_child (dir, g_file_info_get_name (info));
612c0dc
+
612c0dc
+                if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
612c0dc
+                        if (chown_recursively (file, uid, gid, error) == FALSE) {
612c0dc
+                                goto out;
612c0dc
+                        }
612c0dc
+                } else if (chown_file (file, uid, gid, error) == FALSE) {
612c0dc
+                        goto out;
612c0dc
+                }
612c0dc
+
612c0dc
+                g_clear_object (&file;;
612c0dc
+                g_clear_object (&info;;
612c0dc
+        }
612c0dc
+
612c0dc
+        if (*error) {
612c0dc
+                goto out;
612c0dc
+        }
612c0dc
+
612c0dc
+        retval = TRUE;
612c0dc
+out:
612c0dc
+        g_clear_object (&file;;
612c0dc
+        g_clear_object (&info;;
612c0dc
+        g_clear_object (&enumerator);
612c0dc
+
612c0dc
+        return retval;
612c0dc
+}
612c0dc
+
612c0dc
+static void
612c0dc
+chown_initial_setup_home_dir (void)
612c0dc
+{
612c0dc
+        GFile *dir;
612c0dc
+        GError *error;
612c0dc
+        char *gis_dir_path;
612c0dc
+        char *gis_uid_path;
612c0dc
+        char *gis_uid_contents;
612c0dc
+        struct passwd *pwe;
612c0dc
+        uid_t uid;
612c0dc
+
612c0dc
+        if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) {
612c0dc
+                g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME);
612c0dc
+                return;
612c0dc
+        }
612c0dc
+
612c0dc
+        gis_dir_path = g_strdup (pwe->pw_dir);
612c0dc
+
612c0dc
+        gis_uid_path = g_build_filename (gis_dir_path,
612c0dc
+                                         "gnome-initial-setup-uid",
612c0dc
+                                         NULL);
612c0dc
+        if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) {
612c0dc
+                g_warning ("Unable to read %s", gis_uid_path);
612c0dc
+                goto out;
612c0dc
+        }
612c0dc
+
612c0dc
+        uid = (uid_t) atoi (gis_uid_contents);
612c0dc
+        pwe = getpwuid (uid);
612c0dc
+        if (uid == 0 || pwe == NULL) {
612c0dc
+                g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path);
612c0dc
+                goto out;
612c0dc
+        }
612c0dc
+
612c0dc
+        error = NULL;
612c0dc
+        dir = g_file_new_for_path (gis_dir_path);
612c0dc
+        if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) {
612c0dc
+                g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message);
612c0dc
+                g_error_free (error);
612c0dc
+        }
612c0dc
+        g_object_unref (dir);
612c0dc
+out:
612c0dc
+        g_free (gis_uid_contents);
612c0dc
+        g_free (gis_uid_path);
612c0dc
+        g_free (gis_dir_path);
612c0dc
+}
612c0dc
+
612c0dc
 static gboolean
612c0dc
 on_start_user_session (StartUserSessionOperation *operation)
612c0dc
 {
612c0dc
         GdmManager *self = operation->manager;
612c0dc
         gboolean migrated;
612c0dc
         gboolean fail_if_already_switched = TRUE;
612c0dc
         gboolean doing_initial_setup = FALSE;
612c0dc
         GdmDisplay *display;
612c0dc
         const char *session_id;
612c0dc
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
612c0dc
         g_autofree char *display_session_type = NULL;
612c0dc
 #endif
612c0dc
 
612c0dc
         g_debug ("GdmManager: start or jump to session");
612c0dc
 
612c0dc
         /* If there's already a session running, jump to it.
612c0dc
          * If the only session running is the one we just opened,
612c0dc
          * start a session on it.
612c0dc
          */
612c0dc
         migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched);
612c0dc
 
612c0dc
         g_debug ("GdmManager: migrated: %d", migrated);
612c0dc
         if (migrated) {
612c0dc
                 /* We don't stop the manager here because
612c0dc
                    when Xorg exits it switches to the VT it was
612c0dc
                    started from.  That interferes with fast
612c0dc
                    user switching. */
612c0dc
                 gdm_session_reset (operation->session);
612c0dc
                 destroy_start_user_session_operation (operation);
612c0dc
                 goto out;
612c0dc
         }
612c0dc
 
612c0dc
         display = get_display_for_user_session (operation->session);
612c0dc
 
612c0dc
         g_object_get (G_OBJECT (display),
612c0dc
                       "doing-initial-setup", &doing_initial_setup,
612c0dc
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
612c0dc
                       "session-type", &display_session_type,
612c0dc
 #endif
612c0dc
                       NULL);
612c0dc
 
612c0dc
         session_id = gdm_session_get_conversation_session_id (operation->session,
612c0dc
                                                               operation->service_name);
612c0dc
 
612c0dc
         if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) {
612c0dc
                 /* In this case, the greeter's display is morphing into
612c0dc
                  * the user session display. Kill the greeter on this session
612c0dc
                  * and let the user session follow the same display. */
612c0dc
                 gdm_display_stop_greeter_session (display);
612c0dc
                 g_object_set (G_OBJECT (display),
612c0dc
                                 "session-class", "user",
612c0dc
                                 "session-id", session_id,
612c0dc
                                 NULL);
612c0dc
         } else {
612c0dc
                 uid_t allowed_uid;
612c0dc
 
612c0dc
                 g_object_ref (display);
612c0dc
                 if (doing_initial_setup) {
612c0dc
+                        g_autoptr(GError) error = NULL;
612c0dc
+
612c0dc
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
612c0dc
                         if (g_strcmp0 (display_session_type, "wayland") == 0) {
612c0dc
                                 g_debug ("GdmManager: closing down initial setup display in background");
612c0dc
                                 g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL);
612c0dc
                         }
612c0dc
 #endif
612c0dc
                         if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) {
612c0dc
                                 g_debug ("GdmManager: closing down initial setup display");
612c0dc
                                 gdm_display_stop_greeter_session (display);
612c0dc
                                 gdm_display_unmanage (display);
612c0dc
                                 gdm_display_finish (display);
612c0dc
                         }
612c0dc
+
612c0dc
+                        chown_initial_setup_home_dir ();
612c0dc
+
612c0dc
+                        if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
612c0dc
+                                                  "1",
612c0dc
+                                                  1,
612c0dc
+                                                  &error)) {
612c0dc
+                                g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s",
612c0dc
+                                           ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
612c0dc
+                                           error->message);
612c0dc
+                                g_clear_error (&error);
612c0dc
+                        }
612c0dc
                 } else {
612c0dc
                         g_debug ("GdmManager: session has its display server, reusing our server for another login screen");
612c0dc
                 }
612c0dc
 
612c0dc
                 /* The user session is going to follow the session worker
612c0dc
                  * into the new display. Untie it from this display and
612c0dc
                  * create a new session for a future user login. */
612c0dc
                 allowed_uid = gdm_session_get_allowed_user (operation->session);
612c0dc
                 g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL);
612c0dc
                 g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL);
612c0dc
                 create_user_session_for_display (operation->manager, display, allowed_uid);
612c0dc
 
612c0dc
                 if (g_strcmp0 (operation->service_name, "gdm-autologin") == 0) {
612c0dc
                         /* remove the unused prepared greeter display since we're not going
612c0dc
                          * to have a greeter */
612c0dc
                         gdm_display_store_remove (self->priv->display_store, display);
612c0dc
                         g_object_unref (display);
612c0dc
                 }
612c0dc
 
612c0dc
                 /* Give the user session a new display object for bookkeeping purposes */
612c0dc
                 create_display_for_user_session (operation->manager,
612c0dc
                                                  operation->session,
612c0dc
                                                  session_id);
612c0dc
         }
612c0dc
 
612c0dc
         start_user_session (operation->manager, operation);
612c0dc
 
612c0dc
  out:
612c0dc
         return G_SOURCE_REMOVE;
612c0dc
 }
612c0dc
-- 
612c0dc
2.17.1
612c0dc