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

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