Blame SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch

dfaa01
From 3864af1ea06d2125c1b1f5afa6fc12caa833980a Mon Sep 17 00:00:00 2001
dfaa01
From: Ray Strode <rstrode@redhat.com>
dfaa01
Date: Thu, 10 Dec 2020 15:14:20 -0500
dfaa01
Subject: [PATCH] session-worker: Don't switch back VTs until session is fully
dfaa01
 exited
dfaa01
dfaa01
There's a race condition on shutdown where the session worker is
dfaa01
switching VTs back to the initial VT at the same time as the session
dfaa01
exit is being processed.
dfaa01
dfaa01
This means that manager may try to start a login screen (because of
dfaa01
the VT switch) when autologin is enabled when there shouldn't be a
dfaa01
login screen.
dfaa01
dfaa01
This commit makes sure both the PostSession script, and session-exited
dfaa01
signal emission are complete before initiating the VT switch back
dfaa01
to the initial VT.
dfaa01
dfaa01
https://gitlab.gnome.org/GNOME/gdm/-/issues/660
dfaa01
---
dfaa01
 daemon/Makefile.am              | 12 +++++
dfaa01
 daemon/gdm-session-worker.c     | 93 +++++++++++++++++++++++++++------
dfaa01
 daemon/org.freedesktop.DBus.xml | 12 +++++
dfaa01
 3 files changed, 101 insertions(+), 16 deletions(-)
dfaa01
 create mode 100644 daemon/org.freedesktop.DBus.xml
dfaa01
dfaa01
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
dfaa01
index 86a8ee32f..b323f6455 100644
dfaa01
--- a/daemon/Makefile.am
dfaa01
+++ b/daemon/Makefile.am
dfaa01
@@ -7,83 +7,92 @@ AM_CPPFLAGS = \
dfaa01
 	-I$(top_srcdir)/pam-extensions			\
dfaa01
 	-I$(top_builddir)/common			\
dfaa01
 	-DBINDIR=\"$(bindir)\"				\
dfaa01
 	-DDATADIR=\"$(datadir)\"			\
dfaa01
 	-DDMCONFDIR=\"$(dmconfdir)\"			\
dfaa01
 	-DGDMCONFDIR=\"$(gdmconfdir)\"			\
dfaa01
 	-DLIBDIR=\"$(libdir)\"				\
dfaa01
 	-DLIBEXECDIR=\"$(libexecdir)\"			\
dfaa01
 	-DLOCALSTATEDIR=\"$(localstatedir)\"		\
dfaa01
 	-DLOGDIR=\"$(logdir)\"				\
dfaa01
 	-DSBINDIR=\"$(sbindir)\"			\
dfaa01
 	-DSYSCONFDIR=\"$(sysconfdir)\"			\
dfaa01
 	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"	\
dfaa01
 	-DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\"		\
dfaa01
 	-DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\"		\
dfaa01
 	-DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\"		\
dfaa01
 	-DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\"	\
dfaa01
 	-DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \
dfaa01
 	$(DISABLE_DEPRECATED_CFLAGS)			\
dfaa01
 	$(DAEMON_CFLAGS)				\
dfaa01
 	$(XLIB_CFLAGS)					\
dfaa01
 	$(WARN_CFLAGS)					\
dfaa01
 	$(DEBUG_CFLAGS)					\
dfaa01
 	$(SYSTEMD_CFLAGS)				\
dfaa01
 	$(JOURNALD_CFLAGS)				\
dfaa01
 	$(LIBSELINUX_CFLAGS)	 			\
dfaa01
 	-DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\"	\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 BUILT_SOURCES =					\
dfaa01
+	gdm-dbus-glue.h				\
dfaa01
 	gdm-display-glue.h			\
dfaa01
 	gdm-manager-glue.h			\
dfaa01
 	gdm-local-display-glue.h		\
dfaa01
 	gdm-local-display-factory-glue.h	\
dfaa01
 	gdm-session-glue.h			\
dfaa01
 	gdm-session-worker-glue.h		\
dfaa01
 	gdm-session-enum-types.h		\
dfaa01
 	gdm-session-worker-enum-types.h         \
dfaa01
 	com.redhat.AccountsServiceUser.System.h \
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h
dfaa01
 	$(AM_V_GEN) glib-mkenums --template $^ > $@
dfaa01
 
dfaa01
 gdm-session-enum-types.c: gdm-session-enum-types.c.in gdm-session.h
dfaa01
 	$(AM_V_GEN) glib-mkenums --template $^ > $@
dfaa01
 
dfaa01
 gdm-session-worker-enum-types.h: gdm-session-worker-enum-types.h.in gdm-session-worker.h
dfaa01
 	$(AM_V_GEN) glib-mkenums --template $^ > $@
dfaa01
 
dfaa01
 gdm-session-worker-enum-types.c: gdm-session-worker-enum-types.c.in gdm-session-worker.h
dfaa01
 	$(AM_V_GEN) glib-mkenums --template $^ > $@
dfaa01
 
dfaa01
+gdm-dbus-glue.c gdm-dbus-glue.h: org.freedesktop.DBus.xml Makefile.am
dfaa01
+	$(AM_V_GEN)gdbus-codegen 					\
dfaa01
+		--c-namespace=GdmDBus					\
dfaa01
+		--interface-prefix=org.freedesktop.DBus			\
dfaa01
+		--generate-c-code=gdm-dbus-glue				\
dfaa01
+		--c-generate-autocleanup=all				\
dfaa01
+		$(srcdir)/org.freedesktop.DBus.xml
dfaa01
+
dfaa01
 gdm-display-glue.c gdm-display-glue.h: gdm-display.xml Makefile.am
dfaa01
 	$(AM_V_GEN)gdbus-codegen 					\
dfaa01
 		--c-namespace=GdmDBus					\
dfaa01
 		--interface-prefix=org.gnome.DisplayManager		\
dfaa01
 		--generate-c-code=gdm-display-glue			\
dfaa01
 		$(srcdir)/gdm-display.xml
dfaa01
 
dfaa01
 gdm-local-display-glue.c gdm-local-display-glue.h: gdm-local-display.xml Makefile.am
dfaa01
 	$(AM_V_GEN)gdbus-codegen 					\
dfaa01
 		--c-namespace=GdmDBus					\
dfaa01
 		--interface-prefix=org.gnome.DisplayManager		\
dfaa01
 		--generate-c-code=gdm-local-display-glue		\
dfaa01
 		$(srcdir)/gdm-local-display.xml
dfaa01
 
dfaa01
 gdm-local-display-factory-glue.c gdm-local-display-factory-glue.h : gdm-local-display-factory.xml Makefile.am
dfaa01
 	$(AM_V_GEN)gdbus-codegen 					\
dfaa01
 		--c-namespace=GdmDBus					\
dfaa01
 		--interface-prefix=org.gnome.DisplayManager		\
dfaa01
 		--generate-c-code=gdm-local-display-factory-glue	\
dfaa01
 		$(srcdir)/gdm-local-display-factory.xml
dfaa01
 
dfaa01
 gdm-manager-glue.c gdm-manager-glue.h : gdm-manager.xml Makefile.am
dfaa01
 	$(AM_V_GEN)gdbus-codegen 					\
dfaa01
 		--c-namespace=GdmDBus					\
dfaa01
 		--interface-prefix=org.gnome.DisplayManager		\
dfaa01
 		--generate-c-code=gdm-manager-glue			\
dfaa01
 		$(srcdir)/gdm-manager.xml
dfaa01
 
dfaa01
 gdm-session-glue.c gdm-session-glue.h : gdm-session.xml Makefile.am
dfaa01
 	$(AM_V_GEN)gdbus-codegen 					\
dfaa01
@@ -130,60 +139,62 @@ libexec_PROGRAMS = 			\
dfaa01
 	gdm-wayland-session		\
dfaa01
 	gdm-x-session			\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 gdm_session_worker_SOURCES = 			\
dfaa01
 	session-worker-main.c 			\
dfaa01
 	com.redhat.AccountsServiceUser.System.h \
dfaa01
 	com.redhat.AccountsServiceUser.System.c \
dfaa01
 	gdm-session.c				\
dfaa01
 	gdm-session.h				\
dfaa01
 	gdm-session-settings.h			\
dfaa01
 	gdm-session-settings.c			\
dfaa01
 	gdm-session-auditor.h			\
dfaa01
 	gdm-session-auditor.c			\
dfaa01
 	gdm-session-record.c			\
dfaa01
 	gdm-session-record.h			\
dfaa01
 	gdm-session-worker.h			\
dfaa01
 	gdm-session-worker.c			\
dfaa01
 	gdm-session-worker-job.c		\
dfaa01
 	gdm-session-worker-common.c		\
dfaa01
 	gdm-session-worker-common.h		\
dfaa01
 	gdm-dbus-util.c				\
dfaa01
 	gdm-dbus-util.h				\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 if SUPPORTS_PAM_EXTENSIONS
dfaa01
 gdm_session_worker_SOURCES += $(top_srcdir)/pam-extensions/gdm-pam-extensions.h
dfaa01
 endif
dfaa01
 
dfaa01
 nodist_gdm_session_worker_SOURCES =		\
dfaa01
+	gdm-dbus-glue.h				\
dfaa01
+	gdm-dbus-glue.c				\
dfaa01
 	gdm-session-glue.h			\
dfaa01
 	gdm-session-glue.c			\
dfaa01
 	gdm-session-worker-glue.c		\
dfaa01
 	gdm-session-worker-glue.h		\
dfaa01
 	gdm-session-enum-types.c		\
dfaa01
 	gdm-session-worker-enum-types.c		\
dfaa01
 	gdm-session-enum-types.h		\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 gdm_wayland_session_LDADD =		\
dfaa01
 	$(top_builddir)/common/libgdmcommon.la	\
dfaa01
 	$(GTK_LIBS)		\
dfaa01
 	$(COMMON_LIBS)		\
dfaa01
 	$(SYSTEMD_LIBS)         \
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 gdm_wayland_session_SOURCES =	\
dfaa01
 	gdm-manager-glue.h	\
dfaa01
 	gdm-manager-glue.c	\
dfaa01
 	gdm-wayland-session.c	\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 gdm_x_session_LDADD =		\
dfaa01
 	$(top_builddir)/common/libgdmcommon.la	\
dfaa01
 	$(GTK_LIBS)		\
dfaa01
 	$(COMMON_LIBS)		\
dfaa01
 	$(SYSTEMD_LIBS)         \
dfaa01
 	$(XLIB_LIBS)		\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
@@ -271,50 +282,51 @@ nodist_gdm_SOURCES = 			\
dfaa01
 
dfaa01
 XDMCP_SOURCES =				\
dfaa01
 	gdm-xdmcp-display-factory.c	\
dfaa01
 	gdm-xdmcp-display-factory.h	\
dfaa01
 	gdm-xdmcp-display.c		\
dfaa01
 	gdm-xdmcp-display.h		\
dfaa01
 	gdm-xdmcp-chooser-display.c	\
dfaa01
 	gdm-xdmcp-chooser-display.h	\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 if XDMCP_SUPPORT
dfaa01
 gdm_SOURCES += $(XDMCP_SOURCES)
dfaa01
 endif
dfaa01
 
dfaa01
 EXTRA_gdm_SOURCES = 	\
dfaa01
 	$(XDMCP_SOURCES)	\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 gdm_LDADD = \
dfaa01
 	$(top_builddir)/common/libgdmcommon.la	\
dfaa01
 	$(XLIB_LIBS)				\
dfaa01
 	$(DAEMON_LIBS)				\
dfaa01
 	$(XDMCP_LIBS)                           \
dfaa01
 	$(LIBWRAP_LIBS)                         \
dfaa01
 	$(SYSTEMD_LIBS)				\
dfaa01
 	$(JOURNALD_LIBS)				\
dfaa01
 	$(EXTRA_DAEMON_LIBS)			\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 CLEANFILES =					\
dfaa01
+	gdm-dbus-glue.c				\
dfaa01
 	gdm-display-glue.c			\
dfaa01
 	gdm-local-display-factory-glue.c	\
dfaa01
 	gdm-manager-glue.c			\
dfaa01
 	gdm-session-glue.c			\
dfaa01
 	gdm-session-worker-glue.c		\
dfaa01
 	gdm-session-enum-types.c		\
dfaa01
 	gdm-local-display-glue.c		\
dfaa01
 	$(BUILT_SOURCES)			\
dfaa01
 	$(NULL)
dfaa01
 
dfaa01
 EXTRA_DIST = 				\
dfaa01
 	gdm-manager.xml			\
dfaa01
 	gdm-session-worker.xml		\
dfaa01
 	gdm-session.xml			\
dfaa01
 	gdm-display.xml			\
dfaa01
 	gdm-local-display.xml		\
dfaa01
 	gdm-local-display-factory.xml	\
dfaa01
 	gdm-session-enum-types.c.in	\
dfaa01
 	gdm-session-enum-types.h.in	\
dfaa01
 	$(NULL)
dfaa01
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
dfaa01
index 42c415837..c1b2c1765 100644
dfaa01
--- a/daemon/gdm-session-worker.c
dfaa01
+++ b/daemon/gdm-session-worker.c
dfaa01
@@ -39,60 +39,61 @@
dfaa01
 
dfaa01
 #ifdef HAVE_LOGINCAP
dfaa01
 #include <login_cap.h>
dfaa01
 #endif
dfaa01
 
dfaa01
 #include <glib.h>
dfaa01
 #include <glib/gi18n.h>
dfaa01
 #include <glib/gstdio.h>
dfaa01
 #include <glib-object.h>
dfaa01
 #include <gio/gio.h>
dfaa01
 
dfaa01
 #include <X11/Xauth.h>
dfaa01
 
dfaa01
 #include <systemd/sd-daemon.h>
dfaa01
 
dfaa01
 #ifdef ENABLE_SYSTEMD_JOURNAL
dfaa01
 #include <systemd/sd-journal.h>
dfaa01
 #endif
dfaa01
 
dfaa01
 #ifdef HAVE_SELINUX
dfaa01
 #include <selinux/selinux.h>
dfaa01
 #endif /* HAVE_SELINUX */
dfaa01
 
dfaa01
 #include "gdm-common.h"
dfaa01
 #include "gdm-log.h"
dfaa01
 
dfaa01
 #ifdef SUPPORTS_PAM_EXTENSIONS
dfaa01
 #include "gdm-pam-extensions.h"
dfaa01
 #endif
dfaa01
 
dfaa01
+#include "gdm-dbus-glue.h"
dfaa01
 #include "gdm-session-worker.h"
dfaa01
 #include "gdm-session-glue.h"
dfaa01
 #include "gdm-session.h"
dfaa01
 
dfaa01
 #if defined (HAVE_ADT)
dfaa01
 #include "gdm-session-solaris-auditor.h"
dfaa01
 #elif defined (HAVE_LIBAUDIT)
dfaa01
 #include "gdm-session-linux-auditor.h"
dfaa01
 #else
dfaa01
 #include "gdm-session-auditor.h"
dfaa01
 #endif
dfaa01
 
dfaa01
 #include "gdm-session-settings.h"
dfaa01
 
dfaa01
 #define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate))
dfaa01
 
dfaa01
 #define GDM_SESSION_DBUS_PATH         "/org/gnome/DisplayManager/Session"
dfaa01
 #define GDM_SESSION_DBUS_NAME         "org.gnome.DisplayManager.Session"
dfaa01
 #define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel"
dfaa01
 
dfaa01
 #define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker"
dfaa01
 
dfaa01
 #ifndef GDM_PASSWD_AUXILLARY_BUFFER_SIZE
dfaa01
 #define GDM_PASSWD_AUXILLARY_BUFFER_SIZE 1024
dfaa01
 #endif
dfaa01
 
dfaa01
 #ifndef GDM_SESSION_DEFAULT_PATH
dfaa01
 #define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin"
dfaa01
 #endif
dfaa01
 
dfaa01
@@ -1028,72 +1029,60 @@ gdm_session_worker_set_state (GdmSessionWorker      *worker,
dfaa01
 
dfaa01
 static void
dfaa01
 gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
dfaa01
                                      int               status)
dfaa01
 {
dfaa01
         g_debug ("GdmSessionWorker: uninitializing PAM");
dfaa01
 
dfaa01
         if (worker->priv->pam_handle == NULL)
dfaa01
                 return;
dfaa01
 
dfaa01
         gdm_session_worker_get_username (worker, NULL);
dfaa01
 
dfaa01
         if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) {
dfaa01
                 pam_close_session (worker->priv->pam_handle, 0);
dfaa01
                 gdm_session_auditor_report_logout (worker->priv->auditor);
dfaa01
         } else {
dfaa01
                 gdm_session_auditor_report_login_failure (worker->priv->auditor,
dfaa01
                                                           status,
dfaa01
                                                           pam_strerror (worker->priv->pam_handle, status));
dfaa01
         }
dfaa01
 
dfaa01
         if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) {
dfaa01
                 pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED);
dfaa01
         }
dfaa01
 
dfaa01
         pam_end (worker->priv->pam_handle, status);
dfaa01
         worker->priv->pam_handle = NULL;
dfaa01
 
dfaa01
         gdm_session_worker_stop_auditor (worker);
dfaa01
 
dfaa01
-        /* If user-display-server is not enabled the login_vt is always
dfaa01
-         * identical to the session_vt. So in that case we never need to
dfaa01
-         * do a VT switch. */
dfaa01
-#ifdef ENABLE_USER_DISPLAY_SERVER
dfaa01
-        if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) {
dfaa01
-                /* Switch to the login VT if we are not the login screen. */
dfaa01
-                if (worker->priv->session_vt != GDM_INITIAL_VT) {
dfaa01
-                        jump_to_vt (worker, GDM_INITIAL_VT);
dfaa01
-                }
dfaa01
-        }
dfaa01
-#endif
dfaa01
-
dfaa01
         worker->priv->session_vt = 0;
dfaa01
 
dfaa01
         g_debug ("GdmSessionWorker: state NONE");
dfaa01
         gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE);
dfaa01
 }
dfaa01
 
dfaa01
 static char *
dfaa01
 _get_tty_for_pam (const char *x11_display_name,
dfaa01
                   const char *display_device)
dfaa01
 {
dfaa01
 #ifdef __sun
dfaa01
         return g_strdup (display_device);
dfaa01
 #else
dfaa01
         return g_strdup (x11_display_name);
dfaa01
 #endif
dfaa01
 }
dfaa01
 
dfaa01
 #ifdef PAM_XAUTHDATA
dfaa01
 static struct pam_xauth_data *
dfaa01
 _get_xauth_for_pam (const char *x11_authority_file)
dfaa01
 {
dfaa01
         FILE                  *fh;
dfaa01
         Xauth                 *auth = NULL;
dfaa01
         struct pam_xauth_data *retval = NULL;
dfaa01
         gsize                  len = sizeof (*retval) + 1;
dfaa01
 
dfaa01
         fh = fopen (x11_authority_file, "r");
dfaa01
         if (fh) {
dfaa01
                 auth = XauReadAuth (fh);
dfaa01
                 fclose (fh);
dfaa01
@@ -1752,86 +1741,155 @@ gdm_session_worker_accredit_user (GdmSessionWorker  *worker,
dfaa01
                 gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCREDITED);
dfaa01
         } else {
dfaa01
                 gdm_session_worker_uninitialize_pam (worker, error_code);
dfaa01
         }
dfaa01
 
dfaa01
         return ret;
dfaa01
 }
dfaa01
 
dfaa01
 static const char * const *
dfaa01
 gdm_session_worker_get_environment (GdmSessionWorker *worker)
dfaa01
 {
dfaa01
         return (const char * const *) pam_getenvlist (worker->priv->pam_handle);
dfaa01
 }
dfaa01
 
dfaa01
 static gboolean
dfaa01
 run_script (GdmSessionWorker *worker,
dfaa01
             const char       *dir)
dfaa01
 {
dfaa01
         /* scripts are for non-program sessions only */
dfaa01
         if (worker->priv->is_program_session) {
dfaa01
                 return TRUE;
dfaa01
         }
dfaa01
 
dfaa01
         return gdm_run_script (dir,
dfaa01
                                worker->priv->username,
dfaa01
                                worker->priv->x11_display_name,
dfaa01
                                worker->priv->display_is_local? NULL : worker->priv->hostname,
dfaa01
                                worker->priv->x11_authority_file);
dfaa01
 }
dfaa01
 
dfaa01
+static void
dfaa01
+wait_until_dbus_signal_emission_to_manager_finishes (GdmSessionWorker *worker)
dfaa01
+{
dfaa01
+        g_autoptr (GdmDBusPeer) peer_proxy = NULL;
dfaa01
+        g_autoptr (GError) error = NULL;
dfaa01
+        gboolean pinged;
dfaa01
+
dfaa01
+        peer_proxy = gdm_dbus_peer_proxy_new_sync (worker->priv->connection,
dfaa01
+                                                   G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
dfaa01
+                                                   NULL,
dfaa01
+                                                   "/org/freedesktop/DBus",
dfaa01
+                                                   NULL,
dfaa01
+                                                   &error);
dfaa01
+
dfaa01
+        if (peer_proxy == NULL) {
dfaa01
+                g_debug ("GdmSessionWorker: could not create peer proxy to daemon: %s",
dfaa01
+                         error->message);
dfaa01
+                return;
dfaa01
+        }
dfaa01
+
dfaa01
+        pinged = gdm_dbus_peer_call_ping_sync (peer_proxy, NULL, &error);
dfaa01
+
dfaa01
+        if (!pinged) {
dfaa01
+                g_debug ("GdmSessionWorker: could not ping daemon: %s",
dfaa01
+                         error->message);
dfaa01
+                return;
dfaa01
+        }
dfaa01
+}
dfaa01
+
dfaa01
+static void
dfaa01
+jump_back_to_initial_vt (GdmSessionWorker *worker)
dfaa01
+{
dfaa01
+        if (worker->priv->session_vt == 0)
dfaa01
+                return;
dfaa01
+
dfaa01
+        if (worker->priv->session_vt == GDM_INITIAL_VT)
dfaa01
+                return;
dfaa01
+
dfaa01
+        if (g_strcmp0 (worker->priv->display_seat_id, "seat0") != 0)
dfaa01
+                return;
dfaa01
+
dfaa01
+#ifdef ENABLE_USER_DISPLAY_SERVER
dfaa01
+        jump_to_vt (worker, GDM_INITIAL_VT);
dfaa01
+        worker->priv->session_vt = 0;
dfaa01
+#endif
dfaa01
+}
dfaa01
+
dfaa01
 static void
dfaa01
 session_worker_child_watch (GPid              pid,
dfaa01
                             int               status,
dfaa01
                             GdmSessionWorker *worker)
dfaa01
 {
dfaa01
         g_debug ("GdmSessionWorker: child (pid:%d) done (%s:%d)",
dfaa01
                  (int) pid,
dfaa01
                  WIFEXITED (status) ? "status"
dfaa01
                  : WIFSIGNALED (status) ? "signal"
dfaa01
                  : "unknown",
dfaa01
                  WIFEXITED (status) ? WEXITSTATUS (status)
dfaa01
                  : WIFSIGNALED (status) ? WTERMSIG (status)
dfaa01
                  : -1);
dfaa01
 
dfaa01
-
dfaa01
         gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
dfaa01
 
dfaa01
+        worker->priv->child_pid = -1;
dfaa01
+        worker->priv->child_watch_id = 0;
dfaa01
+        run_script (worker, GDMCONFDIR "/PostSession");
dfaa01
+
dfaa01
         gdm_dbus_worker_emit_session_exited (GDM_DBUS_WORKER (worker),
dfaa01
                                              worker->priv->service,
dfaa01
                                              status);
dfaa01
 
dfaa01
         killpg (pid, SIGHUP);
dfaa01
 
dfaa01
-        worker->priv->child_pid = -1;
dfaa01
-        worker->priv->child_watch_id = 0;
dfaa01
-        run_script (worker, GDMCONFDIR "/PostSession");
dfaa01
+        /* FIXME: It's important to give the manager an opportunity to process the
dfaa01
+         * session-exited emission above before switching VTs.
dfaa01
+         *
dfaa01
+         * This is because switching VTs makes the manager try to put a login screen
dfaa01
+         * up on VT 1, but it may actually want to try to auto login again in response
dfaa01
+         * to session-exited.
dfaa01
+         *
dfaa01
+         * This function just does a manager roundtrip over the bus to make sure the
dfaa01
+         * signal has been dispatched before jumping.
dfaa01
+         *
dfaa01
+         * Ultimately, we may want to improve the manager<->worker interface.
dfaa01
+         *
dfaa01
+         * See:
dfaa01
+         *
dfaa01
+         * https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/123
dfaa01
+         *
dfaa01
+         * for some ideas and more discussion.
dfaa01
+         *
dfaa01
+         */
dfaa01
+        wait_until_dbus_signal_emission_to_manager_finishes (worker);
dfaa01
+
dfaa01
+        jump_back_to_initial_vt (worker);
dfaa01
 }
dfaa01
 
dfaa01
 static void
dfaa01
 gdm_session_worker_watch_child (GdmSessionWorker *worker)
dfaa01
 {
dfaa01
         g_debug ("GdmSession worker: watching pid %d", worker->priv->child_pid);
dfaa01
         worker->priv->child_watch_id = g_child_watch_add (worker->priv->child_pid,
dfaa01
                                                           (GChildWatchFunc)session_worker_child_watch,
dfaa01
                                                           worker);
dfaa01
 
dfaa01
 }
dfaa01
 
dfaa01
 static gboolean
dfaa01
 _is_loggable_file (const char* filename)
dfaa01
 {
dfaa01
         struct stat file_info;
dfaa01
 
dfaa01
         if (g_lstat (filename, &file_info) < 0) {
dfaa01
                 return FALSE;
dfaa01
         }
dfaa01
 
dfaa01
         return S_ISREG (file_info.st_mode) && g_access (filename, R_OK | W_OK) == 0;
dfaa01
 }
dfaa01
 
dfaa01
 static void
dfaa01
 rotate_logs (const char *path,
dfaa01
              guint       n_copies)
dfaa01
 {
dfaa01
         int i;
dfaa01
 
dfaa01
@@ -2401,60 +2459,61 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
dfaa01
 
dfaa01
         flags = 0;
dfaa01
 
dfaa01
         if (worker->priv->is_program_session) {
dfaa01
                 flags |= PAM_SILENT;
dfaa01
         }
dfaa01
 
dfaa01
         error_code = pam_open_session (worker->priv->pam_handle, flags);
dfaa01
 
dfaa01
         if (error_code != PAM_SUCCESS) {
dfaa01
                 g_set_error (error,
dfaa01
                              GDM_SESSION_WORKER_ERROR,
dfaa01
                              GDM_SESSION_WORKER_ERROR_OPENING_SESSION,
dfaa01
                              "%s", pam_strerror (worker->priv->pam_handle, error_code));
dfaa01
                 goto out;
dfaa01
         }
dfaa01
 
dfaa01
         g_debug ("GdmSessionWorker: state SESSION_OPENED");
dfaa01
         gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_OPENED);
dfaa01
 
dfaa01
         session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID");
dfaa01
 
dfaa01
         if (session_id != NULL) {
dfaa01
                 g_free (worker->priv->session_id);
dfaa01
                 worker->priv->session_id = session_id;
dfaa01
         }
dfaa01
 
dfaa01
  out:
dfaa01
         if (error_code != PAM_SUCCESS) {
dfaa01
                 gdm_session_worker_uninitialize_pam (worker, error_code);
dfaa01
+                worker->priv->session_vt = 0;
dfaa01
                 return FALSE;
dfaa01
         }
dfaa01
 
dfaa01
         gdm_session_worker_get_username (worker, NULL);
dfaa01
         gdm_session_auditor_report_login (worker->priv->auditor);
dfaa01
 
dfaa01
         return TRUE;
dfaa01
 }
dfaa01
 
dfaa01
 static void
dfaa01
 gdm_session_worker_set_server_address (GdmSessionWorker *worker,
dfaa01
                                        const char       *address)
dfaa01
 {
dfaa01
         g_free (worker->priv->server_address);
dfaa01
         worker->priv->server_address = g_strdup (address);
dfaa01
 }
dfaa01
 
dfaa01
 static void
dfaa01
 gdm_session_worker_set_is_reauth_session (GdmSessionWorker *worker,
dfaa01
                                           gboolean          is_reauth_session)
dfaa01
 {
dfaa01
         worker->priv->is_reauth_session = is_reauth_session;
dfaa01
 }
dfaa01
 
dfaa01
 static void
dfaa01
 gdm_session_worker_set_property (GObject      *object,
dfaa01
                                 guint         prop_id,
dfaa01
                                 const GValue *value,
dfaa01
                                 GParamSpec   *pspec)
dfaa01
 {
dfaa01
@@ -3565,60 +3624,62 @@ gdm_session_worker_unwatch_child (GdmSessionWorker *worker)
dfaa01
                 return;
dfaa01
 
dfaa01
         g_source_remove (worker->priv->child_watch_id);
dfaa01
         worker->priv->child_watch_id = 0;
dfaa01
 }
dfaa01
 
dfaa01
 
dfaa01
 static void
dfaa01
 gdm_session_worker_finalize (GObject *object)
dfaa01
 {
dfaa01
         GdmSessionWorker *worker;
dfaa01
 
dfaa01
         g_return_if_fail (object != NULL);
dfaa01
         g_return_if_fail (GDM_IS_SESSION_WORKER (object));
dfaa01
 
dfaa01
         worker = GDM_SESSION_WORKER (object);
dfaa01
 
dfaa01
         g_return_if_fail (worker->priv != NULL);
dfaa01
 
dfaa01
         gdm_session_worker_unwatch_child (worker);
dfaa01
 
dfaa01
         if (worker->priv->child_pid > 0) {
dfaa01
                 gdm_signal_pid (worker->priv->child_pid, SIGTERM);
dfaa01
                 gdm_wait_on_pid (worker->priv->child_pid);
dfaa01
         }
dfaa01
 
dfaa01
         if (worker->priv->pam_handle != NULL) {
dfaa01
                 gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS);
dfaa01
         }
dfaa01
 
dfaa01
+        jump_back_to_initial_vt (worker);
dfaa01
+
dfaa01
         g_clear_object (&worker->priv->user_settings);
dfaa01
         g_free (worker->priv->service);
dfaa01
         g_free (worker->priv->x11_display_name);
dfaa01
         g_free (worker->priv->x11_authority_file);
dfaa01
         g_free (worker->priv->display_device);
dfaa01
         g_free (worker->priv->display_seat_id);
dfaa01
         g_free (worker->priv->hostname);
dfaa01
         g_free (worker->priv->username);
dfaa01
         g_free (worker->priv->server_address);
dfaa01
         g_strfreev (worker->priv->arguments);
dfaa01
         g_strfreev (worker->priv->extensions);
dfaa01
 
dfaa01
         g_hash_table_unref (worker->priv->reauthentication_requests);
dfaa01
 
dfaa01
         G_OBJECT_CLASS (gdm_session_worker_parent_class)->finalize (object);
dfaa01
 }
dfaa01
 
dfaa01
 GdmSessionWorker *
dfaa01
 gdm_session_worker_new (const char *address,
dfaa01
                         gboolean    is_reauth_session)
dfaa01
 {
dfaa01
         GObject *object;
dfaa01
 
dfaa01
         object = g_object_new (GDM_TYPE_SESSION_WORKER,
dfaa01
                                "server-address", address,
dfaa01
                                "is-reauth-session", is_reauth_session,
dfaa01
                                NULL);
dfaa01
 
dfaa01
         return GDM_SESSION_WORKER (object);
dfaa01
 }
dfaa01
diff --git a/daemon/org.freedesktop.DBus.xml b/daemon/org.freedesktop.DBus.xml
dfaa01
new file mode 100644
dfaa01
index 000000000..5e0814bde
dfaa01
--- /dev/null
dfaa01
+++ b/daemon/org.freedesktop.DBus.xml
dfaa01
@@ -0,0 +1,12 @@
dfaa01
+
dfaa01
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
dfaa01
+<node>
dfaa01
+  <interface name="org.freedesktop.DBus.Peer">
dfaa01
+    <method name="GetMachineId">
dfaa01
+      <arg direction="out" type="s"/>
dfaa01
+    </method>
dfaa01
+    <method name="Ping">
dfaa01
+    </method>
dfaa01
+  </interface>
dfaa01
+</node>
dfaa01
+
dfaa01
-- 
dfaa01
2.28.0
dfaa01