diff --git a/common/gdm-common.c b/common/gdm-common.c
index 654b84e0a..4f56a05d4 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -88,42 +88,6 @@ gdm_get_pwent_for_name (const char     *name,
         return (pwent != NULL);
 }
 
-gboolean
-gdm_get_pwent_for_uid (uid_t           uid,
-                       struct passwd **pwentp)
-{
-        struct passwd *pwent;
-
-        do {
-                errno = 0;
-                pwent = getpwuid (uid);
-        } while (pwent == NULL && errno == EINTR);
-
-        if (pwentp != NULL) {
-                *pwentp = pwent;
-        }
-
-        return (pwent != NULL);
-}
-
-gboolean
-gdm_get_grent_for_name (const char    *name,
-                        struct group **grentp)
-{
-        struct group *grent;
-
-        do {
-                errno = 0;
-                grent = getgrnam (name);
-        } while (grent == NULL && errno == EINTR);
-
-        if (grentp != NULL) {
-                *grentp = grent;
-        }
-
-        return (grent != NULL);
-}
-
 static gboolean
 gdm_get_grent_for_gid (gint           gid,
                        struct group **grentp)
diff --git a/common/gdm-common.h b/common/gdm-common.h
index 3e210b87b..cffefe1e4 100644
--- a/common/gdm-common.h
+++ b/common/gdm-common.h
@@ -24,7 +24,6 @@
 #include <glib-unix.h>
 #include <gio/gio.h>
 
-#include <grp.h>
 #include <pwd.h>
 #include <errno.h>
 
@@ -64,12 +63,6 @@ gboolean       gdm_find_display_session (GPid        pid,
 gboolean       gdm_get_pwent_for_name    (const char     *name,
                                           struct passwd **pwentp);
 
-gboolean       gdm_get_pwent_for_uid     (uid_t           uid,
-                                          struct passwd **pwentp);
-
-gboolean       gdm_get_grent_for_name    (const char     *name,
-                                          struct group  **grentp);
-
 gboolean       gdm_clear_close_on_exec_flag (int fd);
 
 char          *gdm_generate_random_bytes (gsize          size,
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 54e054808..5a5096aa1 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -1678,32 +1678,6 @@ wants_initial_setup (GdmDisplay *self)
         return enabled;
 }
 
-gboolean
-gdm_display_prepare_greeter_session (GdmDisplay          *self,
-                                     GdmDynamicUserStore *dyn_user_store,
-                                     uid_t               *ret_uid)
-{
-        g_autoptr (GError) error = NULL;
-        GdmDisplayPrivate *priv;
-        uid_t uid;
-
-        g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
-        priv = gdm_display_get_instance_private (self);
-        g_return_val_if_fail (g_strcmp0 (priv->session_class, "greeter") == 0, FALSE);
-
-        if (!gdm_launch_environment_ensure_uid (priv->launch_environment,
-                                                dyn_user_store, &uid, &error)) {
-                g_warning ("GdmDisplay: Failed to allocate UID for greeter: %s",
-                           error->message);
-                return FALSE;
-        }
-
-        if (ret_uid != NULL)
-                *ret_uid = uid;
-
-        return TRUE;
-}
-
 void
 gdm_display_start_greeter_session (GdmDisplay *self)
 {
diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h
index c91c44995..1575faac2 100644
--- a/daemon/gdm-display.h
+++ b/daemon/gdm-display.h
@@ -25,8 +25,6 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
-#include "gdm-dynamic-user-store.h"
-
 G_BEGIN_DECLS
 
 #define GDM_TYPE_DISPLAY (gdm_display_get_type ())
@@ -109,9 +107,6 @@ gboolean            gdm_display_add_user_authorization         (GdmDisplay *disp
 gboolean            gdm_display_remove_user_authorization      (GdmDisplay *display,
                                                                 const char *username,
                                                                 GError    **error);
-gboolean            gdm_display_prepare_greeter_session        (GdmDisplay          *display,
-                                                                GdmDynamicUserStore *dyn_user_store,
-                                                                uid_t               *ret_uid);
 void                gdm_display_start_greeter_session          (GdmDisplay  *display);
 void                gdm_display_stop_greeter_session           (GdmDisplay  *display);
 
diff --git a/daemon/gdm-dynamic-user-store.h b/daemon/gdm-dynamic-user-store.h
deleted file mode 100644
index 848f00525..000000000
--- a/daemon/gdm-dynamic-user-store.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright Red Hat
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#pragma once
-
-#include <sys/types.h>
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define GDM_TYPE_DYNAMIC_USER_STORE (gdm_dynamic_user_store_get_type ())
-G_DECLARE_FINAL_TYPE (GdmDynamicUserStore, gdm_dynamic_user_store, GDM, DYNAMIC_USER_STORE, GObject)
-
-typedef enum
-{
-  GDM_DYNAMIC_USER_STORE_ERROR_NO_FREE_UID,
-  GDM_DYNAMIC_USER_STORE_ERROR_NO_SUCH_GROUP,
-} GdmDynamicUserStoreError;
-
-#define GDM_DYNAMIC_USER_STORE_ERROR (gdm_dynamic_user_store_error_quark ())
-
-GQuark               gdm_dynamic_user_store_error_quark (void);
-
-GdmDynamicUserStore *gdm_dynamic_user_store_new         (void);
-
-gboolean             gdm_dynamic_user_store_create      (GdmDynamicUserStore  *store,
-                                                         const char           *preferred_username,
-                                                         const char           *display_name,
-                                                         const char           *member_of,
-                                                         char                **ret_username,
-                                                         uid_t                *ret_uid,
-                                                         char                **ret_home,
-                                                         GError              **error);
-
-void                 gdm_dynamic_user_store_remove      (GdmDynamicUserStore *store,
-                                                         uid_t                uid);
-
-G_END_DECLS
diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
index 67f6c291e..bfba6b3b1 100644
--- a/daemon/gdm-launch-environment.c
+++ b/daemon/gdm-launch-environment.c
@@ -31,6 +31,8 @@
 #include <sys/wait.h>
 #include <errno.h>
 #include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
 #include <signal.h>
 #ifdef HAVE_SYS_PRCTL_H
 #include <sys/prctl.h>
@@ -49,19 +51,9 @@
 #include "gdm-settings-direct.h"
 #include "gdm-settings-keys.h"
 
-#define GDM_GREETER_USERNAME "gdm-greeter"
-#define GDM_GREETER_DISP_NAME "GDM Greeter"
-#define GDM_SESSION_MODE "gdm"
-
-#define INITIAL_SETUP_SESSION "gnome-initial-setup"
 #define INITIAL_SETUP_USERNAME "gnome-initial-setup"
-#define INITIAL_SETUP_DISP_NAME "GNOME Initial Setup"
+#define GDM_SESSION_MODE "gdm"
 #define INITIAL_SETUP_SESSION_MODE "initial-setup"
-#define INITIAL_SETUP_GROUPNAME "gnome-initial-setup"
-#define INITIAL_SETUP_DCONF_PROFILE "gnome-initial-setup"
-
-#define GDM_CHOOSER_USERNAME "gdm-chooser"
-#define GDM_CHOOSER_DISP_NAME "GDM XDMCP Chooser"
 
 extern char **environ;
 
@@ -74,15 +66,8 @@ struct _GdmLaunchEnvironment
 
         GdmSessionVerificationMode verification_mode;
 
-        GdmDynamicUserStore *dyn_user_store;
-        char                *preferred_user_name;
-        char                *user_disp_name;
-        char                *user_member_of;
-        char                *dyn_user_name;
-        uid_t                dyn_uid;
-        char                *dyn_user_home;
-
-        char           *dconf_profile;
+        char           *user_name;
+        char           *runtime_dir;
         char           *session_id;
         char           *session_type;
         char           *session_mode;
@@ -105,10 +90,8 @@ enum {
         PROP_X11_DISPLAY_HOSTNAME,
         PROP_X11_AUTHORITY_FILE,
         PROP_X11_DISPLAY_IS_LOCAL,
-        PROP_PREFERRED_USER_NAME,
-        PROP_USER_DISP_NAME,
-        PROP_USER_MEMBER_OF,
-        PROP_DCONF_PROFILE,
+        PROP_USER_NAME,
+        PROP_RUNTIME_DIR,
         PROP_COMMAND,
 };
 
@@ -272,6 +255,7 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
 {
         gboolean is_initial_setup = FALSE;
         GHashTable    *hash;
+        struct passwd *pwent;
         static const char *const optional_environment[] = {
                 "GI_TYPELIB_PATH",
                 "LANG",
@@ -318,7 +302,7 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
 
         if (launch_environment->session_mode != NULL) {
                 g_hash_table_insert (hash, g_strdup ("GNOME_SHELL_SESSION_MODE"), g_strdup (launch_environment->session_mode));
-                g_hash_table_insert (hash, g_strdup ("DCONF_PROFILE"), g_strdup (launch_environment->dconf_profile));
+                g_hash_table_insert (hash, g_strdup ("DCONF_PROFILE"), g_strdup (launch_environment->user_name));
 
                 is_initial_setup = strcmp (launch_environment->session_mode, INITIAL_SETUP_SESSION_MODE) == 0;
 
@@ -330,16 +314,26 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
 		}
         }
 
-        g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (launch_environment->dyn_user_name));
-        g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (launch_environment->dyn_user_name));
-        g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (launch_environment->dyn_user_name));
+        g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (launch_environment->user_name));
+        g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (launch_environment->user_name));
+        g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (launch_environment->user_name));
 
         g_hash_table_insert (hash, g_strdup ("GDM_VERSION"), g_strdup (VERSION));
         g_hash_table_remove (hash, "MAIL");
 
-        g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (launch_environment->dyn_user_home));
-        g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup (launch_environment->dyn_user_home));
-        g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (NOLOGIN_PATH));
+        g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/"));
+        g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/"));
+        g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh"));
+
+        gdm_get_pwent_for_name (launch_environment->user_name, &pwent);
+        if (pwent != NULL) {
+                if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') {
+                        g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir));
+                        g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup (pwent->pw_dir));
+                }
+
+                g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (pwent->pw_shell));
+       }
 
         if (start_session && launch_environment->x11_display_seat_id != NULL) {
                 char *seat_id;
@@ -351,7 +345,7 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
                 g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id));
 
                 if (!is_initial_setup &&
-                    setup_seat_persist_dirs(seat_id, launch_environment->dyn_uid, &config_dir, &state_dir)) {
+                    setup_seat_persist_dirs(seat_id, pwent->pw_uid, &config_dir, &state_dir)) {
                         g_hash_table_insert (hash, g_strdup ("XDG_CONFIG_HOME"), config_dir);
                         g_hash_table_insert (hash, g_strdup ("XDG_STATE_HOME"), state_dir);
                 }
@@ -473,7 +467,7 @@ on_conversation_started (GdmSession           *session,
 
         gdm_session_setup_for_program (launch_environment->session,
                                        "gdm-launch-environment",
-                                       launch_environment->dyn_user_name,
+                                       launch_environment->user_name,
                                        log_path);
 }
 
@@ -498,31 +492,26 @@ on_conversation_stopped (GdmSession           *session,
         }
 }
 
-gboolean
-gdm_launch_environment_ensure_uid (GdmLaunchEnvironment  *launch_environment,
-                                   GdmDynamicUserStore   *dyn_user_store,
-                                   uid_t                 *uid,
-                                   GError               **error)
+static gboolean
+ensure_directory_with_uid_gid (const char  *path,
+                               uid_t        uid,
+                               gid_t        gid,
+                               GError     **error)
 {
-        if (launch_environment->dyn_uid != 0) {
-                *uid = launch_environment->dyn_uid;
-                return TRUE;
+        if (mkdir (path, 0700) == -1 && errno != EEXIST) {
+                g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                             "Failed to create directory %s: %s", path,
+                             g_strerror (errno));
+                return FALSE;
         }
 
-        if (!gdm_dynamic_user_store_create (dyn_user_store,
-                                            launch_environment->preferred_user_name,
-                                            launch_environment->user_disp_name,
-                                            launch_environment->user_member_of,
-                                            &launch_environment->dyn_user_name,
-                                            &launch_environment->dyn_uid,
-                                            &launch_environment->dyn_user_home,
-                                            error))
+        if (chown (path, uid, gid) == -1) {
+                g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                             "Failed to set owner of %s: %s", path,
+                             g_strerror (errno));
                 return FALSE;
 
-        /* We've allocated the UID, so let's make sure we can deallocate later */
-        g_set_object (&launch_environment->dyn_user_store, dyn_user_store);
-
-        *uid = launch_environment->dyn_uid;
+        }
         return TRUE;
 }
 
@@ -536,14 +525,37 @@ gboolean
 gdm_launch_environment_start (GdmLaunchEnvironment *launch_environment)
 {
         g_autoptr(GError) error = NULL;
+        struct passwd    *passwd_entry;
+        uid_t             uid;
+        gid_t             gid;
 
         g_return_val_if_fail (GDM_IS_LAUNCH_ENVIRONMENT (launch_environment), FALSE);
-        g_return_val_if_fail (launch_environment->dyn_uid != 0, FALSE);
 
         g_debug ("GdmLaunchEnvironment: Starting...");
 
+        if (!gdm_get_pwent_for_name (launch_environment->user_name, &passwd_entry)) {
+                g_critical ("GdmLaunchEnvironment: Unknown user %s", launch_environment->user_name);
+                return FALSE;
+        }
+
+        uid = passwd_entry->pw_uid;
+        gid = passwd_entry->pw_gid;
+
+        g_debug ("GdmLaunchEnvironment: Setting up run time dir %s",
+                 launch_environment->runtime_dir);
+        if (!ensure_directory_with_uid_gid (launch_environment->runtime_dir, uid, gid, &error)) {
+                g_critical ("GdmLaunchEnvironment: %s", error->message);
+                return FALSE;
+        }
+
+       /* Create the home directory too */
+        if (!ensure_directory_with_uid_gid (passwd_entry->pw_dir, uid, gid, &error)) {
+                g_critical ("GdmLaunchEnvironment: %s", error->message);
+                return FALSE;
+        }
+
         launch_environment->session = gdm_session_new (launch_environment->verification_mode,
-                                                       launch_environment->dyn_uid,
+                                                       uid,
                                                        launch_environment->x11_display_name,
                                                        launch_environment->x11_display_hostname,
                                                        launch_environment->x11_display_device,
@@ -621,12 +633,6 @@ gdm_launch_environment_stop (GdmLaunchEnvironment *launch_environment)
                 g_clear_object (&launch_environment->session);
         }
 
-        if (launch_environment->dyn_uid != 0) {
-                gdm_dynamic_user_store_remove (launch_environment->dyn_user_store,
-                                               launch_environment->dyn_uid);
-                launch_environment->dyn_uid = 0;
-        }
-
         g_signal_emit (G_OBJECT (launch_environment), signals [STOPPED], 0);
 
         return TRUE;
@@ -719,35 +725,19 @@ _gdm_launch_environment_set_x11_authority_file (GdmLaunchEnvironment *launch_env
 }
 
 static void
-_gdm_launch_environment_set_preferred_user_name (GdmLaunchEnvironment *launch_environment,
-                                                 const char           *name)
-{
-        g_free (launch_environment->preferred_user_name);
-        launch_environment->preferred_user_name = g_strdup (name);
-}
-
-static void
-_gdm_launch_environment_set_user_disp_name (GdmLaunchEnvironment *launch_environment,
-                                            const char           *disp_name)
-{
-        g_free (launch_environment->user_disp_name);
-        launch_environment->user_disp_name = g_strdup (disp_name);
-}
-
-static void
-_gdm_launch_environment_set_user_member_of (GdmLaunchEnvironment *launch_environment,
-                                            const char           *member_of)
+_gdm_launch_environment_set_user_name (GdmLaunchEnvironment *launch_environment,
+                                       const char           *name)
 {
-        g_free (launch_environment->user_member_of);
-        launch_environment->user_member_of = g_strdup (member_of);
+        g_free (launch_environment->user_name);
+        launch_environment->user_name = g_strdup (name);
 }
 
 static void
-_gdm_launch_environment_set_dconf_profile (GdmLaunchEnvironment *launch_environment,
-                                            const char           *profile)
+_gdm_launch_environment_set_runtime_dir (GdmLaunchEnvironment *launch_environment,
+                                         const char           *dir)
 {
-        g_free (launch_environment->dconf_profile);
-        launch_environment->dconf_profile = g_strdup (profile);
+        g_free (launch_environment->runtime_dir);
+        launch_environment->runtime_dir = g_strdup (dir);
 }
 
 static void
@@ -796,17 +786,11 @@ gdm_launch_environment_set_property (GObject      *object,
         case PROP_X11_AUTHORITY_FILE:
                 _gdm_launch_environment_set_x11_authority_file (self, g_value_get_string (value));
                 break;
-        case PROP_PREFERRED_USER_NAME:
-                _gdm_launch_environment_set_preferred_user_name (self, g_value_get_string (value));
-                break;
-        case PROP_USER_DISP_NAME:
-                _gdm_launch_environment_set_user_disp_name (self, g_value_get_string (value));
+        case PROP_USER_NAME:
+                _gdm_launch_environment_set_user_name (self, g_value_get_string (value));
                 break;
-        case PROP_USER_MEMBER_OF:
-                _gdm_launch_environment_set_user_member_of (self, g_value_get_string (value));
-                break;
-        case PROP_DCONF_PROFILE:
-                _gdm_launch_environment_set_dconf_profile (self, g_value_get_string (value));
+        case PROP_RUNTIME_DIR:
+                _gdm_launch_environment_set_runtime_dir (self, g_value_get_string (value));
                 break;
         case PROP_COMMAND:
                 _gdm_launch_environment_set_command (self, g_value_get_string (value));
@@ -855,17 +839,11 @@ gdm_launch_environment_get_property (GObject    *object,
         case PROP_X11_AUTHORITY_FILE:
                 g_value_set_string (value, self->x11_authority_file);
                 break;
-        case PROP_PREFERRED_USER_NAME:
-                g_value_set_string (value, self->preferred_user_name);
-                break;
-        case PROP_USER_DISP_NAME:
-                g_value_set_string (value, self->user_disp_name);
-                break;
-        case PROP_USER_MEMBER_OF:
-                g_value_set_string (value, self->user_member_of);
+        case PROP_USER_NAME:
+                g_value_set_string (value, self->user_name);
                 break;
-        case PROP_DCONF_PROFILE:
-                g_value_set_string (value, self->dconf_profile);
+        case PROP_RUNTIME_DIR:
+                g_value_set_string (value, self->runtime_dir);
                 break;
         case PROP_COMMAND:
                 g_value_set_string (value, self->command);
@@ -950,31 +928,17 @@ gdm_launch_environment_class_init (GdmLaunchEnvironmentClass *klass)
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
         g_object_class_install_property (object_class,
-                                         PROP_PREFERRED_USER_NAME,
-                                         g_param_spec_string ("preferred-user-name",
-                                                              "preferred user name",
-                                                              "preferred user name",
+                                         PROP_USER_NAME,
+                                         g_param_spec_string ("user-name",
+                                                              "user name",
+                                                              "user name",
                                                               GDM_USERNAME,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
         g_object_class_install_property (object_class,
-                                         PROP_USER_DISP_NAME,
-                                         g_param_spec_string ("user-display-name",
-                                                              "user display name",
-                                                              "user display name",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-        g_object_class_install_property (object_class,
-                                         PROP_USER_MEMBER_OF,
-                                         g_param_spec_string ("user-member-of",
-                                                              "user member of",
-                                                              "user member of",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-        g_object_class_install_property (object_class,
-                                         PROP_DCONF_PROFILE,
-                                         g_param_spec_string ("dconf-profile",
-                                                              "dconf profile",
-                                                              "dconf profile",
+                                         PROP_RUNTIME_DIR,
+                                         g_param_spec_string ("runtime-dir",
+                                                              "runtime dir",
+                                                              "runtime dir",
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
         g_object_class_install_property (object_class,
@@ -1074,12 +1038,8 @@ gdm_launch_environment_finalize (GObject *object)
         }
 
         g_free (launch_environment->command);
-        g_free (launch_environment->preferred_user_name);
-        g_free (launch_environment->dyn_user_name);
-        g_free (launch_environment->dyn_user_home);
-        g_free (launch_environment->user_disp_name);
-        g_free (launch_environment->user_member_of);
-        g_free (launch_environment->dconf_profile);
+        g_free (launch_environment->user_name);
+        g_free (launch_environment->runtime_dir);
         g_free (launch_environment->x11_display_name);
         g_free (launch_environment->x11_display_seat_id);
         g_free (launch_environment->x11_display_device);
@@ -1088,17 +1048,12 @@ gdm_launch_environment_finalize (GObject *object)
         g_free (launch_environment->session_id);
         g_free (launch_environment->session_type);
 
-        g_clear_object (&launch_environment->dyn_user_store);
-
         G_OBJECT_CLASS (gdm_launch_environment_parent_class)->finalize (object);
 }
 
 static GdmLaunchEnvironment *
 create_gnome_session_environment (const char *session_id,
-                                  const char *preferred_user_name,
-                                  const char *user_display_name,
-                                  const char *user_member_of,
-                                  const char *dconf_profile,
+                                  const char *user_name,
                                   const char *display_name,
                                   const char *seat_id,
                                   const char *session_type,
@@ -1117,6 +1072,9 @@ create_gnome_session_environment (const char *session_id,
         args = g_ptr_array_new ();
         g_ptr_array_add (args, "gnome-session");
 
+        g_ptr_array_add (args, "--autostart");
+        g_ptr_array_add (args, DATADIR "/gdm/greeter/autostart");
+
         if (debug) {
                 g_ptr_array_add (args, "--debug");
         }
@@ -1133,16 +1091,14 @@ create_gnome_session_environment (const char *session_id,
 
         launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT,
                                            "command", command,
-                                           "preferred-user-name", preferred_user_name,
-                                           "user-display-name", user_display_name,
-                                           "user-member-of", user_member_of,
-                                           "dconf-profile", dconf_profile,
+                                           "user-name", user_name,
                                            "session-type", session_type,
                                            "session-mode", session_mode,
                                            "x11-display-name", display_name,
                                            "x11-display-seat-id", seat_id,
                                            "x11-display-hostname", display_hostname,
                                            "x11-display-is-local", display_is_local,
+		                                   "runtime-dir", GDM_SCREENSHOT_DIR,
                                            NULL);
 
         return launch_environment;
@@ -1155,11 +1111,10 @@ gdm_create_greeter_launch_environment (const char *display_name,
                                        const char *display_hostname,
                                        gboolean    display_is_local)
 {
-        return create_gnome_session_environment (NULL,
-                                                 GDM_GREETER_USERNAME,
-                                                 GDM_GREETER_DISP_NAME,
-                                                 GDM_GROUPNAME,
-                                                 GDM_DCONF_PROFILE,
+        const char *session_name = NULL;
+
+        return create_gnome_session_environment (session_name,
+                                                 GDM_USERNAME,
                                                  display_name,
                                                  seat_id,
                                                  session_type,
@@ -1175,11 +1130,8 @@ gdm_create_initial_setup_launch_environment (const char *display_name,
                                              const char *display_hostname,
                                              gboolean    display_is_local)
 {
-        return create_gnome_session_environment (INITIAL_SETUP_SESSION,
+        return create_gnome_session_environment ("gnome-initial-setup",
                                                  INITIAL_SETUP_USERNAME,
-                                                 INITIAL_SETUP_DISP_NAME,
-                                                 INITIAL_SETUP_GROUPNAME,
-                                                 INITIAL_SETUP_DCONF_PROFILE,
                                                  display_name,
                                                  seat_id,
                                                  session_type,
@@ -1199,14 +1151,12 @@ gdm_create_chooser_launch_environment (const char *display_name,
         launch_environment = g_object_new (GDM_TYPE_LAUNCH_ENVIRONMENT,
                                            "command", LIBEXECDIR "/gdm-simple-chooser",
                                            "verification-mode", GDM_SESSION_VERIFICATION_MODE_CHOOSER,
-                                           "preferred-user-name", GDM_CHOOSER_USERNAME,
-                                           "user-display-name", GDM_CHOOSER_DISP_NAME,
-                                           "user-member-of", GDM_GROUPNAME,
-                                           "dconf-profile", GDM_DCONF_PROFILE,
+                                           "user-name", GDM_USERNAME,
                                            "x11-display-name", display_name,
                                            "x11-display-seat-id", seat_id,
                                            "x11-display-hostname", display_hostname,
                                            "x11-display-is-local", FALSE,
+		                                   "runtime-dir", GDM_SCREENSHOT_DIR,
                                            NULL);
 
         return launch_environment;
diff --git a/daemon/gdm-launch-environment.h b/daemon/gdm-launch-environment.h
index f0102efe6..5636014f8 100644
--- a/daemon/gdm-launch-environment.h
+++ b/daemon/gdm-launch-environment.h
@@ -23,19 +23,13 @@
 #define __GDM_LAUNCH_ENVIRONMENT_H
 
 #include <glib-object.h>
-
 #include "gdm-session.h"
-#include "gdm-dynamic-user-store.h"
 
 G_BEGIN_DECLS
 
 #define GDM_TYPE_LAUNCH_ENVIRONMENT (gdm_launch_environment_get_type ())
 G_DECLARE_FINAL_TYPE (GdmLaunchEnvironment, gdm_launch_environment, GDM, LAUNCH_ENVIRONMENT, GObject)
 
-gboolean              gdm_launch_environment_ensure_uid         (GdmLaunchEnvironment  *launch_environment,
-                                                                 GdmDynamicUserStore   *dyn_user_store,
-                                                                 uid_t                 *uid,
-                                                                 GError               **error);
 gboolean              gdm_launch_environment_start              (GdmLaunchEnvironment *launch_environment);
 gboolean              gdm_launch_environment_stop               (GdmLaunchEnvironment *launch_environment);
 GdmSession *          gdm_launch_environment_get_session        (GdmLaunchEnvironment *launch_environment);
@@ -46,13 +40,11 @@ GdmLaunchEnvironment *gdm_create_greeter_launch_environment (const char *display
                                                              const char *session_type,
                                                              const char *display_hostname,
                                                              gboolean    display_is_local);
-
 GdmLaunchEnvironment *gdm_create_initial_setup_launch_environment (const char *display_name,
                                                                    const char *seat_id,
                                                                    const char *session_type,
                                                                    const char *display_hostname,
                                                                    gboolean    display_is_local);
-
 GdmLaunchEnvironment *gdm_create_chooser_launch_environment (const char *display_name,
                                                              const char *seat_id,
                                                              const char *display_hostname);
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index f73bccf61..10a5475f2 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -46,7 +46,6 @@
 #include "gdm-manager-glue.h"
 #include "gdm-display-store.h"
 #include "gdm-display-factory.h"
-#include "gdm-dynamic-user-store.h"
 #include "gdm-launch-environment.h"
 #include "gdm-local-display.h"
 #include "gdm-local-display-factory.h"
@@ -63,8 +62,8 @@
 #define GDM_MANAGER_PATH          GDM_DBUS_PATH "/Manager"
 #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"
-#define INITIAL_SETUP_EXPORT_DIR GDM_RUN_DIR "/gnome-initial-setup"
 
 typedef struct
 {
@@ -77,7 +76,6 @@
 struct _GdmManager
 {
         GdmDBusManagerSkeleton parent;
-        GdmDynamicUserStore    *dyn_user_store;
         GdmDisplayStore        *display_store;
         GdmLocalDisplayFactory *local_factory;
 #ifdef HAVE_LIBXDMCP
@@ -903,7 +901,6 @@
         allowed_user = gdm_session_get_allowed_user (session);
 
         if (uid != allowed_user) {
-                g_debug("GdmSession: Denying access to %d, only %d is allowed", uid, allowed_user);
                 g_dbus_method_invocation_return_error_literal (invocation,
                                                                G_DBUS_ERROR,
                                                                G_DBUS_ERROR_ACCESS_DENIED,
@@ -1369,6 +1366,23 @@
         return enabled;
 }
 
+static const char *
+get_username_for_greeter_display (GdmManager *manager,
+                                  GdmDisplay *display)
+{
+        gboolean doing_initial_setup = FALSE;
+
+        g_object_get (G_OBJECT (display),
+                      "doing-initial-setup", &doing_initial_setup,
+                      NULL);
+
+        if (doing_initial_setup) {
+                return INITIAL_SETUP_USERNAME;
+        } else {
+                return GDM_USERNAME;
+        }
+}
+
 static void
 set_up_automatic_login_session (GdmManager *manager,
                                 GdmDisplay *display)
@@ -1400,7 +1414,14 @@
 set_up_chooser_session (GdmManager *manager,
                         GdmDisplay *display)
 {
-        if (!gdm_display_prepare_greeter_session (display, manager->dyn_user_store, NULL)) {
+        const char *allowed_user;
+        struct passwd *passwd_entry;
+
+        allowed_user = get_username_for_greeter_display (manager, display);
+
+        if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) {
+                g_warning ("GdmManager: couldn't look up username %s",
+                           allowed_user);
                 gdm_display_unmanage (display);
                 gdm_display_finish (display);
                 return;
@@ -1414,15 +1435,20 @@
 set_up_greeter_session (GdmManager *manager,
                         GdmDisplay *display)
 {
-        uid_t greeter_uid;
+        const char *allowed_user;
+        struct passwd *passwd_entry;
 
-        if (!gdm_display_prepare_greeter_session (display, manager->dyn_user_store, &greeter_uid)) {
+        allowed_user = get_username_for_greeter_display (manager, display);
+
+        if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) {
+                g_warning ("GdmManager: couldn't look up username %s",
+                           allowed_user);
                 gdm_display_unmanage (display);
                 gdm_display_finish (display);
                 return;
         }
 
-        create_user_session_for_display (manager, display, greeter_uid);
+        create_user_session_for_display (manager, display, passwd_entry->pw_uid);
         gdm_display_start_greeter_session (display);
 }
 
@@ -1703,60 +1729,53 @@
                                 clean_user_session);
 }
 
-static gboolean
-export_initial_setup_home_dir (GdmSession *initial_setup_session)
+static void
+chown_initial_setup_home_dir (void)
 {
-        uid_t gis_uid;
+        GFile *dir;
+        GError *error;
+        char *gis_dir_path;
+        char *gis_uid_path;
+        char *gis_uid_contents;
         struct passwd *pwe;
-        g_autoptr (GFile) gis_home = NULL;
-        g_autoptr (GError) error = NULL;
-        g_autofree char *user_uid_path = NULL;
-        g_autofree char *user_uid_contents = NULL;
-        uid_t user_uid;
-        g_autoptr (GFile) gis_export = NULL;
-
-        gis_uid = gdm_session_get_allowed_user (initial_setup_session);
+        uid_t uid;
 
-        if (!gdm_get_pwent_for_uid (gis_uid, &pwe)) {
-                g_warning ("Failed to resolve gnome-initial-setup UID: %d", gis_uid);
-                return FALSE;
+        if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) {
+                g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME);
+                return;
         }
 
-        gis_home = g_file_new_for_path (pwe->pw_dir);
-
-        user_uid_path = g_build_filename (pwe->pw_dir, "gnome-initial-setup-uid", NULL);
-        if (!g_file_get_contents (user_uid_path, &user_uid_contents, NULL, &error)) {
-                g_warning ("Unable to read %s: %s", user_uid_path, error->message);
-                return FALSE;
-        }
-        user_uid = (uid_t) atoi (user_uid_contents);
+        gis_dir_path = g_strdup (pwe->pw_dir);
 
-        if (!gdm_get_pwent_for_uid (user_uid, &pwe)) {
-                g_warning ("UID '%s' in %s is not valid", user_uid_contents, user_uid_path);
-                return FALSE;
+        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;
         }
 
-        g_debug ("Moving %s to " INITIAL_SETUP_EXPORT_DIR,
-                 g_file_peek_path (gis_home));
-
-        gis_export = g_file_new_for_path (INITIAL_SETUP_EXPORT_DIR);
-        if (!g_file_move (gis_home, gis_export, G_FILE_COPY_OVERWRITE, NULL,
-                          NULL, NULL, &error)) {
-                g_warning ("Failed to move %s to " INITIAL_SETUP_EXPORT_DIR ": %s",
-                           g_file_peek_path (gis_home), error->message);
-                return FALSE;
+        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;
         }
 
-        g_debug ("Changing ownership of " INITIAL_SETUP_EXPORT_DIR " to %u:%u",
-                 pwe->pw_uid, pwe->pw_gid);
+        g_debug ("Changing ownership of %s to %u:%u", gis_dir_path, pwe->pw_uid, pwe->pw_gid);
 
-        if (!gdm_chown_recursively (gis_export, pwe->pw_uid, pwe->pw_gid, &error)) {
-                g_warning ("Failed to change ownership of " INITIAL_SETUP_EXPORT_DIR ": %s",
-                           error->message);
-                return FALSE;
-        }
+        error = NULL;
+        dir = g_file_new_for_path (gis_dir_path);
+        if (!gdm_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);
+         }
 
-        return TRUE;
+        g_object_unref (dir);
+out:
+        g_free (gis_uid_contents);
+        g_free (gis_uid_path);
+        g_free (gis_dir_path);
 }
 
 static gboolean
@@ -1922,7 +1941,7 @@
                       "doing-initial-setup", &doing_initial_setup,
                       NULL);
         if (doing_initial_setup)
-                export_initial_setup_home_dir (session);
+                chown_initial_setup_home_dir ();
 }
 
 static void
@@ -2854,7 +2873,6 @@
 static void
 gdm_manager_init (GdmManager *manager)
 {
-        manager->dyn_user_store = gdm_dynamic_user_store_new ();
         manager->display_store = gdm_display_store_new ();
         manager->user_sessions = NULL;
         manager->open_reauthentication_requests = g_hash_table_new_full (NULL,
@@ -2957,7 +2975,6 @@
         g_clear_object (&manager->connection);
         g_clear_object (&manager->object_manager);
         g_clear_object (&manager->display_store);
-        g_clear_object (&manager->dyn_user_store);
 
         G_OBJECT_CLASS (gdm_manager_parent_class)->dispose (object);
 }
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index b78068d42..08ba39cf6 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -3184,18 +3184,33 @@ gdm_session_start_session (GdmSession *self,
 
                 g_free (command);
         } else {
+                /* FIXME:
+                 * Always use a separate DBus bus for each greeter session.
+                 * Firstly, this means that if we run multiple greeter session
+                 * (which we really should not do, but have to currently), then
+                 * each one will get its own DBus session bus.
+                 * But, we also explicitly do this for seat0, because that way
+                 * it cannot make use of systemd to run the GNOME session. This
+                 * prevents the session lookup logic from getting confused.
+                 * This has a similar effect as passing --builtin to gnome-session.
+                 *
+                 * We really should not be doing this. But the fix is to use
+                 * separate dynamically created users and that requires some
+                 * major refactorings.
+                 */
                 if (run_launcher) {
                         if (is_x11) {
-                                program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"%s\"",
+                                program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"dbus-run-session -- %s\"",
                                                            register_session ? "--register-session " : "",
                                                            self->selected_program);
                         } else {
-                                program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"",
+                                program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"dbus-run-session -- %s\"",
                                                            register_session ? "--register-session " : "",
                                                            self->selected_program);
                         }
                 } else {
-                        program = g_strdup (self->selected_program);
+                        program = g_strdup_printf ("dbus-run-session -- %s",
+                                                   self->selected_program);
                 }
         }
 
diff --git a/daemon/meson.build b/daemon/meson.build
index 26fe79bfc..aaf990e25 100644
--- a/daemon/meson.build
+++ b/daemon/meson.build
@@ -188,7 +188,6 @@ gdm_daemon_sources = files(
   'gdm-display-factory.c',
   'gdm-display-store.c',
   'gdm-display.c',
-  'gdm-dynamic-user-store.c',
   'gdm-launch-environment.c',
   'gdm-legacy-display.c',
   'gdm-local-display-factory.c',
diff --git a/data/autostart/meson.build b/data/autostart/meson.build
new file mode 100644
index 000000000..11ea694ec
--- /dev/null
+++ b/data/autostart/meson.build
@@ -0,0 +1,12 @@
+autostart_files_conf = {
+  'LIBEXECDIR': gdm_prefix / get_option('libexecdir'),
+}
+
+foreach autostart_file : [ 'orca-autostart.desktop' ]
+  configure_file(
+    input: autostart_file,
+    output: autostart_file,
+    configuration: autostart_files_conf,
+    install_dir: gdm_datadir / 'greeter' / 'autostart',
+  )
+endforeach
diff --git a/data/autostart/orca-autostart.desktop b/data/autostart/orca-autostart.desktop
new file mode 100644
index 000000000..944cfd78f
--- /dev/null
+++ b/data/autostart/orca-autostart.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Type=Application
+Name=Orca screen reader
+Exec=orca --disable main-window,splash-window --enable speech,braille
+NoDisplay=true
+AutostartCondition=GSettings org.gnome.desktop.a11y.applications screen-reader-enabled
+X-GNOME-AutoRestart=true
diff --git a/data/gdm.conf.in b/data/gdm.conf.in
index eda131e02..fcc2bd2b1 100644
--- a/data/gdm.conf.in
+++ b/data/gdm.conf.in
@@ -71,7 +71,7 @@
            send_member="CreateTransientDisplay"/>
   </policy>
 
-  <policy group="@GDM_GROUPNAME@">
+  <policy user="@GDM_USERNAME@">
     <allow send_destination="org.gnome.DisplayManager"
            send_interface="org.gnome.DisplayManager.Manager"/>
     <allow send_destination="org.gnome.DisplayManager"
diff --git a/data/gnome-login.session b/data/gnome-login.session
deleted file mode 100644
index 927f63152..000000000
--- a/data/gnome-login.session
+++ /dev/null
@@ -1,3 +0,0 @@
-[GNOME Session]
-Name=GNOME Display Manager
-Kiosk=true
diff --git a/data/gnome-login.session.conf b/data/gnome-login.session.conf
deleted file mode 100644
index 69ae1761c..000000000
--- a/data/gnome-login.session.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[Unit]
-Requires=gnome-session-basic-services.target
diff --git a/data/gnome-login.session.in b/data/gnome-login.session.in
new file mode 100644
index 000000000..63470962e
--- /dev/null
+++ b/data/gnome-login.session.in
@@ -0,0 +1,3 @@
+[GNOME Session]
+Name=Display Manager
+RequiredComponents=@gnome_required_components@;
diff --git a/data/meson.build b/data/meson.build
index 17b0c72d7..5d0703ef7 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -1,4 +1,5 @@
 subdir('applications')
+subdir('autostart')
 subdir('dconf')
 
 # XPath configs
@@ -27,7 +28,7 @@ configure_file(
   input: 'gdm.conf.in',
   output: '@BASENAME@',
   configuration: {
-    'GDM_GROUPNAME': get_option('group'),
+    'GDM_USERNAME': get_option('user'),
   },
   install_dir: dbus_sys_dir,
 )
@@ -61,9 +62,37 @@ install_data('locale.alias',
   install_dir: gdm_datadir,
 )
 
-install_data(
-    'gnome-login.session',
-    install_dir: get_option('datadir') / 'gnome-session' / 'sessions',
+gdm_gnome_shell_component = 'org.gnome.Shell'
+gdm_gnome_session_required_components = [
+  'org.gnome.SettingsDaemon.A11ySettings',
+  'org.gnome.SettingsDaemon.Color',
+  'org.gnome.SettingsDaemon.Datetime',
+  'org.gnome.SettingsDaemon.Housekeeping',
+  'org.gnome.SettingsDaemon.Keyboard',
+  'org.gnome.SettingsDaemon.MediaKeys',
+  'org.gnome.SettingsDaemon.Power',
+  'org.gnome.SettingsDaemon.PrintNotifications',
+  'org.gnome.SettingsDaemon.Rfkill',
+  'org.gnome.SettingsDaemon.ScreensaverProxy',
+  'org.gnome.SettingsDaemon.Sharing',
+  'org.gnome.SettingsDaemon.Smartcard',
+  'org.gnome.SettingsDaemon.Sound',
+]
+
+gdm_gnome_user_session_wanted_components = gdm_gnome_session_required_components
+gdm_gnome_user_session_wanted_components += [
+  'org.gnome.SettingsDaemon.XSettings',
+]
+
+configure_file(
+  input: 'gnome-login.session.in',
+  output: '@BASENAME@',
+  configuration: {
+    'libexecdir': gdm_prefix / get_option('libexecdir'),
+    'gnome_required_components': ';'.join(
+      [ gdm_gnome_shell_component ] + gdm_gnome_session_required_components),
+  },
+  install_dir: get_option('datadir') / 'gnome-session' / 'sessions',
 )
 
 # PAM
@@ -153,9 +182,19 @@ if systemdsystemunitdir != 'no'
   )
 endif
 
+gdm_gnome_session_wanted_targets = []
+foreach component: gdm_gnome_user_session_wanted_components
+  gdm_gnome_session_wanted_targets += 'Wants=@0@.target'.format(component)
+endforeach
+
 if systemduserunitdir != 'no'
-  install_data(
-    'gnome-login.session.conf',
+  configure_file(
+    input: 'session.conf.in',
+    output: 'session.conf',
+    configuration: {
+      'requires_component': gdm_gnome_shell_component,
+      'wants_required_components': '\n'.join(gdm_gnome_session_wanted_targets),
+    },
     install_dir: systemd_userunitdir / 'gnome-session@gnome-login.target.d',
   )
 endif
@@ -178,7 +217,7 @@ configure_file(
   input: 'polkit-gdm.rules.in',
   output: '20-gdm.rules',
   configuration: {
-    'GDM_GROUPNAME': get_option('group'),
+    'GDM_USERNAME': get_option('user'),
   },
   install_dir: get_option('datadir') / 'polkit-1' / 'rules.d',
 )
diff --git a/data/polkit-gdm.rules.in b/data/polkit-gdm.rules.in
index 8faaaffcb..a1951a2a5 100644
--- a/data/polkit-gdm.rules.in
+++ b/data/polkit-gdm.rules.in
@@ -1,5 +1,5 @@
 polkit.addRule(function(action, subject) {
-    if (!subject.isInGroup("@GDM_GROUPNAME@"))
+    if (subject.user !== "@GDM_USERNAME@")
         return undefined;
 
     if (action.id == "org.freedesktop.NetworkManager.settings.modify.system" &&
diff --git a/data/session.conf.in b/data/session.conf.in
new file mode 100644
index 000000000..7bfa36525
--- /dev/null
+++ b/data/session.conf.in
@@ -0,0 +1,4 @@
+[Unit]
+@wants_required_components@
+
+Requires=@requires_component@.target
diff --git a/meson.build b/meson.build
index 25b94f2e4..88df7ab07 100644
--- a/meson.build
+++ b/meson.build
@@ -29,13 +29,14 @@
 gdm_defaults_conf = (get_option('defaults-conf') != '')? get_option('defaults-conf') : gdm_prefix / gdm_datadir / 'defaults.conf'
 gdm_custom_conf = (get_option('custom-conf') != '')? get_option('custom-conf') : gdmconfdir / 'custom.conf'
 gnome_settings_daemon_dir = (get_option('gnome-settings-daemon-dir') != '')? get_option('gnome-settings-daemon-dir') : gdm_prefix / get_option('libexecdir')
-gdm_run_dir = (get_option('run-dir') != '')? get_option('run-dir') : '/run/gdm'
+gdm_run_dir = (get_option('run-dir') != '')? get_option('run-dir') : gdm_prefix / get_option('localstatedir') / 'run' / 'gdm'
 gdm_runtime_conf = (get_option('runtime-conf') != '')? get_option('runtime-conf') : gdm_run_dir / 'custom.conf'
 gdm_pid_file = (get_option('pid-file') != '')? get_option('pid-file') : gdm_run_dir / 'gdm.pid'
 working_dir = (get_option('working-dir') != '')? get_option('working-dir') : gdm_prefix / get_option('localstatedir') / 'lib' / 'gdm'
 gdm_xauth_dir = (get_option('xauth-dir') != '')? get_option('xauth-dir') : gdm_run_dir / 'xauth'
+ran_once_marker_dir = (get_option('ran-once-marker-dir') != '')? get_option('ran-once-marker-dir') : gdm_run_dir
+gdm_screenshot_dir = (get_option('screenshot-dir') != '')? get_option('screenshot-dir') : gdm_run_dir / 'greeter'
 gdm_private_dbus_dir = (get_option('private-dbus-dir') != '')? get_option('private-dbus-dir') : gdm_run_dir / 'dbus'
-gdm_dyn_home_dir = (get_option('dyn-home-dir') != '')? get_option('dyn-home-dir') : gdm_run_dir / 'home'
 pam_prefix = (get_option('pam-prefix') != '')? get_option('pam-prefix') : get_option('sysconfdir')
 pam_profiles_dir = pam_prefix / 'pam.d'
 have_x11_support = get_option('x11-support')
@@ -135,24 +135,12 @@
       '/usr/lib/systemd',
     ])
   systemd_x_server = systemd_multiseat_x.found()? systemd_multiseat_x.path() : '/lib/systemd/systemd-multi-seat-x'
-
-  have_userdb = libsystemd_dep.version().version_compare('>= 257')
-
-  # Our range is documented at https://systemd.io/UIDS-GIDS/
-  greeter_uid_min = systemd_dep.get_variable('greeter_uid_min', default_value: '60578')
-  greeter_uid_max = systemd_dep.get_variable('greeter_uid_max', default_value: '60705')
 else
   elogind_dep = dependency('libelogind')
   logind_dep = elogind_dep
   systemd_x_server = 'disabled'
-  have_userdb = false
-  greeter_uid_min = 0
-  greeter_uid_max = 0
 endif
 
-nologin_program = find_program('nologin', required: false)
-nologin_path = nologin_program.found()? nologin_program.path() : '/sbin/nologin'
-
 # Plymouth
 plymouth_dep = dependency('ply-boot-client', required: get_option('plymouth'))
 # Check for Solaris auditing API (ADT)
@@ -250,6 +238,7 @@
 conf.set_quoted('PACKAGE_VERSION', meson.project_version())
 conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
 conf.set_quoted('DATADIR', gdm_prefix / get_option('datadir'))
+conf.set_quoted('GDM_SCREENSHOT_DIR', gdm_screenshot_dir)
 conf.set_quoted('SYSCONFDIR', gdm_prefix / get_option('sysconfdir'))
 conf.set_quoted('BINDIR', gdm_prefix / get_option('bindir'))
 conf.set_quoted('LIBDIR', gdm_prefix / get_option('libdir'))
@@ -263,9 +252,11 @@
 conf.set_quoted('GDM_DATADIR', gdm_prefix / gdm_datadir)
 conf.set_quoted('GDM_XAUTH_DIR', gdm_xauth_dir)
 conf.set_quoted('GDM_PRIVATE_DBUS_DIR', gdm_private_dbus_dir)
+conf.set_quoted('GDM_RAN_ONCE_MARKER_DIR', ran_once_marker_dir)
 conf.set_quoted('GDM_RUN_DIR', gdm_run_dir)
 conf.set_quoted('GDM_DCONF_PROFILE', 'gdm')
 conf.set_quoted('GDM_WORKING_DIR', working_dir)
+conf.set_quoted('GDM_WORKING_DIR', working_dir)
 conf.set_quoted('GNOMELOCALEDIR', gdm_prefix / get_option('localedir'))
 conf.set_quoted('AT_SPI_REGISTRYD_DIR', at_spi_registryd_dir)
 conf.set_quoted('GDM_PID_FILE', gdm_pid_file)
@@ -303,11 +294,6 @@
 conf.set_quoted('GDM_GROUPNAME', get_option('group'))
 conf.set('HAVE_LIBXDMCP', have_xdmcp)
 conf.set_quoted('SYSTEMD_X_SERVER', systemd_x_server)
-conf.set('HAVE_USERDB', have_userdb)
-conf.set('GREETER_UID_MIN', greeter_uid_min)
-conf.set('GREETER_UID_MAX', greeter_uid_max)
-conf.set_quoted('GDM_DYN_HOME_DIR', gdm_dyn_home_dir)
-conf.set_quoted('NOLOGIN_PATH', nologin_path)
 conf.set('WITH_PLYMOUTH', plymouth_dep.found())
 conf.set_quoted('X_SERVER', x_bin)
 conf.set_quoted('X_PATH', x_path)
@@ -359,9 +345,10 @@
     'System DBus': dbus_sys_dir,
     'DM conf': dmconfdir,
     'GDM conf': gdmconfdir,
+    'GDM Screenshot ': gdm_screenshot_dir,
     'GDM Xauth': gdm_xauth_dir,
+    'GDM RanOnceMarker': ran_once_marker_dir,
     'GDM Run': gdm_run_dir,
-    'GDM Dynamic Homes': gdm_dyn_home_dir,
     'GDM PID file': gdm_pid_file,
     'GDM Defaults config': gdm_defaults_conf,
     'GDM Custom config': gdm_custom_conf,
diff --git a/meson_options.txt b/meson_options.txt
index 3f3865c7a..18f223ddf 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -21,8 +21,10 @@
 option('plymouth', type: 'feature', value: 'auto', description: 'Add plymouth support.')
 option('private-dbus-dir', type: 'string', value: '', description: 'Directory for private D-Bus server sockets')
 option('profiling', type: 'boolean', value: false, description: 'Enable profiling.')
+option('ran-once-marker-dir', type: 'string', value: '', description: 'Ran once marker directory.')
 option('run-dir', type: 'string', value: '', description: 'Runtime directory.')
 option('runtime-conf', type: 'string', value: '', description: 'Filename to give to runtime configuration file.')
+option('screenshot-dir', type: 'string', value: '', description: 'Directory to store greeter screenshot.')
 option('selinux', type: 'feature', value: 'auto', description: 'Add SELinux support.')
 option('solaris', type: 'boolean', value: false, description: 'Build for Solaris')
 option('split-authentication', type: 'boolean', value: true, description: 'Enable multiple simultaneous PAM conversations during login.')
@@ -38,5 +40,4 @@
 option('x11-support', type: 'boolean', value: true, description: 'Enable support for x11 sessions.')
 option('working-dir', type: 'string', value: '', description: 'Working directory.')
 option('xauth-dir', type: 'string', value: '', description: 'XAuth cookie directory.')
-option('xdmcp', type: 'feature', value: 'auto', description: 'Add XDMCP (remote login) support.')
-option('dyn-home-dir', type: 'string', value: '', description: 'Parent directory for dynamic user home directories')
\ No newline at end of file
+option('xdmcp', type: 'feature', value: 'auto', description: 'Add XDMCP (remote login) support.')
\ No newline at end of file
diff --git a/utils/gdm-config.c b/utils/gdm-config.c
index f468312c0..82051a1b1 100644
--- a/utils/gdm-config.c
+++ b/utils/gdm-config.c
@@ -482,6 +482,53 @@ config_command_handler_add_to_group (GdmConfigCommandHandler *command_handler,
                                         command_handler->post_parse_func);
 }
 
+static gboolean
+switch_to_gdm_user (GError **error) {
+        struct passwd *pwent;
+
+        /* We don't care about forking here, as we need to do just one action
+         * so, once we switch, there's no point of return */
+
+        gdm_get_pwent_for_name (GDM_USERNAME, &pwent);
+
+        if (pwent == NULL) {
+                g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                             _("Failed to switch to %s user"), GDM_USERNAME);
+                return FALSE;
+        }
+
+        g_debug ("Switching to %s user (uid:gid) %d:%d",
+                 GDM_USERNAME, pwent->pw_uid, pwent->pw_gid);
+
+        if (setgid (pwent->pw_gid) < 0)  {
+                g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                             _("Couldn’t set groupid to %d"), pwent->pw_gid);
+                return FALSE;
+        }
+
+        if (initgroups (pwent->pw_name, pwent->pw_gid) < 0) {
+                g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                             _("initgroups () failed for %s"), pwent->pw_name);
+                return FALSE;
+        }
+
+        if (setuid (pwent->pw_uid) < 0)  {
+                g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                             _("Couldn’t set userid to %u"), pwent->pw_uid);
+                return FALSE;
+        }
+
+        g_unsetenv ("XDG_RUNTIME_DIR");
+        g_unsetenv ("DISPLAY");
+
+        if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') {
+                g_setenv ("HOME", pwent->pw_dir, TRUE);
+                g_setenv ("PWD", GDM_WORKING_DIR, TRUE);
+        }
+
+        return TRUE;
+}
+
 static GPtrArray *
 read_file_contents_to_array (const char  *file_path,
                              GError     **error)
@@ -1852,6 +1899,15 @@ handle_show (GdmConfigCommand   config_command,
 
         removal_setting = get_smartcard_option (GSD_SC_REMOVAL_ACTION_KEY);
 
+        /* While this may be not super-needed it ensures that we act as if we
+         * were gdm itself */
+        if (!g_getenv ("UNDER_JHBUILD") && !switch_to_gdm_user (&local_error)) {
+                g_critical ("Impossible to switch to GDM user %s: %s",
+                            GDM_USERNAME, local_error->message);
+                g_propagate_error (error, g_steal_pointer (&local_error));
+                return FALSE;
+        }
+
         g_print(_("GDM Authorization configuration\n"
                   "\n"
                   "  Password authentication: %s\n"
