commit 75cea8c72c832751784a19ccc6ffd9204bac260e Author: byeX012 Date: Tue Nov 26 21:35:38 2019 +0800 package init diff --git a/0001-Honor-initial-setup-being-disabled-by-distro-install.patch b/0001-Honor-initial-setup-being-disabled-by-distro-install.patch new file mode 100644 index 0000000..32d135b --- /dev/null +++ b/0001-Honor-initial-setup-being-disabled-by-distro-install.patch @@ -0,0 +1,82 @@ +From 42b18e4c84d470f33cdec5fc1f481cb25c25cf0d Mon Sep 17 00:00:00 2001 +From: Rui Matos +Date: Mon, 23 Jan 2017 20:19:51 +0100 +Subject: [PATCH] Honor initial setup being disabled by distro installer + +Sysadmins might want to disable any kind of initial setup for their +users, perhaps because they pre-configure their environments. We +already provide a configuration file option for this but distro +installers might have their own way of requesting this. + +At least the anaconda installer provides an option to skip any kind +post-install setup tools so, for now we're only adding support for +that but more might be added in the future. + +https://bugzilla.gnome.org/show_bug.cgi?id=777708 +--- + daemon/Makefile.am | 1 + + daemon/gdm-display.c | 29 +++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/daemon/Makefile.am b/daemon/Makefile.am +index 5e9eb5e..3b1b151 100644 +--- a/daemon/Makefile.am ++++ b/daemon/Makefile.am +@@ -15,6 +15,7 @@ AM_CPPFLAGS = \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DLOGDIR=\"$(logdir)\" \ + -DSBINDIR=\"$(sbindir)\" \ ++ -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ + -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ + -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ +diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c +index 5e193f2..878be88 100644 +--- a/daemon/gdm-display.c ++++ b/daemon/gdm-display.c +@@ -1547,6 +1547,31 @@ kernel_cmdline_initial_setup_force_state (gboolean *force_state) + return TRUE; + } + ++static gboolean ++initial_setup_disabled_by_anaconda (void) ++{ ++ GKeyFile *key_file; ++ const gchar *file_name = SYSCONFDIR "/sysconfig/anaconda"; ++ gboolean disabled = FALSE; ++ GError *error = NULL; ++ ++ key_file = g_key_file_new (); ++ if (!g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error)) { ++ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) && ++ !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) { ++ g_warning ("Could not read %s: %s", file_name, error->message); ++ } ++ g_error_free (error); ++ goto out; ++ } ++ ++ disabled = g_key_file_get_boolean (key_file, "General", ++ "post_install_tools_disabled", NULL); ++ out: ++ g_key_file_unref (key_file); ++ return disabled; ++} ++ + static gboolean + wants_initial_setup (GdmDisplay *self) + { +@@ -1587,6 +1612,10 @@ wants_initial_setup (GdmDisplay *self) + return FALSE; + } + ++ if (initial_setup_disabled_by_anaconda ()) { ++ return FALSE; ++ } ++ + return enabled; + } + +-- +2.19.0 + diff --git a/0001-data-disable-wayland-if-modesetting-is-disabled.patch b/0001-data-disable-wayland-if-modesetting-is-disabled.patch new file mode 100644 index 0000000..88c8ba7 --- /dev/null +++ b/0001-data-disable-wayland-if-modesetting-is-disabled.patch @@ -0,0 +1,30 @@ +From a0f3d7108f688d48ad8653c380dba575fcd2fc3f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 15 Apr 2019 10:53:25 -0400 +Subject: [PATCH] data: disable wayland if modesetting is disabled + +wayland requires working modesetting, so don't even +bother trying it if modesetting is disabled. + +This is more efficient and side-steps a bug in the fallback +logic if start up is unreasonably slow. +--- + data/61-gdm.rules.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in +index ad5b87d4c..ebdbfe9c1 100644 +--- a/data/61-gdm.rules.in ++++ b/data/61-gdm.rules.in +@@ -1,6 +1,8 @@ + # disable Wayland on Cirrus chipsets + ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland" + # disable Wayland on Hi1710 chipsets + ATTR{vendor}=="0x19e5", ATTR{device}=="0x1711", RUN+="@libexecdir@/gdm-disable-wayland" + # disable Wayland when using the proprietary nvidia driver + DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland" ++# disable Wayland if modesetting is disabled ++IMPORT{cmdline}="nomodeset", RUN+="@libexecdir@/gdm-disable-wayland" +-- +2.20.1 + diff --git a/0001-local-display-factory-defer-initialization-for-CanGr.patch b/0001-local-display-factory-defer-initialization-for-CanGr.patch new file mode 100644 index 0000000..eae9243 --- /dev/null +++ b/0001-local-display-factory-defer-initialization-for-CanGr.patch @@ -0,0 +1,566 @@ +From 757e620a8dd26902215a332af71cfcdf08574803 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 4 Oct 2018 10:40:41 -0400 +Subject: [PATCH] local-display-factory: defer initialization for + CanGraphical=no seats + +During startup a seat may not be ready for a display server yet. + +This commit changes GDM to wait until the seat reports that it is +CanGraphical capable, before trying to put a login screen on it. + +Closes https://gitlab.gnome.org/bugzilla-migration/gdm/issues/103 +--- + daemon/gdm-local-display-factory.c | 132 +++++++++++++++++++++++++++-- + 1 file changed, 126 insertions(+), 6 deletions(-) + +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 891c25375..5430085ea 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -29,92 +29,98 @@ + #include + + #include + + #include "gdm-common.h" + #include "gdm-manager.h" + #include "gdm-display-factory.h" + #include "gdm-local-display-factory.h" + #include "gdm-local-display-factory-glue.h" + + #include "gdm-settings-keys.h" + #include "gdm-settings-direct.h" + #include "gdm-display-store.h" + #include "gdm-local-display.h" + #include "gdm-legacy-display.h" + + #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate)) + + #define GDM_DBUS_PATH "/org/gnome/DisplayManager" + #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory" + #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory" + + #define MAX_DISPLAY_FAILURES 5 + #define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */ + + struct GdmLocalDisplayFactoryPrivate + { + GdmDBusLocalDisplayFactory *skeleton; + GDBusConnection *connection; + GHashTable *used_display_numbers; ++ GHashTable *seat_proxies; + + /* FIXME: this needs to be per seat? */ + guint num_failures; + + guint seat_new_id; + guint seat_removed_id; + + #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) + char *tty_of_active_vt; + guint active_vt_watch_id; + guint wait_to_finish_timeout_id; + #endif + }; + + enum { + PROP_0, + }; + + static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); + static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); + static void gdm_local_display_factory_finalize (GObject *object); + + static GdmDisplay *create_display (GdmLocalDisplayFactory *factory, + const char *seat_id, + const char *session_type, + gboolean initial_display); + + static void on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmLocalDisplayFactory *factory); + + static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); ++ ++static gboolean create_seat_proxy (GdmLocalDisplayFactory *self, ++ const char *seat_id, ++ const char *seat_path); ++ + static gpointer local_display_factory_object = NULL; + static gboolean lookup_by_session_id (const char *id, + GdmDisplay *display, + gpointer user_data); + + G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) + + GQuark + gdm_local_display_factory_error_quark (void) + { + static GQuark ret = 0; + if (ret == 0) { + ret = g_quark_from_static_string ("gdm_local_display_factory_error"); + } + + return ret; + } + + static void + listify_hash (gpointer key, + GdmDisplay *display, + GList **list) + { + *list = g_list_prepend (*list, key); + } + + static int + sort_nums (gpointer a, + gpointer b) + { +@@ -409,60 +415,61 @@ lookup_by_seat_id (const char *id, + return res; + } + + static gboolean + lookup_prepared_display_by_seat_id (const char *id, + GdmDisplay *display, + gpointer user_data) + { + int status; + + status = gdm_display_get_status (display); + + if (status != GDM_DISPLAY_PREPARED) + return FALSE; + + return lookup_by_seat_id (id, display, user_data); + } + + static GdmDisplay * + create_display (GdmLocalDisplayFactory *factory, + const char *seat_id, + const char *session_type, + gboolean initial) + { + GdmDisplayStore *store; + GdmDisplay *display = NULL; + g_autofree char *login_session_id = NULL; + + g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", + session_type? : "X11", seat_id); ++ + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + if (sd_seat_can_multi_session (seat_id)) + display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); + else + display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); + + /* Ensure we don't create the same display more than once */ + if (display != NULL) { + g_debug ("GdmLocalDisplayFactory: display already created"); + return NULL; + } + + /* If we already have a login window, switch to it */ + if (gdm_get_login_window_session_id (seat_id, &login_session_id)) { + GdmDisplay *display; + + display = gdm_display_store_find (store, + lookup_by_session_id, + (gpointer) login_session_id); + if (display != NULL && + (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED || + gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) { + g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); + g_debug ("GdmLocalDisplayFactory: session %s found, activating.", + login_session_id); + gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id); + return NULL; + } + } +@@ -493,131 +500,236 @@ create_display (GdmLocalDisplayFactory *factory, + + /* let store own the ref */ + g_object_unref (display); + + if (! gdm_display_manage (display)) { + gdm_display_unmanage (display); + } + + return display; + } + + static void + delete_display (GdmLocalDisplayFactory *factory, + const char *seat_id) { + + GdmDisplayStore *store; + + g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id); + } + + static gboolean + gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory) + { + GError *error = NULL; + GVariant *result; + GVariant *array; + GVariantIter iter; +- const char *seat; ++ const char *seat, *path; + + g_debug ("GdmLocalDisplayFactory: enumerating seats from logind"); + result = g_dbus_connection_call_sync (factory->priv->connection, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListSeats", + NULL, + G_VARIANT_TYPE ("(a(so))"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, &error); + + if (!result) { + g_warning ("GdmLocalDisplayFactory: Failed to issue method call: %s", error->message); + g_clear_error (&error); + return FALSE; + } + + array = g_variant_get_child_value (result, 0); + g_variant_iter_init (&iter, array); + +- while (g_variant_iter_loop (&iter, "(&so)", &seat, NULL)) { ++ while (g_variant_iter_loop (&iter, "(&s&o)", &seat, &path)) { + gboolean is_initial; + const char *session_type = NULL; + + if (g_strcmp0 (seat, "seat0") == 0) { + is_initial = TRUE; + if (gdm_local_display_factory_use_wayland ()) + session_type = "wayland"; + } else { + is_initial = FALSE; + } + ++ if (!create_seat_proxy (factory, seat, path)) ++ continue; ++ ++ if (!sd_seat_can_graphical (seat)) { ++ g_debug ("GdmLocalDisplayFactory: seat %s not ready for graphical displays", seat); ++ continue; ++ } ++ + create_display (factory, seat, session_type, is_initial); + } + + g_variant_unref (result); + g_variant_unref (array); + return TRUE; + } + ++static void ++on_seat_proxy_properties_changed (GDBusProxy *proxy, ++ GVariant *changed_properties, ++ char **invalidated_properties, ++ gpointer user_data) ++{ ++ GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); ++ g_autoptr (GVariant) value = NULL; ++ const char *seat; ++ ++ value = g_variant_lookup_value (changed_properties, "CanGraphical", G_VARIANT_TYPE_BOOLEAN); ++ ++ if (!value) ++ return; ++ ++ g_debug ("GdmLocalDisplayFactory: CanGraphical changed"); ++ ++ seat = g_object_get_data (G_OBJECT (proxy), "seat-id"); ++ ++ if (!seat) ++ return; ++ ++ if (g_variant_get_boolean (value)) { ++ gboolean is_initial; ++ const char *session_type = NULL; ++ ++ g_debug ("GdmLocalDisplayFactory: seat '%s' now graphical", seat); ++ ++ if (g_strcmp0 (seat, "seat0") == 0) { ++ is_initial = TRUE; ++ if (gdm_local_display_factory_use_wayland ()) ++ session_type = "wayland"; ++ } else { ++ is_initial = FALSE; ++ } ++ ++ create_display (factory, seat, session_type, is_initial); ++ } else { ++ g_debug ("GdmLocalDisplayFactory: seat '%s' no longer graphical", seat); ++ delete_display (factory, seat); ++ } ++} ++ ++static gboolean ++create_seat_proxy (GdmLocalDisplayFactory *self, ++ const char *seat, ++ const char *path) ++{ ++ g_autoptr (GDBusProxy) proxy = NULL; ++ g_autoptr (GError) error = NULL; ++ ++ g_debug ("GdmLocalDisplayFactory: creating seat proxy for seat '%s' with path '%s'", ++ seat, path); ++ ++ proxy = g_dbus_proxy_new_sync (self->priv->connection, ++ G_DBUS_PROXY_FLAGS_NONE, ++ NULL, ++ "org.freedesktop.login1", ++ path, ++ "org.freedesktop.login1.Seat", ++ NULL, ++ &error); ++ ++ if (proxy == NULL) { ++ g_debug ("GdmLocalDisplayFactory: failed to get proxy to seat '%s' from logind: %s", ++ seat, error->message); ++ return FALSE; ++ } ++ ++ g_hash_table_insert (self->priv->seat_proxies, g_strdup (seat), g_object_ref (proxy)); ++ g_object_set_data_full (G_OBJECT (proxy), "seat-id", g_strdup (seat), (GDestroyNotify) g_free); ++ g_signal_connect_object (G_OBJECT (proxy), ++ "g-properties-changed", ++ G_CALLBACK (on_seat_proxy_properties_changed), ++ self, ++ 0); ++ ++ return TRUE; ++} ++ + static void + on_seat_new (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) + { +- const char *seat; ++ GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); ++ const char *seat, *path; + +- g_variant_get (parameters, "(&s&o)", &seat, NULL); +- create_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat, NULL, FALSE); ++ g_variant_get (parameters, "(&s&o)", &seat, &path); ++ ++ g_debug ("GdmLocalDisplayFactory: new seat '%s' available", seat); ++ ++ if (!create_seat_proxy (factory, seat, path)) ++ return; ++ ++ if (!sd_seat_can_graphical (seat)) { ++ g_debug ("GdmLocalDisplayFactory: but not yet ready for graphical displays"); ++ return; ++ } ++ ++ create_display (factory, seat, NULL, FALSE); + } + + static void + on_seat_removed (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) + { ++ GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); + const char *seat; + + g_variant_get (parameters, "(&s&o)", &seat, NULL); +- delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); ++ ++ g_debug ("GdmLocalDisplayFactory: seat '%s' no longer available", seat); ++ ++ g_hash_table_remove (factory->priv->seat_proxies, (gpointer) seat); ++ delete_display (factory, seat); + } + + static gboolean + lookup_by_session_id (const char *id, + GdmDisplay *display, + gpointer user_data) + { + const char *looking_for = user_data; + const char *current; + + current = gdm_display_get_session_id (display); + return g_strcmp0 (current, looking_for) == 0; + } + + #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) + static gboolean + wait_to_finish_timeout (GdmLocalDisplayFactory *factory) + { + finish_waiting_displays_on_seat (factory, "seat0"); + factory->priv->wait_to_finish_timeout_id = 0; + return G_SOURCE_REMOVE; + } + + static void + maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory, + GdmDisplay *display) + { + g_autofree char *display_session_type = NULL; + gboolean doing_initial_setup = FALSE; + +@@ -737,60 +849,65 @@ on_vt_changed (GIOChannel *source, + + g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt); + if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { + GdmDisplayStore *store; + GdmDisplay *display; + + g_debug ("GdmLocalDisplayFactory: VT switched from login window"); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + display = gdm_display_store_find (store, + lookup_by_session_id, + (gpointer) login_session_id); + + if (display != NULL) + maybe_stop_greeter_in_background (factory, display); + } else { + g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); + } + } + } + + /* if user jumped back to initial vt and it's empty put a login screen + * on it (unless a login screen is already running elsewhere, then + * jump to that login screen) + */ + if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) { + g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring"); + return G_SOURCE_CONTINUE; + } + ++ if (!sd_seat_can_graphical ("seat0")) { ++ g_debug ("GdmLocalDisplayFactory: seat0 not yet ready for graphical displays"); ++ return G_SOURCE_CONTINUE; ++ } ++ + if (gdm_local_display_factory_use_wayland ()) + session_type = "wayland"; + + g_debug ("GdmLocalDisplayFactory: creating new display on seat0 because of VT change"); + + create_display (factory, "seat0", session_type, TRUE); + + return G_SOURCE_CONTINUE; + } + #endif + + static void + gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) + { + g_autoptr (GIOChannel) io_channel = NULL; + + factory->priv->seat_new_id = g_dbus_connection_signal_subscribe (factory->priv->connection, + "org.freedesktop.login1", + "org.freedesktop.login1.Manager", + "SeatNew", + "/org/freedesktop/login1", + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + on_seat_new, + g_object_ref (factory), + g_object_unref); + factory->priv->seat_removed_id = g_dbus_connection_signal_subscribe (factory->priv->connection, + "org.freedesktop.login1", + "org.freedesktop.login1.Manager", + "SeatRemoved", +@@ -1014,69 +1131,72 @@ gdm_local_display_factory_constructor (GType type, + if (! res) { + g_warning ("Unable to register local display factory with system bus"); + } + + return G_OBJECT (factory); + } + + static void + gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdmDisplayFactoryClass *factory_class = GDM_DISPLAY_FACTORY_CLASS (klass); + + object_class->get_property = gdm_local_display_factory_get_property; + object_class->set_property = gdm_local_display_factory_set_property; + object_class->finalize = gdm_local_display_factory_finalize; + object_class->constructor = gdm_local_display_factory_constructor; + + factory_class->start = gdm_local_display_factory_start; + factory_class->stop = gdm_local_display_factory_stop; + + g_type_class_add_private (klass, sizeof (GdmLocalDisplayFactoryPrivate)); + } + + static void + gdm_local_display_factory_init (GdmLocalDisplayFactory *factory) + { + factory->priv = GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE (factory); + + factory->priv->used_display_numbers = g_hash_table_new (NULL, NULL); ++ factory->priv->seat_proxies = g_hash_table_new_full (NULL, NULL, g_free, g_object_unref); + } + + static void + gdm_local_display_factory_finalize (GObject *object) + { + GdmLocalDisplayFactory *factory; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (object)); + + factory = GDM_LOCAL_DISPLAY_FACTORY (object); + + g_return_if_fail (factory->priv != NULL); + ++ g_hash_table_destroy (factory->priv->seat_proxies); ++ + g_clear_object (&factory->priv->connection); + g_clear_object (&factory->priv->skeleton); + + g_hash_table_destroy (factory->priv->used_display_numbers); + + gdm_local_display_factory_stop_monitor (factory); + + G_OBJECT_CLASS (gdm_local_display_factory_parent_class)->finalize (object); + } + + GdmLocalDisplayFactory * + gdm_local_display_factory_new (GdmDisplayStore *store) + { + if (local_display_factory_object != NULL) { + g_object_ref (local_display_factory_object); + } else { + local_display_factory_object = g_object_new (GDM_TYPE_LOCAL_DISPLAY_FACTORY, + "display-store", store, + NULL); + g_object_add_weak_pointer (local_display_factory_object, + (gpointer *) &local_display_factory_object); + } + + return GDM_LOCAL_DISPLAY_FACTORY (local_display_factory_object); + } +-- +2.17.1 + diff --git a/0001-manager-correct-display-confusion.patch b/0001-manager-correct-display-confusion.patch new file mode 100644 index 0000000..acc0396 --- /dev/null +++ b/0001-manager-correct-display-confusion.patch @@ -0,0 +1,87 @@ +From a3904bf5f9e6fe6bc3bb2ad9c856cf1361b8194d Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 1 Oct 2018 11:05:57 -0400 +Subject: [PATCH] manager: correct display confusion + +commit c5c5bf1f reworked autologin and broke it. + +This commit addresses the breakage by accessing +the proper display variable. + +Closes https://gitlab.gnome.org/GNOME/gdm/issues/426 +--- + daemon/gdm-manager.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index b1e9b68be..62a967389 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1662,62 +1662,62 @@ on_start_user_session (StartUserSessionOperation *operation) + if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { + g_debug ("GdmManager: closing down initial setup display"); + gdm_display_stop_greeter_session (display); + gdm_display_unmanage (display); + gdm_display_finish (display); + } + } else { + g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); + } + + /* The user session is going to follow the session worker + * into the new display. Untie it from this display and + * create a new session for a future user login. */ + allowed_uid = gdm_session_get_allowed_user (operation->session); + g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); + g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); + create_user_session_for_display (operation->manager, display, allowed_uid); + + /* Give the user session a new display object for bookkeeping purposes */ + create_display_for_user_session (operation->manager, + operation->session, + session_id); + + + if (g_strcmp0 (operation->service_name, "gdm-autologin") == 0) { + /* remove the unused prepared greeter display since we're not going + * to have a greeter */ + gdm_display_store_remove (self->priv->display_store, display); + g_object_unref (display); + +- self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display"); +- g_object_add_weak_pointer (G_OBJECT (display), (gpointer *) &self->priv->automatic_login_display); ++ self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display"); ++ g_object_add_weak_pointer (G_OBJECT (self->priv->automatic_login_display), (gpointer *) &self->priv->automatic_login_display); + } + } + + start_user_session (operation->manager, operation); + + out: + return G_SOURCE_REMOVE; + } + + static void + queue_start_user_session (GdmManager *manager, + GdmSession *session, + const char *service_name) + { + StartUserSessionOperation *operation; + + operation = g_slice_new0 (StartUserSessionOperation); + operation->manager = manager; + operation->session = g_object_ref (session); + operation->service_name = g_strdup (service_name); + + operation->idle_id = g_idle_add ((GSourceFunc) on_start_user_session, operation); + g_object_set_data (G_OBJECT (session), "start-user-session-operation", operation); + } + + static void + start_user_session_if_ready (GdmManager *manager, + GdmSession *session, + const char *service_name) + { +-- +2.17.1 + diff --git a/0001-manager-do-initial-setup-post-work-in-manager-code.patch b/0001-manager-do-initial-setup-post-work-in-manager-code.patch new file mode 100644 index 0000000..a6f6738 --- /dev/null +++ b/0001-manager-do-initial-setup-post-work-in-manager-code.patch @@ -0,0 +1,694 @@ +From 1984b36ba08506ea65dcb95e565f7d24ecbd1703 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 6 Sep 2018 19:31:50 -0400 +Subject: [PATCH] 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. +--- + daemon/gdm-display.c | 132 ------------------------------------------- + daemon/gdm-manager.c | 132 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 132 insertions(+), 132 deletions(-) + +diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c +index 5e193f2f5..511a5ca3f 100644 +--- a/daemon/gdm-display.c ++++ b/daemon/gdm-display.c +@@ -22,61 +22,60 @@ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + + #include + #include + + #include "gdm-common.h" + #include "gdm-display.h" + #include "gdm-display-glue.h" + #include "gdm-display-access-file.h" + #include "gdm-launch-environment.h" + + #include "gdm-settings-direct.h" + #include "gdm-settings-keys.h" + + #include "gdm-launch-environment.h" + #include "gdm-dbus-util.h" + +-#define INITIAL_SETUP_USERNAME "gnome-initial-setup" + #define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions" + + #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate)) + + struct GdmDisplayPrivate + { + char *id; + char *seat_id; + char *session_id; + char *session_class; + char *session_type; + + char *remote_hostname; + int x11_display_number; + char *x11_display_name; + int status; + time_t creation_time; + GTimer *server_timer; + + char *x11_cookie; + gsize x11_cookie_size; + GdmDisplayAccessFile *access_file; + + guint finish_idle_id; + + xcb_connection_t *xcb_connection; + int xcb_screen_number; + + GDBusConnection *connection; + GdmDisplayAccessFile *user_access_file; +@@ -100,131 +99,60 @@ enum { + PROP_0, + PROP_ID, + PROP_STATUS, + PROP_SEAT_ID, + PROP_SESSION_ID, + PROP_SESSION_CLASS, + PROP_SESSION_TYPE, + PROP_REMOTE_HOSTNAME, + PROP_X11_DISPLAY_NUMBER, + PROP_X11_DISPLAY_NAME, + PROP_X11_COOKIE, + PROP_X11_AUTHORITY_FILE, + PROP_IS_CONNECTED, + PROP_IS_LOCAL, + PROP_LAUNCH_ENVIRONMENT, + PROP_IS_INITIAL, + PROP_ALLOW_TIMED_LOGIN, + PROP_HAVE_EXISTING_USER_ACCOUNTS, + PROP_DOING_INITIAL_SETUP, + }; + + static void gdm_display_class_init (GdmDisplayClass *klass); + static void gdm_display_init (GdmDisplay *self); + static void gdm_display_finalize (GObject *object); + static void queue_finish (GdmDisplay *self); + static void _gdm_display_set_status (GdmDisplay *self, + int status); + static gboolean wants_initial_setup (GdmDisplay *self); + G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT) + +-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; +-} +- + GQuark + gdm_display_error_quark (void) + { + static GQuark ret = 0; + if (ret == 0) { + ret = g_quark_from_static_string ("gdm_display_error"); + } + + return ret; + } + + time_t + gdm_display_get_creation_time (GdmDisplay *self) + { + g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); + + return self->priv->creation_time; + } + + int + gdm_display_get_status (GdmDisplay *self) + { + g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); + + return self->priv->status; + } + + const char * + gdm_display_get_session_id (GdmDisplay *self) + { +@@ -1631,145 +1559,85 @@ gdm_display_start_greeter_session (GdmDisplay *self) + G_CALLBACK (on_launch_environment_session_stopped), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "exited", + G_CALLBACK (on_launch_environment_session_exited), + self, 0); + g_signal_connect_object (self->priv->launch_environment, + "died", + G_CALLBACK (on_launch_environment_session_died), + self, 0); + + if (auth_file != NULL) { + g_object_set (self->priv->launch_environment, + "x11-authority-file", auth_file, + NULL); + } + + gdm_launch_environment_start (self->priv->launch_environment); + + session = gdm_launch_environment_get_session (self->priv->launch_environment); + g_object_set (G_OBJECT (session), + "display-is-initial", self->priv->is_initial, + NULL); + + g_free (display_name); + g_free (seat_id); + g_free (hostname); + g_free (auth_file); + } + +-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); +-} +- + void + gdm_display_stop_greeter_session (GdmDisplay *self) + { + GError *error = NULL; + + if (self->priv->launch_environment != NULL) { + + g_signal_handlers_disconnect_by_func (self->priv->launch_environment, + G_CALLBACK (on_launch_environment_session_opened), + self); + g_signal_handlers_disconnect_by_func (self->priv->launch_environment, + G_CALLBACK (on_launch_environment_session_started), + self); + g_signal_handlers_disconnect_by_func (self->priv->launch_environment, + G_CALLBACK (on_launch_environment_session_stopped), + self); + g_signal_handlers_disconnect_by_func (self->priv->launch_environment, + G_CALLBACK (on_launch_environment_session_exited), + self); + g_signal_handlers_disconnect_by_func (self->priv->launch_environment, + G_CALLBACK (on_launch_environment_session_died), + self); + gdm_launch_environment_stop (self->priv->launch_environment); + g_clear_object (&self->priv->launch_environment); + } +- +- if (self->priv->doing_initial_setup) { +- 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); +- } +- } + } + + static xcb_window_t + get_root_window (xcb_connection_t *connection, + int screen_number) + { + xcb_screen_t *screen = NULL; + xcb_screen_iterator_t iter; + + iter = xcb_setup_roots_iterator (xcb_get_setup (connection)); + while (iter.rem) { + if (screen_number == 0) + screen = iter.data; + screen_number--; + xcb_screen_next (&iter); + } + + if (screen != NULL) { + return screen->root; + } + + return XCB_WINDOW_NONE; + } + + static void + gdm_display_set_windowpath (GdmDisplay *self) + { + /* setting WINDOWPATH for clients */ + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply = NULL; +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 62a967389..4d2ad9dec 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -35,60 +35,61 @@ + #include + + #include + + #include + + #include "gdm-common.h" + + #include "gdm-dbus-util.h" + #include "gdm-manager.h" + #include "gdm-manager-glue.h" + #include "gdm-display-store.h" + #include "gdm-display-factory.h" + #include "gdm-launch-environment.h" + #include "gdm-local-display.h" + #include "gdm-local-display-factory.h" + #include "gdm-session.h" + #include "gdm-session-record.h" + #include "gdm-settings-direct.h" + #include "gdm-settings-keys.h" + #include "gdm-xdmcp-display-factory.h" + #include "gdm-xdmcp-chooser-display.h" + + #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate)) + + #define GDM_DBUS_PATH "/org/gnome/DisplayManager" + #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" + + typedef struct + { + GdmManager *manager; + GdmSession *session; + char *service_name; + guint idle_id; + } StartUserSessionOperation; + + struct GdmManagerPrivate + { + GdmDisplayStore *display_store; + GdmLocalDisplayFactory *local_factory; + #ifdef HAVE_LIBXDMCP + GdmXdmcpDisplayFactory *xdmcp_factory; + #endif + GdmDisplay *automatic_login_display; + GList *user_sessions; + GHashTable *transient_sessions; + GHashTable *open_reauthentication_requests; + gboolean xdmcp_enabled; + + gboolean started; + gboolean show_local_greeter; + + GDBusConnection *connection; + GDBusObjectManagerServer *object_manager; + + #ifdef WITH_PLYMOUTH + guint plymouth_is_running : 1; +@@ -1568,130 +1569,261 @@ start_user_session (GdmManager *manager, + + destroy_start_user_session_operation (operation); + } + + static void + create_display_for_user_session (GdmManager *self, + GdmSession *session, + const char *session_id) + { + GdmDisplay *display; + /* at the moment we only create GdmLocalDisplay objects on seat0 */ + const char *seat_id = "seat0"; + + display = gdm_local_display_new (); + + g_object_set (G_OBJECT (display), + "session-class", "user", + "seat-id", seat_id, + "session-id", session_id, + NULL); + gdm_display_store_add (self->priv->display_store, + display); + g_object_set_data (G_OBJECT (session), "gdm-display", display); + g_object_set_data_full (G_OBJECT (display), + "gdm-user-session", + g_object_ref (session), + (GDestroyNotify) + clean_user_session); + } + ++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; + gboolean migrated; + gboolean fail_if_already_switched = TRUE; + gboolean doing_initial_setup = FALSE; + GdmDisplay *display; + const char *session_id; + #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) + g_autofree char *display_session_type = NULL; + #endif + + g_debug ("GdmManager: start or jump to session"); + + /* If there's already a session running, jump to it. + * If the only session running is the one we just opened, + * start a session on it. + */ + migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched); + + g_debug ("GdmManager: migrated: %d", migrated); + if (migrated) { + /* We don't stop the manager here because + when Xorg exits it switches to the VT it was + started from. That interferes with fast + user switching. */ + gdm_session_reset (operation->session); + destroy_start_user_session_operation (operation); + goto out; + } + + display = get_display_for_user_session (operation->session); + + g_object_get (G_OBJECT (display), + "doing-initial-setup", &doing_initial_setup, + #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) + "session-type", &display_session_type, + #endif + NULL); + + session_id = gdm_session_get_conversation_session_id (operation->session, + operation->service_name); + + if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { + /* In this case, the greeter's display is morphing into + * the user session display. Kill the greeter on this session + * and let the user session follow the same display. */ + gdm_display_stop_greeter_session (display); + g_object_set (G_OBJECT (display), + "session-class", "user", + "session-id", session_id, + NULL); + } else { + uid_t allowed_uid; + + 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"); + g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); + } + #endif + if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { + g_debug ("GdmManager: closing down initial setup display"); + gdm_display_stop_greeter_session (display); + 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"); + } + + /* The user session is going to follow the session worker + * into the new display. Untie it from this display and + * create a new session for a future user login. */ + allowed_uid = gdm_session_get_allowed_user (operation->session); + g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); + g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); + create_user_session_for_display (operation->manager, display, allowed_uid); + + /* Give the user session a new display object for bookkeeping purposes */ + create_display_for_user_session (operation->manager, + operation->session, + session_id); + + + if (g_strcmp0 (operation->service_name, "gdm-autologin") == 0) { + /* remove the unused prepared greeter display since we're not going + * to have a greeter */ + gdm_display_store_remove (self->priv->display_store, display); + g_object_unref (display); + + self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display"); + g_object_add_weak_pointer (G_OBJECT (self->priv->automatic_login_display), (gpointer *) &self->priv->automatic_login_display); + } + } + + start_user_session (operation->manager, operation); +-- +2.17.1 + diff --git a/default.pa-for-gdm b/default.pa-for-gdm new file mode 100644 index 0000000..d633aee --- /dev/null +++ b/default.pa-for-gdm @@ -0,0 +1,10 @@ +load-module module-device-restore +load-module module-card-restore +load-module module-udev-detect +load-module module-native-protocol-unix +load-module module-default-device-restore +load-module module-rescue-streams +load-module module-always-sink +load-module module-intended-roles +load-module module-suspend-on-idle +load-module module-position-event-sounds diff --git a/gdm-3.30.1.tar.xz b/gdm-3.30.1.tar.xz new file mode 100644 index 0000000..e67ddc7 Binary files /dev/null and b/gdm-3.30.1.tar.xz differ diff --git a/gdm.spec b/gdm.spec new file mode 100644 index 0000000..f487427 --- /dev/null +++ b/gdm.spec @@ -0,0 +1,198 @@ +Name: gdm +Epoch: 1 +Version: 3.30.1 +Release: 3 +Summary: A graphical display manager +License: GPLv2+ +URL: https://wiki.gnome.org/Projects/GDM +Source0: http://download.gnome.org/sources/gdm/3.30/gdm-%{version}.tar.xz +Source1: org.gnome.login-screen.gschema.override +Source2: default.pa-for-gdm +Patch0001: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch +Patch0002: 0001-manager-correct-display-confusion.patch +Patch0003: 0001-local-display-factory-defer-initialization-for-CanGr.patch +Patch0004: 0001-manager-do-initial-setup-post-work-in-manager-code.patch +Patch0005: system-dconf.patch + +BuildRequires: pam-devel >= 0:0.99.8.1-11 desktop-file-utils >= 0.2.90 +BuildRequires: libtool automake autoconf libattr-devel gettext-devel libdmx-devel +BuildRequires: audit-libs-devel >= 1.0.6 xorg-x11-server-Xorg nss-devel >= 3.11.1 +BuildRequires: pkgconfig(accountsservice) >= 0.6.3 pkgconfig(check) +BuildRequires: pkgconfig(gobject-introspection-1.0) pkgconfig(gtk+-3.0) >= 2.99.2 +BuildRequires: pkgconfig(iso-codes) pkgconfig(libcanberra-gtk3) pkgconfig(libselinux) +BuildRequires: pkgconfig(libsystemd) pkgconfig(ply-boot-client) pkgconfig(systemd) +BuildRequires: pkgconfig(x11) pkgconfig(xau) pkgconfig(xorg-server) libXdmcp-devel +BuildRequires: systemd keyutils-libs-devel dconf + +Requires(pre): shadow-utils +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd + +Requires: accountsservice audit-libs >= 1.0.6 dconf gnome-keyring-pam gnome-session +Requires: gnome-session-wayland-session gnome-settings-daemon >= 3.27.90 gnome-shell iso-codes +Requires: libXau >= 1.0.4-4 pam >= 0:0.99.8.1-11 util-linux setxkbmap systemd >= 186 +Requires: system-logos xorg-x11-server-utils xorg-x11-xinit + +Provides: service(graphical-login) = %{name} +Provides: gdm-libs%{?_isa} = %{epoch}:%{version}-%{release} +Provides: gdm-plugin-smartcard = %{epoch}:%{version}-%{release} +Provides: gdm-plugin-fingerprint = %{epoch}:%{version}-%{release} +Provides: pulseaudio-gdm-hooks = 1:%{version}-%{release} +Obsoletes: gdm-libs < 1:3.12.0-3 gdm-plugin-smartcard < 1:3.2.1 +Obsoletes: gdm-plugin-fingerprint < 1:3.2.1 pulseaudio-gdm-hooks < 1:11.1-17 + +%description +The GNOME Display Manager is a system service that is responsible for +providing graphical log-ins and managing local and remote displays, +and if the session doesn't provide a display server, GDM will start +the display server. It also provides initiate functionality for +user-switching, so multiple users can be logged in at the same time. + +%package devel +Summary: Development files for gdm +Requires: %{name} = %{epoch}:%{version}-%{release} +Obsoletes: gdm-pam-extensions-devel < 1:3.30.1-3 + +%description devel +The gdm-devel package contains header files and others for building +applications that use GDM. + +%prep +%autosetup -n %{name}-%{version} -S git -p1 +autoreconf -if + +%build +%configure --with-pam-prefix=%{_sysconfdir} --with-run-dir=/run/gdm \ + --with-default-path=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin \ + --enable-split-authentication --enable-profiling --enable-console-helper \ + --with-selinux --with-default-pam-config=arch + +sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0 /g' libtool +sed -i -e 's/ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then/ func_append compile_command " -Wl,-O1,--as-needed"\n func_append finalize_command " -Wl,-O1,--as-needed"\n\0/' libtool + +%make_build + +%install +install -d %{buildroot}%{_sysconfdir}/gdm/Init +install -d %{buildroot}%{_sysconfdir}/gdm/PreSession +install -d %{buildroot}%{_sysconfdir}/gdm/PostSession +install -d %{buildroot}/var/log/gdm +install -d %{buildroot}%{_datadir}/gdm/autostart/LoginWindow +install -d %{buildroot}/run/gdm + +%make_install + +install -D %{SOURCE1} %{buildroot}%{_datadir}/glib-2.0/schemas +install -p -m644 -D %{SOURCE2} %{buildroot}%{_localstatedir}/lib/gdm/.config/pulse/default.pa +(cd %{buildroot}%{_sysconfdir}/gdm; ln -sf ../X11/xinit/Xsession .) + +%delete_la_and_a + +%find_lang gdm --with-gnome + +%pre +/usr/sbin/useradd -M -u 42 -d /var/lib/gdm -s /sbin/nologin -r gdm > /dev/null 2>&1 +/usr/sbin/usermod -d /var/lib/gdm -s /sbin/nologin gdm >/dev/null 2>&1 +exit 0 + +%post +custom=/etc/gdm/custom.conf + +if [ $1 -ge 2 ] ; then + if [ -f /usr/share/gdm/config/gdm.conf-custom ]; then + oldconffile=/usr/share/gdm/config/gdm.conf-custom + elif [ -f /etc/X11/gdm/gdm.conf ]; then + oldconffile=/etc/X11/gdm/gdm.conf + fi + + [ -n "$oldconffile" ] && sed \ + -e 's@^command=/usr/X11R6/bin/X@#command=/usr/bin/Xorg@' \ + -e 's@^Xnest=/usr/X11R6/bin/Xnest@#Xnest=/usr/X11R6/bin/Xnest@' \ + -e 's@^BaseXsession=/etc/X11/xdm/Xsession@#BaseXsession=/etc/X11/xinit/Xsession@' \ + -e 's@^BaseXsession=/etc/X11/gdm/Xsession@#&@' \ + -e 's@^BaseXsession=/etc/gdm/Xsession@#&@' \ + -e 's@^Greeter=/usr/bin/gdmgreeter@#Greeter=/usr/libexec/gdmgreeter@' \ + -e 's@^RemoteGreeter=/usr/bin/gdmlogin@#RemoteGreeter=/usr/libexec/gdmlogin@' \ + -e 's@^GraphicalTheme=Bluecurve@#&@' \ + -e 's@^BackgroundColor=#20305a@#&@' \ + -e 's@^DefaultPath=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin@#&@' \ + -e 's@^RootPath=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin@#&@' \ + -e 's@^HostImageDir=/usr/share/hosts/@#HostImageDir=/usr/share/pixmaps/faces/@' \ + -e 's@^LogDir=/var/log/gdm@#&@' \ + -e 's@^PostLoginScriptDir=/etc/X11/gdm/PostLogin@#&@' \ + -e 's@^PreLoginScriptDir=/etc/X11/gdm/PreLogin@#&@' \ + -e 's@^PreSessionScriptDir=/etc/X11/gdm/PreSession@#&@' \ + -e 's@^PostSessionScriptDir=/etc/X11/gdm/PostSession@#&@' \ + -e 's@^DisplayInitDir=/var/run/gdm.pid@#&@' \ + -e 's@^RebootCommand=/sbin/reboot;/sbin/shutdown -r now;/usr/sbin/shutdown -r now;/usr/bin/reboot@#&@' \ + -e 's@^HaltCommand=/sbin/poweroff;/sbin/shutdown -h now;/usr/sbin/shutdown -h now;/usr/bin/poweroff@#&@' \ + -e 's@^ServAuthDir=/var/gdm@#&@' \ + -e 's@^Greeter=/usr/bin/gdmlogin@Greeter=/usr/libexec/gdmlogin@' \ + -e 's@^RemoteGreeter=/usr/bin/gdmgreeter@RemoteGreeter=/usr/libexec/gdmgreeter@' \ + $oldconffile > $custom +fi + +if [ $1 -ge 2 -a -f $custom ] && grep -q /etc/X11/gdm $custom ; then + sed -i -e 's@/etc/X11/gdm@/etc/gdm@g' $custom +fi + +%systemd_post gdm.service + +%preun +%systemd_preun gdm.service + +%postun +%systemd_postun gdm.service + +%files -f gdm.lang +%doc AUTHORS NEWS README.md COPYING +%config(noreplace) %{_sysconfdir}/gdm/custom.conf +%config %{_sysconfdir}/gdm/Init/* +%config %{_sysconfdir}/gdm/PostLogin/* +%config %{_sysconfdir}/gdm/PreSession/* +%config %{_sysconfdir}/gdm/PostSession/* +%{_sysconfdir}/gdm/Xsession +%config %{_sysconfdir}/pam.d/gdm-autologin +%config %{_sysconfdir}/pam.d/gdm-password +%config %{_sysconfdir}/pam.d/gdm-pin +%config %{_sysconfdir}/pam.d/gdm-smartcard +%config %{_sysconfdir}/pam.d/gdm-fingerprint +%exclude %{_sysconfdir}/pam.d/gdm +%{_sysconfdir}/pam.d/gdm-launch-environment +%{_sysconfdir}/dbus-1/system.d/gdm.conf +%{_datadir}/gdm/gdm.schemas +%{_datadir}/gdm/greeter-dconf-defaults +%{_datadir}/gdm/locale.alias +%{_datadir}/gdm/gdb-cmd +%{_datadir}/gdm/greeter/applications/* +%{_datadir}/gdm/greeter/autostart/* +%{_datadir}/pixmaps/*.png +%{_datadir}/glib-2.0/schemas/* +%{_datadir}/dconf/profile/gdm +%{_datadir}/gnome-session/sessions/gnome-login.session +%{_datadir}/icons/hicolor/*/*/*.png +%{_libexecdir}/* +%{_sbindir}/gdm +%{_bindir}/* +%{_libdir}/girepository-1.0/Gdm-1.0.typelib +%{_libdir}/security/pam_gdm.so +%{_libdir}/libgdm*.so* +%dir %{_localstatedir}/log/gdm +%attr(1770, gdm, gdm) %dir %{_localstatedir}/lib/gdm +%attr(0700, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.config +%attr(0700, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.config/pulse +%attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.config/pulse/default.pa +%attr(0711, root, gdm) %dir /run/gdm +%attr(1755, root, gdm) %dir %{_localstatedir}/cache/gdm +%{_udevrulesdir}/61-gdm.rules +%{_unitdir}/gdm.service + +%files devel +%{_includedir}/gdm/*.h +%{_datadir}/gir-1.0/Gdm-1.0.gir +%{_libdir}/pkgconfig/*.pc + +%changelog +* Wed Nov 23 2019 Jiangping Hu - 1:3.30.1-3 +- Package init diff --git a/org.gnome.login-screen.gschema.override b/org.gnome.login-screen.gschema.override new file mode 100644 index 0000000..d018c5e --- /dev/null +++ b/org.gnome.login-screen.gschema.override @@ -0,0 +1,3 @@ +[org.gnome.login-screen] +logo='/usr/share/pixmaps/fedora-gdm-logo.png' +enable-smartcard-authentication=false diff --git a/system-dconf.patch b/system-dconf.patch new file mode 100644 index 0000000..83d2999 --- /dev/null +++ b/system-dconf.patch @@ -0,0 +1,22 @@ +From 29d374ce6781df6f3b168a8c57163ddb582c998a Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 31 Jul 2013 17:32:55 -0400 +Subject: [PATCH] data: add system dconf databases to gdm profile + +This way system settings can affect the login screen. +--- + data/dconf/gdm.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/data/dconf/gdm.in b/data/dconf/gdm.in +index 4d8bf174..9694078f 100644 +--- a/data/dconf/gdm.in ++++ b/data/dconf/gdm.in +@@ -1,2 +1,5 @@ + user-db:user ++system-db:local ++system-db:site ++system-db:distro + file-db:@DATADIR@/@PACKAGE@/greeter-dconf-defaults +-- +2.11.1