diff --git a/.gdm.metadata b/.gdm.metadata index 8c47fa9..4dc1d6e 100644 --- a/.gdm.metadata +++ b/.gdm.metadata @@ -1 +1 @@ -f0ecbe867bd0ef2b085ef79a56655f51bbef3193 SOURCES/gdm-3.26.2.1.tar.xz +4733edef031ca2618fb48cdbdc0aa23c139edb85 SOURCES/gdm-3.28.2.tar.xz diff --git a/.gitignore b/.gitignore index a865c9f..3ac4a68 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/gdm-3.26.2.1.tar.xz +SOURCES/gdm-3.28.2.tar.xz diff --git a/SOURCES/0001-Revert-data-Add-gnome-login.session.patch b/SOURCES/0001-Revert-data-Add-gnome-login.session.patch index 56be2d7..bf8ec16 100644 --- a/SOURCES/0001-Revert-data-Add-gnome-login.session.patch +++ b/SOURCES/0001-Revert-data-Add-gnome-login.session.patch @@ -1,4 +1,4 @@ -From cbddcc7c8cc8dcccc8c9a616e1decf8a3ed1cb87 Mon Sep 17 00:00:00 2001 +From c35c3fa71f3ecdc4c12d4b90200e41c9ea658366 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 13 Oct 2017 13:56:22 -0400 Subject: [PATCH] Revert "data: Add gnome-login.session" @@ -12,10 +12,13 @@ This reverts commit 1073f0e792d9d5bf9d53bddb6e51177c8024c2b3. delete mode 100644 data/gnome-login.session.in diff --git a/data/Makefile.am b/data/Makefile.am -index c10c9151..f2875fcb 100644 +index a47e7900..f69ec12d 100644 --- a/data/Makefile.am +++ b/data/Makefile.am -@@ -59,74 +59,63 @@ schemas_in_files = gdm.schemas.in +@@ -56,74 +56,63 @@ gsettings_SCHEMAS = org.gnome.login-screen.gschema.xml + + schemasdir = $(pkgdatadir) + schemas_in_files = gdm.schemas.in schemas_DATA = $(schemas_in_files:.schemas.in=.schemas) gdm.schemas.in: $(srcdir)/gdm.schemas.in.in @@ -32,9 +35,6 @@ index c10c9151..f2875fcb 100644 -e 's,[@]ALWAYS_RESTART_SERVER[@],$(ALWAYS_RESTART_SERVER),g' \ -e 's,[@]X_CONFIG_OPTIONS[@],$(X_CONFIG_OPTIONS),g' \ -e 's,[@]X_SERVER[@],$(X_SERVER),g' \ - -e 's,[@]X_XNEST_CMD[@],$(X_XNEST_CMD),g' \ - -e 's,[@]X_XNEST_CONFIG_OPTIONS[@],$(X_XNEST_CONFIG_OPTIONS),g' \ - -e 's,[@]X_XNEST_UNSCALED_FONTPATH[@],$(X_XNEST_UNSCALED_FONTPATH),g' \ -e 's,[@]GDM_RBAC_SYSCMD_KEYS[@],$(GDM_RBAC_SYSCMD_KEYS),g' \ -e 's,[@]datadir[@],$(datadir),g' \ -e 's,[@]gdmconfdir[@],$(gdmconfdir),g' \ @@ -90,14 +90,14 @@ index c10c9151..f2875fcb 100644 pam-lfs/gdm-autologin.pam \ pam-lfs/gdm-launch-environment.pam \ pam-lfs/gdm-fingerprint.pam \ -@@ -163,61 +152,60 @@ endif - +@@ -164,61 +153,60 @@ udevrules_DATA = 61-gdm.rules EXTRA_DIST += \ $(dconf_db_files) \ $(schemas_in_files) \ $(schemas_DATA) \ $(dbusconf_in_files) \ $(localealias_DATA) \ + $(udevrules_DATA) \ gdm.schemas.in.in \ gdm.conf-custom.in \ Xsession.in \ @@ -200,13 +200,13 @@ index 603903e6..f109e0a9 100644 media='' diff --git a/data/gnome-login.session.in b/data/gnome-login.session.in deleted file mode 100644 -index 764afd15..00000000 +index fbc10580..00000000 --- a/data/gnome-login.session.in +++ /dev/null @@ -1,3 +0,0 @@ -[GNOME Session] -Name=Display Manager --RequiredComponents=org.gnome.Shell;org.gnome.SettingsDaemon.A11yKeyboard;org.gnome.SettingsDaemon.A11ySettings;org.gnome.SettingsDaemon.Clipboard;org.gnome.SettingsDaemon.Color;org.gnome.SettingsDaemon.Datetime;org.gnome.SettingsDaemon.Housekeeping;org.gnome.SettingsDaemon.Keyboard;org.gnome.SettingsDaemon.MediaKeys;org.gnome.SettingsDaemon.Mouse;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;org.gnome.SettingsDaemon.Wacom;org.gnome.SettingsDaemon.XSettings; +-RequiredComponents=org.gnome.Shell;org.gnome.SettingsDaemon.A11ySettings;org.gnome.SettingsDaemon.Clipboard;org.gnome.SettingsDaemon.Color;org.gnome.SettingsDaemon.Datetime;org.gnome.SettingsDaemon.Housekeeping;org.gnome.SettingsDaemon.Keyboard;org.gnome.SettingsDaemon.MediaKeys;org.gnome.SettingsDaemon.Mouse;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;org.gnome.SettingsDaemon.Wacom;org.gnome.SettingsDaemon.XSettings; -- -2.14.2 +1.8.3.1 diff --git a/SOURCES/0001-Revert-session-don-t-call-gdm_session_defaults_chang.patch b/SOURCES/0001-Revert-session-don-t-call-gdm_session_defaults_chang.patch deleted file mode 100644 index 213fe0f..0000000 --- a/SOURCES/0001-Revert-session-don-t-call-gdm_session_defaults_chang.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0012497171500090b55e4c8e967809a5b2daaa94 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 14 Feb 2018 16:07:15 -0500 -Subject: [PATCH] Revert "session: don't call gdm_session_defaults_changed from - setup" - -This reverts commit 572a19324b75cc1f1b2db4908e2d7c9f06e4e335. - -It turns out we need this call for more than just the session type, -we also need to it to inform the greeter about the default session -to use. ---- - daemon/gdm-session.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 3a1b7f23..e9cbd0ec 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -2368,78 +2368,80 @@ initialize (GdmSession *self, - g_variant_builder_add_parsed (&details, "{'seat-id', <%s>}", self->priv->display_seat_id); - - if (self->priv->display_x11_authority_file != NULL) - g_variant_builder_add_parsed (&details, "{'x11-authority-file', <%s>}", self->priv->display_x11_authority_file); - - g_debug ("GdmSession: Beginning initialization"); - - conversation = find_conversation_by_name (self, service_name); - if (conversation != NULL) { - gdm_dbus_worker_call_initialize (conversation->worker_proxy, - g_variant_builder_end (&details), - - conversation->worker_cancellable, - (GAsyncReadyCallback) on_initialization_complete_cb, - conversation); - } - - g_free (extensions); - } - - void - gdm_session_setup (GdmSession *self, - const char *service_name) - { - - g_return_if_fail (GDM_IS_SESSION (self)); - - update_session_type (self); - - initialize (self, service_name, NULL, NULL); -+ gdm_session_defaults_changed (self); - } - - - void - gdm_session_setup_for_user (GdmSession *self, - const char *service_name, - const char *username) - { - - g_return_if_fail (GDM_IS_SESSION (self)); - g_return_if_fail (username != NULL); - - update_session_type (self); - - gdm_session_select_user (self, username); - - self->priv->is_program_session = FALSE; - initialize (self, service_name, self->priv->selected_user, NULL); -+ gdm_session_defaults_changed (self); - } - - void - gdm_session_setup_for_program (GdmSession *self, - const char *service_name, - const char *username, - const char *log_file) - { - - g_return_if_fail (GDM_IS_SESSION (self)); - - self->priv->is_program_session = TRUE; - initialize (self, service_name, username, log_file); - } - - void - gdm_session_authenticate (GdmSession *self, - const char *service_name) - { - GdmSessionConversation *conversation; - - g_return_if_fail (GDM_IS_SESSION (self)); - - conversation = find_conversation_by_name (self, service_name); - if (conversation != NULL) { - gdm_dbus_worker_call_authenticate (conversation->worker_proxy, - conversation->worker_cancellable, - (GAsyncReadyCallback) on_authenticate_cb, - conversation); - } --- -2.14.3 - diff --git a/SOURCES/0001-daemon-gdm-session-record.c-open-close-the-utmp-data.patch b/SOURCES/0001-daemon-gdm-session-record.c-open-close-the-utmp-data.patch new file mode 100644 index 0000000..c3b6a2c --- /dev/null +++ b/SOURCES/0001-daemon-gdm-session-record.c-open-close-the-utmp-data.patch @@ -0,0 +1,136 @@ +From 086d68f24d984fb48e44aa16aa815825cd5ed0bc Mon Sep 17 00:00:00 2001 +From: Jason Pleau +Date: Wed, 30 May 2018 21:48:22 -0400 +Subject: [PATCH] daemon/gdm-session-record.c: open/close the utmp database + +pututxline() was used without first opening the utxmp database and +without closing it, preventing the logout entry from being fully +committed. + +This caused the number of logged-in users to increment after each login, +as logging out did not correctly remove the user login record from utmp. + +This commit wraps pututxline() between setutxent() and endutxent(), +making sure that the login/logout operation are fully flushed. + +Fixes #381 +--- + daemon/gdm-session-record.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c +index 487f10047..d2df58873 100644 +--- a/daemon/gdm-session-record.c ++++ b/daemon/gdm-session-record.c +@@ -186,104 +186,108 @@ gdm_session_record_login (GPid session_pid, + + g_debug ("Writing login record"); + + #if defined(HAVE_UT_UT_TYPE) + session_record.ut_type = USER_PROCESS; + g_debug ("using ut_type USER_PROCESS"); + #endif + + record_set_timestamp (&session_record); + record_set_pid (&session_record, session_pid); + record_set_host (&session_record, x11_display_name, host_name); + record_set_line (&session_record, display_device, x11_display_name); + + /* Handle wtmp */ + g_debug ("Writing wtmp session record to " GDM_NEW_SESSION_RECORDS_FILE); + #if defined(HAVE_UPDWTMPX) + updwtmpx (GDM_NEW_SESSION_RECORDS_FILE, &session_record); + #elif defined(HAVE_UPDWTMP) + updwtmp (GDM_NEW_SESSION_RECORDS_FILE, &session_record); + #elif defined(HAVE_LOGWTMP) && defined(HAVE_UT_UT_HOST) + #if defined(HAVE_UT_UT_USER) + logwtmp (session_record.ut_line, session_record.ut_user, session_record.ut_host); + #elif defined(HAVE_UT_UT_NAME) + logwtmp (session_record.ut_line, session_record.ut_name, session_record.ut_host); + #endif + #endif + + /* Handle utmp */ + #if defined(HAVE_GETUTXENT) + g_debug ("Adding or updating utmp record for login"); ++ setutxent(); + pututxline (&session_record); ++ endutxent(); + #elif defined(HAVE_LOGIN) + login (&session_record); + #endif + } + + void + gdm_session_record_logout (GPid session_pid, + const char *user_name, + const char *host_name, + const char *x11_display_name, + const char *display_device) + { + UTMP session_record = { 0 }; + + if (x11_display_name == NULL) + x11_display_name = display_device; + + g_debug ("Writing logout record"); + + #if defined(HAVE_UT_UT_TYPE) + session_record.ut_type = DEAD_PROCESS; + g_debug ("using ut_type DEAD_PROCESS"); + #endif + + record_set_timestamp (&session_record); + record_set_pid (&session_record, session_pid); + record_set_host (&session_record, x11_display_name, host_name); + record_set_line (&session_record, display_device, x11_display_name); + + /* Handle wtmp */ + g_debug ("Writing wtmp logout record to " GDM_NEW_SESSION_RECORDS_FILE); + #if defined(HAVE_UPDWTMPX) + updwtmpx (GDM_NEW_SESSION_RECORDS_FILE, &session_record); + #elif defined (HAVE_UPDWTMP) + updwtmp (GDM_NEW_SESSION_RECORDS_FILE, &session_record); + #elif defined(HAVE_LOGWTMP) + logwtmp (session_record.ut_line, "", ""); + #endif + + /* Handle utmp */ + #if defined(HAVE_GETUTXENT) + g_debug ("Adding or updating utmp record for logout"); ++ setutxent(); + pututxline (&session_record); ++ endutxent(); + #elif defined(HAVE_LOGOUT) + logout (session_record.ut_line); + #endif + } + + void + gdm_session_record_failed (GPid session_pid, + const char *user_name, + const char *host_name, + const char *x11_display_name, + const char *display_device) + { + UTMP session_record = { 0 }; + + if (x11_display_name == NULL) + x11_display_name = display_device; + + record_set_username (&session_record, user_name); + + g_debug ("Writing failed session attempt record"); + + #if defined(HAVE_UT_UT_TYPE) + session_record.ut_type = USER_PROCESS; + g_debug ("using ut_type USER_PROCESS"); + #endif + + record_set_timestamp (&session_record); + record_set_pid (&session_record, session_pid); + record_set_host (&session_record, x11_display_name, host_name); + record_set_line (&session_record, display_device, x11_display_name); +-- +2.17.1 + diff --git a/SOURCES/0001-data-change-cirrus-blacklist-to-use-gdm-disable-wayl.patch b/SOURCES/0001-data-change-cirrus-blacklist-to-use-gdm-disable-wayl.patch new file mode 100644 index 0000000..d892e74 --- /dev/null +++ b/SOURCES/0001-data-change-cirrus-blacklist-to-use-gdm-disable-wayl.patch @@ -0,0 +1,112 @@ +From a9b82ca4a87315235924317c0fc48324a8b7cb9f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 21 May 2018 11:13:31 -0400 +Subject: [PATCH] data: change cirrus blacklist to use gdm-disable-wayland + +Now that we have a gdm-disable-wayland binary for disabling +wayland at boot, we should use it. + +This commit changes the cirrus udev rule to use gdm-disable-wayland, +rather than running sh and printf. + +https://bugzilla.gnome.org/show_bug.cgi?id=796315 + + +(cherry picked from commit a913eea70342411247e770a91b75dd800941bb6e) +--- + data/61-gdm.rules | 2 -- + data/61-gdm.rules.in | 2 ++ + data/Makefile.am | 5 +++++ + 3 files changed, 7 insertions(+), 2 deletions(-) + delete mode 100644 data/61-gdm.rules + create mode 100644 data/61-gdm.rules.in + +diff --git a/data/61-gdm.rules b/data/61-gdm.rules +deleted file mode 100644 +index 5ffa8b8a0..000000000 +--- a/data/61-gdm.rules ++++ /dev/null +@@ -1,2 +0,0 @@ +-# disable Wayland on Cirrus chipsets +-ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="/bin/sh -c '/bin/mkdir /run/gdm ; /usr/bin/printf \"[daemon]\nWaylandEnable=false\" >> /run/gdm/custom.conf'" +diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in +new file mode 100644 +index 000000000..de8e17903 +--- /dev/null ++++ b/data/61-gdm.rules.in +@@ -0,0 +1,2 @@ ++# disable Wayland on Cirrus chipsets ++ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland" +diff --git a/data/Makefile.am b/data/Makefile.am +index a47e7900f..192dfa052 100644 +--- a/data/Makefile.am ++++ b/data/Makefile.am +@@ -134,60 +134,65 @@ pam_lfs_files = \ + EXTRA_DIST += $(pam_lfs_files) + + pam_arch_files = pam-arch/gdm-autologin.pam \ + pam-arch/gdm-launch-environment.pam \ + pam-arch/gdm-fingerprint.pam \ + pam-arch/gdm-smartcard.pam \ + pam-arch/gdm-password.pam \ + pam-arch/gdm-pin.pam \ + $(NULL) + EXTRA_DIST += $(pam_arch_files) + + if ENABLE_REDHAT_PAM_CONFIG + pam_files = $(pam_redhat_files) + endif + if ENABLE_OPENEMBEDDED_PAM_CONFIG + pam_files = $(pam_openembedded_files) + endif + if ENABLE_EXHERBO_PAM_CONFIG + pam_files = $(pam_exherbo_files) + endif + if ENABLE_LFS_PAM_CONFIG + pam_files = $(pam_lfs_files) + endif + if ENABLE_ARCH_PAM_CONFIG + pam_files = $(pam_arch_files) + endif + + udevrulesdir = $(prefix)/lib/udev/rules.d + udevrules_DATA = 61-gdm.rules + ++EXTRA_DIST += $(srcdir)/61-gdm.rules.in ++61-gdm.rules: $(srcdir)/61-gdm.rules.in ++ sed -e 's,[@]libexecdir[@],$(libexecdir),g' \ ++ < $< > $@.tmp && mv $@.tmp $@ ++ + EXTRA_DIST += \ + $(dconf_db_files) \ + $(schemas_in_files) \ + $(schemas_DATA) \ + $(dbusconf_in_files) \ + $(localealias_DATA) \ + $(udevrules_DATA) \ + gdm.schemas.in.in \ + gdm.conf-custom.in \ + Xsession.in \ + Init.in \ + PreSession.in \ + PostSession.in \ + PostLogin \ + org.gnome.login-screen.gschema.xml.in \ + $(NULL) + + CLEANFILES = \ + Xsession \ + gdm.conf-custom \ + Init \ + PreSession \ + PostSession \ + $(gsettings_SCHEMAS) \ + greeter-dconf-defaults \ + $(NULL) + + DISTCLEANFILES = \ + $(dbusconf_DATA) \ + gdm.schemas \ +-- +2.17.1 + diff --git a/SOURCES/0001-manager-plug-leak-in-maybe_activate_other_session.patch b/SOURCES/0001-manager-plug-leak-in-maybe_activate_other_session.patch new file mode 100644 index 0000000..847870b --- /dev/null +++ b/SOURCES/0001-manager-plug-leak-in-maybe_activate_other_session.patch @@ -0,0 +1,103 @@ +From 82006d15b70842d2b1ad7d47d9490e315436cb5f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 22 Jun 2018 14:44:11 -0400 +Subject: [PATCH 1/6] manager: plug leak in maybe_activate_other_session + +The function asks logind what the currently active session is on the +given seat. It then leaks the response. + +This commit plugs the leak. +--- + daemon/gdm-manager.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 7539acf11..129cc0de4 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1394,79 +1394,81 @@ get_login_window_session_id (const char *seat_id, + out: + if (sessions) { + for (i = 0; sessions[i]; i ++) { + free (sessions[i]); + } + + free (sessions); + } + + return ret; + } + + static void + activate_login_window_session_on_seat (GdmManager *self, + const char *seat_id) + { + char *session_id; + + if (!get_login_window_session_id (seat_id, &session_id)) { + return; + } + + activate_session_id (self, seat_id, session_id); + } + + static void + maybe_activate_other_session (GdmManager *self, + GdmDisplay *old_display) + { + char *seat_id = NULL; +- char *session_id; ++ char *session_id = NULL; + int ret; + + g_object_get (G_OBJECT (old_display), + "seat-id", &seat_id, + NULL); + + ret = sd_seat_get_active (seat_id, &session_id, NULL); + + if (ret == 0) { + GdmDisplay *display; + + display = gdm_display_store_find (self->priv->display_store, + lookup_by_session_id, + (gpointer) session_id); + + if (display == NULL) { + activate_login_window_session_on_seat (self, seat_id); + } ++ ++ g_free (session_id); + } + + g_free (seat_id); + } + + 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) + { + GdmSession *session; + char *display_session_type = NULL; + gboolean is_initial; + +-- +2.19.0 + diff --git a/SOURCES/0002-manager-start-login-screen-if-old-one-is-finished.patch b/SOURCES/0002-manager-start-login-screen-if-old-one-is-finished.patch new file mode 100644 index 0000000..d14b87b --- /dev/null +++ b/SOURCES/0002-manager-start-login-screen-if-old-one-is-finished.patch @@ -0,0 +1,92 @@ +From 6b4402fb0bbf17803c2354e92fc448a537d2d506 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 22 Jun 2018 14:55:39 -0400 +Subject: [PATCH 2/6] manager: start login screen if old one is finished + +Since commit 22c332ba we try to start a login screen if we end up +on an empty VT and there isn't one running. + +Unfortunately the check for "is on an empty VT" is a little busted. +It counts the VT has non-empty if there's a display associated with +it, even if that display is in the FINISHED state about to be +reaped. + +That means, in some cases, we'll still leave the user on an empty +VT with no login screen. + +This commit addresses the problem by explicitly checking for +FINISHED displays, and proceeding even in their presense. +--- + daemon/gdm-manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 129cc0de4..3f5772e65 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1410,61 +1410,61 @@ activate_login_window_session_on_seat (GdmManager *self, + char *session_id; + + if (!get_login_window_session_id (seat_id, &session_id)) { + return; + } + + activate_session_id (self, seat_id, session_id); + } + + static void + maybe_activate_other_session (GdmManager *self, + GdmDisplay *old_display) + { + char *seat_id = NULL; + char *session_id = NULL; + int ret; + + g_object_get (G_OBJECT (old_display), + "seat-id", &seat_id, + NULL); + + ret = sd_seat_get_active (seat_id, &session_id, NULL); + + if (ret == 0) { + GdmDisplay *display; + + display = gdm_display_store_find (self->priv->display_store, + lookup_by_session_id, + (gpointer) session_id); + +- if (display == NULL) { ++ if (display == NULL || gdm_display_get_status (display) == GDM_DISPLAY_FINISHED) { + activate_login_window_session_on_seat (self, seat_id); + } + + g_free (session_id); + } + + g_free (seat_id); + } + + 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) + { +-- +2.19.0 + diff --git a/SOURCES/0003-manager-don-t-bail-if-session-disappears-out-from-un.patch b/SOURCES/0003-manager-don-t-bail-if-session-disappears-out-from-un.patch new file mode 100644 index 0000000..5a85f3e --- /dev/null +++ b/SOURCES/0003-manager-don-t-bail-if-session-disappears-out-from-un.patch @@ -0,0 +1,126 @@ +From 64779fcad9efa9fdb4b1a8963e2386cf763e53d8 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 22 Jun 2018 15:26:03 -0400 +Subject: [PATCH 3/6] manager: don't bail if session disappears out from under + us + +It's entirely possible for a session returned by +sd_seat_get_sessions to disappear immediately after the +sd_seat_get_sessions call returns. This is especially +likely at logout time where the session will briefly be +in the "closing" state before getting reaped. + +If that happens when we're looking for a greeter session, we +stop looking for a greeter session and bail out all confused. + +This commit fixes the confusion by gracefully handling the +session disappearing by just proceeding to the next session +in the list. +--- + daemon/gdm-manager.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 3f5772e65..c391307fa 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1318,87 +1318,96 @@ maybe_start_pending_initial_login (GdmManager *manager, + g_free (user_session_seat_id); + } + + static gboolean + get_login_window_session_id (const char *seat_id, + char **session_id) + { + gboolean ret; + int res, i; + char **sessions; + char *service_id; + char *service_class; + char *state; + + res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); + if (res < 0) { + g_debug ("Failed to determine sessions: %s", strerror (-res)); + return FALSE; + } + + if (sessions == NULL || sessions[0] == NULL) { + *session_id = NULL; + ret = TRUE; + goto out; + } + + for (i = 0; sessions[i]; i ++) { + + res = sd_session_get_class (sessions[i], &service_class); + if (res < 0) { ++ if (res == -ENOENT || res == -ENXIO) { ++ continue; ++ } ++ + g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (strcmp (service_class, "greeter") != 0) { + free (service_class); + continue; + } + + free (service_class); + + ret = sd_session_get_state (sessions[i], &state); + if (ret < 0) { ++ if (res == -ENOENT || res == -ENXIO) ++ continue; ++ + g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (g_strcmp0 (state, "closing") == 0) { + free (state); + continue; + } + free (state); + + res = sd_session_get_service (sessions[i], &service_id); + if (res < 0) { ++ if (res == -ENOENT || res == -ENXIO) ++ continue; + g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (strcmp (service_id, "gdm-launch-environment") == 0) { + *session_id = g_strdup (sessions[i]); + ret = TRUE; + + free (service_id); + goto out; + } + + free (service_id); + } + + *session_id = NULL; + ret = TRUE; + + out: + if (sessions) { + for (i = 0; sessions[i]; i ++) { + free (sessions[i]); + } + + free (sessions); + } + + return ret; + } +-- +2.19.0 + diff --git a/SOURCES/0004-manager-make-get_login_window_session_id-fail-if-no-.patch b/SOURCES/0004-manager-make-get_login_window_session_id-fail-if-no-.patch new file mode 100644 index 0000000..35acf75 --- /dev/null +++ b/SOURCES/0004-manager-make-get_login_window_session_id-fail-if-no-.patch @@ -0,0 +1,146 @@ +From 65c3fc674ee4ec0f5139973aa53114db2f1fcf45 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 17 Jul 2018 15:40:25 -0400 +Subject: [PATCH 4/6] manager: make get_login_window_session_id fail if no + login screen + +Right now we oddly succeed from get_login_window_session_id +if we can't find a login window. + +None of the caller expect that, so fail instead. +--- + 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 c391307fa..34ee74033 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1310,122 +1310,122 @@ maybe_start_pending_initial_login (GdmManager *manager, + NULL); + + if (g_strcmp0 (greeter_seat_id, user_session_seat_id) == 0) { + start_user_session (manager, operation); + manager->priv->initial_login_operation = NULL; + } + + g_free (greeter_seat_id); + g_free (user_session_seat_id); + } + + static gboolean + get_login_window_session_id (const char *seat_id, + char **session_id) + { + gboolean ret; + int res, i; + char **sessions; + char *service_id; + char *service_class; + char *state; + + res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); + if (res < 0) { + g_debug ("Failed to determine sessions: %s", strerror (-res)); + return FALSE; + } + + if (sessions == NULL || sessions[0] == NULL) { + *session_id = NULL; +- ret = TRUE; ++ ret = FALSE; + goto out; + } + + for (i = 0; sessions[i]; i ++) { + + res = sd_session_get_class (sessions[i], &service_class); + if (res < 0) { + if (res == -ENOENT || res == -ENXIO) { + continue; + } + + g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (strcmp (service_class, "greeter") != 0) { + free (service_class); + continue; + } + + free (service_class); + + ret = sd_session_get_state (sessions[i], &state); + if (ret < 0) { + if (res == -ENOENT || res == -ENXIO) + continue; + + g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (g_strcmp0 (state, "closing") == 0) { + free (state); + continue; + } + free (state); + + res = sd_session_get_service (sessions[i], &service_id); + if (res < 0) { + if (res == -ENOENT || res == -ENXIO) + continue; + g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (strcmp (service_id, "gdm-launch-environment") == 0) { + *session_id = g_strdup (sessions[i]); + ret = TRUE; + + free (service_id); + goto out; + } + + free (service_id); + } + + *session_id = NULL; +- ret = TRUE; ++ ret = FALSE; + + out: + if (sessions) { + for (i = 0; sessions[i]; i ++) { + free (sessions[i]); + } + + free (sessions); + } + + return ret; + } + + static void + activate_login_window_session_on_seat (GdmManager *self, + const char *seat_id) + { + char *session_id; + + if (!get_login_window_session_id (seat_id, &session_id)) { + return; + } + + activate_session_id (self, seat_id, session_id); + } + + static void + maybe_activate_other_session (GdmManager *self, + GdmDisplay *old_display) + { +-- +2.19.0 + diff --git a/SOURCES/0005-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch b/SOURCES/0005-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch new file mode 100644 index 0000000..2d000a8 --- /dev/null +++ b/SOURCES/0005-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch @@ -0,0 +1,654 @@ +From b7b492296a69bc5100ff5908048ed5ef121d3587 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 30 Jul 2018 16:21:29 -0400 +Subject: [PATCH 5/6] daemon: try harder to get to a login screen at logout + +commit 22c332ba and some follow up commits try to ensure the +user never stays on a blank VT by jumping to a login screen in +the event they'd end up on one. + +Unfortunately, that part of the code can't start a login screen +if there's not one running at all. + +This commit moves the code to GdmLocalDisplyFactor where the +login screens are created, so users won't end up on a blank +VT even if no login screen is yet running. +--- + daemon/gdm-local-display-factory.c | 161 ++++++++++++++++++++++++++++- + daemon/gdm-manager.c | 54 ---------- + 2 files changed, 156 insertions(+), 59 deletions(-) + +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index b29f5ac52..cf852b55a 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -1,60 +1,62 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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. + * + */ + + #include "config.h" + + #include + #include + + #include + #include + #include + #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 + + struct GdmLocalDisplayFactoryPrivate + { + GdmDBusLocalDisplayFactory *skeleton; + GDBusConnection *connection; + GHashTable *used_display_numbers; + + /* FIXME: this needs to be per seat? */ + guint num_failures; + + guint seat_new_id; +@@ -226,171 +228,320 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact + store_display (factory, display); + + if (! gdm_display_manage (display)) { + display = NULL; + goto out; + } + + if (! gdm_display_get_id (display, id, NULL)) { + display = NULL; + goto out; + } + + ret = TRUE; + out: + /* ref either held by store or not at all */ + g_object_unref (display); + + return ret; + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmLocalDisplayFactory *factory) + { + int status; + GdmDisplayStore *store; + int num; + char *seat_id = NULL; + char *session_type = NULL; ++ char *session_class = NULL; + gboolean is_initial = TRUE; + gboolean is_local = TRUE; + + num = -1; + gdm_display_get_x11_display_number (display, &num, NULL); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + g_object_get (display, + "seat-id", &seat_id, + "is-initial", &is_initial, + "is-local", &is_local, + "session-type", &session_type, ++ "session-class", &session_class, + NULL); + + status = gdm_display_get_status (display); + + g_debug ("GdmLocalDisplayFactory: display status changed: %d", status); + switch (status) { + case GDM_DISPLAY_FINISHED: + /* remove the display number from factory->priv->used_display_numbers + so that it may be reused */ + if (num != -1) { + g_hash_table_remove (factory->priv->used_display_numbers, GUINT_TO_POINTER (num)); + } + gdm_display_store_remove (store, display); + + /* if this is a local display, do a full resync. Only + * seats without displays will get created anyway. This + * ensures we get a new login screen when the user logs out, + * if there isn't one. + */ +- if (is_local) { ++ if (is_local && g_strcmp0 (session_class, "greeter") != 0) { + /* reset num failures */ + factory->priv->num_failures = 0; + + gdm_local_display_factory_sync_seats (factory); + } + break; + case GDM_DISPLAY_FAILED: + /* leave the display number in factory->priv->used_display_numbers + so that it doesn't get reused */ + gdm_display_store_remove (store, display); + + /* Create a new equivalent display if it was static */ + if (is_local) { + + factory->priv->num_failures++; + + if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) { + /* oh shit */ + g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors"); + } else { + #ifdef ENABLE_WAYLAND_SUPPORT + if (g_strcmp0 (session_type, "wayland") == 0) { + g_free (session_type); + session_type = NULL; + } + + #endif + create_display (factory, seat_id, session_type, is_initial); + } + } + break; + case GDM_DISPLAY_UNMANAGED: + break; + case GDM_DISPLAY_PREPARED: + break; + case GDM_DISPLAY_MANAGED: + break; + default: + g_assert_not_reached (); + break; + } + + g_free (seat_id); + g_free (session_type); ++ g_free (session_class); + } + + static gboolean + lookup_by_seat_id (const char *id, + GdmDisplay *display, + gpointer user_data) + { + const char *looking_for = user_data; + char *current; + gboolean res; + + g_object_get (G_OBJECT (display), "seat-id", ¤t, NULL); + + res = g_strcmp0 (current, looking_for) == 0; + + g_free(current); + + return res; + } + ++static gboolean ++activate_session_id (GdmLocalDisplayFactory *self, ++ const char *seat_id, ++ const char *session_id) ++{ ++ GError *error = NULL; ++ GVariant *reply; ++ ++ reply = g_dbus_connection_call_sync (self->priv->connection, ++ "org.freedesktop.login1", ++ "/org/freedesktop/login1", ++ "org.freedesktop.login1.Manager", ++ "ActivateSessionOnSeat", ++ g_variant_new ("(ss)", session_id, seat_id), ++ NULL, /* expected reply */ ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, ++ &error); ++ if (reply == NULL) { ++ g_debug ("GdmManager: logind 'ActivateSessionOnSeat' %s raised:\n %s\n\n", ++ g_dbus_error_get_remote_error (error), error->message); ++ g_error_free (error); ++ return FALSE; ++ } ++ ++ g_variant_unref (reply); ++ ++ return TRUE; ++} ++ ++static gboolean ++get_login_window_session_id (const char *seat_id, ++ char **session_id) ++{ ++ gboolean ret; ++ int res, i; ++ char **sessions; ++ char *service_id; ++ char *service_class; ++ char *state; ++ ++ res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); ++ if (res < 0) { ++ g_debug ("Failed to determine sessions: %s", strerror (-res)); ++ return FALSE; ++ } ++ ++ if (sessions == NULL || sessions[0] == NULL) { ++ *session_id = NULL; ++ ret = TRUE; ++ goto out; ++ } ++ ++ for (i = 0; sessions[i]; i ++) { ++ ++ res = sd_session_get_class (sessions[i], &service_class); ++ if (res < 0) { ++ if (res == -ENOENT || res == -ENXIO) { ++ continue; ++ } ++ ++ g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); ++ ret = FALSE; ++ goto out; ++ } ++ ++ if (strcmp (service_class, "greeter") != 0) { ++ free (service_class); ++ continue; ++ } ++ ++ free (service_class); ++ ++ ret = sd_session_get_state (sessions[i], &state); ++ if (ret < 0) { ++ if (res == -ENOENT || res == -ENXIO) ++ continue; ++ ++ g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); ++ ret = FALSE; ++ goto out; ++ } ++ ++ if (g_strcmp0 (state, "closing") == 0) { ++ free (state); ++ continue; ++ } ++ free (state); ++ ++ res = sd_session_get_service (sessions[i], &service_id); ++ if (res < 0) { ++ if (res == -ENOENT || res == -ENXIO) ++ continue; ++ g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); ++ ret = FALSE; ++ goto out; ++ } ++ ++ if (strcmp (service_id, "gdm-launch-environment") == 0) { ++ *session_id = g_strdup (sessions[i]); ++ ret = TRUE; ++ ++ free (service_id); ++ goto out; ++ } ++ ++ free (service_id); ++ } ++ ++ *session_id = NULL; ++ ret = FALSE; ++ ++out: ++ if (sessions) { ++ for (i = 0; sessions[i]; i ++) { ++ free (sessions[i]); ++ } ++ ++ free (sessions); ++ } ++ ++ return ret; ++} ++ + static GdmDisplay * + create_display (GdmLocalDisplayFactory *factory, + const char *seat_id, + const char *session_type, + gboolean initial) + { + GdmDisplayStore *store; + GdmDisplay *display = NULL; ++ char *active_session_id = NULL; ++ int ret; + +- /* Ensure we don't create the same display more than once */ + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); +- display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); +- if (display != NULL) { +- return NULL; ++ ++ ret = sd_seat_get_active (seat_id, &active_session_id, NULL); ++ ++ if (ret == 0) { ++ char *login_session_id = NULL; ++ ++ /* If we already have a login window, switch to it */ ++ if (get_login_window_session_id (seat_id, &login_session_id)) { ++ if (g_strcmp0 (active_session_id, login_session_id) != 0) { ++ activate_session_id (factory, seat_id, login_session_id); ++ } ++ g_clear_pointer (&login_session_id, g_free); ++ g_clear_pointer (&active_session_id, g_free); ++ return NULL; ++ } ++ g_clear_pointer (&active_session_id, g_free); ++ } else { ++ /* Ensure we don't create the same display more than once */ ++ display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); ++ ++ if (display != NULL) { ++ return NULL; ++ } + } + + g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); + + #ifdef ENABLE_USER_DISPLAY_SERVER + if (g_strcmp0 (seat_id, "seat0") == 0) { + display = gdm_local_display_new (); + if (session_type != NULL) { + g_object_set (G_OBJECT (display), "session-type", session_type, NULL); + } + } + #endif + + if (display == NULL) { + guint32 num; + + num = take_next_display_number (factory); + + display = gdm_legacy_display_new (num); + } + + g_object_set (display, "seat-id", seat_id, NULL); + g_object_set (display, "is-initial", initial, NULL); + + store_display (factory, display); + + /* let store own the ref */ + g_object_unref (display); + + if (! gdm_display_manage (display)) { +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 34ee74033..031c61ce6 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1318,171 +1318,118 @@ maybe_start_pending_initial_login (GdmManager *manager, + g_free (user_session_seat_id); + } + + static gboolean + get_login_window_session_id (const char *seat_id, + char **session_id) + { + gboolean ret; + int res, i; + char **sessions; + char *service_id; + char *service_class; + char *state; + + res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL); + if (res < 0) { + g_debug ("Failed to determine sessions: %s", strerror (-res)); + return FALSE; + } + + if (sessions == NULL || sessions[0] == NULL) { + *session_id = NULL; + ret = FALSE; + goto out; + } + + for (i = 0; sessions[i]; i ++) { + + res = sd_session_get_class (sessions[i], &service_class); + if (res < 0) { +- if (res == -ENOENT || res == -ENXIO) { +- continue; +- } +- + g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (strcmp (service_class, "greeter") != 0) { + free (service_class); + continue; + } + + free (service_class); + + ret = sd_session_get_state (sessions[i], &state); + if (ret < 0) { +- if (res == -ENOENT || res == -ENXIO) +- continue; +- + g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (g_strcmp0 (state, "closing") == 0) { + free (state); + continue; + } + free (state); + + res = sd_session_get_service (sessions[i], &service_id); + if (res < 0) { +- if (res == -ENOENT || res == -ENXIO) +- continue; + g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); + ret = FALSE; + goto out; + } + + if (strcmp (service_id, "gdm-launch-environment") == 0) { + *session_id = g_strdup (sessions[i]); + ret = TRUE; + + free (service_id); + goto out; + } + + free (service_id); + } + + *session_id = NULL; + ret = FALSE; + + out: + if (sessions) { + for (i = 0; sessions[i]; i ++) { + free (sessions[i]); + } + + free (sessions); + } + + return ret; + } + +-static void +-activate_login_window_session_on_seat (GdmManager *self, +- const char *seat_id) +-{ +- char *session_id; +- +- if (!get_login_window_session_id (seat_id, &session_id)) { +- return; +- } +- +- activate_session_id (self, seat_id, session_id); +-} +- +-static void +-maybe_activate_other_session (GdmManager *self, +- GdmDisplay *old_display) +-{ +- char *seat_id = NULL; +- char *session_id = NULL; +- int ret; +- +- g_object_get (G_OBJECT (old_display), +- "seat-id", &seat_id, +- NULL); +- +- ret = sd_seat_get_active (seat_id, &session_id, NULL); +- +- if (ret == 0) { +- GdmDisplay *display; +- +- display = gdm_display_store_find (self->priv->display_store, +- lookup_by_session_id, +- (gpointer) session_id); +- +- if (display == NULL || gdm_display_get_status (display) == GDM_DISPLAY_FINISHED) { +- activate_login_window_session_on_seat (self, seat_id); +- } +- +- g_free (session_id); +- } +- +- g_free (seat_id); +-} +- + 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) + { + GdmSession *session; + char *display_session_type = NULL; + gboolean is_initial; + + /* 0 is root user; since the daemon talks to the session object + * directly, itself, for automatic login + */ + session = create_user_session_for_display (manager, display, 0); + +@@ -1674,61 +1621,60 @@ on_display_status_changed (GdmDisplay *display, + if ((display_number == -1 && status == GDM_DISPLAY_PREPARED) || + (display_number != -1 && status == GDM_DISPLAY_MANAGED)) { + char *session_class; + + g_object_get (display, + "session-class", &session_class, + NULL); + if (g_strcmp0 (session_class, "greeter") == 0) + set_up_session (manager, display); + g_free (session_class); + } + + if (status == GDM_DISPLAY_MANAGED) { + greeter_display_started (manager, display); + } + break; + case GDM_DISPLAY_FAILED: + case GDM_DISPLAY_UNMANAGED: + case GDM_DISPLAY_FINISHED: + #ifdef WITH_PLYMOUTH + if (quit_plymouth) { + plymouth_quit_without_transition (); + manager->priv->plymouth_is_running = FALSE; + } + #endif + + if (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0) { + manager->priv->ran_once = TRUE; + } + maybe_start_pending_initial_login (manager, display); +- maybe_activate_other_session (manager, display); + break; + default: + break; + } + + } + + static void + on_display_removed (GdmDisplayStore *display_store, + const char *id, + GdmManager *manager) + { + GdmDisplay *display; + + display = gdm_display_store_lookup (display_store, id); + if (display != NULL) { + g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); + + g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); + + g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, id); + } + } + + static void + destroy_start_user_session_operation (StartUserSessionOperation *operation) + { + g_object_set_data (G_OBJECT (operation->session), + "start-user-session-operation", + NULL); +-- +2.19.0 + diff --git a/SOURCES/0006-daemon-ensure-is-initial-bit-is-transferred-to-new-l.patch b/SOURCES/0006-daemon-ensure-is-initial-bit-is-transferred-to-new-l.patch new file mode 100644 index 0000000..633a3d9 --- /dev/null +++ b/SOURCES/0006-daemon-ensure-is-initial-bit-is-transferred-to-new-l.patch @@ -0,0 +1,97 @@ +From 91eee14bcd2447d78ad00e3de9d4380e423cb897 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 24 Sep 2018 10:53:53 -0400 +Subject: [PATCH 6/6] daemon: ensure is-initial bit is transferred to new login + screen at logout + +At the moment, when a user logs out we call sync_seats to restart the +login screen. sync_seats doesn't know whether or not vt1 is occupied. + +This commit changes the code to call the more targeted `create_display` +function, which we can inform of vt1's availability by the is_initial +flag. +--- + daemon/gdm-local-display-factory.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index cf852b55a..9a07f03ed 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -257,70 +257,68 @@ on_display_status_changed (GdmDisplay *display, + char *session_type = NULL; + char *session_class = NULL; + gboolean is_initial = TRUE; + gboolean is_local = TRUE; + + num = -1; + gdm_display_get_x11_display_number (display, &num, NULL); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + g_object_get (display, + "seat-id", &seat_id, + "is-initial", &is_initial, + "is-local", &is_local, + "session-type", &session_type, + "session-class", &session_class, + NULL); + + status = gdm_display_get_status (display); + + g_debug ("GdmLocalDisplayFactory: display status changed: %d", status); + switch (status) { + case GDM_DISPLAY_FINISHED: + /* remove the display number from factory->priv->used_display_numbers + so that it may be reused */ + if (num != -1) { + g_hash_table_remove (factory->priv->used_display_numbers, GUINT_TO_POINTER (num)); + } + gdm_display_store_remove (store, display); + +- /* if this is a local display, do a full resync. Only +- * seats without displays will get created anyway. This +- * ensures we get a new login screen when the user logs out, +- * if there isn't one. ++ /* if this is a local display, recreate the display so ++ * a new login screen comes up if one is missing. + */ + if (is_local && g_strcmp0 (session_class, "greeter") != 0) { + /* reset num failures */ + factory->priv->num_failures = 0; + +- gdm_local_display_factory_sync_seats (factory); ++ create_display (factory, seat_id, session_type, is_initial); + } + break; + case GDM_DISPLAY_FAILED: + /* leave the display number in factory->priv->used_display_numbers + so that it doesn't get reused */ + gdm_display_store_remove (store, display); + + /* Create a new equivalent display if it was static */ + if (is_local) { + + factory->priv->num_failures++; + + if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) { + /* oh shit */ + g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors"); + } else { + #ifdef ENABLE_WAYLAND_SUPPORT + if (g_strcmp0 (session_type, "wayland") == 0) { + g_free (session_type); + session_type = NULL; + } + + #endif + create_display (factory, seat_id, session_type, is_initial); + } + } + break; + case GDM_DISPLAY_UNMANAGED: + break; + case GDM_DISPLAY_PREPARED: +-- +2.19.0 + diff --git a/SPECS/gdm.spec b/SPECS/gdm.spec index c0d6e19..47295ce 100644 --- a/SPECS/gdm.spec +++ b/SPECS/gdm.spec @@ -2,30 +2,25 @@ %global _hardened_build 1 %define libauditver 1.0.6 -%define pango_version 1.2.0 %define gtk3_version 2.99.2 %define pam_version 0.99.8.1-11 %define desktop_file_utils_version 0.2.90 %define nss_version 3.11.1 -%define fontconfig_version 2.6.0 -Summary: The GNOME Display Manager Name: gdm -Version: 3.26.2.1 -Release: 5%{?dist} Epoch: 1 +Version: 3.28.2 +Release: 9%{?dist} +Summary: The GNOME Display Manager + License: GPLv2+ -Group: User Interface/X -URL: http://download.gnome.org/sources/gdm -#VCS: git:git://git.gnome.org/gdm -Source: http://download.gnome.org/sources/gdm/3.22/gdm-%{version}.tar.xz +URL: https://wiki.gnome.org/Projects/GDM +Source0: http://download.gnome.org/sources/gdm/3.28/gdm-%{version}.tar.xz Source1: org.gnome.login-screen.gschema.override Source2: ja.po Patch0: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch -patch10: 0001-Revert-session-don-t-call-gdm_session_defaults_chang.patch - Patch20: 0001-Revert-session-forward-is-initial-from-display-to-wo.patch Patch21: 0001-worker-add-compat-patch-to-make-new-worker-work-with.patch @@ -34,6 +29,17 @@ Patch40: 0001-Revert-data-Add-gnome-login.session.patch # we don't have new enough dbus for this and don't need it with our old dbus Patch41: 0001-Revert-gdm-sessions-force-a-session-bus-for-non-seat.patch +Patch50: 0001-data-change-cirrus-blacklist-to-use-gdm-disable-wayl.patch + +Patch60: 0001-manager-plug-leak-in-maybe_activate_other_session.patch +Patch61: 0002-manager-start-login-screen-if-old-one-is-finished.patch +Patch62: 0003-manager-don-t-bail-if-session-disappears-out-from-un.patch +Patch63: 0004-manager-make-get_login_window_session_id-fail-if-no-.patch +Patch64: 0005-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch +Patch65: 0006-daemon-ensure-is-initial-bit-is-transferred-to-new-l.patch + +Patch70: 0001-daemon-gdm-session-record.c-open-close-the-utmp-data.patch + Patch90: audit-4.patch Patch91: clear-screen.patch Patch92: 0001-gdm.conf-custom.in-strip-out-reference-to-wayland.patch @@ -41,18 +47,19 @@ Patch93: system-dconf.patch Patch94: classic-session.patch Patch95: 0001-data-drop-pam_gdm-reintroduce-pam_env-postlogin.patch -BuildRequires: git BuildRequires: pam-devel >= 0:%{pam_version} BuildRequires: desktop-file-utils >= %{desktop_file_utils_version} BuildRequires: libtool automake autoconf BuildRequires: libattr-devel BuildRequires: gettext +BuildRequires: git BuildRequires: libdmx-devel BuildRequires: audit-libs-devel >= %{libauditver} BuildRequires: autoconf automake libtool BuildRequires: intltool %ifnarch s390 s390x ppc ppc64 BuildRequires: xorg-x11-server-Xorg +BuildRequires: pkgconfig(xorg-server) %endif BuildRequires: nss-devel >= %{nss_version} BuildRequires: pkgconfig(accountsservice) >= 0.6.3 @@ -85,7 +92,7 @@ Requires: dconf # since we use it, and pam spams the log if the module is missing Requires: gnome-keyring-pam Requires: gnome-session -Requires: gnome-settings-daemon >= 2.21.92 +Requires: gnome-settings-daemon >= 3.27.90 Requires: gnome-shell Requires: iso-codes # We need 1.0.4-5 since it lets us use "localhost" in auth cookies @@ -110,12 +117,17 @@ Obsoletes: gdm-plugin-fingerprint < 1:3.2.1 Provides: gdm-plugin-fingerprint = %{epoch}:%{version}-%{release} %description -GDM provides the graphical login screen, shown shortly after boot up, -log out, and when user-switching. +GDM, the GNOME Display Manager, handles authentication-related backend +functionality for logging in a user and unlocking the user's session after +it's been locked. GDM also provides functionality for initiating user-switching, +so more than one user can be logged in at the same time. It handles +graphical session registration with the system for both local and remote +sessions (in the latter case, via the XDMCP protocol). In cases where the +session doesn't provide it's own display server, GDM can start the display +server on behalf of the session. %package devel Summary: Development files for gdm -Group: Development/Libraries Requires: %{name}%{?_isa} = %{epoch}:%{version}-%{release} Requires: gdm-pam-extensions-devel = %{epoch}:%{version}-%{release} @@ -127,6 +139,8 @@ files needed to build custom greeters. Summary: Macros for developing GDM extensions to PAM Group: Development/Libraries Requires: pam-devel +Obsoletes: gdm-pam-extensions < 1:3.28.2-5 +Provides: gdm-pam-extensions = %{epoch}:%{version}-%{release} %description pam-extensions-devel The gdm-pam-extensions-devel package contains headers and other @@ -163,38 +177,31 @@ make %{?_smp_mflags} %install -mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/gdm/Init -mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/gdm/PreSession -mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/gdm/PostSession +mkdir -p %{buildroot}%{_sysconfdir}/gdm/Init +mkdir -p %{buildroot}%{_sysconfdir}/gdm/PreSession +mkdir -p %{buildroot}%{_sysconfdir}/gdm/PostSession -make install DESTDIR=$RPM_BUILD_ROOT +make install DESTDIR=%{buildroot} -rm -f $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/gdm +rm -f %{buildroot}%{_sysconfdir}/pam.d/gdm # add logo to shell greeter -cp %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/glib-2.0/schemas - -mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dconf/db/gdm.d/locks +cp -a %{SOURCE1} %{buildroot}%{_datadir}/glib-2.0/schemas # docs go elsewhere -rm -rf $RPM_BUILD_ROOT/%{_prefix}/doc +rm -rf %{buildroot}/%{_prefix}/doc # create log dir -mkdir -p $RPM_BUILD_ROOT/var/log/gdm +mkdir -p %{buildroot}/var/log/gdm -# remove the gdm Xsession as we're using the xdm one -rm -f $RPM_BUILD_ROOT%{_sysconfdir}/gdm/Xsession -(cd $RPM_BUILD_ROOT%{_sysconfdir}/gdm; ln -sf ../X11/xinit/Xsession .) +(cd %{buildroot}%{_sysconfdir}/gdm; ln -sf ../X11/xinit/Xsession .) -rm -f $RPM_BUILD_ROOT%{_libdir}/gtk-2.0/modules/*.a -rm -f $RPM_BUILD_ROOT%{_libdir}/gtk-2.0/modules/*.la +mkdir -p %{buildroot}%{_datadir}/gdm/autostart/LoginWindow -mkdir -p $RPM_BUILD_ROOT%{_datadir}/gdm/autostart/LoginWindow +mkdir -p %{buildroot}/run/gdm -mkdir -p $RPM_BUILD_ROOT/run/gdm - -find $RPM_BUILD_ROOT -name '*.a' -delete -find $RPM_BUILD_ROOT -name '*.la' -delete +find %{buildroot} -name '*.a' -delete +find %{buildroot} -name '*.la' -delete %find_lang gdm --with-gnome @@ -259,7 +266,6 @@ fi %systemd_post gdm.service %preun -%gconf_schema_remove gdm-simple-greeter %systemd_preun gdm.service %postun @@ -283,8 +289,8 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : /usr/bin/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %files -f gdm.lang -%doc AUTHORS COPYING NEWS README - +%doc AUTHORS NEWS README +%license COPYING %dir %{_sysconfdir}/gdm %config(noreplace) %{_sysconfdir}/gdm/custom.conf %config %{_sysconfdir}/gdm/Init/* @@ -312,8 +318,13 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %{_sbindir}/gdm %{_bindir}/gdmflexiserver %{_bindir}/gdm-screenshot +%dir %{_datadir}/dconf +%dir %{_datadir}/dconf/profile %{_datadir}/dconf/profile/gdm +%dir %{_datadir}/gdm/greeter +%dir %{_datadir}/gdm/greeter/applications %{_datadir}/gdm/greeter/applications/* +%dir %{_datadir}/gdm/greeter/autostart %{_datadir}/gdm/greeter/autostart/* %{_datadir}/gdm/greeter-dconf-defaults %{_datadir}/gdm/locale.alias @@ -325,19 +336,19 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %attr(1770, gdm, gdm) %dir %{_localstatedir}/lib/gdm %attr(0711, root, gdm) %dir /run/gdm %attr(1755, root, gdm) %dir %{_localstatedir}/cache/gdm -%dir %{_sysconfdir}/dconf/db/gdm.d/locks -%dir %{_sysconfdir}/dconf/db/gdm.d %{_datadir}/icons/hicolor/*/*/*.png %config %{_sysconfdir}/pam.d/gdm-pin %config %{_sysconfdir}/pam.d/gdm-smartcard %config %{_sysconfdir}/pam.d/gdm-fingerprint %{_sysconfdir}/pam.d/gdm-launch-environment +%{_udevrulesdir}/61-gdm.rules %{_unitdir}/gdm.service %files devel %dir %{_includedir}/gdm %{_includedir}/gdm/*.h %exclude %{_includedir}/gdm/gdm-pam-extensions.h +%dir %{_datadir}/gir-1.0 %{_datadir}/gir-1.0/Gdm-1.0.gir %{_libdir}/pkgconfig/gdm.pc @@ -346,6 +357,43 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %{_libdir}/pkgconfig/gdm-pam-extensions.pc %changelog +* Mon Sep 24 2018 Ray Strode - 3.28.2-9 +- fast user switching fix + Related: #1597339 + +* Tue Sep 04 2018 Ray Strode - 3.28.2-8 +- Clear utmp entries properly + Resolves: #1600079 + +* Mon Jul 30 2018 Ray Strode - 3.28.2-7 +- Another crack at the blank login screen problem + Resolves: #1489977 + +* Mon Jul 16 2018 Ray Strode - 3.28.2-6 +- add gdm-pam-extension provides to fix upgrades + Resolves: #1601598 + +* Tue Jun 26 2018 Ray Strode - 3.28.2-5 +- Fix double free + Related: #1489977 + Resolves: 1594814 + +* Fri Jun 22 2018 Ray Strode - 3.28.2-4 +- Fix blank login screen problem + Resolves: #1489977 + +* Wed Jun 20 2018 Ray Strode - 3.28.2-3 +- Make udev script more friendly to RHEL 7 udev + Resolves: #1593356 + +* Tue May 29 2018 Ray Strode - 1:3.28.2-2 +- Drop reference to gconf + Resolves: #1542702 + +* Thu May 17 2018 Kalev Lember - 1:3.28.2-1 +- Update to 3.28.2 +- Resolves: #1567200 + * Wed Feb 14 2018 Ray Strode - 3.26.2.1-5 - Fix bullet in session list Resolves: #1527145