summaryrefslogtreecommitdiff
path: root/daemon/gdm-manager.c
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2018-09-06 19:31:50 -0400
committerRay Strode <rstrode@redhat.com>2018-10-06 09:40:39 -0400
commit36fe0a152cef027da93c4d16a3b2a05fade174a4 (patch)
tree33f4c6ce9fc5be66300d6b0b7582c6426e349ebf /daemon/gdm-manager.c
parentb569c1ef3fcb62292b7d66b950757a471dace3eb (diff)
downloadgdm-36fe0a152cef027da93c4d16a3b2a05fade174a4.tar.gz
manager: do initial-setup post work in manager code
Right now we do the initial-setup related post work when stopping the greeter, but the problem is we delay stopping the greeter now until after the user session is started. That post-work needs to be done before the user session is started. This commit moves the code to a more logical place.
Diffstat (limited to 'daemon/gdm-manager.c')
-rw-r--r--daemon/gdm-manager.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 62a96738..4d2ad9de 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -62,6 +62,7 @@
#define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays"
#define INITIAL_SETUP_USERNAME "gnome-initial-setup"
+#define ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT GDM_RUN_DIR "/gdm.ran-initial-setup"
typedef struct
{
@@ -1596,6 +1597,123 @@ create_display_for_user_session (GdmManager *self,
}
static gboolean
+chown_file (GFile *file,
+ uid_t uid,
+ gid_t gid,
+ GError **error)
+{
+ if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, error)) {
+ return FALSE;
+ }
+ if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, error)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+chown_recursively (GFile *dir,
+ uid_t uid,
+ gid_t gid,
+ GError **error)
+{
+ GFile *file = NULL;
+ GFileInfo *info = NULL;
+ GFileEnumerator *enumerator = NULL;
+ gboolean retval = FALSE;
+
+ if (chown_file (dir, uid, gid, error) == FALSE) {
+ goto out;
+ }
+
+ enumerator = g_file_enumerate_children (dir,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE","
+ G_FILE_ATTRIBUTE_STANDARD_NAME,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, error);
+ if (!enumerator) {
+ goto out;
+ }
+
+ while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) {
+ file = g_file_get_child (dir, g_file_info_get_name (info));
+
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
+ if (chown_recursively (file, uid, gid, error) == FALSE) {
+ goto out;
+ }
+ } else if (chown_file (file, uid, gid, error) == FALSE) {
+ goto out;
+ }
+
+ g_clear_object (&file);
+ g_clear_object (&info);
+ }
+
+ if (*error) {
+ goto out;
+ }
+
+ retval = TRUE;
+out:
+ g_clear_object (&file);
+ g_clear_object (&info);
+ g_clear_object (&enumerator);
+
+ return retval;
+}
+
+static void
+chown_initial_setup_home_dir (void)
+{
+ GFile *dir;
+ GError *error;
+ char *gis_dir_path;
+ char *gis_uid_path;
+ char *gis_uid_contents;
+ struct passwd *pwe;
+ uid_t uid;
+
+ if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) {
+ g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME);
+ return;
+ }
+
+ gis_dir_path = g_strdup (pwe->pw_dir);
+
+ gis_uid_path = g_build_filename (gis_dir_path,
+ "gnome-initial-setup-uid",
+ NULL);
+ if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) {
+ g_warning ("Unable to read %s", gis_uid_path);
+ goto out;
+ }
+
+ uid = (uid_t) atoi (gis_uid_contents);
+ pwe = getpwuid (uid);
+ if (uid == 0 || pwe == NULL) {
+ g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path);
+ goto out;
+ }
+
+ error = NULL;
+ dir = g_file_new_for_path (gis_dir_path);
+ if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) {
+ g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message);
+ g_error_free (error);
+ }
+ g_object_unref (dir);
+out:
+ g_free (gis_uid_contents);
+ g_free (gis_uid_path);
+ g_free (gis_dir_path);
+}
+
+static gboolean
on_start_user_session (StartUserSessionOperation *operation)
{
GdmManager *self = operation->manager;
@@ -1653,6 +1771,8 @@ on_start_user_session (StartUserSessionOperation *operation)
g_object_ref (display);
if (doing_initial_setup) {
+ g_autoptr(GError) error = NULL;
+
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
if (g_strcmp0 (display_session_type, "wayland") == 0) {
g_debug ("GdmManager: closing down initial setup display in background");
@@ -1665,6 +1785,18 @@ on_start_user_session (StartUserSessionOperation *operation)
gdm_display_unmanage (display);
gdm_display_finish (display);
}
+
+ chown_initial_setup_home_dir ();
+
+ if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
+ "1",
+ 1,
+ &error)) {
+ g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s",
+ ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT,
+ error->message);
+ g_clear_error (&error);
+ }
} else {
g_debug ("GdmManager: session has its display server, reusing our server for another login screen");
}