From 7de8cc966a723b7e5c1a46098df34ef67db37e95 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 9 Nov 2021 05:00:59 -0500 Subject: [PATCH] import gdm-40.0-15.el8 --- .gdm.metadata | 2 +- .gitignore | 2 +- ...tup-being-disabled-by-distro-install.patch | 119 +- ...nd-x-session-don-t-overwrite-user-en.patch | 241 ++ ...nd-detection-when-deciding-to-bypass.patch | 135 - ...etwork-configuration-on-login-screen.patch | 103 + ...ystem-dconf-databases-to-gdm-profile.patch | 8 +- ...land-for-proprietary-nvidia-machines.patch | 28 - ...-disable-wayland-on-certain-hardware.patch | 63 + ...land-on-server-chips-and-dual-gpu-se.patch | 44 - .../0001-data-enable-wayland-on-cirrus.patch | 44 - ...e-wayland-on-passthrough-virt-setups.patch | 55 - ...1-data-reap-gdm-sessions-on-shutdown.patch | 55 + ...h-failure-if-loading-existing-users-.patch | 140 - ...failure-before-display-registration.patch} | 72 +- ...lay-access-file-drop-unused-function.patch | 206 -- ...untservice-if-there-are-users-rather.patch | 269 -- ...avoid-removing-a-display-from-store-.patch | 433 --- ...ctory-Don-t-try-to-respawn-displays-.patch | 325 ++ ...ctory-Provide-more-flexibility-for-c.patch | 2765 +++++++++++++++++ ...ctory-pause-for-a-few-seconds-before.patch | 140 +- ...1-manager-Don-t-leak-session-objects.patch | 353 --- ...ltiple-xdmcp-logins-for-the-same-use.patch | 45 +- ...ll-timed-login-session-immediately-a.patch | 87 - ...on-t-switch-back-VTs-until-session-i.patch | 683 ---- ...xpose-worker-state-enum-to-type-syst.patch | 470 --- SOURCES/0001-utils-Drop-gdm-screenshot.patch | 362 +++ ...s-add-new-gdm-disable-wayland-binary.patch | 161 - ...d-user-settings-for-program-sessions.patch | 68 +- ...n-run-session-bus-on-non-seat0-seats.patch | 106 +- SOURCES/0002-libgdm-Sort-session-list.patch | 131 + ...ctory-Add-gdm_local_display_factory_.patch | 164 - ...Add-some-debugging-around-starting-r.patch | 1015 ------ ...-Don-t-leak-remote-greeter-interface.patch | 87 - ...new-accountsservice-Session-and-Sess.patch | 311 +- ...ill-user-sessions-when-stop-gdm-serv.patch | 922 ------ ...n-save-os-release-in-accountsservice.patch | 459 ++- ...ctory-Use-correct-session-type-for-n.patch | 83 - ...low-greeter-operations-on-an-running.patch | 227 -- ...gin-screen-over-XDMCP-connects-to-i.patch} | 14 +- ...uninitialize-pam-if-worker-is-killed.patch | 85 - ...ctory-Clear-launch-environment-when-.patch | 87 - ...ctory-Set-supported-session-types-fo.patch | 122 + ...-perform-timed-login-if-session-gets.patch | 105 - ...4-daemon-handle-upgrades-from-RHEL-7.patch | 126 +- ...4-data-reap-gdm-sessions-on-shutdown.patch | 28 - ..._login_window_session_id-fail-if-no-.patch | 137 - ...005-manager-avoid-leaking-session_id.patch | 79 - ...ly-handle-the-case-of-no-session-for.patch | 89 - ...dupe-gdm_get_login_window_session_id.patch | 432 --- ...08-common-dedupe-activate_session_id.patch | 401 --- ...leak-in-maybe_activate_other_session.patch | 103 - ...-login-screen-if-old-one-is-finished.patch | 92 - ...il-if-session-disappears-out-from-un.patch | 127 - ...r-to-get-to-a-login-screen-at-logout.patch | 563 ---- ...ctory-ensure-non-seat0-codepath-does.patch | 87 - ...restart-greeter-on-demand-under-wayl.patch | 369 --- ...ctory-add-more-debug-messages-to-new.patch | 235 -- ...ctory-don-t-start-two-greeters-at-st.patch | 97 - ...on-t-switch-VTs-if-we-re-already-on-.patch | 128 - ...ix-current-vt-detection-short-circui.patch | 87 - ...factory-don-t-jump-to-failed-display.patch | 168 - ...ctory-add-some-more-debug-statements.patch | 161 - ...ctory-ignore-spurios-SeatNew-signal-.patch | 162 - .../0022-common-remove-unnecessary-free.patch | 91 - ...l-if-session-disappears-out-from-und.patch | 133 - .../0024-manager-better-logind-handling.patch | 138 - ...worker-clear-VT-before-jumping-to-it.patch | 90 - ...t-ran_once-after-running-initial-set.patch | 133 - ...nager-start-initial-setup-right-away.patch | 418 --- ...ion-gdm-x-session-register-after-del.patch | 309 -- ...ctory-defer-killing-greeter-until-ne.patch | 399 --- ...waiting-the-session-to-have-taken-ov.patch | 708 ----- ...factory-don-t-autoreap-initial-setup.patch | 100 - ...-rework-how-autologin-is-figured-out.patch | 460 --- ...33-manager-correct-display-confusion.patch | 85 - ...-don-t-run-autologin-display-on-tty1.patch | 99 - ...ctory-Remove-initial-VT-is-in-use-ch.patch | 110 - ...ctory-Remove-same-VT-so-don-t-switch.patch | 140 - ...ctory-handle-reviving-displays-that-.patch | 88 - ...ll-initial-setup-before-starting-use.patch | 151 - ...tial-setup-post-work-in-manager-code.patch | 694 ----- ...ke-foreach-ignore-callback-return-va.patch | 117 - ...ctory-don-t-return-value-from-foreac.patch | 180 -- ...actory-Store-VT-number-not-tty-ident.patch | 538 ---- ...er-Drop-login_vt-assuming-it-is-GDM_.patch | 344 -- ...nsure-initial-vt-is-never-picked-for.patch | 160 - ...ctory-Always-force-login-screen-to-V.patch | 114 - ...ssion-tell-x-server-to-not-vt-switch.patch | 81 - ...ctory-kill-X-on-login-just-like-wayl.patch | 115 - ...ll-initial-setup-right-away-with-Xor.patch | 149 - ...dmDisplay-Add-RegisterSession-method.patch | 551 ---- ...-Allow-sessions-to-register-with-GDM.patch | 1917 ------------ SPECS/gdm.spec | 247 +- 94 files changed, 5098 insertions(+), 18828 deletions(-) create mode 100644 SOURCES/0001-Revert-gdm-wayland-x-session-don-t-overwrite-user-en.patch delete mode 100644 SOURCES/0001-daemon-fix-wayland-detection-when-deciding-to-bypass.patch create mode 100644 SOURCES/0001-data-Disable-network-configuration-on-login-screen.patch delete mode 100644 SOURCES/0001-data-disable-wayland-for-proprietary-nvidia-machines.patch create mode 100644 SOURCES/0001-data-disable-wayland-on-certain-hardware.patch delete mode 100644 SOURCES/0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch delete mode 100644 SOURCES/0001-data-enable-wayland-on-cirrus.patch delete mode 100644 SOURCES/0001-data-only-disable-wayland-on-passthrough-virt-setups.patch create mode 100644 SOURCES/0001-data-reap-gdm-sessions-on-shutdown.patch delete mode 100644 SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch rename SOURCES/{0051-display-Handle-failure-before-display-registration.patch => 0001-display-Handle-failure-before-display-registration.patch} (67%) delete mode 100644 SOURCES/0001-display-access-file-drop-unused-function.patch delete mode 100644 SOURCES/0001-display-ask-accountservice-if-there-are-users-rather.patch delete mode 100644 SOURCES/0001-display-factory-avoid-removing-a-display-from-store-.patch create mode 100644 SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch create mode 100644 SOURCES/0001-local-display-factory-Provide-more-flexibility-for-c.patch delete mode 100644 SOURCES/0001-manager-Don-t-leak-session-objects.patch delete mode 100644 SOURCES/0001-manager-don-t-kill-timed-login-session-immediately-a.patch delete mode 100644 SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch delete mode 100644 SOURCES/0001-session-worker-expose-worker-state-enum-to-type-syst.patch create mode 100644 SOURCES/0001-utils-Drop-gdm-screenshot.patch delete mode 100644 SOURCES/0001-utils-add-new-gdm-disable-wayland-binary.patch create mode 100644 SOURCES/0002-libgdm-Sort-session-list.patch delete mode 100644 SOURCES/0002-local-display-factory-Add-gdm_local_display_factory_.patch delete mode 100644 SOURCES/0002-manager-session-Add-some-debugging-around-starting-r.patch delete mode 100644 SOURCES/0002-session-Don-t-leak-remote-greeter-interface.patch delete mode 100644 SOURCES/0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch delete mode 100644 SOURCES/0003-local-display-factory-Use-correct-session-type-for-n.patch delete mode 100644 SOURCES/0003-session-Don-t-allow-greeter-operations-on-an-running.patch rename SOURCES/{0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch => 0003-session-ensure-login-screen-over-XDMCP-connects-to-i.patch} (91%) delete mode 100644 SOURCES/0003-session-worker-uninitialize-pam-if-worker-is-killed.patch delete mode 100644 SOURCES/0003-xdmcp-display-factory-Clear-launch-environment-when-.patch create mode 100644 SOURCES/0003-xdmcp-display-factory-Set-supported-session-types-fo.patch delete mode 100644 SOURCES/0004-GdmManager-Don-t-perform-timed-login-if-session-gets.patch delete mode 100644 SOURCES/0004-data-reap-gdm-sessions-on-shutdown.patch delete mode 100644 SOURCES/0004-manager-make-get_login_window_session_id-fail-if-no-.patch delete mode 100644 SOURCES/0005-manager-avoid-leaking-session_id.patch delete mode 100644 SOURCES/0006-manager-gracefully-handle-the-case-of-no-session-for.patch delete mode 100644 SOURCES/0007-common-dedupe-gdm_get_login_window_session_id.patch delete mode 100644 SOURCES/0008-common-dedupe-activate_session_id.patch delete mode 100644 SOURCES/0009-manager-plug-leak-in-maybe_activate_other_session.patch delete mode 100644 SOURCES/0010-manager-start-login-screen-if-old-one-is-finished.patch delete mode 100644 SOURCES/0011-manager-don-t-bail-if-session-disappears-out-from-un.patch delete mode 100644 SOURCES/0012-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch delete mode 100644 SOURCES/0013-local-display-factory-ensure-non-seat0-codepath-does.patch delete mode 100644 SOURCES/0014-daemon-kill-and-restart-greeter-on-demand-under-wayl.patch delete mode 100644 SOURCES/0015-local-display-factory-add-more-debug-messages-to-new.patch delete mode 100644 SOURCES/0016-local-display-factory-don-t-start-two-greeters-at-st.patch delete mode 100644 SOURCES/0017-session-worker-don-t-switch-VTs-if-we-re-already-on-.patch delete mode 100644 SOURCES/0018-session-worker-fix-current-vt-detection-short-circui.patch delete mode 100644 SOURCES/0019-local-display-factory-don-t-jump-to-failed-display.patch delete mode 100644 SOURCES/0020-local-display-factory-add-some-more-debug-statements.patch delete mode 100644 SOURCES/0021-local-display-factory-ignore-spurios-SeatNew-signal-.patch delete mode 100644 SOURCES/0022-common-remove-unnecessary-free.patch delete mode 100644 SOURCES/0023-common-don-t-bail-if-session-disappears-out-from-und.patch delete mode 100644 SOURCES/0024-manager-better-logind-handling.patch delete mode 100644 SOURCES/0025-session-worker-clear-VT-before-jumping-to-it.patch delete mode 100644 SOURCES/0026-manager-don-t-set-ran_once-after-running-initial-set.patch delete mode 100644 SOURCES/0027-manager-start-initial-setup-right-away.patch delete mode 100644 SOURCES/0028-gdm-wayland-session-gdm-x-session-register-after-del.patch delete mode 100644 SOURCES/0029-local-display-factory-defer-killing-greeter-until-ne.patch delete mode 100644 SOURCES/0030-daemon-Move-the-waiting-the-session-to-have-taken-ov.patch delete mode 100644 SOURCES/0031-local-display-factory-don-t-autoreap-initial-setup.patch delete mode 100644 SOURCES/0032-manager-rework-how-autologin-is-figured-out.patch delete mode 100644 SOURCES/0033-manager-correct-display-confusion.patch delete mode 100644 SOURCES/0034-manager-don-t-run-autologin-display-on-tty1.patch delete mode 100644 SOURCES/0035-local-display-factory-Remove-initial-VT-is-in-use-ch.patch delete mode 100644 SOURCES/0036-local-display-factory-Remove-same-VT-so-don-t-switch.patch delete mode 100644 SOURCES/0037-local-display-factory-handle-reviving-displays-that-.patch delete mode 100644 SOURCES/0038-manager-don-t-kill-initial-setup-before-starting-use.patch delete mode 100644 SOURCES/0039-manager-do-initial-setup-post-work-in-manager-code.patch delete mode 100644 SOURCES/0040-display-store-make-foreach-ignore-callback-return-va.patch delete mode 100644 SOURCES/0041-xdmcp-display-factory-don-t-return-value-from-foreac.patch delete mode 100644 SOURCES/0042-GdmLocalDisplayFactory-Store-VT-number-not-tty-ident.patch delete mode 100644 SOURCES/0043-gdm-session-worker-Drop-login_vt-assuming-it-is-GDM_.patch delete mode 100644 SOURCES/0044-session-worker-ensure-initial-vt-is-never-picked-for.patch delete mode 100644 SOURCES/0045-local-display-factory-Always-force-login-screen-to-V.patch delete mode 100644 SOURCES/0046-gdm-x-session-tell-x-server-to-not-vt-switch.patch delete mode 100644 SOURCES/0047-local-display-factory-kill-X-on-login-just-like-wayl.patch delete mode 100644 SOURCES/0048-manager-don-t-kill-initial-setup-right-away-with-Xor.patch delete mode 100644 SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch delete mode 100644 SOURCES/0050-Allow-sessions-to-register-with-GDM.patch diff --git a/.gdm.metadata b/.gdm.metadata index 7343b77..9840d19 100644 --- a/.gdm.metadata +++ b/.gdm.metadata @@ -1 +1 @@ -3c619c91941b2df0362a67b905669f8852106bf5 SOURCES/gdm-3.28.3.tar.xz +05c48de8765bde97768b6740417ad6c374c20763 SOURCES/gdm-40.0.tar.xz diff --git a/.gitignore b/.gitignore index 03d9ac4..77cb1f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/gdm-3.28.3.tar.xz +SOURCES/gdm-40.0.tar.xz diff --git a/SOURCES/0001-Honor-initial-setup-being-disabled-by-distro-install.patch b/SOURCES/0001-Honor-initial-setup-being-disabled-by-distro-install.patch index 96a78f5..9a1fb1f 100644 --- a/SOURCES/0001-Honor-initial-setup-being-disabled-by-distro-install.patch +++ b/SOURCES/0001-Honor-initial-setup-being-disabled-by-distro-install.patch @@ -1,4 +1,4 @@ -From fa5733788ae5f8e8caeb07e956be370e96f9b6b1 Mon Sep 17 00:00:00 2001 +From a447cd87b99868348ecf69479eb7958f20a318a2 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 23 Jan 2017 20:19:51 +0100 Subject: [PATCH] Honor initial setup being disabled by distro installer @@ -14,30 +14,45 @@ that but more might be added in the future. https://bugzilla.gnome.org/show_bug.cgi?id=777708 --- - daemon/Makefile.am | 1 + daemon/gdm-display.c | 29 +++++++++++++++++++++++++++++ - 2 files changed, 30 insertions(+) + 1 file changed, 29 insertions(+) -diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index ab5dda0..786e0c5 100644 ---- a/daemon/Makefile.am -+++ b/daemon/Makefile.am -@@ -14,6 +14,7 @@ AM_CPPFLAGS = \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DLOGDIR=\"$(logdir)\" \ - -DSBINDIR=\"$(sbindir)\" \ -+ -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ - -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ - -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 0057e2c..2af8e13 100644 +index 687e7da4b..b3bdf066d 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c -@@ -1456,6 +1456,31 @@ can_create_environment (const char *session_id) +@@ -1591,103 +1591,132 @@ kernel_cmdline_initial_setup_force_state (gboolean *force_state) + GError *error = NULL; + gchar *contents = NULL; + gchar *setup_argument = NULL; + + g_return_val_if_fail (force_state != NULL, FALSE); + + if (!g_file_get_contents ("/proc/cmdline", &contents, NULL, &error)) { + g_debug ("GdmDisplay: Could not check kernel parameters, not forcing initial setup: %s", + error->message); + g_clear_error (&error); + return FALSE; + } + + g_debug ("GdmDisplay: Checking kernel command buffer %s", contents); + + if (!kernel_cmdline_initial_setup_argument (contents, &setup_argument, &error)) { + g_debug ("GdmDisplay: Failed to read kernel commandline: %s", error->message); + g_clear_pointer (&contents, g_free); + return FALSE; + } + + g_clear_pointer (&contents, g_free); + + /* Poor-man's check for truthy or falsey values */ + *force_state = setup_argument[0] == '1'; + + g_free (setup_argument); + return TRUE; } - static gboolean ++static gboolean +initial_setup_disabled_by_anaconda (void) +{ + GKeyFile *key_file; @@ -62,11 +77,46 @@ index 0057e2c..2af8e13 100644 + return disabled; +} + -+static gboolean + static gboolean wants_initial_setup (GdmDisplay *self) { + GdmDisplayPrivate *priv; gboolean enabled = FALSE; -@@ -1480,6 +1505,10 @@ wants_initial_setup (GdmDisplay *self) + gboolean forced = FALSE; + + priv = gdm_display_get_instance_private (self); + + if (already_done_initial_setup_on_this_boot ()) { + return FALSE; + } + + if (kernel_cmdline_initial_setup_force_state (&forced)) { + if (forced) { + g_debug ("GdmDisplay: Forcing gnome-initial-setup"); + return TRUE; + } + + g_debug ("GdmDisplay: Forcing no gnome-initial-setup"); + return FALSE; + } + + /* don't run initial-setup on remote displays + */ + if (!priv->is_local) { + return FALSE; + } + + /* don't run if the system has existing users */ + if (priv->have_existing_user_accounts) { + return FALSE; + } + + /* don't run if initial-setup is unavailable */ + if (!can_create_environment ("gnome-initial-setup")) { + return FALSE; + } + + if (!gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled)) { return FALSE; } @@ -77,6 +127,33 @@ index 0057e2c..2af8e13 100644 return enabled; } + void + gdm_display_start_greeter_session (GdmDisplay *self) + { + GdmDisplayPrivate *priv; + GdmSession *session; + char *display_name; + char *seat_id; + char *hostname; + char *auth_file = NULL; + + priv = gdm_display_get_instance_private (self); + g_return_if_fail (g_strcmp0 (priv->session_class, "greeter") == 0); + + g_debug ("GdmDisplay: Running greeter"); + + display_name = NULL; + seat_id = NULL; + hostname = NULL; + + g_object_get (self, + "x11-display-name", &display_name, + "seat-id", &seat_id, + "remote-hostname", &hostname, + NULL); + if (priv->access_file != NULL) { + auth_file = gdm_display_access_file_get_path (priv->access_file); + } -- -2.9.3 +2.28.0 diff --git a/SOURCES/0001-Revert-gdm-wayland-x-session-don-t-overwrite-user-en.patch b/SOURCES/0001-Revert-gdm-wayland-x-session-don-t-overwrite-user-en.patch new file mode 100644 index 0000000..4f36edc --- /dev/null +++ b/SOURCES/0001-Revert-gdm-wayland-x-session-don-t-overwrite-user-en.patch @@ -0,0 +1,241 @@ +From 85951a0384cb7f37d99669575fad4aea155f25a8 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 5 May 2021 10:50:56 -0400 +Subject: [PATCH 1/5] Revert "gdm-{wayland,x}-session: don't overwrite user env + with fallback vars" + +This reverts commit ccecd9c975d04da80db4cd547b67a1a94fa83292. +--- + daemon/gdm-wayland-session.c | 22 +--------------------- + daemon/gdm-x-session.c | 22 +--------------------- + 2 files changed, 2 insertions(+), 42 deletions(-) + +diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c +index d0404d2c1..35679b194 100644 +--- a/daemon/gdm-wayland-session.c ++++ b/daemon/gdm-wayland-session.c +@@ -262,112 +262,92 @@ on_session_finished (GSubprocess *subprocess, + + state->session_exit_status = exit_status; + } else { + int signal_number; + + signal_number = g_subprocess_get_term_sig (subprocess); + g_debug ("session was killed with status %d", signal_number); + } + + g_clear_object (&state->session_subprocess); + out: + g_main_loop_quit (state->main_loop); + } + + static gboolean + spawn_session (State *state, + GCancellable *cancellable) + { + GSubprocessLauncher *launcher = NULL; + GSubprocess *subprocess = NULL; + GError *error = NULL; + gboolean is_running = FALSE; + int ret; + char **argv = NULL; + static const char *session_variables[] = { "DISPLAY", + "XAUTHORITY", + "WAYLAND_DISPLAY", + "WAYLAND_SOCKET", + "GNOME_SHELL_SESSION_MODE", + NULL }; +- /* The environment variables listed below are those we have set (or +- * received from our own execution environment) only as a fallback to +- * make things work, as opposed to a information directly pertaining to +- * the session about to be started. Variables listed here will not +- * overwrite the existing environment (possibly) imported from the +- * systemd --user instance. +- * As an example: We need a PATH for some of the launched subprocesses +- * to work, but if the user (or the distributor) has customized the PATH +- * via one of systemds user-environment-generators, that version should +- * be preferred. */ +- static const char *fallback_variables[] = { "PATH", NULL }; + + g_debug ("Running wayland session"); + + ret = g_shell_parse_argv (state->session_command, + NULL, + &argv, + &error); + + if (!ret) { + g_debug ("could not parse session arguments: %s", error->message); + goto out; + } + + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); + + if (state->environment != NULL) { + size_t i; + + for (i = 0; state->environment[i] != NULL; i++) { + g_auto(GStrv) environment_entry = NULL; + + if (state->environment[i][0] == '\0') { + continue; + } + + environment_entry = g_strsplit (state->environment[i], "=", 2); + + if (environment_entry[0] == NULL || environment_entry[1] == NULL) { + continue; + } + +- /* Merge the environment block imported from systemd --user with the +- * environment we have set for ourselves (and thus pass on to the +- * launcher process). Variables we have set have precedence, as to not +- * import stale data from prior user sessions, with the exception of +- * those listed in fallback_variables. See the comment there for more +- * explanations. */ +- g_subprocess_launcher_setenv (launcher, +- environment_entry[0], +- environment_entry[1], +- g_strv_contains (fallback_variables, environment_entry[0])); ++ g_subprocess_launcher_setenv (launcher, environment_entry[0], environment_entry[1], FALSE); + } + + /* Don't allow session specific environment variables from earlier sessions to + * leak through */ + for (i = 0; session_variables[i] != NULL; i++) { + if (g_getenv (session_variables[i]) == NULL) { + g_subprocess_launcher_unsetenv (launcher, session_variables[i]); + } + } + } + + if (state->bus_address != NULL) { + g_subprocess_launcher_setenv (launcher, "DBUS_SESSION_BUS_ADDRESS", state->bus_address, TRUE); + } + + subprocess = g_subprocess_launcher_spawnv (launcher, + (const char * const *) argv, + &error); + g_strfreev (argv); + + if (subprocess == NULL) { + g_debug ("could not start session: %s", error->message); + goto out; + } + + state->session_subprocess = g_object_ref (subprocess); + + g_subprocess_wait_async (state->session_subprocess, + cancellable, + (GAsyncReadyCallback) +diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c +index 5962da572..b15483614 100644 +--- a/daemon/gdm-x-session.c ++++ b/daemon/gdm-x-session.c +@@ -588,102 +588,82 @@ on_session_finished (GSubprocess *subprocess, + + state->session_exit_status = exit_status; + } else { + int signal_number; + + signal_number = g_subprocess_get_term_sig (subprocess); + g_debug ("session was killed with status %d", signal_number); + } + + g_clear_object (&state->session_subprocess); + out: + g_main_loop_quit (state->main_loop); + } + + static gboolean + spawn_session (State *state, + gboolean run_script, + GCancellable *cancellable) + { + GSubprocessLauncher *launcher = NULL; + GSubprocess *subprocess = NULL; + GError *error = NULL; + gboolean is_running = FALSE; + const char *vt; + static const char *session_variables[] = { "DISPLAY", + "XAUTHORITY", + "WAYLAND_DISPLAY", + "WAYLAND_SOCKET", + "GNOME_SHELL_SESSION_MODE", + NULL }; +- /* The environment variables listed below are those we have set (or +- * received from our own execution environment) only as a fallback to +- * make things work, as opposed to a information directly pertaining to +- * the session about to be started. Variables listed here will not +- * overwrite the existing environment (possibly) imported from the +- * systemd --user instance. +- * As an example: We need a PATH for some of the launched subprocesses +- * to work, but if the user (or the distributor) has customized the PATH +- * via one of systemds user-environment-generators, that version should +- * be preferred. */ +- static const char *fallback_variables[] = { "PATH", NULL }; + + g_debug ("Running X session"); + + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); + + if (state->environment != NULL) { + size_t i; + + for (i = 0; state->environment[i] != NULL; i++) { + g_auto(GStrv) environment_entry = NULL; + + if (state->environment[i][0] == '\0') { + continue; + } + + environment_entry = g_strsplit (state->environment[i], "=", 2); + + if (environment_entry[0] == NULL || environment_entry[1] == NULL) { + continue; + } + +- /* Merge the environment block imported from systemd --user with the +- * environment we have set for ourselves (and thus pass on to the +- * launcher process). Variables we have set have precedence, as to not +- * import stale data from prior user sessions, with the exception of +- * those listed in fallback_variables. See the comment there for more +- * explanations. */ +- g_subprocess_launcher_setenv (launcher, +- environment_entry[0], +- environment_entry[1], +- g_strv_contains (fallback_variables, environment_entry[0])); ++ g_subprocess_launcher_setenv (launcher, environment_entry[0], environment_entry[1], FALSE); + } + + /* Don't allow session specific environment variables from earlier sessions to + * leak through */ + for (i = 0; session_variables[i] != NULL; i++) { + if (g_getenv (session_variables[i]) == NULL) { + g_subprocess_launcher_unsetenv (launcher, session_variables[i]); + } + } + } + + g_subprocess_launcher_setenv (launcher, "DISPLAY", state->display_name, TRUE); + g_subprocess_launcher_setenv (launcher, "XAUTHORITY", state->auth_file, TRUE); + + if (state->bus_address != NULL) { + g_subprocess_launcher_setenv (launcher, "DBUS_SESSION_BUS_ADDRESS", state->bus_address, TRUE); + } + + vt = g_getenv ("XDG_VTNR"); + + if (vt != NULL) { + g_subprocess_launcher_setenv (launcher, "WINDOWPATH", vt, TRUE); + } + + if (run_script) { + subprocess = g_subprocess_launcher_spawn (launcher, + &error, + GDMCONFDIR "/Xsession", + state->session_command, + NULL); +-- +2.30.1 + diff --git a/SOURCES/0001-daemon-fix-wayland-detection-when-deciding-to-bypass.patch b/SOURCES/0001-daemon-fix-wayland-detection-when-deciding-to-bypass.patch deleted file mode 100644 index c442a45..0000000 --- a/SOURCES/0001-daemon-fix-wayland-detection-when-deciding-to-bypass.patch +++ /dev/null @@ -1,135 +0,0 @@ -From b9f38b65417923624bf97a18daf1c2ede5e8651e Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Sun, 15 Dec 2019 14:51:44 -0500 -Subject: [PATCH] daemon: fix wayland detection when deciding to bypass - Xsession - -At the moment if there's a session file with the same name in -both /usr/share/xsessions and /usr/share/wayland-sessions, GDM -will think the wayland is getting used when deciding whether or -not to bypass the /etc/gdm/Xsession script, even if wayland is -explicitly being ignored. - -This commit fixes the check. ---- - daemon/gdm-session.c | 28 ++++++++++++++-------------- - 1 file changed, 14 insertions(+), 14 deletions(-) - -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index a8263ba11..ecb2b3cac 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -3145,96 +3145,96 @@ gdm_session_get_session_id (GdmSession *self) - return conversation->session_id; - } - - const char * - gdm_session_get_conversation_session_id (GdmSession *self, - const char *service_name) - { - GdmSessionConversation *conversation; - - g_return_val_if_fail (GDM_IS_SESSION (self), NULL); - - conversation = find_conversation_by_name (self, service_name); - - if (conversation == NULL) { - return NULL; - } - - return conversation->session_id; - } - - static char * - get_session_filename (GdmSession *self) - { - return g_strdup_printf ("%s.desktop", get_session_name (self)); - } - - #ifdef ENABLE_WAYLAND_SUPPORT - static gboolean - gdm_session_is_wayland_session (GdmSession *self) - { -- GKeyFile *key_file; -+ g_autoptr (GKeyFile) key_file = NULL; - gboolean is_wayland_session = FALSE; -- char *filename; -- char *full_path = NULL; -+ g_autofree char *filename = NULL; -+ g_autofree char *full_path = NULL; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); - - filename = get_session_filename (self); - -- key_file = load_key_file_for_file (self, filename, "wayland", &full_path); -+ if (!self->priv->ignore_wayland) { -+ key_file = load_key_file_for_file (self, filename, "wayland", &full_path); - -- if (key_file == NULL) { -- goto out; -- } -+ if (key_file == NULL) { -+ goto out; -+ } - -- if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { -- is_wayland_session = TRUE; -+ if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { -+ is_wayland_session = TRUE; -+ } - } -- g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); - - out: -- g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free); -- g_free (filename); -+ g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); -+ - return is_wayland_session; - } - #endif - - static void - update_session_type (GdmSession *self) - { - #ifdef ENABLE_WAYLAND_SUPPORT - gboolean is_wayland_session = FALSE; - -- if (!self->priv->ignore_wayland) -- is_wayland_session = gdm_session_is_wayland_session (self); -+ is_wayland_session = gdm_session_is_wayland_session (self); - - if (is_wayland_session) { - set_session_type (self, "wayland"); - } else { - set_session_type (self, NULL); - } - #endif - } - - gboolean - gdm_session_bypasses_xsession (GdmSession *self) - { - GError *error; - GKeyFile *key_file; - gboolean res; - gboolean bypasses_xsession = FALSE; - char *filename = NULL; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); - - #ifdef ENABLE_WAYLAND_SUPPORT - if (gdm_session_is_wayland_session (self)) { - bypasses_xsession = TRUE; - goto out; - } - #endif - - filename = get_session_filename (self); - --- -2.18.1 - diff --git a/SOURCES/0001-data-Disable-network-configuration-on-login-screen.patch b/SOURCES/0001-data-Disable-network-configuration-on-login-screen.patch new file mode 100644 index 0000000..e87a1b7 --- /dev/null +++ b/SOURCES/0001-data-Disable-network-configuration-on-login-screen.patch @@ -0,0 +1,103 @@ +From cebcf2a4d29f01061dedf8714db2842b9582900c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 8 Jun 2021 20:45:00 +0200 +Subject: [PATCH 1/3] data: Disable network configuration on login screen + +--- + data/meson.build | 10 ++++++++++ + data/org.gnome.gdm.rules.in | 8 ++++++++ + 2 files changed, 18 insertions(+) + create mode 100644 data/org.gnome.gdm.rules.in + +diff --git a/data/meson.build b/data/meson.build +index 23e2d7f9f..cbd6a6a21 100644 +--- a/data/meson.build ++++ b/data/meson.build +@@ -131,60 +131,70 @@ pam_data_files_map = { + 'arch': [ + 'gdm-autologin', + 'gdm-launch-environment', + 'gdm-fingerprint', + 'gdm-smartcard', + 'gdm-password', + 'gdm-pin', + ], + 'none': [], + # We should no longer have 'autodetect' at this point + } + + pam_data_files = pam_data_files_map[default_pam_config] + pam_prefix = (get_option('pam-prefix') != '')? get_option('pam-prefix') : get_option('sysconfdir') + foreach _pam_filename : pam_data_files + install_data('pam-@0@/@1@.pam'.format(default_pam_config, _pam_filename), + rename: _pam_filename, + install_dir: pam_prefix / 'pam.d', + ) + endforeach + + gdm_rules = configure_file( + input: '61-gdm.rules.in', + output: '@BASENAME@', + configuration: { + 'libexecdir': gdm_prefix / get_option('libexecdir'), + }, + install_dir: udev_dir, + ) + ++# Polkit rules ++polkit_rules = configure_file( ++ input: 'org.gnome.gdm.rules.in', ++ output: '@BASENAME@', ++ configuration: { ++ 'GDM_USERNAME': get_option('user'), ++ }, ++ install_dir: get_option('datadir') / 'polkit-1' / 'rules.d', ++) ++ + # DBus service files + service_config = configuration_data() + service_config.set('sbindir', gdm_prefix / get_option('sbindir')) + service_config.set('GDM_INITIAL_VT', get_option('initial-vt')) + service_config.set('LANG_CONFIG_FILE', lang_config_file) + if plymouth_dep.found() + service_config.set('PLYMOUTH_QUIT_SERVICE', 'plymouth-quit.service') + else + service_config.set('PLYMOUTH_QUIT_SERVICE', '') + endif + + if get_option('systemdsystemunitdir') != '' + systemd_systemunitdir = get_option('systemdsystemunitdir') + else + systemd_systemunitdir = systemd_dep.get_pkgconfig_variable('systemdsystemunitdir') + endif + + if get_option('systemduserunitdir') != '' + systemd_userunitdir = get_option('systemduserunitdir') + else + systemd_userunitdir = systemd_dep.get_pkgconfig_variable('systemduserunitdir', + define_variable: ['prefix', get_option('prefix')]) + endif + + configure_file( + input: 'gdm.service.in', + output: '@BASENAME@', + configuration: service_config, + install_dir: systemd_systemunitdir, + format: 'cmake' +diff --git a/data/org.gnome.gdm.rules.in b/data/org.gnome.gdm.rules.in +new file mode 100644 +index 000000000..09544f11e +--- /dev/null ++++ b/data/org.gnome.gdm.rules.in +@@ -0,0 +1,8 @@ ++polkit.addRule(function(action, subject) { ++ if (action.id == "org.freedesktop.NetworkManager.network-control" && ++ subject.user == "@GDM_USERNAME@") { ++ return polkit.Result.NO; ++ } ++ ++ return polkit.Result.NOT_HANDLED; ++}); +-- +2.30.1 + diff --git a/SOURCES/0001-data-add-system-dconf-databases-to-gdm-profile.patch b/SOURCES/0001-data-add-system-dconf-databases-to-gdm-profile.patch index 5ae16e2..8fa2615 100644 --- a/SOURCES/0001-data-add-system-dconf-databases-to-gdm-profile.patch +++ b/SOURCES/0001-data-add-system-dconf-databases-to-gdm-profile.patch @@ -1,7 +1,7 @@ -From 53c549876bcb7363d1d6dca70f2e1d3889741a06 Mon Sep 17 00:00:00 2001 +From 8c9fe8ebd9e584adaec0a80ee4c4eaf5357422a5 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 31 Jul 2013 17:32:55 -0400 -Subject: [PATCH] data: add system dconf databases to gdm profile +Subject: [PATCH 1/2] data: add system dconf databases to gdm profile This way system settings can affect the login screen. --- @@ -9,7 +9,7 @@ This way system settings can affect the login screen. 1 file changed, 4 insertions(+) diff --git a/data/dconf/gdm.in b/data/dconf/gdm.in -index 4d8bf1748..606e0b863 100644 +index 4d8bf1748..9694078fb 100644 --- a/data/dconf/gdm.in +++ b/data/dconf/gdm.in @@ -1,2 +1,6 @@ @@ -20,5 +20,5 @@ index 4d8bf1748..606e0b863 100644 +system-db:distro file-db:@DATADIR@/@PACKAGE@/greeter-dconf-defaults -- -2.26.0 +2.30.1 diff --git a/SOURCES/0001-data-disable-wayland-for-proprietary-nvidia-machines.patch b/SOURCES/0001-data-disable-wayland-for-proprietary-nvidia-machines.patch deleted file mode 100644 index f636a97..0000000 --- a/SOURCES/0001-data-disable-wayland-for-proprietary-nvidia-machines.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f2ac0603854c7933ecea4a13876fa7e72fd66d1a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jonas=20=C3=85dahl?= -Date: Thu, 6 Sep 2018 10:14:08 -0400 -Subject: [PATCH] data: disable wayland for proprietary nvidia machines - -At the moment GLX applications don't work well when the -proprietary nvidia driver is used with a wayland session. - -For now, disable wayland on that hardware, and users who -want to opt in can just edit the udev rule. -(or add their own that overrides it) ---- - data/61-gdm.rules.in | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in -index de8e17903..26cf9cf51 100644 ---- a/data/61-gdm.rules.in -+++ b/data/61-gdm.rules.in -@@ -1,2 +1,5 @@ - # disable Wayland on Cirrus chipsets - ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland" -+ -+# disable Wayland when using the proprietary nvidia driver -+DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland" --- -2.20.1 - diff --git a/SOURCES/0001-data-disable-wayland-on-certain-hardware.patch b/SOURCES/0001-data-disable-wayland-on-certain-hardware.patch new file mode 100644 index 0000000..2e346cb --- /dev/null +++ b/SOURCES/0001-data-disable-wayland-on-certain-hardware.patch @@ -0,0 +1,63 @@ +From e01c0894669f5fe3d1a1c4148b7507e61b95d035 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 11 Feb 2019 18:14:07 -0500 +Subject: [PATCH] data: disable wayland on certain hardware + +We're having issues with wayland on passthrough to virt +setups and with the vendor nvidia driver on hybrid graphics +setups, so disable it in those cases. + +Also disable it on server chips for performance reasons. +--- + data/61-gdm.rules.in | 39 +++++++++++++++++++++++++++++++++++---- + 1 file changed, 35 insertions(+), 4 deletions(-) + +diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in +index b1da191f..d599a146 100644 +--- a/data/61-gdm.rules.in ++++ b/data/61-gdm.rules.in +@@ -1,6 +1,37 @@ + # disable Wayland on Hi1710 chipsets +-ATTR{vendor}=="0x19e5", ATTR{device}=="0x1711", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false" +-# disable Wayland when using the proprietary nvidia driver +-DRIVER=="nvidia", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false" ++ATTR{vendor}=="0x19e5", ATTR{device}=="0x1711", RUN+="@libexecdir@/gdm-disable-wayland" ++ ++# disable Wayland on Matrox chipsets ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland" ++ ++# disable Wayland on aspeed chipsets ++ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland" ++ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland" ++ ++# disable Wayland on hybrid systems with vendor nvidia driver ++# default to Xorg on single gpu vendor nvidia systems ++DRIVER=="nvidia", ENV{GDM_HAS_VENDOR_NVIDIA_DRIVER}="1" ++DRIVER=="nvidia", RUN+="@libexecdir@/gdm-runtime-config set daemon PreferredDisplayServer xorg" ++SUBSYSTEM=="drm", KERNEL=="card[1-9]*", ENV{GDM_HAS_NVIDIA_DRIVER}=="1", RUN+="@libexecdir@/gdm-disable-wayland" ++ACTION=="add", SUBSYSTEM=="module", KERNEL=="nvidia_drm", ATTR{parameters/modeset}=="N", RUN+="/usr/libexec/gdm-disable-wayland" ++ ++# disable Wayland on HyperV guests ++DRIVER=="hyperv_fb", RUN+="@libexecdir@/gdm-disable-wayland" ++ ++# disable Wayland on passthrough graphics setups for now (assumes passthrough if ++# there is more than one card, and one of the cards is virt: cirrus, bochs, qxl) ++ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", ENV{GDM_HAS_VIRTUAL_GPU}="1" ++ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", ENV{GDM_HAS_VIRTUAL_GPU}="1" ++ATTR{vendor}=="0x1234", ATTR{device}=="0x1111", ENV{GDM_HAS_VIRTUAL_GPU}="1" ++ ++SUBSYSTEM=="drm", KERNEL=="card[1-9]*", ENV{GDM_HAS_VIRTUAL_GPU}=="1", RUN+="@libexecdir@/gdm-disable-wayland" ++ + # disable Wayland if modesetting is disabled +-IMPORT{cmdline}="nomodeset", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false" ++IMPORT{cmdline}="nomodeset", RUN+="@libexecdir@/gdm-disable-wayland" +-- +2.27.0 + diff --git a/SOURCES/0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch b/SOURCES/0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch deleted file mode 100644 index 67f27fd..0000000 --- a/SOURCES/0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 13a617e15cca421962be888b5607a9900bbfef51 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 11 Feb 2019 18:14:07 -0500 -Subject: [PATCH] data: disable wayland on server chips and dual gpu setups - -We're still having a variety of issues on server chips and -dual gpu/hybrid graphics setups. - -This commit forces Xorg for those cases. ---- - data/61-gdm.rules.in | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in -index 26cf9cf51..e3631740d 100644 ---- a/data/61-gdm.rules.in -+++ b/data/61-gdm.rules.in -@@ -1,5 +1,23 @@ - # disable Wayland on Cirrus chipsets - ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland" - -+# disable Wayland on Matrox chipsets -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland" -+ -+# disable Wayland on aspeed chipsets -+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland" -+ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland" -+ - # disable Wayland when using the proprietary nvidia driver - DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland" -+ -+# disable Wayland on hybrid graphics setups for now -+SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland" -+ --- -2.21.0 - diff --git a/SOURCES/0001-data-enable-wayland-on-cirrus.patch b/SOURCES/0001-data-enable-wayland-on-cirrus.patch deleted file mode 100644 index 7442200..0000000 --- a/SOURCES/0001-data-enable-wayland-on-cirrus.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 7d9b41f1d82589999f8c89ed3bcc4eec6cee4978 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 6 Dec 2019 13:59:43 -0500 -Subject: [PATCH] data: enable wayland on cirrus - -cirrus in the 5.2 kernel was substantially rewritten and is more wayland -ready. - -This commit reenables wayland on cirrus. ---- - data/61-gdm.rules.in | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in -index e3631740d..fc2e3315c 100644 ---- a/data/61-gdm.rules.in -+++ b/data/61-gdm.rules.in -@@ -1,23 +1,20 @@ --# disable Wayland on Cirrus chipsets --ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", RUN+="@libexecdir@/gdm-disable-wayland" -- - # disable Wayland on Matrox chipsets - ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland" - - # disable Wayland on aspeed chipsets - ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland" - - # disable Wayland when using the proprietary nvidia driver - DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland" - - # disable Wayland on hybrid graphics setups for now - SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland" - --- -2.21.0 - diff --git a/SOURCES/0001-data-only-disable-wayland-on-passthrough-virt-setups.patch b/SOURCES/0001-data-only-disable-wayland-on-passthrough-virt-setups.patch deleted file mode 100644 index 24a222f..0000000 --- a/SOURCES/0001-data-only-disable-wayland-on-passthrough-virt-setups.patch +++ /dev/null @@ -1,55 +0,0 @@ -From ab9510df0b5f7bc29662804991729c6d6ee38b70 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 12 Dec 2019 16:56:16 -0500 -Subject: [PATCH] data: only disable wayland on passthrough virt setups - -at the moment we disable wayland on all hybrid graphics setups, -but most hybrid graphics setups work fine. - -The case we really care about is passthrough virt. in that case, -wayland is a bad idea because: -1) kernel crashes -2) mutter provides no way to disable one of the cards, and will -always use one as a secondary gpu - -This commit forces xorg in passthrough setups so the user can use -an xorg.conf to turn one of the cards off. ---- - data/61-gdm.rules.in | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/data/61-gdm.rules.in b/data/61-gdm.rules.in -index fc2e3315c..f971224cf 100644 ---- a/data/61-gdm.rules.in -+++ b/data/61-gdm.rules.in -@@ -1,20 +1,25 @@ - # disable Wayland on Matrox chipsets - ATTR{vendor}=="0x102b", ATTR{device}=="0x0522", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0524", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0530", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0532", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0533", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0534", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0536", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x102b", ATTR{device}=="0x0538", RUN+="@libexecdir@/gdm-disable-wayland" - - # disable Wayland on aspeed chipsets - ATTR{vendor}=="0x1a03", ATTR{device}=="0x2010", RUN+="@libexecdir@/gdm-disable-wayland" - ATTR{vendor}=="0x1a03", ATTR{device}=="0x2000", RUN+="@libexecdir@/gdm-disable-wayland" - - # disable Wayland when using the proprietary nvidia driver - DRIVER=="nvidia", RUN+="@libexecdir@/gdm-disable-wayland" - --# disable Wayland on hybrid graphics setups for now --SUBSYSTEM=="drm", KERNEL=="card[1-9]*", RUN+="@libexecdir@/gdm-disable-wayland" -+# disable Wayland on passthrough graphics setups for now (assumes passthrough if -+# there is more than one card, and one of the cards is virt: cirrus, bochs, qxl) -+ATTR{vendor}=="0x1013", ATTR{device}=="0x00b8", ATTR{subsystem_vendor}=="0x1af4", ATTR{subsystem_device}=="0x1100", ENV{GDM_HAS_VIRTUAL_GPU}="1" -+ATTR{vendor}=="0x1b36", ATTR{device}=="0x0100", ENV{GDM_HAS_VIRTUAL_GPU}="1" -+ATTR{vendor}=="0x1234", ATTR{device}=="0x1111", ENV{GDM_HAS_VIRTUAL_GPU}="1" -+ -+SUBSYSTEM=="drm", KERNEL=="card[1-9]*", ENV{GDM_HAS_VIRTUAL_GPU}=="1", RUN+="@libexecdir@/gdm-disable-wayland" - --- -2.21.0 - diff --git a/SOURCES/0001-data-reap-gdm-sessions-on-shutdown.patch b/SOURCES/0001-data-reap-gdm-sessions-on-shutdown.patch new file mode 100644 index 0000000..2db5283 --- /dev/null +++ b/SOURCES/0001-data-reap-gdm-sessions-on-shutdown.patch @@ -0,0 +1,55 @@ +From 7f910ee7554703a2e775e73ace10ced5d7a0fe66 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 26 Jul 2019 14:06:16 -0400 +Subject: [PATCH] data: reap gdm sessions on shutdown + +If GDM gets shutdown we should make sure all sessions get shutdown too. + +This is a bit of a safety net in case any processes in the session are +lingering after the orderly shutdown. +--- + data/gdm.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/data/gdm.service.in b/data/gdm.service.in +index 17e8a8de8..195bd0fdc 100644 +--- a/data/gdm.service.in ++++ b/data/gdm.service.in +@@ -1,33 +1,34 @@ + [Unit] + Description=GNOME Display Manager + + # replaces the getty + Conflicts=getty@tty${GDM_INITIAL_VT}.service + After=getty@tty${GDM_INITIAL_VT}.service + + # replaces plymouth-quit since it quits plymouth on its own + Conflicts=${PLYMOUTH_QUIT_SERVICE} + After=${PLYMOUTH_QUIT_SERVICE} + + # Needs all the dependencies of the services it's replacing + # pulled from getty@.service and ${PLYMOUTH_QUIT_SERVICE} + # (except for plymouth-quit-wait.service since it waits until + # plymouth is quit, which we do) + After=rc-local.service plymouth-start.service systemd-user-sessions.service + + # GDM takes responsibility for stopping plymouth, so if it fails + # for any reason, make sure plymouth still stops + OnFailure=plymouth-quit.service + + [Service] + ExecStart=${sbindir}/gdm ++ExecStopPost=-/usr/bin/bash -c 'for f in /run/systemd/sessions/*; do [ -f $f ] && /usr/bin/fgrep -q SERVICE=gdm $f && loginctl terminate-session $(basename $f); done' + KillMode=mixed + Restart=always + IgnoreSIGPIPE=no + BusName=org.gnome.DisplayManager + EnvironmentFile=-${LANG_CONFIG_FILE} + ExecReload=/bin/kill -SIGHUP $MAINPID + KeyringMode=shared + + [Install] + Alias=display-manager.service +-- +2.28.0 + diff --git a/SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch b/SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch deleted file mode 100644 index ffd5b94..0000000 --- a/SOURCES/0001-display-Exit-with-failure-if-loading-existing-users-.patch +++ /dev/null @@ -1,140 +0,0 @@ -From e339ad74ca408c665a62bb4bd98dd1ef6caedd20 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Tue, 27 Oct 2020 15:14:27 +0100 -Subject: [PATCH] display: Exit with failure if loading existing users fails - -Given not having users may make GDM to launch initial setup, that -allows to create new users (potentially with sudo capabilities), it's -better to make look_for_existing_users() to return its status and only -if it didn't fail continue the gdm execution. - -GHSL-2020-202 -CVE-2020-16125 - -Fixes #642 ---- - daemon/gdm-display.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 929fa13bd..1b60eb621 100644 ---- a/daemon/gdm-display.c -+++ b/daemon/gdm-display.c -@@ -436,106 +436,110 @@ finish_idle (GdmDisplay *self) - static void - queue_finish (GdmDisplay *self) - { - if (self->priv->finish_idle_id == 0) { - self->priv->finish_idle_id = g_idle_add ((GSourceFunc)finish_idle, self); - } - } - - static void - _gdm_display_set_status (GdmDisplay *self, - int status) - { - if (status != self->priv->status) { - self->priv->status = status; - g_object_notify (G_OBJECT (self), "status"); - } - } - - static gboolean - gdm_display_real_prepare (GdmDisplay *self) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - g_debug ("GdmDisplay: prepare display"); - - _gdm_display_set_status (self, GDM_DISPLAY_PREPARED); - - return TRUE; - } - --static void -+static gboolean - look_for_existing_users_sync (GdmDisplay *self) - { - g_autoptr (GVariant) result = NULL; - g_autoptr (GVariant) result_child = NULL; - g_autoptr (GError) error = NULL; - gboolean has_no_users = FALSE; - - result = g_dbus_connection_call_sync (self->priv->connection, - "org.freedesktop.Accounts", - "/org/freedesktop/Accounts", - "org.freedesktop.DBus.Properties", - "Get", - g_variant_new ("(ss)", "org.freedesktop.Accounts", "HasNoUsers"), - G_VARIANT_TYPE ("(v)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - - if (result == NULL) { -- g_warning ("Failed to contact accountsservice: %s", error->message); -- return; -+ g_critical ("Failed to contact accountsservice: %s", error->message); -+ goto out; - } - - g_variant_get (result, "(v)", &result_child); - has_no_users = g_variant_get_boolean (result_child); - self->priv->have_existing_user_accounts = !has_no_users; - - g_debug ("GdmDisplay: machine does %shave existing user accounts", - has_no_users? "not " : ""); -+out: -+ return result != NULL; - } - - gboolean - gdm_display_prepare (GdmDisplay *self) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - g_debug ("GdmDisplay: Preparing display: %s", self->priv->id); - - /* FIXME: we should probably do this in a more global place, - * asynchronously - */ -- look_for_existing_users_sync (self); -+ if (!look_for_existing_users_sync (self)) { -+ exit (EXIT_FAILURE); -+ } - - self->priv->doing_initial_setup = wants_initial_setup (self); - - g_object_ref (self); - ret = GDM_DISPLAY_GET_CLASS (self)->prepare (self); - g_object_unref (self); - - return ret; - } - - gboolean - gdm_display_manage (GdmDisplay *self) - { - gboolean res; - - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - g_debug ("GdmDisplay: Managing display: %s", self->priv->id); - - /* If not explicitly prepared, do it now */ - if (self->priv->status == GDM_DISPLAY_UNMANAGED) { - res = gdm_display_prepare (self); - if (! res) { - return FALSE; - } - } - - if (g_strcmp0 (self->priv->session_class, "greeter") == 0) { - if (GDM_DISPLAY_GET_CLASS (self)->manage != NULL) { - GDM_DISPLAY_GET_CLASS (self)->manage (self); --- -2.28.0 - diff --git a/SOURCES/0051-display-Handle-failure-before-display-registration.patch b/SOURCES/0001-display-Handle-failure-before-display-registration.patch similarity index 67% rename from SOURCES/0051-display-Handle-failure-before-display-registration.patch rename to SOURCES/0001-display-Handle-failure-before-display-registration.patch index 1e4c7c0..219a865 100644 --- a/SOURCES/0051-display-Handle-failure-before-display-registration.patch +++ b/SOURCES/0001-display-Handle-failure-before-display-registration.patch @@ -1,7 +1,7 @@ -From f6a8a36717afc7ce00bdb2305a6219c28abc36fb Mon Sep 17 00:00:00 2001 +From cbfb3ef99ecc9cbb4e6850e5dd0cc9fb65dd398a Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 1 Sep 2020 13:49:27 -0400 -Subject: [PATCH 51/51] display: Handle failure before display registration +Subject: [PATCH 1/3] display: Handle failure before display registration Normally, e.g., gdm-wayland-session would register its display before starting the session. This display registration is how @@ -17,14 +17,10 @@ display isn't yet fully managed. 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index ae20491cd..b8ccbbd72 100644 +index 7c954ad24..3a260923a 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c -@@ -575,80 +575,79 @@ gdm_display_disconnect (GdmDisplay *self) - return; - } - - setup = xcb_get_setup (self->priv->xcb_connection); +@@ -648,62 +648,60 @@ gdm_display_disconnect (GdmDisplay *self) /* resource_id_mask is the bits given to each client for * addressing resources */ @@ -38,40 +34,43 @@ index ae20491cd..b8ccbbd72 100644 client += client_increment) { if (client != setup->resource_id_base) - xcb_kill_client (self->priv->xcb_connection, client); + xcb_kill_client (priv->xcb_connection, client); } - xcb_flush (self->priv->xcb_connection); + xcb_flush (priv->xcb_connection); - g_clear_pointer (&self->priv->xcb_connection, xcb_disconnect); + g_clear_pointer (&priv->xcb_connection, xcb_disconnect); } gboolean gdm_display_unmanage (GdmDisplay *self) { + GdmDisplayPrivate *priv; + g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); + priv = gdm_display_get_instance_private (self); + - g_debug ("GdmDisplay: unmanage display"); - gdm_display_disconnect (self); - if (self->priv->user_access_file != NULL) { - gdm_display_access_file_close (self->priv->user_access_file); - g_object_unref (self->priv->user_access_file); - self->priv->user_access_file = NULL; + if (priv->user_access_file != NULL) { + gdm_display_access_file_close (priv->user_access_file); + g_object_unref (priv->user_access_file); + priv->user_access_file = NULL; } - if (self->priv->access_file != NULL) { - gdm_display_access_file_close (self->priv->access_file); - g_object_unref (self->priv->access_file); - self->priv->access_file = NULL; + if (priv->access_file != NULL) { + gdm_display_access_file_close (priv->access_file); + g_object_unref (priv->access_file); + priv->access_file = NULL; } - if (!self->priv->session_registered) { + if (!priv->session_registered) { g_warning ("GdmDisplay: Session never registered, failing"); _gdm_display_set_status (self, GDM_DISPLAY_FAILED); } else { -+ g_debug ("GdmDisplay: Unmanage display"); _gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED); } @@ -83,31 +82,13 @@ index ae20491cd..b8ccbbd72 100644 char **id, GError **error) { - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - if (id != NULL) { - *id = g_strdup (self->priv->id); - } - - return TRUE; - } - - gboolean - gdm_display_get_x11_display_name (GdmDisplay *self, - char **x11_display, - GError **error) + GdmDisplayPrivate *priv; +@@ -1446,63 +1444,63 @@ gdm_display_get_object_skeleton (GdmDisplay *self) { - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); + GdmDisplayPrivate *priv; - if (x11_display != NULL) { - *x11_display = g_strdup (self->priv->x11_display_name); - } -@@ -1309,63 +1308,62 @@ gdm_display_finalize (GObject *object) - - GDBusObjectSkeleton * - gdm_display_get_object_skeleton (GdmDisplay *self) - { - return self->priv->object_skeleton; + priv = gdm_display_get_instance_private (self); + return priv->object_skeleton; } static void @@ -136,6 +117,7 @@ index ae20491cd..b8ccbbd72 100644 - if (gdm_display_get_status (self) == GDM_DISPLAY_MANAGED) { - gdm_display_unmanage (self); - } ++ + g_debug ("GdmDisplay: initiating display self-destruct"); + gdm_display_unmanage (self); @@ -169,5 +151,5 @@ index ae20491cd..b8ccbbd72 100644 { g_debug ("GdmDisplay: Greeter died: %d", signal); -- -2.27.0 +2.31.1 diff --git a/SOURCES/0001-display-access-file-drop-unused-function.patch b/SOURCES/0001-display-access-file-drop-unused-function.patch deleted file mode 100644 index 12bf24e..0000000 --- a/SOURCES/0001-display-access-file-drop-unused-function.patch +++ /dev/null @@ -1,206 +0,0 @@ -From fb55ec1c2e2957eb4c11a220874e5089fd357286 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 16 May 2018 14:06:29 -0400 -Subject: [PATCH] display-access-file: drop unused function - -gdm_display_access_file_remove_display is unused. - -This commit drops it. - -https://bugzilla.gnome.org/show_bug.cgi?id=796176 ---- - daemon/gdm-display-access-file.c | 79 -------------------------------- - daemon/gdm-display-access-file.h | 3 -- - 2 files changed, 82 deletions(-) - -diff --git a/daemon/gdm-display-access-file.c b/daemon/gdm-display-access-file.c -index 9bf818d2a..c1f0f17a8 100644 ---- a/daemon/gdm-display-access-file.c -+++ b/daemon/gdm-display-access-file.c -@@ -536,139 +536,60 @@ gdm_display_access_file_add_display_with_cookie (GdmDisplayAccessFile *file, - || fflush (file->priv->fp) == EOF) { - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (errno), - "%s", g_strerror (errno)); - display_added = FALSE; - } else { - display_added = TRUE; - } - - /* If we wrote a FamilyLocal entry, we still want a FamilyWild - * entry, because it's more resiliant against hostname changes - * - */ - if (auth_entry.family == FamilyLocal) { - auth_entry.family = FamilyWild; - - if (XauWriteAuth (file->priv->fp, &auth_entry) - && fflush (file->priv->fp) != EOF) { - display_added = TRUE; - } - } - - g_free (auth_entry.address); - g_free (auth_entry.number); - g_free (auth_entry.name); - - return display_added; - } - --gboolean --gdm_display_access_file_remove_display (GdmDisplayAccessFile *file, -- GdmDisplay *display, -- GError **error) --{ -- Xauth *auth_entry; -- unsigned short family; -- unsigned short address_length; -- char *address; -- unsigned short number_length; -- char *number; -- unsigned short name_length; -- char *name; -- -- gboolean result = FALSE; -- -- g_return_val_if_fail (file != NULL, FALSE); -- g_return_val_if_fail (file->priv->path != NULL, FALSE); -- -- _get_auth_info_for_display (file, display, -- &family, -- &address_length, -- &address, -- &number_length, -- &number, -- &name_length, -- &name); -- -- auth_entry = XauGetAuthByAddr (family, -- address_length, -- address, -- number_length, -- number, -- name_length, -- name); -- g_free (address); -- g_free (number); -- g_free (name); -- -- if (auth_entry != NULL) { -- XauDisposeAuth (auth_entry); -- result = TRUE; -- } -- -- /* If FamilyLocal, we also added a FamilyWild entry, -- * so we need to clean that up too -- */ -- if (family == FamilyLocal) { -- auth_entry = XauGetAuthByAddr (FamilyWild, -- address_length, -- address, -- number_length, -- number, -- name_length, -- name); -- -- if (auth_entry != NULL) { -- XauDisposeAuth (auth_entry); -- result = TRUE; -- } -- } -- -- -- if (result == FALSE) { -- g_set_error (error, -- GDM_DISPLAY_ACCESS_FILE_ERROR, -- GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY, -- "could not find authorization entry"); -- } else if (fflush (file->priv->fp) == EOF) { -- g_set_error (error, -- G_FILE_ERROR, -- g_file_error_from_errno (errno), -- "%s", g_strerror (errno)); -- result = FALSE; -- } -- -- return result; --} -- - void - gdm_display_access_file_close (GdmDisplayAccessFile *file) - { - char *auth_dir; - - g_return_if_fail (file != NULL); - g_return_if_fail (file->priv->fp != NULL); - g_return_if_fail (file->priv->path != NULL); - - errno = 0; - if (g_unlink (file->priv->path) != 0) { - g_warning ("GdmDisplayAccessFile: Unable to remove X11 authority database '%s': %s", - file->priv->path, - g_strerror (errno)); - } - - /* still try to remove dir even if file remove failed, - may have already been removed by someone else */ - /* we own the parent directory too */ - auth_dir = g_path_get_dirname (file->priv->path); - if (auth_dir != NULL) { - errno = 0; - if (g_rmdir (auth_dir) != 0) { - g_warning ("GdmDisplayAccessFile: Unable to remove X11 authority directory '%s': %s", - auth_dir, - g_strerror (errno)); - } - g_free (auth_dir); - } - -diff --git a/daemon/gdm-display-access-file.h b/daemon/gdm-display-access-file.h -index cc7de9e35..eff8dd011 100644 ---- a/daemon/gdm-display-access-file.h -+++ b/daemon/gdm-display-access-file.h -@@ -50,39 +50,36 @@ struct _GdmDisplayAccessFile - GdmDisplayAccessFilePrivate *priv; - }; - - struct _GdmDisplayAccessFileClass - { - GObjectClass parent_class; - }; - - enum _GdmDisplayAccessFileError - { - GDM_DISPLAY_ACCESS_FILE_ERROR_GENERAL = 0, - GDM_DISPLAY_ACCESS_FILE_ERROR_FINDING_AUTH_ENTRY - }; - - GQuark gdm_display_access_file_error_quark (void); - GType gdm_display_access_file_get_type (void); - - GdmDisplayAccessFile *gdm_display_access_file_new (const char *username); - gboolean gdm_display_access_file_open (GdmDisplayAccessFile *file, - GError **error); - gboolean gdm_display_access_file_add_display (GdmDisplayAccessFile *file, - GdmDisplay *display, - char **cookie, - gsize *cookie_size, - GError **error); - gboolean gdm_display_access_file_add_display_with_cookie (GdmDisplayAccessFile *file, - GdmDisplay *display, - const char *cookie, - gsize cookie_size, - GError **error); --gboolean gdm_display_access_file_remove_display (GdmDisplayAccessFile *file, -- GdmDisplay *display, -- GError **error); - - void gdm_display_access_file_close (GdmDisplayAccessFile *file); - char *gdm_display_access_file_get_path (GdmDisplayAccessFile *file); - - G_END_DECLS - #endif /* __GDM_DISPLAY_ACCESS_FILE_H__ */ --- -2.17.1 - diff --git a/SOURCES/0001-display-ask-accountservice-if-there-are-users-rather.patch b/SOURCES/0001-display-ask-accountservice-if-there-are-users-rather.patch deleted file mode 100644 index cd35a63..0000000 --- a/SOURCES/0001-display-ask-accountservice-if-there-are-users-rather.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 781e865705b0c134271c9ec21655cd5d8ce37fec Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Sat, 14 Dec 2019 13:50:53 -0500 -Subject: [PATCH] display: ask accountservice if there are users rather than - enumerate users - -At the moment we ask accountsservice to give us the list of users just -to find out if there is a list of users. - -That's rather inefficient and might be wrong for directory server users -that have never logged in before. - -This commit changes gdm to ask accountsservice the question we really -want to know the answer to; whether or not there are users. ---- - daemon/gdm-display.c | 55 ++++++++++++++++++-------------------------- - 1 file changed, 22 insertions(+), 33 deletions(-) - -diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 878be88da..875534272 100644 ---- a/daemon/gdm-display.c -+++ b/daemon/gdm-display.c -@@ -57,62 +57,60 @@ - struct GdmDisplayPrivate - { - char *id; - char *seat_id; - char *session_id; - char *session_class; - char *session_type; - - char *remote_hostname; - int x11_display_number; - char *x11_display_name; - int status; - time_t creation_time; - GTimer *server_timer; - - char *x11_cookie; - gsize x11_cookie_size; - GdmDisplayAccessFile *access_file; - - guint finish_idle_id; - - xcb_connection_t *xcb_connection; - int xcb_screen_number; - - GDBusConnection *connection; - GdmDisplayAccessFile *user_access_file; - - GdmDBusDisplay *display_skeleton; - GDBusObjectSkeleton *object_skeleton; - -- GDBusProxy *accountsservice_proxy; -- - /* this spawns and controls the greeter session */ - GdmLaunchEnvironment *launch_environment; - - guint is_local : 1; - guint is_initial : 1; - guint allow_timed_login : 1; - guint have_existing_user_accounts : 1; - guint doing_initial_setup : 1; - }; - - enum { - PROP_0, - PROP_ID, - PROP_STATUS, - PROP_SEAT_ID, - PROP_SESSION_ID, - PROP_SESSION_CLASS, - PROP_SESSION_TYPE, - PROP_REMOTE_HOSTNAME, - PROP_X11_DISPLAY_NUMBER, - PROP_X11_DISPLAY_NAME, - PROP_X11_COOKIE, - PROP_X11_AUTHORITY_FILE, - PROP_IS_CONNECTED, - PROP_IS_LOCAL, - PROP_LAUNCH_ENVIRONMENT, - PROP_IS_INITIAL, - PROP_ALLOW_TIMED_LOGIN, - PROP_HAVE_EXISTING_USER_ACCOUNTS, - PROP_DOING_INITIAL_SETUP, -@@ -512,96 +510,88 @@ queue_finish (GdmDisplay *self) - if (self->priv->finish_idle_id == 0) { - self->priv->finish_idle_id = g_idle_add ((GSourceFunc)finish_idle, self); - } - } - - static void - _gdm_display_set_status (GdmDisplay *self, - int status) - { - if (status != self->priv->status) { - self->priv->status = status; - g_object_notify (G_OBJECT (self), "status"); - } - } - - static gboolean - gdm_display_real_prepare (GdmDisplay *self) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - g_debug ("GdmDisplay: prepare display"); - - _gdm_display_set_status (self, GDM_DISPLAY_PREPARED); - - return TRUE; - } - - static void - look_for_existing_users_sync (GdmDisplay *self) - { -- GError *error = NULL; -- GVariant *call_result; -- GVariant *user_list; -- -- self->priv->accountsservice_proxy = g_dbus_proxy_new_sync (self->priv->connection, -- 0, NULL, -- "org.freedesktop.Accounts", -- "/org/freedesktop/Accounts", -- "org.freedesktop.Accounts", -- NULL, -- &error); -- -- if (!self->priv->accountsservice_proxy) { -- g_warning ("Failed to contact accountsservice: %s", error->message); -- goto out; -- } -- -- call_result = g_dbus_proxy_call_sync (self->priv->accountsservice_proxy, -- "ListCachedUsers", -- NULL, -- 0, -+ g_autoptr (GVariant) result = NULL; -+ g_autoptr (GVariant) result_child = NULL; -+ g_autoptr (GError) error = NULL; -+ gboolean has_no_users = FALSE; -+ -+ result = g_dbus_connection_call_sync (self->priv->connection, -+ "org.freedesktop.Accounts", -+ "/org/freedesktop/Accounts", -+ "org.freedesktop.DBus.Properties", -+ "Get", -+ g_variant_new ("(ss)", "org.freedesktop.Accounts", "HasNoUsers"), -+ G_VARIANT_TYPE ("(v)"), -+ G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - -- if (!call_result) { -- g_warning ("Failed to list cached users: %s", error->message); -- goto out; -+ if (result == NULL) { -+ g_warning ("Failed to contact accountsservice: %s", error->message); -+ return; - } - -- g_variant_get (call_result, "(@ao)", &user_list); -- self->priv->have_existing_user_accounts = g_variant_n_children (user_list) > 0; -- g_variant_unref (user_list); -- g_variant_unref (call_result); --out: -- g_clear_error (&error); -+ g_variant_get (result, "(v)", &result_child); -+ has_no_users = g_variant_get_boolean (result_child); -+ self->priv->have_existing_user_accounts = !has_no_users; -+ -+ g_debug ("GdmDisplay: machine does %shave existing user accounts", -+ has_no_users? "not " : ""); - } - - gboolean - gdm_display_prepare (GdmDisplay *self) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - g_debug ("GdmDisplay: Preparing display: %s", self->priv->id); - - /* FIXME: we should probably do this in a more global place, - * asynchronously - */ - look_for_existing_users_sync (self); - - self->priv->doing_initial_setup = wants_initial_setup (self); - - g_object_ref (self); - ret = GDM_DISPLAY_GET_CLASS (self)->prepare (self); - g_object_unref (self); - - return ret; - } - - gboolean - gdm_display_manage (GdmDisplay *self) - { - gboolean res; - -@@ -1332,61 +1322,60 @@ gdm_display_init (GdmDisplay *self) - - self->priv = GDM_DISPLAY_GET_PRIVATE (self); - - self->priv->creation_time = time (NULL); - self->priv->server_timer = g_timer_new (); - } - - static void - gdm_display_finalize (GObject *object) - { - GdmDisplay *self; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_DISPLAY (object)); - - self = GDM_DISPLAY (object); - - g_return_if_fail (self->priv != NULL); - - g_debug ("GdmDisplay: Finalizing display: %s", self->priv->id); - g_free (self->priv->id); - g_free (self->priv->seat_id); - g_free (self->priv->session_class); - g_free (self->priv->remote_hostname); - g_free (self->priv->x11_display_name); - g_free (self->priv->x11_cookie); - - g_clear_object (&self->priv->display_skeleton); - g_clear_object (&self->priv->object_skeleton); - g_clear_object (&self->priv->connection); -- g_clear_object (&self->priv->accountsservice_proxy); - - if (self->priv->access_file != NULL) { - g_object_unref (self->priv->access_file); - } - - if (self->priv->user_access_file != NULL) { - g_object_unref (self->priv->user_access_file); - } - - if (self->priv->server_timer != NULL) { - g_timer_destroy (self->priv->server_timer); - } - - G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object); - } - - GDBusObjectSkeleton * - gdm_display_get_object_skeleton (GdmDisplay *self) - { - return self->priv->object_skeleton; - } - - static void - on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment, - GdmDisplay *self) - { - char *session_id; - - g_debug ("GdmDisplay: Greeter session opened"); - session_id = gdm_launch_environment_get_session_id (launch_environment); --- -2.21.0 - diff --git a/SOURCES/0001-display-factory-avoid-removing-a-display-from-store-.patch b/SOURCES/0001-display-factory-avoid-removing-a-display-from-store-.patch deleted file mode 100644 index bd73d6d..0000000 --- a/SOURCES/0001-display-factory-avoid-removing-a-display-from-store-.patch +++ /dev/null @@ -1,433 +0,0 @@ -From a9422c7b5f4200ad36300bb06134d545bb9d48d2 Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Tue, 17 Jul 2018 20:20:55 +0000 -Subject: [PATCH 01/51] display-factory: avoid removing a display from store - while iterating it - ---- - daemon/gdm-display-factory.c | 41 ++++++++++++++++++++++++++++++ - daemon/gdm-display-factory.h | 1 + - daemon/gdm-local-display-factory.c | 7 ++--- - daemon/gdm-xdmcp-display-factory.c | 7 ++--- - 4 files changed, 46 insertions(+), 10 deletions(-) - -diff --git a/daemon/gdm-display-factory.c b/daemon/gdm-display-factory.c -index d86a4c8ad..c520e1088 100644 ---- a/daemon/gdm-display-factory.c -+++ b/daemon/gdm-display-factory.c -@@ -8,84 +8,120 @@ - * (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 "gdm-display-factory.h" - #include "gdm-display-store.h" - - #define GDM_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY_FACTORY, GdmDisplayFactoryPrivate)) - - struct GdmDisplayFactoryPrivate - { - GdmDisplayStore *display_store; -+ guint purge_displays_id; - }; - - enum { - PROP_0, - PROP_DISPLAY_STORE, - }; - - static void gdm_display_factory_class_init (GdmDisplayFactoryClass *klass); - static void gdm_display_factory_init (GdmDisplayFactory *factory); - static void gdm_display_factory_finalize (GObject *object); - - G_DEFINE_ABSTRACT_TYPE (GdmDisplayFactory, gdm_display_factory, G_TYPE_OBJECT) - - GQuark - gdm_display_factory_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_display_factory_error"); - } - - return ret; - } - -+static gboolean -+purge_display (char *id, -+ GdmDisplay *display, -+ gpointer user_data) -+{ -+ int status; -+ -+ status = gdm_display_get_status (display); -+ -+ switch (status) { -+ case GDM_DISPLAY_FINISHED: -+ case GDM_DISPLAY_FAILED: -+ return TRUE; -+ default: -+ return FALSE; -+ } -+} -+ -+static void -+purge_displays (GdmDisplayFactory *factory) -+{ -+ factory->priv->purge_displays_id = 0; -+ gdm_display_store_foreach_remove (factory->priv->display_store, -+ (GdmDisplayStoreFunc)purge_display, -+ NULL); -+} -+ -+void -+gdm_display_factory_queue_purge_displays (GdmDisplayFactory *factory) -+{ -+ if (factory->priv->purge_displays_id == 0) { -+ factory->priv->purge_displays_id = g_idle_add ((GSourceFunc) purge_displays, factory); -+ } -+} -+ - GdmDisplayStore * - gdm_display_factory_get_display_store (GdmDisplayFactory *factory) - { - g_return_val_if_fail (GDM_IS_DISPLAY_FACTORY (factory), NULL); - - return factory->priv->display_store; - } - - gboolean - gdm_display_factory_start (GdmDisplayFactory *factory) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_DISPLAY_FACTORY (factory), FALSE); - - g_object_ref (factory); - ret = GDM_DISPLAY_FACTORY_GET_CLASS (factory)->start (factory); - g_object_unref (factory); - - return ret; - } - - gboolean - gdm_display_factory_stop (GdmDisplayFactory *factory) - { - gboolean ret; - - g_return_val_if_fail (GDM_IS_DISPLAY_FACTORY (factory), FALSE); - - g_object_ref (factory); -@@ -160,32 +196,37 @@ gdm_display_factory_class_init (GdmDisplayFactoryClass *klass) - - g_object_class_install_property (object_class, - PROP_DISPLAY_STORE, - g_param_spec_object ("display-store", - "display store", - "display store", - GDM_TYPE_DISPLAY_STORE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_type_class_add_private (klass, sizeof (GdmDisplayFactoryPrivate)); - } - - static void - gdm_display_factory_init (GdmDisplayFactory *factory) - { - factory->priv = GDM_DISPLAY_FACTORY_GET_PRIVATE (factory); - } - - static void - gdm_display_factory_finalize (GObject *object) - { - GdmDisplayFactory *factory; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_DISPLAY_FACTORY (object)); - - factory = GDM_DISPLAY_FACTORY (object); - - g_return_if_fail (factory->priv != NULL); - -+ if (factory->priv->purge_displays_id != 0) { -+ g_source_remove (factory->priv->purge_displays_id); -+ factory->priv->purge_displays_id = 0; -+ } -+ - G_OBJECT_CLASS (gdm_display_factory_parent_class)->finalize (object); - } -diff --git a/daemon/gdm-display-factory.h b/daemon/gdm-display-factory.h -index 6b30f83dc..1cffa1bd5 100644 ---- a/daemon/gdm-display-factory.h -+++ b/daemon/gdm-display-factory.h -@@ -37,34 +37,35 @@ G_BEGIN_DECLS - - typedef struct GdmDisplayFactoryPrivate GdmDisplayFactoryPrivate; - - typedef struct - { - GObject parent; - GdmDisplayFactoryPrivate *priv; - } GdmDisplayFactory; - - typedef struct - { - GObjectClass parent_class; - - gboolean (*start) (GdmDisplayFactory *factory); - gboolean (*stop) (GdmDisplayFactory *factory); - } GdmDisplayFactoryClass; - - typedef enum - { - GDM_DISPLAY_FACTORY_ERROR_GENERAL - } GdmDisplayFactoryError; - - #define GDM_DISPLAY_FACTORY_ERROR gdm_display_factory_error_quark () - - GQuark gdm_display_factory_error_quark (void); - GType gdm_display_factory_get_type (void); - - gboolean gdm_display_factory_start (GdmDisplayFactory *manager); - gboolean gdm_display_factory_stop (GdmDisplayFactory *manager); - GdmDisplayStore * gdm_display_factory_get_display_store (GdmDisplayFactory *manager); -+void gdm_display_factory_queue_purge_displays (GdmDisplayFactory *manager); - - G_END_DECLS - - #endif /* __GDM_DISPLAY_FACTORY_H */ -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index ab7e12e91..1a9196ee1 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -222,107 +222,104 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact - "seat-id", "seat0", - "allow-timed-login", FALSE, - NULL); - - 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; - 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, - 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); -+ gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - - /* 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) { - /* 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); -+ gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - - /* 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; - - /* workaround logind race for now - * bug 1643874 - */ - g_usleep (2 * G_USEC_PER_SEC); - } - - #endif - create_display (factory, seat_id, session_type, is_initial); - } - } - break; - case GDM_DISPLAY_UNMANAGED: - break; - case GDM_DISPLAY_PREPARED: - break; -diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c -index 46a0d9ffa..5b5786c6f 100644 ---- a/daemon/gdm-xdmcp-display-factory.c -+++ b/daemon/gdm-xdmcp-display-factory.c -@@ -2039,93 +2039,90 @@ on_hostname_selected (GdmXdmcpChooserDisplay *display, - char *ip; - ic->chosen_address = gdm_address_new_from_sockaddr (ai->ai_addr, ai->ai_addrlen); - - ip = NULL; - gdm_address_get_numeric_info (ic->chosen_address, &ip, NULL); - g_debug ("GdmXdmcpDisplayFactory: hostname resolves to %s", - ip ? ip : "(null)"); - g_free (ip); - } - - freeaddrinfo (ai_list); - } - - static void - on_client_disconnected (GdmDisplay *display) - { - if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) - return; - - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - } - - static void - on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmXdmcpDisplayFactory *factory) - { - int status; -- GdmDisplayStore *store; - GdmLaunchEnvironment *launch_environment; - GdmSession *session; - GdmAddress *address; - gint32 session_number; - int display_number; - -- store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); -- - launch_environment = NULL; - g_object_get (display, "launch-environment", &launch_environment, NULL); - - session = NULL; - if (launch_environment != NULL) { - session = gdm_launch_environment_get_session (launch_environment); - } - - status = gdm_display_get_status (display); - - g_debug ("GdmXdmcpDisplayFactory: xdmcp display status changed: %d", status); - switch (status) { - case GDM_DISPLAY_FINISHED: - g_object_get (display, - "remote-address", &address, - "x11-display-number", &display_number, - "session-number", &session_number, - NULL); - gdm_xdmcp_send_alive (factory, address, display_number, session_number); - -- gdm_display_store_remove (store, display); -+ gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - break; - case GDM_DISPLAY_FAILED: -- gdm_display_store_remove (store, display); -+ gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - break; - case GDM_DISPLAY_UNMANAGED: - if (session != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (session), - G_CALLBACK (on_client_disconnected), - display); - } - break; - case GDM_DISPLAY_PREPARED: - break; - case GDM_DISPLAY_MANAGED: - if (session != NULL) { - g_signal_connect_object (G_OBJECT (session), - "client-disconnected", - G_CALLBACK (on_client_disconnected), - display, G_CONNECT_SWAPPED); - g_signal_connect_object (G_OBJECT (session), - "disconnected", - G_CALLBACK (on_client_disconnected), - display, G_CONNECT_SWAPPED); - } - break; - default: - g_assert_not_reached (); - break; - } - } - - static GdmDisplay * - gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory, --- -2.27.0 - diff --git a/SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch b/SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch new file mode 100644 index 0000000..080052f --- /dev/null +++ b/SOURCES/0001-local-display-factory-Don-t-try-to-respawn-displays-.patch @@ -0,0 +1,325 @@ +From d8fd8d4d6ff6a119f6bd27eb07316384c4776d12 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 15 Sep 2021 11:23:17 -0400 +Subject: [PATCH] local-display-factory: Don't try to respawn displays on + shutdown + +At the moment in the shutdown path we may try to respawn displays +that just got killed. + +The respawning happens when things are half torn down leading to +crashes. + +This commit makes sure we turn off the respawn logic in the shutdown +path. +--- + daemon/gdm-local-display-factory.c | 11 ++++++++++- + daemon/gdm-manager.c | 2 ++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 11dcda2c..a0884893 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -46,60 +46,62 @@ + #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory" + #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory" + + #define MAX_DISPLAY_FAILURES 5 + #define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */ + #define SEAT0_GRAPHICS_CHECK_TIMEOUT 10 /* seconds */ + + struct _GdmLocalDisplayFactory + { + GdmDisplayFactory parent; + + GdmDBusLocalDisplayFactory *skeleton; + GDBusConnection *connection; + GHashTable *used_display_numbers; + + /* FIXME: this needs to be per seat? */ + guint num_failures; + + guint seat_new_id; + guint seat_removed_id; + guint seat_properties_changed_id; + + gboolean seat0_graphics_check_timed_out; + guint seat0_graphics_check_timeout_id; + + #if defined(ENABLE_USER_DISPLAY_SERVER) + unsigned int active_vt; + guint active_vt_watch_id; + guint wait_to_finish_timeout_id; + #endif ++ ++ gboolean is_started; + }; + + enum { + PROP_0, + }; + + static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); + static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); + static void gdm_local_display_factory_finalize (GObject *object); + + static void ensure_display_for_seat (GdmLocalDisplayFactory *factory, + const char *seat_id); + + static void on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmLocalDisplayFactory *factory); + + static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); + static gpointer local_display_factory_object = NULL; + static gboolean lookup_by_session_id (const char *id, + GdmDisplay *display, + gpointer user_data); + + G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) + + GQuark + gdm_local_display_factory_error_quark (void) + { + static GQuark ret = 0; + if (ret == 0) { +@@ -478,60 +480,64 @@ on_session_registered_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) + { + GdmDisplay *display = GDM_DISPLAY (gobject); + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); + gboolean registered; + + g_object_get (display, "session-registered", ®istered, NULL); + + if (!registered) + return; + + g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill"); + + finish_waiting_displays_on_seat (factory, "seat0"); + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmLocalDisplayFactory *factory) + { + int status; + int num; + char *seat_id = NULL; + char *session_type = NULL; + char *session_class = NULL; + gboolean is_initial = TRUE; + gboolean is_local = TRUE; + ++ ++ if (!factory->is_started) ++ return; ++ + num = -1; + gdm_display_get_x11_display_number (display, &num, NULL); + + 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->used_display_numbers + so that it may be reused */ + if (num != -1) { + g_hash_table_remove (factory->used_display_numbers, GUINT_TO_POINTER (num)); + } + gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); + + /* 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 && g_strcmp0 (session_class, "greeter") != 0) { + /* reset num failures */ +@@ -1250,99 +1256,102 @@ on_display_added (GdmDisplayStore *display_store, + + display = gdm_display_store_lookup (display_store, id); + + if (display != NULL) { + g_signal_connect_object (display, "notify::status", + G_CALLBACK (on_display_status_changed), + factory, + 0); + + g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); + } + } + + static void + on_display_removed (GdmDisplayStore *display_store, + GdmDisplay *display, + GdmLocalDisplayFactory *factory) + { + g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), factory); + g_object_weak_unref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); + } + + static gboolean + gdm_local_display_factory_start (GdmDisplayFactory *base_factory) + { + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); + GdmDisplayStore *store; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + ++ factory->is_started = TRUE; ++ + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + g_signal_connect_object (G_OBJECT (store), + "display-added", + G_CALLBACK (on_display_added), + factory, + 0); + + g_signal_connect_object (G_OBJECT (store), + "display-removed", + G_CALLBACK (on_display_removed), + factory, + 0); + + gdm_local_display_factory_start_monitor (factory); + return gdm_local_display_factory_sync_seats (factory); + } + + static gboolean + gdm_local_display_factory_stop (GdmDisplayFactory *base_factory) + { + GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (base_factory); + GdmDisplayStore *store; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + + gdm_local_display_factory_stop_monitor (factory); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + g_signal_handlers_disconnect_by_func (G_OBJECT (store), + G_CALLBACK (on_display_added), + factory); + g_signal_handlers_disconnect_by_func (G_OBJECT (store), + G_CALLBACK (on_display_removed), + factory); +- + g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove); + ++ factory->is_started = FALSE; ++ + return TRUE; + } + + static void + gdm_local_display_factory_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) + { + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static void + gdm_local_display_factory_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) + { + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static gboolean +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index b3d0a2b5..4b62b8b1 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -2774,60 +2774,62 @@ unexport_display (const char *id, + GdmDisplay *display, + GdmManager *manager) + { + if (!g_dbus_connection_is_closed (manager->priv->connection)) + g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); + } + + static void + finish_display (const char *id, + GdmDisplay *display, + GdmManager *manager) + { + gdm_display_stop_greeter_session (display); + if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) + gdm_display_unmanage (display); + gdm_display_finish (display); + } + + static void + gdm_manager_dispose (GObject *object) + { + GdmManager *manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_MANAGER (object)); + + manager = GDM_MANAGER (object); + + g_return_if_fail (manager->priv != NULL); + ++ gdm_manager_stop (manager); ++ + g_clear_weak_pointer (&manager->priv->automatic_login_display); + + #ifdef HAVE_LIBXDMCP + g_clear_object (&manager->priv->xdmcp_factory); + #endif + g_clear_object (&manager->priv->local_factory); + g_clear_pointer (&manager->priv->open_reauthentication_requests, + g_hash_table_unref); + g_clear_pointer (&manager->priv->transient_sessions, + g_hash_table_unref); + + g_list_foreach (manager->priv->user_sessions, + (GFunc) gdm_session_close, + NULL); + g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref); + manager->priv->user_sessions = NULL; + + g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), + G_CALLBACK (on_display_added), + manager); + g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), + G_CALLBACK (on_display_removed), + manager); + + if (!g_dbus_connection_is_closed (manager->priv->connection)) { + gdm_display_store_foreach (manager->priv->display_store, + (GdmDisplayStoreFunc)unexport_display, + manager); + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager)); + } +-- +2.31.1 + diff --git a/SOURCES/0001-local-display-factory-Provide-more-flexibility-for-c.patch b/SOURCES/0001-local-display-factory-Provide-more-flexibility-for-c.patch new file mode 100644 index 0000000..346c27e --- /dev/null +++ b/SOURCES/0001-local-display-factory-Provide-more-flexibility-for-c.patch @@ -0,0 +1,2765 @@ +From 4ef82bf0fe40dd3952997a77539a57e8cb8b99ef Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 16 Jul 2021 12:34:57 -0400 +Subject: [PATCH 1/2] local-display-factory: Provide more flexibility for + configuring display server + +There's currently a way to disable wayland, but no way to disable Xorg. +We currently prefer wayland if it's not disabled, but have no way to +prefer Xorg without disabling wayland entirely. + +There's currently no way use legacy Xorg support at all if user display +server support is enabled at a build time. + +This commit adds more flexibility to display server selection. It adds +two new keys: XorgEnable and and PreferredDisplayServer. + +XorgEnable=false disables Xorg support entirely on seat 0. + +PreferredDisplayServer can be set to "wayland", "xorg", "legacy-xorg" or +"none" to select which display server is used by default. If it's set to +"wayland", it will fall back to "xorg". If it's set to "xorg" it will +fall back to "wayland". +--- + common/gdm-settings-keys.h | 2 + + daemon/gdm-display.c | 36 ++++ + daemon/gdm-launch-environment.c | 9 + + daemon/gdm-local-display-factory.c | 267 ++++++++++++++++++++++++----- + daemon/gdm-manager.c | 20 +-- + daemon/gdm-session.c | 169 ++++++++++-------- + data/gdm.schemas.in | 10 ++ + libgdm/gdm-sessions.c | 72 +++++--- + 8 files changed, 437 insertions(+), 148 deletions(-) + +diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h +index f0059b5c..87685d3c 100644 +--- a/common/gdm-settings-keys.h ++++ b/common/gdm-settings-keys.h +@@ -6,59 +6,61 @@ + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + #ifndef _GDM_SETTINGS_KEYS_H + #define _GDM_SETTINGS_KEYS_H + + #include + + G_BEGIN_DECLS + + #define GDM_KEY_USER "daemon/User" + #define GDM_KEY_GROUP "daemon/Group" + #define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable" + #define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin" + #define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable" + #define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin" + #define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay" + #define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable" ++#define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer" + #define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable" ++#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable" + + #define GDM_KEY_DEBUG "debug/Enable" + + #define GDM_KEY_INCLUDE "greeter/Include" + #define GDM_KEY_EXCLUDE "greeter/Exclude" + #define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll" + + #define GDM_KEY_DISALLOW_TCP "security/DisallowTCP" + #define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin" + + #define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable" + #define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter" + #define GDM_KEY_MAX_PENDING "xdmcp/MaxPending" + #define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions" + #define GDM_KEY_MAX_WAIT "xdmcp/MaxWait" + #define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost" + #define GDM_KEY_UDP_PORT "xdmcp/Port" + #define GDM_KEY_INDIRECT "xdmcp/HonorIndirect" + #define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect" + #define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds" + #define GDM_KEY_WILLING "xdmcp/Willing" + + #define GDM_KEY_MULTICAST "chooser/Multicast" + #define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr" + + G_END_DECLS + + #endif /* _GDM_SETTINGS_KEYS_H */ +diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c +index 7c954ad2..bd96dd03 100644 +--- a/daemon/gdm-display.c ++++ b/daemon/gdm-display.c +@@ -66,83 +66,86 @@ typedef struct _GdmDisplayPrivate + char *x11_display_name; + int status; + time_t creation_time; + + char *x11_cookie; + gsize x11_cookie_size; + GdmDisplayAccessFile *access_file; + + guint finish_idle_id; + + xcb_connection_t *xcb_connection; + int xcb_screen_number; + + GDBusConnection *connection; + GdmDisplayAccessFile *user_access_file; + + GdmDBusDisplay *display_skeleton; + GDBusObjectSkeleton *object_skeleton; + + GDBusProxy *accountsservice_proxy; + + /* this spawns and controls the greeter session */ + GdmLaunchEnvironment *launch_environment; + + guint is_local : 1; + guint is_initial : 1; + guint allow_timed_login : 1; + guint have_existing_user_accounts : 1; + guint doing_initial_setup : 1; + guint session_registered : 1; ++ ++ GStrv supported_session_types; + } GdmDisplayPrivate; + + enum { + PROP_0, + PROP_ID, + PROP_STATUS, + PROP_SEAT_ID, + PROP_SESSION_ID, + PROP_SESSION_CLASS, + PROP_SESSION_TYPE, + PROP_REMOTE_HOSTNAME, + PROP_X11_DISPLAY_NUMBER, + PROP_X11_DISPLAY_NAME, + PROP_X11_COOKIE, + PROP_X11_AUTHORITY_FILE, + PROP_IS_CONNECTED, + PROP_IS_LOCAL, + PROP_LAUNCH_ENVIRONMENT, + PROP_IS_INITIAL, + PROP_ALLOW_TIMED_LOGIN, + PROP_HAVE_EXISTING_USER_ACCOUNTS, + PROP_DOING_INITIAL_SETUP, + PROP_SESSION_REGISTERED, ++ PROP_SUPPORTED_SESSION_TYPES, + }; + + static void gdm_display_class_init (GdmDisplayClass *klass); + static void gdm_display_init (GdmDisplay *self); + static void gdm_display_finalize (GObject *object); + static void queue_finish (GdmDisplay *self); + static void _gdm_display_set_status (GdmDisplay *self, + int status); + static gboolean wants_initial_setup (GdmDisplay *self); + G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdmDisplay, gdm_display, G_TYPE_OBJECT) + + GQuark + gdm_display_error_quark (void) + { + static GQuark ret = 0; + if (ret == 0) { + ret = g_quark_from_static_string ("gdm_display_error"); + } + + return ret; + } + + time_t + gdm_display_get_creation_time (GdmDisplay *self) + { + GdmDisplayPrivate *priv; + + g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); + + priv = gdm_display_get_instance_private (self); +@@ -885,116 +888,136 @@ _gdm_display_set_launch_environment (GdmDisplay *self, + + priv = gdm_display_get_instance_private (self); + + g_clear_object (&priv->launch_environment); + + priv->launch_environment = g_object_ref (launch_environment); + } + + static void + _gdm_display_set_is_initial (GdmDisplay *self, + gboolean initial) + { + GdmDisplayPrivate *priv; + + priv = gdm_display_get_instance_private (self); + g_debug ("GdmDisplay: initial: %s", initial? "yes" : "no"); + priv->is_initial = initial; + } + + static void + _gdm_display_set_allow_timed_login (GdmDisplay *self, + gboolean allow_timed_login) + { + GdmDisplayPrivate *priv; + + priv = gdm_display_get_instance_private (self); + g_debug ("GdmDisplay: allow timed login: %s", allow_timed_login? "yes" : "no"); + priv->allow_timed_login = allow_timed_login; + } + ++static void ++_gdm_display_set_supported_session_types (GdmDisplay *self, ++ const char * const *supported_session_types) ++ ++{ ++ GdmDisplayPrivate *priv; ++ g_autofree char *supported_session_types_string = NULL; ++ ++ if (supported_session_types != NULL) ++ supported_session_types_string = g_strjoinv (":", (GStrv) supported_session_types); ++ ++ priv = gdm_display_get_instance_private (self); ++ g_debug ("GdmDisplay: supported session types: %s", supported_session_types_string); ++ g_strfreev (priv->supported_session_types); ++ priv->supported_session_types = g_strdupv ((GStrv) supported_session_types); ++} ++ + static void + gdm_display_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) + { + GdmDisplay *self; + + self = GDM_DISPLAY (object); + + switch (prop_id) { + case PROP_ID: + _gdm_display_set_id (self, g_value_get_string (value)); + break; + case PROP_STATUS: + _gdm_display_set_status (self, g_value_get_int (value)); + break; + case PROP_SEAT_ID: + _gdm_display_set_seat_id (self, g_value_get_string (value)); + break; + case PROP_SESSION_ID: + _gdm_display_set_session_id (self, g_value_get_string (value)); + break; + case PROP_SESSION_CLASS: + _gdm_display_set_session_class (self, g_value_get_string (value)); + break; + case PROP_SESSION_TYPE: + _gdm_display_set_session_type (self, g_value_get_string (value)); + break; + case PROP_REMOTE_HOSTNAME: + _gdm_display_set_remote_hostname (self, g_value_get_string (value)); + break; + case PROP_X11_DISPLAY_NUMBER: + _gdm_display_set_x11_display_number (self, g_value_get_int (value)); + break; + case PROP_X11_DISPLAY_NAME: + _gdm_display_set_x11_display_name (self, g_value_get_string (value)); + break; + case PROP_X11_COOKIE: + _gdm_display_set_x11_cookie (self, g_value_get_string (value)); + break; + case PROP_IS_LOCAL: + _gdm_display_set_is_local (self, g_value_get_boolean (value)); + break; + case PROP_ALLOW_TIMED_LOGIN: + _gdm_display_set_allow_timed_login (self, g_value_get_boolean (value)); + break; + case PROP_LAUNCH_ENVIRONMENT: + _gdm_display_set_launch_environment (self, g_value_get_object (value)); + break; + case PROP_IS_INITIAL: + _gdm_display_set_is_initial (self, g_value_get_boolean (value)); + break; + case PROP_SESSION_REGISTERED: + _gdm_display_set_session_registered (self, g_value_get_boolean (value)); + break; ++ case PROP_SUPPORTED_SESSION_TYPES: ++ _gdm_display_set_supported_session_types (self, g_value_get_boxed (value)); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static void + gdm_display_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) + { + GdmDisplay *self; + GdmDisplayPrivate *priv; + + self = GDM_DISPLAY (object); + priv = gdm_display_get_instance_private (self); + + switch (prop_id) { + case PROP_ID: + g_value_set_string (value, priv->id); + break; + case PROP_STATUS: + g_value_set_int (value, priv->status); + break; + case PROP_SEAT_ID: + g_value_set_string (value, priv->seat_id); + break; + case PROP_SESSION_ID: + g_value_set_string (value, priv->session_id); +@@ -1019,60 +1042,63 @@ gdm_display_get_property (GObject *object, + break; + case PROP_X11_AUTHORITY_FILE: + g_value_take_string (value, + priv->access_file? + gdm_display_access_file_get_path (priv->access_file) : NULL); + break; + case PROP_IS_LOCAL: + g_value_set_boolean (value, priv->is_local); + break; + case PROP_IS_CONNECTED: + g_value_set_boolean (value, priv->xcb_connection != NULL); + break; + case PROP_LAUNCH_ENVIRONMENT: + g_value_set_object (value, priv->launch_environment); + break; + case PROP_IS_INITIAL: + g_value_set_boolean (value, priv->is_initial); + break; + case PROP_HAVE_EXISTING_USER_ACCOUNTS: + g_value_set_boolean (value, priv->have_existing_user_accounts); + break; + case PROP_DOING_INITIAL_SETUP: + g_value_set_boolean (value, priv->doing_initial_setup); + break; + case PROP_SESSION_REGISTERED: + g_value_set_boolean (value, priv->session_registered); + break; + case PROP_ALLOW_TIMED_LOGIN: + g_value_set_boolean (value, priv->allow_timed_login); + break; ++ case PROP_SUPPORTED_SESSION_TYPES: ++ g_value_set_boxed (value, priv->supported_session_types); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static gboolean + handle_get_id (GdmDBusDisplay *skeleton, + GDBusMethodInvocation *invocation, + GdmDisplay *self) + { + char *id; + + gdm_display_get_id (self, &id, NULL); + + gdm_dbus_display_complete_get_id (skeleton, invocation, id); + + g_free (id); + return TRUE; + } + + static gboolean + handle_get_remote_hostname (GdmDBusDisplay *skeleton, + GDBusMethodInvocation *invocation, + GdmDisplay *self) + { + char *hostname; + + gdm_display_get_remote_hostname (self, &hostname, NULL); + +@@ -1204,60 +1230,61 @@ gdm_display_constructor (GType type, + priv = gdm_display_get_instance_private (self); + + g_free (priv->id); + priv->id = g_strdup_printf ("/org/gnome/DisplayManager/Displays/%lu", + (gulong) self); + + res = register_display (self); + if (! res) { + g_warning ("Unable to register display with system bus"); + } + + return G_OBJECT (self); + } + + static void + gdm_display_dispose (GObject *object) + { + GdmDisplay *self; + GdmDisplayPrivate *priv; + + self = GDM_DISPLAY (object); + priv = gdm_display_get_instance_private (self); + + g_debug ("GdmDisplay: Disposing display"); + + if (priv->finish_idle_id != 0) { + g_source_remove (priv->finish_idle_id); + priv->finish_idle_id = 0; + } + g_clear_object (&priv->launch_environment); ++ g_clear_pointer (&priv->supported_session_types, g_strfreev); + + g_warn_if_fail (priv->status != GDM_DISPLAY_MANAGED); + g_warn_if_fail (priv->user_access_file == NULL); + g_warn_if_fail (priv->access_file == NULL); + + G_OBJECT_CLASS (gdm_display_parent_class)->dispose (object); + } + + static void + gdm_display_class_init (GdmDisplayClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdm_display_get_property; + object_class->set_property = gdm_display_set_property; + object_class->constructor = gdm_display_constructor; + object_class->dispose = gdm_display_dispose; + object_class->finalize = gdm_display_finalize; + + klass->prepare = gdm_display_real_prepare; + + g_object_class_install_property (object_class, + PROP_ID, + g_param_spec_string ("id", + "id", + "id", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_REMOTE_HOSTNAME, +@@ -1364,60 +1391,68 @@ gdm_display_class_init (GdmDisplayClass *klass) + PROP_DOING_INITIAL_SETUP, + g_param_spec_boolean ("doing-initial-setup", + NULL, + NULL, + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_SESSION_REGISTERED, + g_param_spec_boolean ("session-registered", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_LAUNCH_ENVIRONMENT, + g_param_spec_object ("launch-environment", + NULL, + NULL, + GDM_TYPE_LAUNCH_ENVIRONMENT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_STATUS, + g_param_spec_int ("status", + "status", + "status", + -1, + G_MAXINT, + GDM_DISPLAY_UNMANAGED, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); ++ ++ g_object_class_install_property (object_class, ++ PROP_SUPPORTED_SESSION_TYPES, ++ g_param_spec_boxed ("supported-session-types", ++ "supported session types", ++ "supported session types", ++ G_TYPE_STRV, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + } + + static void + gdm_display_init (GdmDisplay *self) + { + GdmDisplayPrivate *priv; + + priv = gdm_display_get_instance_private (self); + + priv->creation_time = time (NULL); + } + + static void + gdm_display_finalize (GObject *object) + { + GdmDisplay *self; + GdmDisplayPrivate *priv; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_DISPLAY (object)); + + self = GDM_DISPLAY (object); + priv = gdm_display_get_instance_private (self); + + g_return_if_fail (priv != NULL); + + g_debug ("GdmDisplay: Finalizing display: %s", priv->id); + g_free (priv->id); + g_free (priv->seat_id); + g_free (priv->session_class); +@@ -1696,60 +1731,61 @@ gdm_display_start_greeter_session (GdmDisplay *self) + G_CALLBACK (on_launch_environment_session_opened), + self, 0); + g_signal_connect_object (priv->launch_environment, + "started", + G_CALLBACK (on_launch_environment_session_started), + self, 0); + g_signal_connect_object (priv->launch_environment, + "stopped", + G_CALLBACK (on_launch_environment_session_stopped), + self, 0); + g_signal_connect_object (priv->launch_environment, + "exited", + G_CALLBACK (on_launch_environment_session_exited), + self, 0); + g_signal_connect_object (priv->launch_environment, + "died", + G_CALLBACK (on_launch_environment_session_died), + self, 0); + + if (auth_file != NULL) { + g_object_set (priv->launch_environment, + "x11-authority-file", auth_file, + NULL); + } + + gdm_launch_environment_start (priv->launch_environment); + + session = gdm_launch_environment_get_session (priv->launch_environment); + g_object_set (G_OBJECT (session), + "display-is-initial", priv->is_initial, ++ "supported-session-types", priv->supported_session_types, + NULL); + + g_free (display_name); + g_free (seat_id); + g_free (hostname); + g_free (auth_file); + } + + void + gdm_display_stop_greeter_session (GdmDisplay *self) + { + GdmDisplayPrivate *priv; + + priv = gdm_display_get_instance_private (self); + + if (priv->launch_environment != NULL) { + + g_signal_handlers_disconnect_by_func (priv->launch_environment, + G_CALLBACK (on_launch_environment_session_opened), + self); + g_signal_handlers_disconnect_by_func (priv->launch_environment, + G_CALLBACK (on_launch_environment_session_started), + self); + g_signal_handlers_disconnect_by_func (priv->launch_environment, + G_CALLBACK (on_launch_environment_session_stopped), + self); + g_signal_handlers_disconnect_by_func (priv->launch_environment, + G_CALLBACK (on_launch_environment_session_exited), + self); + g_signal_handlers_disconnect_by_func (priv->launch_environment, +diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c +index feccf057..5044290c 100644 +--- a/daemon/gdm-launch-environment.c ++++ b/daemon/gdm-launch-environment.c +@@ -117,60 +117,61 @@ static GHashTable * + build_launch_environment (GdmLaunchEnvironment *launch_environment, + gboolean start_session) + { + GHashTable *hash; + struct passwd *pwent; + static const char *const optional_environment[] = { + "GI_TYPELIB_PATH", + "LANG", + "LANGUAGE", + "LC_ADDRESS", + "LC_ALL", + "LC_COLLATE", + "LC_CTYPE", + "LC_IDENTIFICATION", + "LC_MEASUREMENT", + "LC_MESSAGES", + "LC_MONETARY", + "LC_NAME", + "LC_NUMERIC", + "LC_PAPER", + "LC_TELEPHONE", + "LC_TIME", + "LD_LIBRARY_PATH", + "PATH", + "WINDOWPATH", + "XCURSOR_PATH", + "XDG_CONFIG_DIRS", + NULL + }; + char *system_data_dirs; ++ g_auto (GStrv) supported_session_types = NULL; + int i; + + /* create a hash table of current environment, then update keys has necessary */ + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + for (i = 0; optional_environment[i] != NULL; i++) { + if (g_getenv (optional_environment[i]) == NULL) { + continue; + } + + g_hash_table_insert (hash, + g_strdup (optional_environment[i]), + g_strdup (g_getenv (optional_environment[i]))); + } + + system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ()); + + g_hash_table_insert (hash, + g_strdup ("XDG_DATA_DIRS"), + g_strdup_printf ("%s:%s", + DATADIR "/gdm/greeter", + system_data_dirs)); + g_free (system_data_dirs); + + if (launch_environment->priv->x11_authority_file != NULL) + g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (launch_environment->priv->x11_authority_file)); + + if (launch_environment->priv->session_mode != NULL) { + g_hash_table_insert (hash, g_strdup ("GNOME_SHELL_SESSION_MODE"), g_strdup (launch_environment->priv->session_mode)); + +@@ -191,60 +192,68 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment, + g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (launch_environment->priv->user_name)); + g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (launch_environment->priv->user_name)); + + g_hash_table_insert (hash, g_strdup ("GDM_VERSION"), g_strdup (VERSION)); + g_hash_table_remove (hash, "MAIL"); + + g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/")); + g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/")); + g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh")); + + gdm_get_pwent_for_name (launch_environment->priv->user_name, &pwent); + if (pwent != NULL) { + if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') { + g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir)); + g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup (pwent->pw_dir)); + } + + g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (pwent->pw_shell)); + } + + if (start_session && launch_environment->priv->x11_display_seat_id != NULL) { + char *seat_id; + + seat_id = launch_environment->priv->x11_display_seat_id; + + g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id)); + } + + g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true")); + ++ g_object_get (launch_environment->priv->session, ++ "supported-session-types", ++ &supported_session_types, ++ NULL); ++ g_hash_table_insert (hash, ++ g_strdup ("GDM_SUPPORTED_SESSION_TYPES"), ++ g_strjoinv (":", supported_session_types)); ++ + return hash; + } + + static void + on_session_setup_complete (GdmSession *session, + const char *service_name, + GdmLaunchEnvironment *launch_environment) + { + GHashTable *hash; + GHashTableIter iter; + gpointer key, value; + + hash = build_launch_environment (launch_environment, TRUE); + + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, &key, &value)) { + gdm_session_set_environment_variable (launch_environment->priv->session, key, value); + } + g_hash_table_destroy (hash); + } + + static void + on_session_opened (GdmSession *session, + const char *service_name, + const char *session_id, + GdmLaunchEnvironment *launch_environment) + { + launch_environment->priv->session_id = g_strdup (session_id); + + g_signal_emit (G_OBJECT (launch_environment), signals [OPENED], 0); +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 8a4ef06c..eba38671 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -156,126 +156,287 @@ take_next_display_number (GdmLocalDisplayFactory *factory) + + g_debug ("GdmLocalDisplayFactory: Found the following X displays:"); + for (l = list; l != NULL; l = l->next) { + g_debug ("GdmLocalDisplayFactory: %u", GPOINTER_TO_UINT (l->data)); + } + + for (l = list; l != NULL; l = l->next) { + guint32 num; + num = GPOINTER_TO_UINT (l->data); + + /* always fill zero */ + if (l->prev == NULL && num != 0) { + ret = 0; + break; + } + /* now find the first hole */ + if (l->next == NULL || GPOINTER_TO_UINT (l->next->data) != (num + 1)) { + ret = num + 1; + break; + } + } + out: + + /* now reserve this number */ + g_debug ("GdmLocalDisplayFactory: Reserving X display: %u", ret); + g_hash_table_insert (factory->used_display_numbers, GUINT_TO_POINTER (ret), NULL); + + return ret; + } + ++static char * ++get_preferred_display_server (GdmLocalDisplayFactory *factory) ++{ ++ g_autofree gchar *preferred_display_server = NULL; ++ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE; ++ ++ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled); ++ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled); ++ ++ if (wayland_enabled && !xorg_enabled) { ++ return g_strdup ("wayland"); ++ } ++ ++ if (!wayland_enabled && !xorg_enabled) { ++ return g_strdup ("none"); ++ } ++ ++ gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server); ++ ++ if (g_strcmp0 (preferred_display_server, "wayland") == 0) { ++ if (wayland_enabled) ++ return g_strdup (preferred_display_server); ++ else ++ return g_strdup ("xorg"); ++ } ++ ++ if (g_strcmp0 (preferred_display_server, "xorg") == 0) { ++ if (xorg_enabled) ++ return g_strdup (preferred_display_server); ++ else ++ return g_strdup ("wayland"); ++ } ++ ++ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { ++ if (xorg_enabled) ++ return g_strdup (preferred_display_server); ++ } ++ ++ return g_strdup ("none"); ++} ++ ++struct GdmDisplayServerConfiguration { ++ const char *display_server; ++ const char *key; ++ const char *binary; ++ const char *session_type; ++} display_server_configuration[] = { ++#ifdef ENABLE_WAYLAND_SUPPORT ++ { "wayland", GDM_KEY_WAYLAND_ENABLE, "/usr/bin/Xwayland", "wayland" }, ++#endif ++ { "xorg", GDM_KEY_XORG_ENABLE, "/usr/bin/Xorg", "x11" }, ++ { NULL, NULL, NULL }, ++}; ++ ++static gboolean ++display_server_enabled (GdmLocalDisplayFactory *factory, ++ const char *display_server) ++{ ++ size_t i; ++ ++ for (i = 0; display_server_configuration[i].display_server != NULL; i++) { ++ const char *key = display_server_configuration[i].key; ++ const char *binary = display_server_configuration[i].binary; ++ gboolean enabled = FALSE; ++ ++ if (!g_str_equal (display_server_configuration[i].display_server, ++ display_server)) ++ continue; ++ ++ if (!gdm_settings_direct_get_boolean (key, &enabled) || !enabled) ++ return FALSE; ++ ++ if (!g_file_test (binary, G_FILE_TEST_IS_EXECUTABLE)) ++ return FALSE; ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++static const char * ++get_session_type_for_display_server (GdmLocalDisplayFactory *factory, ++ const char *display_server) ++{ ++ size_t i; ++ ++ for (i = 0; display_server_configuration[i].display_server != NULL; i++) { ++ if (!g_str_equal (display_server_configuration[i].display_server, ++ display_server)) ++ continue; ++ ++ return display_server_configuration[i].session_type; ++ } ++ ++ return NULL; ++} ++ ++static char ** ++gdm_local_display_factory_get_session_types (GdmLocalDisplayFactory *factory, ++ gboolean should_fall_back) ++{ ++ g_autofree gchar *preferred_display_server = NULL; ++ const char *fallback_display_server = NULL; ++ gboolean wayland_preferred = FALSE; ++ gboolean xorg_preferred = FALSE; ++ g_autoptr (GPtrArray) session_types_array = NULL; ++ char **session_types; ++ ++ session_types_array = g_ptr_array_new (); ++ ++ preferred_display_server = get_preferred_display_server (factory); ++ ++ g_debug ("GdmLocalDisplayFactory: Getting session type (prefers %s, falling back: %s)", ++ preferred_display_server, should_fall_back? "yes" : "no"); ++ ++ wayland_preferred = g_str_equal (preferred_display_server, "wayland"); ++ xorg_preferred = g_str_equal (preferred_display_server, "xorg"); ++ ++ if (wayland_preferred) ++ fallback_display_server = "xorg"; ++ else if (xorg_preferred) ++ fallback_display_server = "wayland"; ++ else ++ return NULL; ++ ++ if (!should_fall_back) { ++ if (display_server_enabled (factory, preferred_display_server)) ++ g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, preferred_display_server)); ++ } ++ ++ if (display_server_enabled (factory, fallback_display_server)) ++ g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, fallback_display_server)); ++ ++ if (session_types_array->len == 0) ++ return NULL; ++ ++ g_ptr_array_add (session_types_array, NULL); ++ ++ session_types = g_strdupv ((char **) session_types_array->pdata); ++ ++ return session_types; ++} ++ + static void + on_display_disposed (GdmLocalDisplayFactory *factory, + GdmDisplay *display) + { + g_debug ("GdmLocalDisplayFactory: Display %p disposed", display); + } + + static void + store_display (GdmLocalDisplayFactory *factory, + GdmDisplay *display) + { + GdmDisplayStore *store; + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + gdm_display_store_add (store, display); + } + +-static gboolean +-gdm_local_display_factory_use_wayland (void) +-{ +-#ifdef ENABLE_WAYLAND_SUPPORT +- gboolean wayland_enabled = FALSE; +- if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { +- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) +- return TRUE; +- } +-#endif +- return FALSE; +-} +- + /* + Example: + dbus-send --system --dest=org.gnome.DisplayManager \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/gnome/DisplayManager/Manager \ + org.gnome.DisplayManager.Manager.GetDisplays + */ + gboolean + gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory, + char **id, + GError **error) + { + gboolean ret; + GdmDisplay *display = NULL; + gboolean is_initial = FALSE; ++ const char *session_type; ++ g_autofree gchar *preferred_display_server = NULL; + + g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); + + ret = FALSE; + + g_debug ("GdmLocalDisplayFactory: Creating transient display"); + +-#ifdef ENABLE_USER_DISPLAY_SERVER +- display = gdm_local_display_new (); +- if (gdm_local_display_factory_use_wayland ()) +- g_object_set (G_OBJECT (display), "session-type", "wayland", NULL); +- is_initial = TRUE; +-#else +- if (display == NULL) { +- guint32 num; ++ preferred_display_server = get_preferred_display_server (factory); + +- num = take_next_display_number (factory); ++#ifdef ENABLE_USER_DISPLAY_SERVER ++ if (g_strcmp0 (preferred_display_server, "wayland") == 0 || ++ g_strcmp0 (preferred_display_server, "xorg") == 0) { ++ g_auto(GStrv) session_types = NULL; ++ ++ session_types = gdm_local_display_factory_get_session_types (factory, FALSE); ++ ++ if (session_types == NULL) { ++ g_set_error_literal (error, ++ GDM_DISPLAY_ERROR, ++ GDM_DISPLAY_ERROR_GENERAL, ++ "Both Wayland and Xorg are unavailable"); ++ return FALSE; ++ } + +- display = gdm_legacy_display_new (num); ++ display = gdm_local_display_new (); ++ g_object_set (G_OBJECT (display), ++ "session-type", session_types[0], ++ "supported-session-tyes", session_types, ++ NULL); ++ is_initial = TRUE; + } + #endif ++ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { ++ if (display == NULL) { ++ guint32 num; ++ ++ num = take_next_display_number (factory); ++ ++ display = gdm_legacy_display_new (num); ++ } ++ } ++ ++ if (display == NULL) { ++ g_set_error_literal (error, ++ GDM_DISPLAY_ERROR, ++ GDM_DISPLAY_ERROR_GENERAL, ++ "Invalid preferred display server configured"); ++ return FALSE; ++ } + + g_object_set (display, + "seat-id", "seat0", + "allow-timed-login", FALSE, + "is-initial", is_initial, + NULL); + + 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 + finish_display_on_seat_if_waiting (GdmDisplayStore *display_store, + GdmDisplay *display, +@@ -450,194 +611,220 @@ lookup_prepared_display_by_seat_id (const char *id, + + if (status != GDM_DISPLAY_PREPARED) + return FALSE; + + return lookup_by_seat_id (id, display, user_data); + } + + static int + on_seat0_graphics_check_timeout (gpointer user_data) + { + GdmLocalDisplayFactory *factory = user_data; + + factory->seat0_graphics_check_timeout_id = 0; + + /* Simply try to re-add seat0. If it is there already (i.e. CanGraphical + * turned TRUE, then we'll find it and it will not be created again). + */ + factory->seat0_graphics_check_timed_out = TRUE; + ensure_display_for_seat (factory, "seat0"); + + return G_SOURCE_REMOVE; + } + + static void + ensure_display_for_seat (GdmLocalDisplayFactory *factory, + const char *seat_id) + { + int ret; + gboolean seat_supports_graphics; + gboolean is_seat0; +- const char *session_type = "wayland"; ++ g_auto (GStrv) session_types = NULL; ++ const char *legacy_session_types[] = { "x11", NULL }; + GdmDisplayStore *store; + GdmDisplay *display = NULL; + g_autofree char *login_session_id = NULL; ++ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE; ++ g_autofree gchar *preferred_display_server = NULL; ++ gboolean falling_back = FALSE; ++ ++ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled); ++ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled); ++ ++ preferred_display_server = get_preferred_display_server (factory); ++ ++ if (g_strcmp0 (preferred_display_server, "none") == 0) { ++ g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display"); ++ return; ++ } + + ret = sd_seat_can_graphical (seat_id); + + if (ret < 0) { + g_critical ("Failed to query CanGraphical information for seat %s", seat_id); + return; + } + + if (ret == 0) { + g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics"); + seat_supports_graphics = FALSE; + } else { + g_debug ("GdmLocalDisplayFactory: System supports graphics"); + seat_supports_graphics = TRUE; + } + + if (g_strcmp0 (seat_id, "seat0") == 0) { + is_seat0 = TRUE; + +- /* If we've failed, or are explicitly told to, fall back to legacy X11 support +- */ +- if (factory->num_failures > 0 || !gdm_local_display_factory_use_wayland ()) { +- session_type = NULL; +- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use X11 fallback"); +- } else { +- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use wayland"); +- } ++ falling_back = factory->num_failures > 0; ++ session_types = gdm_local_display_factory_get_session_types (factory, falling_back); ++ ++ g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s", ++ session_types[0], falling_back? " fallback" : ""); + } else { + is_seat0 = FALSE; + + g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id); + /* Force legacy X11 for all auxiliary seats */ + seat_supports_graphics = TRUE; +- session_type = NULL; ++ session_types = g_strdupv ((char **) legacy_session_types); + } + + /* For seat0, we have a fallback logic to still try starting it after + * SEAT0_GRAPHICS_CHECK_TIMEOUT seconds. i.e. we simply continue even if + * CanGraphical is unset. + * This is ugly, but it means we'll come up eventually in some + * scenarios where no master device is present. + * Note that we'll force an X11 fallback even though there might be + * cases where an wayland capable device is present and simply not marked as + * master-of-seat. In these cases, this should likely be fixed in the + * udev rules. + * + * At the moment, systemd always sets CanGraphical for non-seat0 seats. + * This is because non-seat0 seats are defined by having master-of-seat + * set. This means we can avoid the fallback check for non-seat0 seats, + * which simplifies the code. + */ + if (is_seat0) { + if (!seat_supports_graphics) { + if (!factory->seat0_graphics_check_timed_out) { + if (factory->seat0_graphics_check_timeout_id == 0) { + g_debug ("GdmLocalDisplayFactory: seat0 doesn't yet support graphics. Waiting %d seconds to try again.", SEAT0_GRAPHICS_CHECK_TIMEOUT); + factory->seat0_graphics_check_timeout_id = g_timeout_add_seconds (SEAT0_GRAPHICS_CHECK_TIMEOUT, + on_seat0_graphics_check_timeout, + factory); + + } else { + /* It is not yet time to force X11 fallback. */ + g_debug ("GdmLocalDisplayFactory: seat0 display requested when there is no graphics support before graphics check timeout."); + } + + return; + } + + g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!"); + g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev."); + seat_supports_graphics = TRUE; +- session_type = NULL; ++ wayland_enabled = FALSE; ++ g_strfreev (session_types); ++ session_types = g_strdupv ((char **) legacy_session_types); + } else { + g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove); + } + } + + if (!seat_supports_graphics) + return; + +- g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", +- session_type? : "X11", seat_id); ++ if (session_types != NULL) ++ g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", ++ session_types[0], seat_id); ++ else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) ++ g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested", ++ seat_id); ++ + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + if (is_seat0) + display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); + else + display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); + + /* Ensure we don't create the same display more than once */ + if (display != NULL) { + g_debug ("GdmLocalDisplayFactory: display already created"); + return; + } + + /* If we already have a login window, switch to it */ + if (gdm_get_login_window_session_id (seat_id, &login_session_id)) { + GdmDisplay *display; + + display = gdm_display_store_find (store, + lookup_by_session_id, + (gpointer) login_session_id); + if (display != NULL && + (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED || + gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) { + g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); + g_debug ("GdmLocalDisplayFactory: session %s found, activating.", + login_session_id); + gdm_activate_session_by_id (factory->connection, seat_id, login_session_id); + return; + } + } + + g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); + + #ifdef ENABLE_USER_DISPLAY_SERVER +- if (is_seat0) { +- display = gdm_local_display_new (); +- if (session_type != NULL) { +- g_object_set (G_OBJECT (display), "session-type", session_type, NULL); ++ if (g_strcmp0 (preferred_display_server, "wayland") == 0 || ++ g_strcmp0 (preferred_display_server, "xorg") == 0) { ++ if (is_seat0) { ++ display = gdm_local_display_new (); ++ g_object_set (G_OBJECT (display), ++ "session-type", session_types[0], ++ "supported-session-types", session_types, ++ NULL); + } + } + #endif + + if (display == NULL) { + guint32 num; + + num = take_next_display_number (factory); + + display = gdm_legacy_display_new (num); ++ g_object_set (G_OBJECT (display), ++ "session-type", legacy_session_types[0], ++ "supported-session-types", legacy_session_types, ++ NULL); + } + + g_object_set (display, "seat-id", seat_id, NULL); + g_object_set (display, "is-initial", is_seat0, NULL); + + store_display (factory, display); + + /* let store own the ref */ + g_object_unref (display); + + if (! gdm_display_manage (display)) { + gdm_display_unmanage (display); + } + + return; + } + + static void + delete_display (GdmLocalDisplayFactory *factory, + const char *seat_id) { + + GdmDisplayStore *store; + + g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id); + } + + static gboolean +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 9c10adff..24219691 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1306,74 +1306,75 @@ get_automatic_login_details (GdmManager *manager, + *usernamep = username; + } else { + g_free (username); + } + + return enabled; + } + + static const char * + get_username_for_greeter_display (GdmManager *manager, + GdmDisplay *display) + { + gboolean doing_initial_setup = FALSE; + + g_object_get (G_OBJECT (display), + "doing-initial-setup", &doing_initial_setup, + NULL); + + if (doing_initial_setup) { + return INITIAL_SETUP_USERNAME; + } else { + return GDM_USERNAME; + } + } + + static void + set_up_automatic_login_session (GdmManager *manager, + GdmDisplay *display) + { + GdmSession *session; +- char *display_session_type = NULL; ++ g_auto (GStrv) supported_session_types = NULL; + + /* 0 is root user; since the daemon talks to the session object + * directly, itself, for automatic login + */ + create_user_session_for_display (manager, display, 0); + session = get_user_session_for_display (display); + + g_object_get (G_OBJECT (display), +- "session-type", &display_session_type, ++ "supported-session-types", &supported_session_types, + NULL); + + g_object_set (G_OBJECT (session), + "display-is-initial", FALSE, ++ "supported-session-types", supported_session_types, + NULL); + + g_debug ("GdmManager: Starting automatic login conversation"); + gdm_session_start_conversation (session, "gdm-autologin"); + } + + static void + set_up_chooser_session (GdmManager *manager, + GdmDisplay *display) + { + const char *allowed_user; + struct passwd *passwd_entry; + + allowed_user = get_username_for_greeter_display (manager, display); + + if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) { + g_warning ("GdmManager: couldn't look up username %s", + allowed_user); + gdm_display_unmanage (display); + gdm_display_finish (display); + return; + } + + gdm_display_start_greeter_session (display); + } + + static void + set_up_greeter_session (GdmManager *manager, + GdmDisplay *display) + { +@@ -2278,87 +2279,83 @@ on_session_reauthentication_started (GdmSession *session, + + if (invocation != NULL) { + g_hash_table_steal (manager->priv->open_reauthentication_requests, + source_tag); + gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), + invocation, + address); + } + } + + static void + clean_user_session (GdmSession *session) + { + g_object_set_data (G_OBJECT (session), "gdm-display", NULL); + g_object_unref (session); + } + + static void + create_user_session_for_display (GdmManager *manager, + GdmDisplay *display, + uid_t allowed_user) + { + GdmSession *session; + gboolean display_is_local = FALSE; + char *display_name = NULL; + char *display_device = NULL; + char *remote_hostname = NULL; + char *display_auth_file = NULL; + char *display_seat_id = NULL; + char *display_id = NULL; +-#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) +- g_autofree char *display_session_type = NULL; +- gboolean greeter_is_wayland; +-#endif ++ g_auto (GStrv) supported_session_types = NULL; + + g_object_get (G_OBJECT (display), + "id", &display_id, + "x11-display-name", &display_name, + "is-local", &display_is_local, + "remote-hostname", &remote_hostname, + "x11-authority-file", &display_auth_file, + "seat-id", &display_seat_id, +-#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) +- "session-type", &display_session_type, +-#endif ++ "supported-session-types", &supported_session_types, + NULL); + display_device = get_display_device (manager, display); + + session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN, + allowed_user, + display_name, + remote_hostname, + display_device, + display_seat_id, + display_auth_file, + display_is_local, + NULL); ++ g_object_set (G_OBJECT (session), "supported-session-types", supported_session_types, NULL); + + g_debug ("GdmSession: Created user session for user %d on display %s (seat %s)", + (int) allowed_user, + display_id, + display_seat_id); + + g_free (display_name); + g_free (remote_hostname); + g_free (display_auth_file); + g_free (display_seat_id); + + g_signal_connect (session, + "reauthentication-started", + G_CALLBACK (on_session_reauthentication_started), + manager); + g_signal_connect (session, + "reauthenticated", + G_CALLBACK (on_session_reauthenticated), + manager); + g_signal_connect (session, + "client-ready-for-session-to-start", + G_CALLBACK (on_session_client_ready_for_session_to_start), + manager); + g_signal_connect (session, + "client-connected", + G_CALLBACK (on_session_client_connected), + manager); + g_signal_connect (session, + "client-disconnected", + G_CALLBACK (on_session_client_disconnected), +@@ -2378,65 +2375,60 @@ create_user_session_for_display (GdmManager *manager, + g_signal_connect (session, + "authentication-failed", + G_CALLBACK (on_session_authentication_failed), + manager); + g_signal_connect (session, + "session-opened", + G_CALLBACK (on_user_session_opened), + manager); + g_signal_connect (session, + "session-started", + G_CALLBACK (on_user_session_started), + manager); + g_signal_connect (session, + "session-start-failed", + G_CALLBACK (on_session_start_failed), + manager); + g_signal_connect (session, + "session-exited", + G_CALLBACK (on_user_session_exited), + manager); + g_signal_connect (session, + "session-died", + G_CALLBACK (on_user_session_died), + manager); + g_object_set_data (G_OBJECT (session), "gdm-display", display); + g_object_set_data_full (G_OBJECT (display), + "gdm-user-session", + session, + (GDestroyNotify) + clean_user_session); +- +-#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) +- greeter_is_wayland = g_strcmp0 (display_session_type, "wayland") == 0; +- g_object_set (G_OBJECT (session), "ignore-wayland", !greeter_is_wayland, NULL); +-#endif + } + + static void + on_display_added (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_export (manager->priv->object_manager, + gdm_display_get_object_skeleton (display)); + + g_signal_connect (display, "notify::status", + G_CALLBACK (on_display_status_changed), + manager); + g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id); + } + } + + GQuark + gdm_manager_error_quark (void) + { + static GQuark ret = 0; + if (ret == 0) { + ret = g_quark_from_static_string ("gdm_manager_error"); + } + +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index 5c5903a4..7b0ade1e 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -105,100 +105,98 @@ struct _GdmSession + GdmDBusUserVerifier *user_verifier_interface; + GHashTable *user_verifier_extensions; + GdmDBusGreeter *greeter_interface; + GdmDBusRemoteGreeter *remote_greeter_interface; + GdmDBusChooser *chooser_interface; + + GList *pending_worker_connections; + GList *outside_connections; + + GPid session_pid; + + /* object lifetime scope */ + char *session_type; + char *display_name; + char *display_hostname; + char *display_device; + char *display_seat_id; + char *display_x11_authority_file; + gboolean display_is_local; + + GdmSessionVerificationMode verification_mode; + + uid_t allowed_user; + + char *fallback_session_name; + + GDBusServer *worker_server; + GDBusServer *outside_server; + GHashTable *environment; + ++ GStrv supported_session_types; ++ + guint32 is_program_session : 1; + guint32 display_is_initial : 1; +-#ifdef ENABLE_WAYLAND_SUPPORT +- guint32 ignore_wayland : 1; +-#endif + }; + + enum { + PROP_0, + PROP_VERIFICATION_MODE, + PROP_ALLOWED_USER, + PROP_DISPLAY_NAME, + PROP_DISPLAY_HOSTNAME, + PROP_DISPLAY_IS_LOCAL, + PROP_DISPLAY_IS_INITIAL, + PROP_SESSION_TYPE, + PROP_DISPLAY_DEVICE, + PROP_DISPLAY_SEAT_ID, + PROP_DISPLAY_X11_AUTHORITY_FILE, + PROP_USER_X11_AUTHORITY_FILE, + PROP_CONVERSATION_ENVIRONMENT, +-#ifdef ENABLE_WAYLAND_SUPPORT +- PROP_IGNORE_WAYLAND, +-#endif ++ PROP_SUPPORTED_SESSION_TYPES, + }; + + enum { + CONVERSATION_STARTED = 0, + CONVERSATION_STOPPED, + SETUP_COMPLETE, + CANCELLED, + HOSTNAME_SELECTED, + CLIENT_REJECTED, + CLIENT_CONNECTED, + CLIENT_DISCONNECTED, + CLIENT_READY_FOR_SESSION_TO_START, + DISCONNECTED, + AUTHENTICATION_FAILED, + VERIFICATION_COMPLETE, + SESSION_OPENED, ++ SESSION_OPENED_FAILED, + SESSION_STARTED, + SESSION_START_FAILED, + SESSION_EXITED, + SESSION_DIED, + REAUTHENTICATION_STARTED, + REAUTHENTICATED, + LAST_SIGNAL + }; + + #ifdef ENABLE_WAYLAND_SUPPORT + static gboolean gdm_session_is_wayland_session (GdmSession *self); + #endif + static void update_session_type (GdmSession *self); + static void set_session_type (GdmSession *self, + const char *session_type); + static void close_conversation (GdmSessionConversation *conversation); + + static guint signals [LAST_SIGNAL] = { 0, }; + + G_DEFINE_TYPE (GdmSession, + gdm_session, + G_TYPE_OBJECT); + + static GdmSessionConversation * + find_conversation_by_name (GdmSession *self, + const char *service_name) + { + GdmSessionConversation *conversation; + + conversation = g_hash_table_lookup (self->conversations, service_name); +@@ -295,128 +293,136 @@ on_authorize_cb (GdmDBusWorker *proxy, + + if (worked) { + gdm_session_accredit (self, service_name); + } else { + report_and_stop_conversation (self, service_name, error); + } + } + + static void + on_establish_credentials_cb (GdmDBusWorker *proxy, + GAsyncResult *res, + gpointer user_data) + { + GdmSessionConversation *conversation = user_data; + GdmSession *self; + char *service_name; + + GError *error = NULL; + gboolean worked; + + worked = gdm_dbus_worker_call_establish_credentials_finish (proxy, res, &error); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = g_object_ref (conversation->session); + service_name = g_strdup (conversation->service_name); + + if (worked) { +- if (self->user_verifier_interface != NULL) { +- gdm_dbus_user_verifier_emit_verification_complete (self->user_verifier_interface, +- service_name); +- g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name); +- } +- + switch (self->verification_mode) { + case GDM_SESSION_VERIFICATION_MODE_LOGIN: + case GDM_SESSION_VERIFICATION_MODE_CHOOSER: + gdm_session_open_session (self, service_name); + break; + case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE: ++ if (self->user_verifier_interface != NULL) { ++ gdm_dbus_user_verifier_emit_verification_complete (self->user_verifier_interface, ++ service_name); ++ g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name); ++ } ++ break; + default: + break; + } + } else { + report_and_stop_conversation (self, service_name, error); + } + + g_free (service_name); + g_object_unref (self); + } + ++static gboolean ++supports_session_type (GdmSession *self, ++ const char *session_type) ++{ ++ if (session_type == NULL) ++ return TRUE; ++ ++ return g_strv_contains ((const char * const *) self->supported_session_types, ++ session_type); ++} ++ + static char ** + get_system_session_dirs (GdmSession *self) + { + GArray *search_array = NULL; + char **search_dirs; +- int i; ++ int i, j; + const gchar * const *system_data_dirs = g_get_system_data_dirs (); + + static const char *x_search_dirs[] = { + "/etc/X11/sessions/", + DMCONFDIR "/Sessions/", + DATADIR "/gdm/BuiltInSessions/", + DATADIR "/xsessions/", + }; + + static const char *wayland_search_dir = DATADIR "/wayland-sessions/"; + + search_array = g_array_new (TRUE, TRUE, sizeof (char *)); + +- for (i = 0; system_data_dirs[i]; i++) { +- gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL); +- g_array_append_val (search_array, dir); +- } ++ for (j = 0; self->supported_session_types[j] != NULL; j++) { ++ const char *supported_type = self->supported_session_types[j]; + +- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); ++ if (g_str_equal (supported_type, "x11")) { ++ for (i = 0; system_data_dirs[i]; i++) { ++ gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL); ++ g_array_append_val (search_array, dir); ++ } ++ ++ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); ++ } + + #ifdef ENABLE_WAYLAND_SUPPORT +- if (!self->ignore_wayland) { +-#ifdef ENABLE_USER_DISPLAY_SERVER +- g_array_prepend_val (search_array, wayland_search_dir); ++ if (g_str_equal (supported_type, "wayland")) { ++ for (i = 0; system_data_dirs[i]; i++) { ++ gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); ++ g_array_append_val (search_array, dir); ++ } + +- for (i = 0; system_data_dirs[i]; i++) { +- gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); +- g_array_insert_val (search_array, i, dir); +- } +-#else +- for (i = 0; system_data_dirs[i]; i++) { +- gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); +- g_array_append_val (search_array, dir); ++ g_array_append_val (search_array, wayland_search_dir); + } +- +- g_array_append_val (search_array, wayland_search_dir); + #endif + } +-#endif + + search_dirs = g_strdupv ((char **) search_array->data); + + g_array_free (search_array, TRUE); + + return search_dirs; + } + + static gboolean + is_prog_in_path (const char *prog) + { + char *f; + gboolean ret; + + f = g_find_program_in_path (prog); + ret = (f != NULL); + g_free (f); + return ret; + } + + static GKeyFile * + load_key_file_for_file (GdmSession *self, + const char *file, + char **full_path) + { + GKeyFile *key_file; + GError *error; + gboolean res; + char **search_dirs; + +@@ -839,78 +845,78 @@ static void + on_opened (GdmDBusWorker *worker, + GAsyncResult *res, + gpointer user_data) + { + GdmSessionConversation *conversation = user_data; + GdmSession *self; + char *service_name; + + GError *error = NULL; + gboolean worked; + char *session_id; + + worked = gdm_dbus_worker_call_open_finish (worker, + &session_id, + res, + &error); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = conversation->session; + service_name = conversation->service_name; + + if (worked) { + g_clear_pointer (&conversation->session_id, + (GDestroyNotify) g_free); + + conversation->session_id = g_strdup (session_id); + +- if (self->greeter_interface != NULL) { +- gdm_dbus_greeter_emit_session_opened (self->greeter_interface, +- service_name); +- } +- + if (self->user_verifier_interface != NULL) { + gdm_dbus_user_verifier_emit_verification_complete (self->user_verifier_interface, + service_name); + g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name); + } + ++ if (self->greeter_interface != NULL) { ++ gdm_dbus_greeter_emit_session_opened (self->greeter_interface, ++ service_name); ++ } ++ + g_debug ("GdmSession: Emitting 'session-opened' signal"); + g_signal_emit (self, signals[SESSION_OPENED], 0, service_name, session_id); + } else { + report_and_stop_conversation (self, service_name, error); + + g_debug ("GdmSession: Emitting 'session-start-failed' signal"); +- g_signal_emit (self, signals[SESSION_START_FAILED], 0, service_name, error->message); ++ g_signal_emit (self, signals[SESSION_OPENED_FAILED], 0, service_name, error->message); + } + } + + static void + worker_on_username_changed (GdmDBusWorker *worker, + const char *username, + GdmSessionConversation *conversation) + { + GdmSession *self = conversation->session; + + g_debug ("GdmSession: changing username from '%s' to '%s'", + self->selected_user != NULL ? self->selected_user : "", + (strlen (username)) ? username : ""); + + gdm_session_select_user (self, (strlen (username) > 0) ? g_strdup (username) : NULL); + gdm_session_defaults_changed (self); + } + + static void + worker_on_session_exited (GdmDBusWorker *worker, + const char *service_name, + int status, + GdmSessionConversation *conversation) + { + GdmSession *self = conversation->session; + + self->session_conversation = NULL; + + if (WIFEXITED (status)) { + g_debug ("GdmSession: Emitting 'session-exited' signal with exit code '%d'", +@@ -968,73 +974,76 @@ worker_on_reauthenticated (GdmDBusWorker *worker, + static void + worker_on_saved_language_name_read (GdmDBusWorker *worker, + const char *language_name, + GdmSessionConversation *conversation) + { + GdmSession *self = conversation->session; + + if (strlen (language_name) > 0) { + g_free (self->saved_language); + self->saved_language = g_strdup (language_name); + + if (self->greeter_interface != NULL) { + gdm_dbus_greeter_emit_default_language_name_changed (self->greeter_interface, + language_name); + } + } + } + + static void + worker_on_saved_session_name_read (GdmDBusWorker *worker, + const char *session_name, + GdmSessionConversation *conversation) + { + GdmSession *self = conversation->session; + + if (! get_session_command_for_name (self, session_name, NULL)) { + /* ignore sessions that don't exist */ + g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name); + g_free (self->saved_session); + self->saved_session = NULL; +- } else if (strcmp (session_name, +- get_default_session_name (self)) != 0) { +- g_free (self->saved_session); +- self->saved_session = g_strdup (session_name); +- +- if (self->greeter_interface != NULL) { +- gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface, +- session_name); ++ update_session_type (self); ++ } else { ++ if (strcmp (session_name, ++ get_default_session_name (self)) != 0) { ++ g_free (self->saved_session); ++ self->saved_session = g_strdup (session_name); ++ ++ if (self->greeter_interface != NULL) { ++ gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface, ++ session_name); ++ } + } ++ if (self->saved_session_type != NULL) ++ set_session_type (self, self->saved_session_type); + } + +- update_session_type (self); +- + } + + static GdmSessionConversation * + find_conversation_by_pid (GdmSession *self, + GPid pid) + { + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, self->conversations); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionConversation *conversation; + + conversation = (GdmSessionConversation *) value; + + if (conversation->worker_pid == pid) { + return conversation; + } + } + + return NULL; + } + + static gboolean + allow_worker_function (GDBusAuthObserver *observer, + GIOStream *stream, + GCredentials *credentials, + GdmSession *self) + { + uid_t connecting_user; +@@ -2197,68 +2206,72 @@ close_conversation (GdmSessionConversation *conversation) + + if (conversation->worker_manager_interface != NULL) { + unexport_worker_manager_interface (self, conversation->worker_manager_interface); + g_clear_object (&conversation->worker_manager_interface); + } + + if (conversation->worker_proxy != NULL) { + GDBusConnection *connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (conversation->worker_proxy)); + g_dbus_connection_close_sync (connection, NULL, NULL); + } + } + + static void + stop_conversation (GdmSessionConversation *conversation) + { + close_conversation (conversation); + + conversation->is_stopping = TRUE; + gdm_session_worker_job_stop (conversation->job); + } + + static void + stop_conversation_now (GdmSessionConversation *conversation) + { + close_conversation (conversation); + + gdm_session_worker_job_stop_now (conversation->job); + g_clear_object (&conversation->job); + } + +-#ifdef ENABLE_WAYLAND_SUPPORT + void +-gdm_session_set_ignore_wayland (GdmSession *self, +- gboolean ignore_wayland) ++gdm_session_set_supported_session_types (GdmSession *self, ++ const char * const *supported_session_types) + { +- self->ignore_wayland = ignore_wayland; ++ const char * const session_types[] = { "wayland", "x11", NULL }; ++ g_strfreev (self->supported_session_types); ++ ++ if (supported_session_types == NULL) ++ self->supported_session_types = g_strdupv ((GStrv) session_types); ++ else ++ self->supported_session_types = g_strdupv ((GStrv) supported_session_types); + } +-#endif + + gboolean + gdm_session_start_conversation (GdmSession *self, + const char *service_name) + { + GdmSessionConversation *conversation; + + g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); + + conversation = g_hash_table_lookup (self->conversations, + service_name); + + if (conversation != NULL) { + if (!conversation->is_stopping) { + g_warning ("GdmSession: conversation %s started more than once", service_name); + return FALSE; + } + g_debug ("GdmSession: stopping old conversation %s", service_name); + gdm_session_worker_job_stop_now (conversation->job); + g_object_unref (conversation->job); + conversation->job = NULL; + } + + g_debug ("GdmSession: starting conversation %s for session (%p)", service_name, self); + + conversation = start_conversation (self, service_name); + + g_hash_table_insert (self->conversations, + g_strdup (service_name), conversation); + return TRUE; +@@ -3137,64 +3150,66 @@ gdm_session_get_conversation_session_id (GdmSession *self, + + conversation = find_conversation_by_name (self, service_name); + + if (conversation == NULL) { + return NULL; + } + + return conversation->session_id; + } + + static char * + get_session_filename (GdmSession *self) + { + return g_strdup_printf ("%s.desktop", get_session_name (self)); + } + + #ifdef ENABLE_WAYLAND_SUPPORT + static gboolean + gdm_session_is_wayland_session (GdmSession *self) + { + GKeyFile *key_file; + gboolean is_wayland_session = FALSE; + char *filename; + char *full_path = NULL; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); + + filename = get_session_filename (self); + +- key_file = load_key_file_for_file (self, filename, &full_path); ++ if (supports_session_type (self, "wayland")) { ++ key_file = load_key_file_for_file (self, filename, &full_path); + +- if (key_file == NULL) { +- goto out; ++ if (key_file == NULL) { ++ goto out; ++ } + } + + if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { + is_wayland_session = TRUE; + } + g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); + + out: + g_clear_pointer (&key_file, g_key_file_free); + g_free (filename); + return is_wayland_session; + } + #endif + + static void + update_session_type (GdmSession *self) + { + #ifdef ENABLE_WAYLAND_SUPPORT + gboolean is_wayland_session; + + is_wayland_session = gdm_session_is_wayland_session (self); + if (is_wayland_session) { + set_session_type (self, "wayland"); + } else { + set_session_type (self, NULL); + } + #endif + } + + gboolean +@@ -3424,195 +3439,192 @@ set_display_is_initial (GdmSession *self, + { + self->display_is_initial = is_initial; + } + + static void + set_verification_mode (GdmSession *self, + GdmSessionVerificationMode verification_mode) + { + self->verification_mode = verification_mode; + } + + static void + set_allowed_user (GdmSession *self, + uid_t allowed_user) + { + self->allowed_user = allowed_user; + } + + static void + set_conversation_environment (GdmSession *self, + char **environment) + { + g_strfreev (self->conversation_environment); + self->conversation_environment = g_strdupv (environment); + } + + static void + set_session_type (GdmSession *self, + const char *session_type) + { +- ++ g_debug ("GdmSession: setting session to type '%s'", session_type? session_type : ""); + if (g_strcmp0 (self->session_type, session_type) != 0) { +- g_debug ("GdmSession: setting session to type '%s'", session_type? session_type : ""); + g_free (self->session_type); + self->session_type = g_strdup (session_type); + } + } + + static void + gdm_session_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) + { + GdmSession *self; + + self = GDM_SESSION (object); + + switch (prop_id) { + case PROP_SESSION_TYPE: + set_session_type (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_NAME: + set_display_name (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_HOSTNAME: + set_display_hostname (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_DEVICE: + set_display_device (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_SEAT_ID: + set_display_seat_id (self, g_value_get_string (value)); + break; + case PROP_USER_X11_AUTHORITY_FILE: + set_user_x11_authority_file (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_X11_AUTHORITY_FILE: + set_display_x11_authority_file (self, g_value_get_string (value)); + break; + case PROP_DISPLAY_IS_LOCAL: + set_display_is_local (self, g_value_get_boolean (value)); + break; + case PROP_DISPLAY_IS_INITIAL: + set_display_is_initial (self, g_value_get_boolean (value)); + break; + case PROP_VERIFICATION_MODE: + set_verification_mode (self, g_value_get_enum (value)); + break; + case PROP_ALLOWED_USER: + set_allowed_user (self, g_value_get_uint (value)); + break; + case PROP_CONVERSATION_ENVIRONMENT: + set_conversation_environment (self, g_value_get_pointer (value)); + break; +-#ifdef ENABLE_WAYLAND_SUPPORT +- case PROP_IGNORE_WAYLAND: +- gdm_session_set_ignore_wayland (self, g_value_get_boolean (value)); ++ case PROP_SUPPORTED_SESSION_TYPES: ++ gdm_session_set_supported_session_types (self, g_value_get_boxed (value)); + break; +-#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static void + gdm_session_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) + { + GdmSession *self; + + self = GDM_SESSION (object); + + switch (prop_id) { + case PROP_SESSION_TYPE: + g_value_set_string (value, self->session_type); + break; + case PROP_DISPLAY_NAME: + g_value_set_string (value, self->display_name); + break; + case PROP_DISPLAY_HOSTNAME: + g_value_set_string (value, self->display_hostname); + break; + case PROP_DISPLAY_DEVICE: + g_value_set_string (value, self->display_device); + break; + case PROP_DISPLAY_SEAT_ID: + g_value_set_string (value, self->display_seat_id); + break; + case PROP_USER_X11_AUTHORITY_FILE: + g_value_set_string (value, self->user_x11_authority_file); + break; + case PROP_DISPLAY_X11_AUTHORITY_FILE: + g_value_set_string (value, self->display_x11_authority_file); + break; + case PROP_DISPLAY_IS_LOCAL: + g_value_set_boolean (value, self->display_is_local); + break; + case PROP_DISPLAY_IS_INITIAL: + g_value_set_boolean (value, self->display_is_initial); + break; + case PROP_VERIFICATION_MODE: + g_value_set_enum (value, self->verification_mode); + break; + case PROP_ALLOWED_USER: + g_value_set_uint (value, self->allowed_user); + break; + case PROP_CONVERSATION_ENVIRONMENT: + g_value_set_pointer (value, self->environment); + break; +-#ifdef ENABLE_WAYLAND_SUPPORT +- case PROP_IGNORE_WAYLAND: +- g_value_set_boolean (value, self->ignore_wayland); ++ case PROP_SUPPORTED_SESSION_TYPES: ++ g_value_set_boxed (value, self->supported_session_types); + break; +-#endif + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } + } + + static void + gdm_session_dispose (GObject *object) + { + GdmSession *self; + + self = GDM_SESSION (object); + + g_debug ("GdmSession: Disposing session"); + + gdm_session_close (self); + ++ g_clear_pointer (&self->supported_session_types, ++ g_strfreev); + g_clear_pointer (&self->conversations, + g_hash_table_unref); + + g_clear_object (&self->user_verifier_interface); + g_clear_pointer (&self->user_verifier_extensions, + g_hash_table_unref); + g_clear_object (&self->greeter_interface); + g_clear_object (&self->remote_greeter_interface); + g_clear_object (&self->chooser_interface); + + g_free (self->display_name); + self->display_name = NULL; + + g_free (self->display_hostname); + self->display_hostname = NULL; + + g_free (self->display_device); + self->display_device = NULL; + + g_free (self->display_seat_id); + self->display_seat_id = NULL; + + g_free (self->display_x11_authority_file); + self->display_x11_authority_file = NULL; + + g_strfreev (self->conversation_environment); + self->conversation_environment = NULL; + + if (self->worker_server != NULL) { + g_dbus_server_stop (self->worker_server); +@@ -3719,60 +3731,71 @@ gdm_session_class_init (GdmSessionClass *session_class) + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_INT); + signals [VERIFICATION_COMPLETE] = + g_signal_new ("verification-complete", + GDM_TYPE_SESSION, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + signals [SESSION_OPENED] = + g_signal_new ("session-opened", + GDM_TYPE_SESSION, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_STRING); ++ signals [SESSION_OPENED_FAILED] = ++ g_signal_new ("session-opened-failed", ++ GDM_TYPE_SESSION, ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, ++ NULL, ++ g_cclosure_marshal_generic, ++ G_TYPE_NONE, ++ 2, ++ G_TYPE_STRING, G_TYPE_STRING); + signals [SESSION_STARTED] = + g_signal_new ("session-started", + GDM_TYPE_SESSION, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_INT); + signals [SESSION_START_FAILED] = + g_signal_new ("session-start-failed", + GDM_TYPE_SESSION, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 2, + G_TYPE_STRING, G_TYPE_STRING); + signals [SESSION_EXITED] = + g_signal_new ("session-exited", + GDM_TYPE_SESSION, + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, +@@ -3962,69 +3985,67 @@ gdm_session_class_init (GdmSessionClass *session_class) + PROP_DISPLAY_X11_AUTHORITY_FILE, + g_param_spec_string ("display-x11-authority-file", + "display x11 authority file", + "display x11 authority file", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + /* not construct only */ + g_object_class_install_property (object_class, + PROP_USER_X11_AUTHORITY_FILE, + g_param_spec_string ("user-x11-authority-file", + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_DISPLAY_DEVICE, + g_param_spec_string ("display-device", + "display device", + "display device", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (object_class, + PROP_DISPLAY_SEAT_ID, + g_param_spec_string ("display-seat-id", + "display seat id", + "display seat id", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + +-#ifdef ENABLE_WAYLAND_SUPPORT + g_object_class_install_property (object_class, +- PROP_IGNORE_WAYLAND, +- g_param_spec_boolean ("ignore-wayland", +- "ignore wayland", +- "ignore wayland", +- FALSE, +- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); +-#endif ++ PROP_SUPPORTED_SESSION_TYPES, ++ g_param_spec_boxed ("supported-session-types", ++ "supported session types", ++ "supported session types", ++ G_TYPE_STRV, ++ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + + /* Ensure we can resolve errors */ + gdm_dbus_error_ensure (GDM_SESSION_WORKER_ERROR); + } + + GdmSession * + gdm_session_new (GdmSessionVerificationMode verification_mode, + uid_t allowed_user, + const char *display_name, + const char *display_hostname, + const char *display_device, + const char *display_seat_id, + const char *display_x11_authority_file, + gboolean display_is_local, + const char * const *environment) + { + GdmSession *self; + + self = g_object_new (GDM_TYPE_SESSION, + "verification-mode", verification_mode, + "allowed-user", (guint) allowed_user, + "display-name", display_name, + "display-hostname", display_hostname, + "display-device", display_device, + "display-seat-id", display_seat_id, + "display-x11-authority-file", display_x11_authority_file, + "display-is-local", display_is_local, + "conversation-environment", environment, + NULL); + +diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in +index 255bff02..a1035f95 100644 +--- a/data/gdm.schemas.in ++++ b/data/gdm.schemas.in +@@ -25,65 +25,75 @@ + + daemon/AutomaticLoginEnable + b + false + + + daemon/AutomaticLogin + s + + + + daemon/TimedLoginEnable + b + false + + + daemon/TimedLogin + s + + + + daemon/TimedLoginDelay + i + 30 + + + daemon/InitialSetupEnable + b + true + ++ ++ daemon/PreferredDisplayServer ++ s ++ wayland ++ + + daemon/WaylandEnable + b + true + ++ ++ daemon/XorgEnable ++ b ++ true ++ + + security/AllowRemoteAutoLogin + b + false + + + + debug/Enable + b + false + + + + security/DisallowTCP + b + true + + + xdmcp/Enable + b + false + + + xdmcp/ShowLocalGreeter + b + true + + + xdmcp/MaxPending + i +diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c +index 75d442ee..97ed5ef3 100644 +--- a/libgdm/gdm-sessions.c ++++ b/libgdm/gdm-sessions.c +@@ -163,171 +163,203 @@ load_session_file (const char *id, + + static gboolean + remove_duplicate_sessions (gpointer key, + gpointer value, + gpointer user_data) + { + gboolean already_known; + GHashTable *names_seen_before; + GdmSessionFile *session; + + names_seen_before = (GHashTable *) user_data; + session = (GdmSessionFile *) value; + already_known = !g_hash_table_add (names_seen_before, session->translated_name); + + if (already_known) + g_debug ("GdmSession: Removing %s (%s) as we already have a session by this name", + session->id, + session->path); + + return already_known; + } + + static void + collect_sessions_from_directory (const char *dirname) + { + GDir *dir; + const char *filename; + + gboolean is_x11 = g_getenv ("WAYLAND_DISPLAY") == NULL && + g_getenv ("RUNNING_UNDER_GDM") != NULL; ++ gboolean is_wayland = g_getenv ("WAYLAND_DISPLAY") != NULL && ++ g_getenv ("RUNNING_UNDER_GDM") != NULL; + + /* FIXME: add file monitor to directory */ + + dir = g_dir_open (dirname, 0, NULL); + if (dir == NULL) { + return; + } + + while ((filename = g_dir_read_name (dir))) { + char *id; + char *full_path; + + if (! g_str_has_suffix (filename, ".desktop")) { + continue; + } + +- if (is_x11 && g_str_has_suffix (filename, "-xorg.desktop")) { +- char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop")); +- char *fallback_name = g_strconcat (base_name, ".desktop", NULL); +- g_free (base_name); +- char *fallback_path = g_build_filename (dirname, fallback_name, NULL); +- g_free (fallback_name); +- if (g_file_test (fallback_path, G_FILE_TEST_EXISTS)) { +- g_free (fallback_path); +- g_debug ("Running under X11, ignoring %s", filename); +- continue; ++ if (is_wayland) { ++ if (g_str_has_suffix (filename, "-wayland.desktop")) { ++ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-wayland.desktop")); ++ g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL); ++ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); ++ ++ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { ++ g_debug ("Running under Wayland, ignoring %s", filename); ++ continue; ++ } ++ } else { ++ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop")); ++ g_autofree char *other_name = g_strdup_printf ("%s-xorg.desktop", base_name); ++ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); ++ ++ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { ++ g_debug ("Running under Wayland, ignoring %s", filename); ++ continue; ++ } ++ } ++ } else if (is_x11) { ++ if (g_str_has_suffix (filename, "-xorg.desktop")) { ++ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop")); ++ g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL); ++ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); ++ ++ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { ++ g_debug ("Running under X11, ignoring %s", filename); ++ continue; ++ } ++ } else { ++ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop")); ++ g_autofree char *other_name = g_strdup_printf ("%s-wayland.desktop", base_name); ++ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); ++ ++ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { ++ g_debug ("Running under X11, ignoring %s", filename); ++ continue; ++ } + } +- g_free (fallback_path); + } + + id = g_strndup (filename, strlen (filename) - strlen (".desktop")); + + full_path = g_build_filename (dirname, filename, NULL); + + load_session_file (id, full_path); + + g_free (id); + g_free (full_path); + } + + g_dir_close (dir); + } + + static void + collect_sessions (void) + { + g_autoptr(GHashTable) names_seen_before = NULL; + g_autoptr(GPtrArray) xorg_search_array = NULL; + g_autoptr(GPtrArray) wayland_search_array = NULL; + gchar *session_dir = NULL; + int i; + const char *xorg_search_dirs[] = { + "/etc/X11/sessions/", + DMCONFDIR "/Sessions/", + DATADIR "/gdm/BuiltInSessions/", + DATADIR "/xsessions/", + }; ++ g_auto (GStrv) supported_session_types = NULL; ++ ++ supported_session_types = g_strsplit (g_getenv ("GDM_SUPPORTED_SESSION_TYPES"), ":", -1); + + names_seen_before = g_hash_table_new (g_str_hash, g_str_equal); + xorg_search_array = g_ptr_array_new_with_free_func (g_free); + + const gchar * const *system_data_dirs = g_get_system_data_dirs (); + + for (i = 0; system_data_dirs[i]; i++) { + session_dir = g_build_filename (system_data_dirs[i], "xsessions", NULL); + g_ptr_array_add (xorg_search_array, session_dir); + } + + for (i = 0; i < G_N_ELEMENTS (xorg_search_dirs); i++) { + g_ptr_array_add (xorg_search_array, g_strdup (xorg_search_dirs[i])); + } + + #ifdef ENABLE_WAYLAND_SUPPORT + const char *wayland_search_dirs[] = { + DATADIR "/wayland-sessions/", + }; + + wayland_search_array = g_ptr_array_new_with_free_func (g_free); + + for (i = 0; system_data_dirs[i]; i++) { + session_dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); + g_ptr_array_add (wayland_search_array, session_dir); + } + + for (i = 0; i < G_N_ELEMENTS (wayland_search_dirs); i++) { + g_ptr_array_add (wayland_search_array, g_strdup (wayland_search_dirs[i])); + } + #endif + + if (gdm_available_sessions_map == NULL) { + gdm_available_sessions_map = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify)gdm_session_file_free); + } + +- for (i = 0; i < xorg_search_array->len; i++) { +- collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i)); ++ if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "x11")) { ++ for (i = 0; i < xorg_search_array->len; i++) { ++ collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i)); ++ } + } + + #ifdef ENABLE_WAYLAND_SUPPORT + #ifdef ENABLE_USER_DISPLAY_SERVER +- if (g_getenv ("WAYLAND_DISPLAY") == NULL && g_getenv ("RUNNING_UNDER_GDM") != NULL) { +- goto out; ++ if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "wayland")) { ++ for (i = 0; i < wayland_search_array->len; i++) { ++ collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i)); ++ } + } + #endif +- +- for (i = 0; i < wayland_search_array->len; i++) { +- collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i)); +- } + #endif + +-out: + g_hash_table_foreach_remove (gdm_available_sessions_map, + remove_duplicate_sessions, + names_seen_before); + } + + /** + * gdm_get_session_ids: + * + * Reads /usr/share/xsessions and other relevant places for possible sessions + * to log into and returns the complete list. + * + * Returns: (transfer full): a %NULL terminated list of session ids + */ + char ** + gdm_get_session_ids (void) + { + GHashTableIter iter; + gpointer key, value; + GPtrArray *array; + + if (!gdm_sessions_map_is_initialized) { + collect_sessions (); + + gdm_sessions_map_is_initialized = TRUE; + } + + array = g_ptr_array_new (); + g_hash_table_iter_init (&iter, gdm_available_sessions_map); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionFile *session; +-- +2.27.0 + diff --git a/SOURCES/0001-local-display-factory-pause-for-a-few-seconds-before.patch b/SOURCES/0001-local-display-factory-pause-for-a-few-seconds-before.patch index 56e096c..9a5582a 100644 --- a/SOURCES/0001-local-display-factory-pause-for-a-few-seconds-before.patch +++ b/SOURCES/0001-local-display-factory-pause-for-a-few-seconds-before.patch @@ -1,8 +1,8 @@ -From f9662449f0f7dbb452ba11fe85a3c81b386f6dab Mon Sep 17 00:00:00 2001 +From 903dd62114d24a90fe55a7cf42ea07233fe71879 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 29 Oct 2018 06:57:59 -0400 -Subject: [PATCH] local-display-factory: pause for a few seconds before falling - back to X +Subject: [PATCH] local-display-factory: pause for a few seconds before + falling back to X logind currently gets confused if a session is started immediately as one is shutting down. @@ -12,79 +12,81 @@ back to X. http://bugzilla.redhat.com/1643874 --- - daemon/gdm-local-display-factory.c | 5 +++++ - 1 file changed, 5 insertions(+) + daemon/gdm-local-display-factory.c | 7 +++++++ + 1 file changed, 7 insertions(+) diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 403921d32..ab7e12e91 100644 +index eba38671..948c5d98 100644 --- a/daemon/gdm-local-display-factory.c +++ b/daemon/gdm-local-display-factory.c -@@ -283,60 +283,65 @@ on_display_status_changed (GdmDisplay *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) { - /* reset num failures */ - factory->priv->num_failures = 0; +@@ -653,60 +653,67 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory, + preferred_display_server = get_preferred_display_server (factory); - 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; -+ -+ /* workaround logind race for now -+ * bug 1643874 -+ */ -+ g_usleep (2 * G_USEC_PER_SEC); - } - - #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; + if (g_strcmp0 (preferred_display_server, "none") == 0) { + g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display"); + return; } - g_free (seat_id); - g_free (session_type); - } + ret = sd_seat_can_graphical (seat_id); - static gboolean - lookup_by_seat_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - const char *looking_for = user_data; - char *current; - gboolean res; + if (ret < 0) { + g_critical ("Failed to query CanGraphical information for seat %s", seat_id); + return; + } + + if (ret == 0) { + g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics"); + seat_supports_graphics = FALSE; + } else { + g_debug ("GdmLocalDisplayFactory: System supports graphics"); + seat_supports_graphics = TRUE; + } + + if (g_strcmp0 (seat_id, "seat0") == 0) { + is_seat0 = TRUE; + + falling_back = factory->num_failures > 0; + session_types = gdm_local_display_factory_get_session_types (factory, falling_back); + + g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s", + session_types[0], falling_back? " fallback" : ""); ++ ++ if (falling_back) { ++ /* workaround logind race for now ++ * bug 1643874 ++ */ ++ g_usleep (2 * G_USEC_PER_SEC); ++ } + } else { + is_seat0 = FALSE; + + g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id); + /* Force legacy X11 for all auxiliary seats */ + seat_supports_graphics = TRUE; + session_types = g_strdupv ((char **) legacy_session_types); + } + + /* For seat0, we have a fallback logic to still try starting it after + * SEAT0_GRAPHICS_CHECK_TIMEOUT seconds. i.e. we simply continue even if + * CanGraphical is unset. + * This is ugly, but it means we'll come up eventually in some + * scenarios where no master device is present. + * Note that we'll force an X11 fallback even though there might be + * cases where an wayland capable device is present and simply not marked as + * master-of-seat. In these cases, this should likely be fixed in the + * udev rules. + * + * At the moment, systemd always sets CanGraphical for non-seat0 seats. + * This is because non-seat0 seats are defined by having master-of-seat + * set. This means we can avoid the fallback check for non-seat0 seats, + * which simplifies the code. + */ + if (is_seat0) { + if (!seat_supports_graphics) { + if (!factory->seat0_graphics_check_timed_out) { + if (factory->seat0_graphics_check_timeout_id == 0) { + g_debug ("GdmLocalDisplayFactory: seat0 doesn't yet support graphics. Waiting %d seconds to try again.", SEAT0_GRAPHICS_CHECK_TIMEOUT); + factory->seat0_graphics_check_timeout_id = g_timeout_add_seconds (SEAT0_GRAPHICS_CHECK_TIMEOUT, -- -2.19.1 +2.27.0 diff --git a/SOURCES/0001-manager-Don-t-leak-session-objects.patch b/SOURCES/0001-manager-Don-t-leak-session-objects.patch deleted file mode 100644 index 909ca20..0000000 --- a/SOURCES/0001-manager-Don-t-leak-session-objects.patch +++ /dev/null @@ -1,353 +0,0 @@ -From de229615d80fd7c8a38ab5d5d7b30aa98f43721d Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 14 Sep 2020 16:20:09 -0400 -Subject: [PATCH 1/3] manager: Don't leak session objects - -The first is from create_user_session_for display. Most callers don't -check the return value, so it should just be void. - -The user data associated with the session also isn't unlinked from the -display when the display is finishing up, preventing the display and -session object from getting freed. - -This commit makes both changes. ---- - daemon/gdm-manager.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index bff602a07..738671679 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -94,63 +94,63 @@ struct GdmManagerPrivate - #ifdef WITH_PLYMOUTH - guint plymouth_is_running : 1; - #endif - guint did_automatic_login : 1; - }; - - enum { - PROP_0, - PROP_XDMCP_ENABLED, - PROP_SHOW_LOCAL_GREETER - }; - - enum { - DISPLAY_ADDED, - DISPLAY_REMOVED, - LAST_SIGNAL - }; - - typedef enum { - SESSION_RECORD_LOGIN, - SESSION_RECORD_LOGOUT, - SESSION_RECORD_FAILED, - } SessionRecord; - - static guint signals [LAST_SIGNAL] = { 0, }; - - static void gdm_manager_class_init (GdmManagerClass *klass); - static void gdm_manager_init (GdmManager *manager); - static void gdm_manager_dispose (GObject *object); - --static GdmSession *create_user_session_for_display (GdmManager *manager, -- GdmDisplay *display, -- uid_t allowed_user); -+static void create_user_session_for_display (GdmManager *manager, -+ GdmDisplay *display, -+ uid_t allowed_user); - static void start_user_session (GdmManager *manager, - StartUserSessionOperation *operation); - static void clean_user_session (GdmSession *session); - - static gpointer manager_object = NULL; - - static void manager_interface_init (GdmDBusManagerIface *interface); - - G_DEFINE_TYPE_WITH_CODE (GdmManager, - gdm_manager, - GDM_DBUS_TYPE_MANAGER_SKELETON, - G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_MANAGER, - manager_interface_init)); - - #ifdef WITH_PLYMOUTH - static gboolean - plymouth_is_running (void) - { - int status; - gboolean res; - GError *error; - - error = NULL; - res = g_spawn_command_line_sync ("/bin/plymouth --ping", - NULL, NULL, &status, &error); - if (! res) { - g_debug ("Could not ping plymouth: %s", error->message); - g_error_free (error); - return FALSE; - } -@@ -1343,61 +1343,62 @@ get_automatic_login_details (GdmManager *manager, - return enabled; - } - - static const char * - get_username_for_greeter_display (GdmManager *manager, - GdmDisplay *display) - { - gboolean doing_initial_setup = FALSE; - - g_object_get (G_OBJECT (display), - "doing-initial-setup", &doing_initial_setup, - NULL); - - if (doing_initial_setup) { - return INITIAL_SETUP_USERNAME; - } else { - return GDM_USERNAME; - } - } - - static void - set_up_automatic_login_session (GdmManager *manager, - GdmDisplay *display) - { - GdmSession *session; - char *display_session_type = NULL; - - /* 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); -+ create_user_session_for_display (manager, display, 0); -+ session = get_user_session_for_display (display); - - g_object_get (G_OBJECT (display), - "session-type", &display_session_type, - NULL); - - g_object_set (G_OBJECT (session), - "display-is-initial", FALSE, - NULL); - - g_debug ("GdmManager: Starting automatic login conversation"); - gdm_session_start_conversation (session, "gdm-autologin"); - } - - static void - set_up_chooser_session (GdmManager *manager, - GdmDisplay *display) - { - const char *allowed_user; - struct passwd *passwd_entry; - - allowed_user = get_username_for_greeter_display (manager, display); - - if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) { - g_warning ("GdmManager: couldn't look up username %s", - allowed_user); - gdm_display_unmanage (display); - gdm_display_finish (display); - return; - } - -@@ -1549,60 +1550,62 @@ on_display_status_changed (GdmDisplay *display, - "session-type", &session_type, - NULL); - - status = gdm_display_get_status (display); - - switch (status) { - case GDM_DISPLAY_PREPARED: - case GDM_DISPLAY_MANAGED: - 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); - } - 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 - -+ g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); -+ - if (display == manager->priv->automatic_login_display) { - g_clear_weak_pointer (&manager->priv->automatic_login_display); - - manager->priv->did_automatic_login = TRUE; - - #ifdef ENABLE_WAYLAND_SUPPORT - if (g_strcmp0 (session_type, "wayland") != 0 && status == GDM_DISPLAY_FAILED) { - /* we're going to fall back to X11, so try to autologin again - */ - manager->priv->did_automatic_login = FALSE; - } - #endif - } - break; - default: - break; - } - - } - - static void - on_display_removed (GdmDisplayStore *display_store, - GdmDisplay *display, - GdmManager *manager) - { - char *id; - - gdm_display_get_id (display, &id, NULL); - g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); - g_free (id); -@@ -2292,61 +2295,61 @@ on_session_reauthentication_started (GdmSession *session, - int pid_of_caller, - const char *address, - GdmManager *manager) - { - GDBusMethodInvocation *invocation; - gpointer source_tag; - - g_debug ("GdmManager: reauthentication started"); - - source_tag = GINT_TO_POINTER (pid_of_caller); - - invocation = g_hash_table_lookup (manager->priv->open_reauthentication_requests, - source_tag); - - if (invocation != NULL) { - g_hash_table_steal (manager->priv->open_reauthentication_requests, - source_tag); - gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), - invocation, - address); - } - } - - static void - clean_user_session (GdmSession *session) - { - g_object_set_data (G_OBJECT (session), "gdm-display", NULL); - g_object_unref (session); - } - --static GdmSession * -+static void - create_user_session_for_display (GdmManager *manager, - GdmDisplay *display, - uid_t allowed_user) - { - GdmSession *session; - gboolean display_is_local = FALSE; - char *display_name = NULL; - char *display_device = NULL; - char *remote_hostname = NULL; - char *display_auth_file = NULL; - char *display_seat_id = NULL; - char *display_id = NULL; - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - char *display_session_type = NULL; - gboolean greeter_is_wayland; - #endif - - g_object_get (G_OBJECT (display), - "id", &display_id, - "x11-display-name", &display_name, - "is-local", &display_is_local, - "remote-hostname", &remote_hostname, - "x11-authority-file", &display_auth_file, - "seat-id", &display_seat_id, - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - "session-type", &display_session_type, - #endif - NULL); - display_device = get_display_device (manager, display); - -@@ -2402,70 +2405,68 @@ create_user_session_for_display (GdmManager *manager, - "conversation-stopped", - G_CALLBACK (on_session_conversation_stopped), - manager); - g_signal_connect (session, - "authentication-failed", - G_CALLBACK (on_session_authentication_failed), - manager); - g_signal_connect (session, - "session-opened", - G_CALLBACK (on_user_session_opened), - manager); - g_signal_connect (session, - "session-started", - G_CALLBACK (on_user_session_started), - manager); - g_signal_connect (session, - "session-start-failed", - G_CALLBACK (on_session_start_failed), - manager); - g_signal_connect (session, - "session-exited", - G_CALLBACK (on_user_session_exited), - manager); - g_signal_connect (session, - "session-died", - G_CALLBACK (on_user_session_died), - manager); - g_object_set_data (G_OBJECT (session), "gdm-display", display); - g_object_set_data_full (G_OBJECT (display), - "gdm-user-session", -- g_object_ref (session), -+ session, - (GDestroyNotify) - clean_user_session); - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - greeter_is_wayland = g_strcmp0 (display_session_type, "wayland") == 0; - g_object_set (G_OBJECT (session), "ignore-wayland", !greeter_is_wayland, NULL); - #endif -- -- return session; - } - - static void - on_display_added (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_export (manager->priv->object_manager, - gdm_display_get_object_skeleton (display)); - - g_signal_connect (display, "notify::status", - G_CALLBACK (on_display_status_changed), - manager); - g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id); - } - } - - GQuark - gdm_manager_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_manager_error"); - } - --- -2.26.2 - diff --git a/SOURCES/0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch b/SOURCES/0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch index 0b1d1a2..718486c 100644 --- a/SOURCES/0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch +++ b/SOURCES/0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch @@ -1,28 +1,28 @@ -From bb58b5762272840a414f2bfe3ab59d733099a06c Mon Sep 17 00:00:00 2001 -From: rpm-build +From d80807171a457ff87bdc9bd861939161749a37a8 Mon Sep 17 00:00:00 2001 +From: Ray Strode Date: Thu, 20 Dec 2018 14:51:38 -0500 -Subject: [PATCH 1/2] manager: allow multiple xdmcp logins for the same user +Subject: [PATCH 1/3] manager: allow multiple xdmcp logins for the same user --- common/gdm-settings-keys.h | 1 + daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++---------- - data/gdm.schemas.in.in | 5 +++ + data/gdm.schemas.in | 5 +++ 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h -index f0059b5cf..33676a851 100644 +index 87685d3cd..4b3a1ffeb 100644 --- a/common/gdm-settings-keys.h +++ b/common/gdm-settings-keys.h -@@ -28,37 +28,38 @@ G_BEGIN_DECLS - #define GDM_KEY_USER "daemon/User" - #define GDM_KEY_GROUP "daemon/Group" +@@ -30,37 +30,38 @@ G_BEGIN_DECLS #define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable" #define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin" #define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable" #define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin" #define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay" #define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable" + #define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer" #define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable" + #define GDM_KEY_XORG_ENABLE "daemon/XorgEnable" #define GDM_KEY_DEBUG "debug/Enable" @@ -53,11 +53,10 @@ index f0059b5cf..33676a851 100644 #endif /* _GDM_SETTINGS_KEYS_H */ diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 056560b20..de7357ad5 100644 +index e433acf3b..ce8565bf9 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c -@@ -594,93 +594,106 @@ get_display_and_details_for_bus_sender (GdmManager *self, - if (out_tty != NULL) { +@@ -566,93 +566,106 @@ get_display_and_details_for_bus_sender (GdmManager *self, *out_tty = get_tty_for_session_id (session_id, &error); if (error != NULL) { @@ -71,10 +70,11 @@ index 056560b20..de7357ad5 100644 lookup_by_session_id, (gpointer) session_id); + out: if (out_display != NULL) { *out_display = display; } - out: + g_free (session_id); } @@ -112,7 +112,7 @@ index 056560b20..de7357ad5 100644 - if (existing_session != NULL) { - ssid_to_activate = gdm_session_get_session_id (existing_session); - if (seat_id != NULL) { -- res = activate_session_id (manager, seat_id, ssid_to_activate); +- res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate); - if (! res) { - g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); - goto out; @@ -138,7 +138,7 @@ index 056560b20..de7357ad5 100644 } + if (seat_id != NULL) { -+ res = activate_session_id (manager, seat_id, ssid_to_activate); ++ res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate); + if (! res) { + g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); + goto out; @@ -181,7 +181,7 @@ index 056560b20..de7357ad5 100644 { const char *username; char *display_name, *hostname, *display_device; -@@ -1088,92 +1101,114 @@ open_temporary_reauthentication_channel (GdmManager *self, +@@ -1089,92 +1102,114 @@ open_temporary_reauthentication_channel (GdmManager *self, g_signal_connect (session, "client-disconnected", G_CALLBACK (on_reauthentication_client_disconnected), @@ -263,7 +263,7 @@ index 056560b20..de7357ad5 100644 + G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Login screen creates new sessions for remote connections"); -+ return TRUE; ++ return TRUE; + } + if (is_login_screen) { @@ -296,11 +296,11 @@ index 056560b20..de7357ad5 100644 pid, uid, is_remote); -diff --git a/data/gdm.schemas.in.in b/data/gdm.schemas.in.in -index 8ad203101..003f92c63 100644 ---- a/data/gdm.schemas.in.in -+++ b/data/gdm.schemas.in.in -@@ -102,32 +102,37 @@ +diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in +index a1035f95e..929d13d90 100644 +--- a/data/gdm.schemas.in ++++ b/data/gdm.schemas.in +@@ -112,33 +112,38 @@ xdmcp/DisplaysPerHost i @@ -338,6 +338,7 @@ index 8ad203101..003f92c63 100644 + + -- -2.21.1 +2.30.1 diff --git a/SOURCES/0001-manager-don-t-kill-timed-login-session-immediately-a.patch b/SOURCES/0001-manager-don-t-kill-timed-login-session-immediately-a.patch deleted file mode 100644 index 014d385..0000000 --- a/SOURCES/0001-manager-don-t-kill-timed-login-session-immediately-a.patch +++ /dev/null @@ -1,87 +0,0 @@ -From ecd37ba6d56a49dd896613f68d1e1754633b9f0c Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 6 Feb 2019 16:14:52 -0500 -Subject: [PATCH 1/4] manager: don't kill timed login session immediately after - it starts - -At the moment GDM is misidentifying timed login sessions as if -they are automatic login sessions. That leads to their displays -getting killed sometimes shortly after log in. - -This commit corrects the check, so that timed login sessions aren't -treated as autologin sessions. ---- - daemon/gdm-manager.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 1943d89e4..72d44b006 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1838,61 +1838,62 @@ on_start_user_session (StartUserSessionOperation *operation) - NULL); - } else { - uid_t allowed_uid; - - g_object_ref (display); - if (doing_initial_setup) { - g_debug ("GdmManager: closing down initial setup display"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - - /* We can't start the user session until the finished display - * starts to respawn (since starting an X server and bringing - * one down at the same time is a no go) - */ - g_assert (self->priv->initial_login_operation == NULL); - self->priv->initial_login_operation = operation; - starting_user_session_right_away = FALSE; - } else { - g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); - } - - /* The user session is going to follow the session worker - * into the new display. Untie it from this display and - * create a new session for a future user login. */ - allowed_uid = gdm_session_get_allowed_user (operation->session); - g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); - g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); - create_user_session_for_display (operation->manager, display, allowed_uid); - -- if (g_strcmp0 (operation->service_name, "gdm-autologin") == 0) { -+ if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) && -+ !gdm_session_client_is_connected (operation->session)) { - /* remove the unused prepared greeter display since we're not going - * to have a greeter */ - gdm_display_store_remove (self->priv->display_store, display); - g_object_unref (display); - } - - /* Give the user session a new display object for bookkeeping purposes */ - create_display_for_user_session (operation->manager, - operation->session, - session_id); - } - - if (starting_user_session_right_away) { - start_user_session (operation->manager, operation); - } - - out: - return G_SOURCE_REMOVE; - } - - static void - queue_start_user_session (GdmManager *manager, - GdmSession *session, - const char *service_name) - { - StartUserSessionOperation *operation; - - operation = g_slice_new0 (StartUserSessionOperation); - operation->manager = manager; - operation->session = g_object_ref (session); --- -2.26.0 - diff --git a/SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch b/SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch deleted file mode 100644 index 9a4c4df..0000000 --- a/SOURCES/0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch +++ /dev/null @@ -1,683 +0,0 @@ -From 3864af1ea06d2125c1b1f5afa6fc12caa833980a Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 10 Dec 2020 15:14:20 -0500 -Subject: [PATCH] session-worker: Don't switch back VTs until session is fully - exited - -There's a race condition on shutdown where the session worker is -switching VTs back to the initial VT at the same time as the session -exit is being processed. - -This means that manager may try to start a login screen (because of -the VT switch) when autologin is enabled when there shouldn't be a -login screen. - -This commit makes sure both the PostSession script, and session-exited -signal emission are complete before initiating the VT switch back -to the initial VT. - -https://gitlab.gnome.org/GNOME/gdm/-/issues/660 ---- - daemon/Makefile.am | 12 +++++ - daemon/gdm-session-worker.c | 93 +++++++++++++++++++++++++++------ - daemon/org.freedesktop.DBus.xml | 12 +++++ - 3 files changed, 101 insertions(+), 16 deletions(-) - create mode 100644 daemon/org.freedesktop.DBus.xml - -diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index 86a8ee32f..b323f6455 100644 ---- a/daemon/Makefile.am -+++ b/daemon/Makefile.am -@@ -7,83 +7,92 @@ AM_CPPFLAGS = \ - -I$(top_srcdir)/pam-extensions \ - -I$(top_builddir)/common \ - -DBINDIR=\"$(bindir)\" \ - -DDATADIR=\"$(datadir)\" \ - -DDMCONFDIR=\"$(dmconfdir)\" \ - -DGDMCONFDIR=\"$(gdmconfdir)\" \ - -DLIBDIR=\"$(libdir)\" \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DLOGDIR=\"$(logdir)\" \ - -DSBINDIR=\"$(sbindir)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ - -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ - -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ - -DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \ - -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ - -DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \ - $(DISABLE_DEPRECATED_CFLAGS) \ - $(DAEMON_CFLAGS) \ - $(XLIB_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DEBUG_CFLAGS) \ - $(SYSTEMD_CFLAGS) \ - $(JOURNALD_CFLAGS) \ - $(LIBSELINUX_CFLAGS) \ - -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \ - $(NULL) - - BUILT_SOURCES = \ -+ gdm-dbus-glue.h \ - gdm-display-glue.h \ - gdm-manager-glue.h \ - gdm-local-display-glue.h \ - gdm-local-display-factory-glue.h \ - gdm-session-glue.h \ - gdm-session-worker-glue.h \ - gdm-session-enum-types.h \ - gdm-session-worker-enum-types.h \ - com.redhat.AccountsServiceUser.System.h \ - $(NULL) - - gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - - gdm-session-enum-types.c: gdm-session-enum-types.c.in gdm-session.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - - gdm-session-worker-enum-types.h: gdm-session-worker-enum-types.h.in gdm-session-worker.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - - gdm-session-worker-enum-types.c: gdm-session-worker-enum-types.c.in gdm-session-worker.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - -+gdm-dbus-glue.c gdm-dbus-glue.h: org.freedesktop.DBus.xml Makefile.am -+ $(AM_V_GEN)gdbus-codegen \ -+ --c-namespace=GdmDBus \ -+ --interface-prefix=org.freedesktop.DBus \ -+ --generate-c-code=gdm-dbus-glue \ -+ --c-generate-autocleanup=all \ -+ $(srcdir)/org.freedesktop.DBus.xml -+ - gdm-display-glue.c gdm-display-glue.h: gdm-display.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-display-glue \ - $(srcdir)/gdm-display.xml - - gdm-local-display-glue.c gdm-local-display-glue.h: gdm-local-display.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-local-display-glue \ - $(srcdir)/gdm-local-display.xml - - gdm-local-display-factory-glue.c gdm-local-display-factory-glue.h : gdm-local-display-factory.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-local-display-factory-glue \ - $(srcdir)/gdm-local-display-factory.xml - - gdm-manager-glue.c gdm-manager-glue.h : gdm-manager.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-manager-glue \ - $(srcdir)/gdm-manager.xml - - gdm-session-glue.c gdm-session-glue.h : gdm-session.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ -@@ -130,60 +139,62 @@ libexec_PROGRAMS = \ - gdm-wayland-session \ - gdm-x-session \ - $(NULL) - - gdm_session_worker_SOURCES = \ - session-worker-main.c \ - com.redhat.AccountsServiceUser.System.h \ - com.redhat.AccountsServiceUser.System.c \ - gdm-session.c \ - gdm-session.h \ - gdm-session-settings.h \ - gdm-session-settings.c \ - gdm-session-auditor.h \ - gdm-session-auditor.c \ - gdm-session-record.c \ - gdm-session-record.h \ - gdm-session-worker.h \ - gdm-session-worker.c \ - gdm-session-worker-job.c \ - gdm-session-worker-common.c \ - gdm-session-worker-common.h \ - gdm-dbus-util.c \ - gdm-dbus-util.h \ - $(NULL) - - if SUPPORTS_PAM_EXTENSIONS - gdm_session_worker_SOURCES += $(top_srcdir)/pam-extensions/gdm-pam-extensions.h - endif - - nodist_gdm_session_worker_SOURCES = \ -+ gdm-dbus-glue.h \ -+ gdm-dbus-glue.c \ - gdm-session-glue.h \ - gdm-session-glue.c \ - gdm-session-worker-glue.c \ - gdm-session-worker-glue.h \ - gdm-session-enum-types.c \ - gdm-session-worker-enum-types.c \ - gdm-session-enum-types.h \ - $(NULL) - - gdm_wayland_session_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(GTK_LIBS) \ - $(COMMON_LIBS) \ - $(SYSTEMD_LIBS) \ - $(NULL) - - gdm_wayland_session_SOURCES = \ - gdm-manager-glue.h \ - gdm-manager-glue.c \ - gdm-wayland-session.c \ - $(NULL) - - gdm_x_session_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(GTK_LIBS) \ - $(COMMON_LIBS) \ - $(SYSTEMD_LIBS) \ - $(XLIB_LIBS) \ - $(NULL) - -@@ -271,50 +282,51 @@ nodist_gdm_SOURCES = \ - - XDMCP_SOURCES = \ - gdm-xdmcp-display-factory.c \ - gdm-xdmcp-display-factory.h \ - gdm-xdmcp-display.c \ - gdm-xdmcp-display.h \ - gdm-xdmcp-chooser-display.c \ - gdm-xdmcp-chooser-display.h \ - $(NULL) - - if XDMCP_SUPPORT - gdm_SOURCES += $(XDMCP_SOURCES) - endif - - EXTRA_gdm_SOURCES = \ - $(XDMCP_SOURCES) \ - $(NULL) - - gdm_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(XLIB_LIBS) \ - $(DAEMON_LIBS) \ - $(XDMCP_LIBS) \ - $(LIBWRAP_LIBS) \ - $(SYSTEMD_LIBS) \ - $(JOURNALD_LIBS) \ - $(EXTRA_DAEMON_LIBS) \ - $(NULL) - - CLEANFILES = \ -+ gdm-dbus-glue.c \ - gdm-display-glue.c \ - gdm-local-display-factory-glue.c \ - gdm-manager-glue.c \ - gdm-session-glue.c \ - gdm-session-worker-glue.c \ - gdm-session-enum-types.c \ - gdm-local-display-glue.c \ - $(BUILT_SOURCES) \ - $(NULL) - - EXTRA_DIST = \ - gdm-manager.xml \ - gdm-session-worker.xml \ - gdm-session.xml \ - gdm-display.xml \ - gdm-local-display.xml \ - gdm-local-display-factory.xml \ - gdm-session-enum-types.c.in \ - gdm-session-enum-types.h.in \ - $(NULL) -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index 42c415837..c1b2c1765 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -39,60 +39,61 @@ - - #ifdef HAVE_LOGINCAP - #include - #endif - - #include - #include - #include - #include - #include - - #include - - #include - - #ifdef ENABLE_SYSTEMD_JOURNAL - #include - #endif - - #ifdef HAVE_SELINUX - #include - #endif /* HAVE_SELINUX */ - - #include "gdm-common.h" - #include "gdm-log.h" - - #ifdef SUPPORTS_PAM_EXTENSIONS - #include "gdm-pam-extensions.h" - #endif - -+#include "gdm-dbus-glue.h" - #include "gdm-session-worker.h" - #include "gdm-session-glue.h" - #include "gdm-session.h" - - #if defined (HAVE_ADT) - #include "gdm-session-solaris-auditor.h" - #elif defined (HAVE_LIBAUDIT) - #include "gdm-session-linux-auditor.h" - #else - #include "gdm-session-auditor.h" - #endif - - #include "gdm-session-settings.h" - - #define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate)) - - #define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session" - #define GDM_SESSION_DBUS_NAME "org.gnome.DisplayManager.Session" - #define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel" - - #define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker" - - #ifndef GDM_PASSWD_AUXILLARY_BUFFER_SIZE - #define GDM_PASSWD_AUXILLARY_BUFFER_SIZE 1024 - #endif - - #ifndef GDM_SESSION_DEFAULT_PATH - #define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin" - #endif - -@@ -1028,72 +1029,60 @@ gdm_session_worker_set_state (GdmSessionWorker *worker, - - static void - gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, - int status) - { - g_debug ("GdmSessionWorker: uninitializing PAM"); - - if (worker->priv->pam_handle == NULL) - return; - - gdm_session_worker_get_username (worker, NULL); - - if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { - pam_close_session (worker->priv->pam_handle, 0); - gdm_session_auditor_report_logout (worker->priv->auditor); - } else { - gdm_session_auditor_report_login_failure (worker->priv->auditor, - status, - pam_strerror (worker->priv->pam_handle, status)); - } - - if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) { - pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED); - } - - pam_end (worker->priv->pam_handle, status); - worker->priv->pam_handle = NULL; - - gdm_session_worker_stop_auditor (worker); - -- /* If user-display-server is not enabled the login_vt is always -- * identical to the session_vt. So in that case we never need to -- * do a VT switch. */ --#ifdef ENABLE_USER_DISPLAY_SERVER -- if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) { -- /* Switch to the login VT if we are not the login screen. */ -- if (worker->priv->session_vt != GDM_INITIAL_VT) { -- jump_to_vt (worker, GDM_INITIAL_VT); -- } -- } --#endif -- - worker->priv->session_vt = 0; - - g_debug ("GdmSessionWorker: state NONE"); - gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE); - } - - static char * - _get_tty_for_pam (const char *x11_display_name, - const char *display_device) - { - #ifdef __sun - return g_strdup (display_device); - #else - return g_strdup (x11_display_name); - #endif - } - - #ifdef PAM_XAUTHDATA - static struct pam_xauth_data * - _get_xauth_for_pam (const char *x11_authority_file) - { - FILE *fh; - Xauth *auth = NULL; - struct pam_xauth_data *retval = NULL; - gsize len = sizeof (*retval) + 1; - - fh = fopen (x11_authority_file, "r"); - if (fh) { - auth = XauReadAuth (fh); - fclose (fh); -@@ -1752,86 +1741,155 @@ gdm_session_worker_accredit_user (GdmSessionWorker *worker, - gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCREDITED); - } else { - gdm_session_worker_uninitialize_pam (worker, error_code); - } - - return ret; - } - - static const char * const * - gdm_session_worker_get_environment (GdmSessionWorker *worker) - { - return (const char * const *) pam_getenvlist (worker->priv->pam_handle); - } - - static gboolean - run_script (GdmSessionWorker *worker, - const char *dir) - { - /* scripts are for non-program sessions only */ - if (worker->priv->is_program_session) { - return TRUE; - } - - return gdm_run_script (dir, - worker->priv->username, - worker->priv->x11_display_name, - worker->priv->display_is_local? NULL : worker->priv->hostname, - worker->priv->x11_authority_file); - } - -+static void -+wait_until_dbus_signal_emission_to_manager_finishes (GdmSessionWorker *worker) -+{ -+ g_autoptr (GdmDBusPeer) peer_proxy = NULL; -+ g_autoptr (GError) error = NULL; -+ gboolean pinged; -+ -+ peer_proxy = gdm_dbus_peer_proxy_new_sync (worker->priv->connection, -+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, -+ NULL, -+ "/org/freedesktop/DBus", -+ NULL, -+ &error); -+ -+ if (peer_proxy == NULL) { -+ g_debug ("GdmSessionWorker: could not create peer proxy to daemon: %s", -+ error->message); -+ return; -+ } -+ -+ pinged = gdm_dbus_peer_call_ping_sync (peer_proxy, NULL, &error); -+ -+ if (!pinged) { -+ g_debug ("GdmSessionWorker: could not ping daemon: %s", -+ error->message); -+ return; -+ } -+} -+ -+static void -+jump_back_to_initial_vt (GdmSessionWorker *worker) -+{ -+ if (worker->priv->session_vt == 0) -+ return; -+ -+ if (worker->priv->session_vt == GDM_INITIAL_VT) -+ return; -+ -+ if (g_strcmp0 (worker->priv->display_seat_id, "seat0") != 0) -+ return; -+ -+#ifdef ENABLE_USER_DISPLAY_SERVER -+ jump_to_vt (worker, GDM_INITIAL_VT); -+ worker->priv->session_vt = 0; -+#endif -+} -+ - static void - session_worker_child_watch (GPid pid, - int status, - GdmSessionWorker *worker) - { - g_debug ("GdmSessionWorker: child (pid:%d) done (%s:%d)", - (int) pid, - WIFEXITED (status) ? "status" - : WIFSIGNALED (status) ? "signal" - : "unknown", - WIFEXITED (status) ? WEXITSTATUS (status) - : WIFSIGNALED (status) ? WTERMSIG (status) - : -1); - -- - gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); - -+ worker->priv->child_pid = -1; -+ worker->priv->child_watch_id = 0; -+ run_script (worker, GDMCONFDIR "/PostSession"); -+ - gdm_dbus_worker_emit_session_exited (GDM_DBUS_WORKER (worker), - worker->priv->service, - status); - - killpg (pid, SIGHUP); - -- worker->priv->child_pid = -1; -- worker->priv->child_watch_id = 0; -- run_script (worker, GDMCONFDIR "/PostSession"); -+ /* FIXME: It's important to give the manager an opportunity to process the -+ * session-exited emission above before switching VTs. -+ * -+ * This is because switching VTs makes the manager try to put a login screen -+ * up on VT 1, but it may actually want to try to auto login again in response -+ * to session-exited. -+ * -+ * This function just does a manager roundtrip over the bus to make sure the -+ * signal has been dispatched before jumping. -+ * -+ * Ultimately, we may want to improve the manager<->worker interface. -+ * -+ * See: -+ * -+ * https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/123 -+ * -+ * for some ideas and more discussion. -+ * -+ */ -+ wait_until_dbus_signal_emission_to_manager_finishes (worker); -+ -+ jump_back_to_initial_vt (worker); - } - - static void - gdm_session_worker_watch_child (GdmSessionWorker *worker) - { - g_debug ("GdmSession worker: watching pid %d", worker->priv->child_pid); - worker->priv->child_watch_id = g_child_watch_add (worker->priv->child_pid, - (GChildWatchFunc)session_worker_child_watch, - worker); - - } - - static gboolean - _is_loggable_file (const char* filename) - { - struct stat file_info; - - if (g_lstat (filename, &file_info) < 0) { - return FALSE; - } - - return S_ISREG (file_info.st_mode) && g_access (filename, R_OK | W_OK) == 0; - } - - static void - rotate_logs (const char *path, - guint n_copies) - { - int i; - -@@ -2401,60 +2459,61 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, - - flags = 0; - - if (worker->priv->is_program_session) { - flags |= PAM_SILENT; - } - - error_code = pam_open_session (worker->priv->pam_handle, flags); - - if (error_code != PAM_SUCCESS) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_OPENING_SESSION, - "%s", pam_strerror (worker->priv->pam_handle, error_code)); - goto out; - } - - g_debug ("GdmSessionWorker: state SESSION_OPENED"); - gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_OPENED); - - session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID"); - - if (session_id != NULL) { - g_free (worker->priv->session_id); - worker->priv->session_id = session_id; - } - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); -+ worker->priv->session_vt = 0; - return FALSE; - } - - gdm_session_worker_get_username (worker, NULL); - gdm_session_auditor_report_login (worker->priv->auditor); - - return TRUE; - } - - static void - gdm_session_worker_set_server_address (GdmSessionWorker *worker, - const char *address) - { - g_free (worker->priv->server_address); - worker->priv->server_address = g_strdup (address); - } - - static void - gdm_session_worker_set_is_reauth_session (GdmSessionWorker *worker, - gboolean is_reauth_session) - { - worker->priv->is_reauth_session = is_reauth_session; - } - - static void - gdm_session_worker_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) - { -@@ -3565,60 +3624,62 @@ gdm_session_worker_unwatch_child (GdmSessionWorker *worker) - return; - - g_source_remove (worker->priv->child_watch_id); - worker->priv->child_watch_id = 0; - } - - - static void - gdm_session_worker_finalize (GObject *object) - { - GdmSessionWorker *worker; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_SESSION_WORKER (object)); - - worker = GDM_SESSION_WORKER (object); - - g_return_if_fail (worker->priv != NULL); - - gdm_session_worker_unwatch_child (worker); - - if (worker->priv->child_pid > 0) { - gdm_signal_pid (worker->priv->child_pid, SIGTERM); - gdm_wait_on_pid (worker->priv->child_pid); - } - - if (worker->priv->pam_handle != NULL) { - gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); - } - -+ jump_back_to_initial_vt (worker); -+ - g_clear_object (&worker->priv->user_settings); - g_free (worker->priv->service); - g_free (worker->priv->x11_display_name); - g_free (worker->priv->x11_authority_file); - g_free (worker->priv->display_device); - g_free (worker->priv->display_seat_id); - g_free (worker->priv->hostname); - g_free (worker->priv->username); - g_free (worker->priv->server_address); - g_strfreev (worker->priv->arguments); - g_strfreev (worker->priv->extensions); - - g_hash_table_unref (worker->priv->reauthentication_requests); - - G_OBJECT_CLASS (gdm_session_worker_parent_class)->finalize (object); - } - - GdmSessionWorker * - gdm_session_worker_new (const char *address, - gboolean is_reauth_session) - { - GObject *object; - - object = g_object_new (GDM_TYPE_SESSION_WORKER, - "server-address", address, - "is-reauth-session", is_reauth_session, - NULL); - - return GDM_SESSION_WORKER (object); - } -diff --git a/daemon/org.freedesktop.DBus.xml b/daemon/org.freedesktop.DBus.xml -new file mode 100644 -index 000000000..5e0814bde ---- /dev/null -+++ b/daemon/org.freedesktop.DBus.xml -@@ -0,0 +1,12 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ --- -2.28.0 - diff --git a/SOURCES/0001-session-worker-expose-worker-state-enum-to-type-syst.patch b/SOURCES/0001-session-worker-expose-worker-state-enum-to-type-syst.patch deleted file mode 100644 index 3de78e9..0000000 --- a/SOURCES/0001-session-worker-expose-worker-state-enum-to-type-syst.patch +++ /dev/null @@ -1,470 +0,0 @@ -From 521ff70fe447558461dd38cdec62a7c0a5a74f7a Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 24 Jun 2019 14:48:23 -0400 -Subject: [PATCH 1/3] session-worker: expose worker state enum to type system - -We're going to need to access the worker state as a property on -the worker object. - -This commit hooks it up to glib-mkenums so the requisite goo can -get generated ---- - daemon/Makefile.am | 8 +++++ - daemon/gdm-session-worker-enum-types.c.in | 42 +++++++++++++++++++++++ - daemon/gdm-session-worker-enum-types.h.in | 24 +++++++++++++ - daemon/gdm-session-worker.c | 16 +++------ - daemon/gdm-session-worker.h | 12 +++++++ - 5 files changed, 90 insertions(+), 12 deletions(-) - create mode 100644 daemon/gdm-session-worker-enum-types.c.in - create mode 100644 daemon/gdm-session-worker-enum-types.h.in - -diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index b77c9276e..86a8ee32f 100644 ---- a/daemon/Makefile.am -+++ b/daemon/Makefile.am -@@ -14,69 +14,76 @@ AM_CPPFLAGS = \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DLOGDIR=\"$(logdir)\" \ - -DSBINDIR=\"$(sbindir)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ - -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ - -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ - -DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \ - -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ - -DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \ - $(DISABLE_DEPRECATED_CFLAGS) \ - $(DAEMON_CFLAGS) \ - $(XLIB_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DEBUG_CFLAGS) \ - $(SYSTEMD_CFLAGS) \ - $(JOURNALD_CFLAGS) \ - $(LIBSELINUX_CFLAGS) \ - -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \ - $(NULL) - - BUILT_SOURCES = \ - gdm-display-glue.h \ - gdm-manager-glue.h \ - gdm-local-display-glue.h \ - gdm-local-display-factory-glue.h \ - gdm-session-glue.h \ - gdm-session-worker-glue.h \ - gdm-session-enum-types.h \ -+ gdm-session-worker-enum-types.h \ - com.redhat.AccountsServiceUser.System.h \ - $(NULL) - - gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - - gdm-session-enum-types.c: gdm-session-enum-types.c.in gdm-session.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - -+gdm-session-worker-enum-types.h: gdm-session-worker-enum-types.h.in gdm-session-worker.h -+ $(AM_V_GEN) glib-mkenums --template $^ > $@ -+ -+gdm-session-worker-enum-types.c: gdm-session-worker-enum-types.c.in gdm-session-worker.h -+ $(AM_V_GEN) glib-mkenums --template $^ > $@ -+ - gdm-display-glue.c gdm-display-glue.h: gdm-display.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-display-glue \ - $(srcdir)/gdm-display.xml - - gdm-local-display-glue.c gdm-local-display-glue.h: gdm-local-display.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-local-display-glue \ - $(srcdir)/gdm-local-display.xml - - gdm-local-display-factory-glue.c gdm-local-display-factory-glue.h : gdm-local-display-factory.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-local-display-factory-glue \ - $(srcdir)/gdm-local-display-factory.xml - - gdm-manager-glue.c gdm-manager-glue.h : gdm-manager.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-manager-glue \ - $(srcdir)/gdm-manager.xml - - gdm-session-glue.c gdm-session-glue.h : gdm-session.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ -@@ -128,60 +135,61 @@ gdm_session_worker_SOURCES = \ - session-worker-main.c \ - com.redhat.AccountsServiceUser.System.h \ - com.redhat.AccountsServiceUser.System.c \ - gdm-session.c \ - gdm-session.h \ - gdm-session-settings.h \ - gdm-session-settings.c \ - gdm-session-auditor.h \ - gdm-session-auditor.c \ - gdm-session-record.c \ - gdm-session-record.h \ - gdm-session-worker.h \ - gdm-session-worker.c \ - gdm-session-worker-job.c \ - gdm-session-worker-common.c \ - gdm-session-worker-common.h \ - gdm-dbus-util.c \ - gdm-dbus-util.h \ - $(NULL) - - if SUPPORTS_PAM_EXTENSIONS - gdm_session_worker_SOURCES += $(top_srcdir)/pam-extensions/gdm-pam-extensions.h - endif - - nodist_gdm_session_worker_SOURCES = \ - gdm-session-glue.h \ - gdm-session-glue.c \ - gdm-session-worker-glue.c \ - gdm-session-worker-glue.h \ - gdm-session-enum-types.c \ -+ gdm-session-worker-enum-types.c \ - gdm-session-enum-types.h \ - $(NULL) - - gdm_wayland_session_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(GTK_LIBS) \ - $(COMMON_LIBS) \ - $(SYSTEMD_LIBS) \ - $(NULL) - - gdm_wayland_session_SOURCES = \ - gdm-manager-glue.h \ - gdm-manager-glue.c \ - gdm-wayland-session.c \ - $(NULL) - - gdm_x_session_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(GTK_LIBS) \ - $(COMMON_LIBS) \ - $(SYSTEMD_LIBS) \ - $(XLIB_LIBS) \ - $(NULL) - - gdm_x_session_SOURCES = \ - gdm-manager-glue.h \ - gdm-manager-glue.c \ - gdm-x-session.c \ - $(NULL) - -diff --git a/daemon/gdm-session-worker-enum-types.c.in b/daemon/gdm-session-worker-enum-types.c.in -new file mode 100644 -index 000000000..c02869076 ---- /dev/null -+++ b/daemon/gdm-session-worker-enum-types.c.in -@@ -0,0 +1,42 @@ -+/*** BEGIN file-header ***/ -+ -+#include -+ -+/*** END file-header ***/ -+ -+/*** BEGIN file-production ***/ -+#include "@filename@" -+/* enumerations from "@filename@" */ -+/*** END file-production ***/ -+ -+/*** BEGIN value-header ***/ -+GType @enum_name@_get_type (void) G_GNUC_CONST; -+ -+GType -+@enum_name@_get_type (void) -+{ -+ static GType etype = 0; -+ -+ if (G_UNLIKELY(etype == 0)) { -+ static const G@Type@Value values[] = { -+/*** END value-header ***/ -+ -+/*** BEGIN value-production ***/ -+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -+/*** END value-production ***/ -+ -+/*** BEGIN value-tail ***/ -+ { 0, NULL, NULL } -+ }; -+ -+ etype = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); -+ } -+ -+ return etype; -+} -+ -+/*** END value-tail ***/ -+ -+/*** BEGIN file-tail ***/ -+ /**/ -+/*** END file-tail ***/ -diff --git a/daemon/gdm-session-worker-enum-types.h.in b/daemon/gdm-session-worker-enum-types.h.in -new file mode 100644 -index 000000000..64f4b4bb6 ---- /dev/null -+++ b/daemon/gdm-session-worker-enum-types.h.in -@@ -0,0 +1,24 @@ -+/*** BEGIN file-header ***/ -+#ifndef GDM_SESSION_WORKER_ENUM_TYPES_H -+#define GDM_SESSION_WORKER_ENUM_TYPES_H -+ -+#include -+ -+G_BEGIN_DECLS -+/*** END file-header ***/ -+ -+/*** BEGIN file-production ***/ -+ -+/* enumerations from "@filename@" */ -+/*** END file-production ***/ -+ -+/*** BEGIN value-header ***/ -+GType @enum_name@_get_type (void) G_GNUC_CONST; -+#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) -+/*** END value-header ***/ -+ -+/*** BEGIN file-tail ***/ -+G_END_DECLS -+ -+#endif /* GDM_SESSION_WORKER_ENUM_TYPES_H */ -+/*** END file-tail ***/ -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index ae86d28ac..f6935ab1d 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -83,83 +83,72 @@ - #define GDM_SESSION_WORKER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerPrivate)) - - #define GDM_SESSION_DBUS_PATH "/org/gnome/DisplayManager/Session" - #define GDM_SESSION_DBUS_NAME "org.gnome.DisplayManager.Session" - #define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel" - - #define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker" - - #ifndef GDM_PASSWD_AUXILLARY_BUFFER_SIZE - #define GDM_PASSWD_AUXILLARY_BUFFER_SIZE 1024 - #endif - - #ifndef GDM_SESSION_DEFAULT_PATH - #define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin" - #endif - - #ifndef GDM_SESSION_ROOT_UID - #define GDM_SESSION_ROOT_UID 0 - #endif - - #ifndef GDM_SESSION_LOG_FILENAME - #define GDM_SESSION_LOG_FILENAME "session.log" - #endif - - #define MAX_FILE_SIZE 65536 - #define MAX_LOGS 5 - - #define RELEASE_DISPLAY_SIGNAL (SIGRTMAX) - #define ACQUIRE_DISPLAY_SIGNAL (SIGRTMAX - 1) - --enum { -- GDM_SESSION_WORKER_STATE_NONE = 0, -- GDM_SESSION_WORKER_STATE_SETUP_COMPLETE, -- GDM_SESSION_WORKER_STATE_AUTHENTICATED, -- GDM_SESSION_WORKER_STATE_AUTHORIZED, -- GDM_SESSION_WORKER_STATE_ACCREDITED, -- GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED, -- GDM_SESSION_WORKER_STATE_SESSION_OPENED, -- GDM_SESSION_WORKER_STATE_SESSION_STARTED --}; -- - typedef struct - { - GdmSessionWorker *worker; - GdmSession *session; - GPid pid_of_caller; - uid_t uid_of_caller; - - } ReauthenticationRequest; - - struct GdmSessionWorkerPrivate - { -- int state; -+ GdmSessionWorkerState state; - - int exit_code; - - pam_handle_t *pam_handle; - - GPid child_pid; - guint child_watch_id; - - /* from Setup */ - char *service; - char *x11_display_name; - char *x11_authority_file; - char *display_device; - char *display_seat_id; - char *hostname; - char *username; - char *log_file; - char *session_id; - uid_t uid; - gid_t gid; - gboolean password_is_required; - char **extensions; - - int cred_flags; - int login_vt; - int session_vt; - int session_tty_fd; - - char **arguments; - guint32 cancelled : 1; -@@ -2455,60 +2444,63 @@ gdm_session_worker_set_property (GObject *object, - switch (prop_id) { - case PROP_SERVER_ADDRESS: - gdm_session_worker_set_server_address (self, g_value_get_string (value)); - break; - case PROP_IS_REAUTH_SESSION: - gdm_session_worker_set_is_reauth_session (self, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - gdm_session_worker_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) - { - GdmSessionWorker *self; - - self = GDM_SESSION_WORKER (object); - - switch (prop_id) { - case PROP_SERVER_ADDRESS: - g_value_set_string (value, self->priv->server_address); - break; - case PROP_IS_REAUTH_SESSION: - g_value_set_boolean (value, self->priv->is_reauth_session); - break; -+ case PROP_STATE: -+ g_value_set_int (value, self->priv->state); -+ break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static gboolean - gdm_session_worker_handle_set_environment_variable (GdmDBusWorker *object, - GDBusMethodInvocation *invocation, - const char *key, - const char *value) - { - GdmSessionWorker *worker = GDM_SESSION_WORKER (object); - gdm_session_worker_set_environment_variable (worker, key, value); - gdm_dbus_worker_complete_set_environment_variable (object, invocation); - return TRUE; - } - - static gboolean - gdm_session_worker_handle_set_session_name (GdmDBusWorker *object, - GDBusMethodInvocation *invocation, - const char *session_name) - { - GdmSessionWorker *worker = GDM_SESSION_WORKER (object); - g_debug ("GdmSessionWorker: session name set to %s", session_name); - if (worker->priv->user_settings != NULL) - gdm_session_settings_set_session_name (worker->priv->user_settings, - session_name); - gdm_dbus_worker_complete_set_session_name (object, invocation); - return TRUE; -diff --git a/daemon/gdm-session-worker.h b/daemon/gdm-session-worker.h -index 5603e80e0..2814eab4d 100644 ---- a/daemon/gdm-session-worker.h -+++ b/daemon/gdm-session-worker.h -@@ -1,56 +1,68 @@ - /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2006 Ray Strode - * - * 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, 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. - */ - - #ifndef __GDM_SESSION_WORKER_H - #define __GDM_SESSION_WORKER_H - - #include - - #include "gdm-session-worker-glue.h" - #include "gdm-session-worker-common.h" -+#include "gdm-session-worker-enum-types.h" - - G_BEGIN_DECLS - - #define GDM_TYPE_SESSION_WORKER (gdm_session_worker_get_type ()) - #define GDM_SESSION_WORKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SESSION_WORKER, GdmSessionWorker)) - #define GDM_SESSION_WORKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerClass)) - #define GDM_IS_SESSION_WORKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SESSION_WORKER)) - #define GDM_IS_SESSION_WORKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SESSION_WORKER)) - #define GDM_SESSION_WORKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION_WORKER, GdmSessionWorkerClass)) - -+typedef enum { -+ GDM_SESSION_WORKER_STATE_NONE = 0, -+ GDM_SESSION_WORKER_STATE_SETUP_COMPLETE, -+ GDM_SESSION_WORKER_STATE_AUTHENTICATED, -+ GDM_SESSION_WORKER_STATE_AUTHORIZED, -+ GDM_SESSION_WORKER_STATE_ACCREDITED, -+ GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED, -+ GDM_SESSION_WORKER_STATE_SESSION_OPENED, -+ GDM_SESSION_WORKER_STATE_SESSION_STARTED -+} GdmSessionWorkerState; -+ - typedef struct GdmSessionWorkerPrivate GdmSessionWorkerPrivate; - - typedef struct - { - GdmDBusWorkerSkeleton parent; - GdmSessionWorkerPrivate *priv; - } GdmSessionWorker; - - typedef struct - { - GdmDBusWorkerSkeletonClass parent_class; - } GdmSessionWorkerClass; - - GType gdm_session_worker_get_type (void); - - GdmSessionWorker * gdm_session_worker_new (const char *server_address, - gboolean is_for_reauth) G_GNUC_MALLOC; - G_END_DECLS - #endif /* GDM_SESSION_WORKER_H */ --- -2.18.1 - diff --git a/SOURCES/0001-utils-Drop-gdm-screenshot.patch b/SOURCES/0001-utils-Drop-gdm-screenshot.patch new file mode 100644 index 0000000..64974d6 --- /dev/null +++ b/SOURCES/0001-utils-Drop-gdm-screenshot.patch @@ -0,0 +1,362 @@ +From 7b5ee288d992f85eaefbfbc4dac663a29fcae446 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 5 May 2021 11:06:58 -0400 +Subject: [PATCH] 0001-utils-Drop-gdm-screenshot.patch + +--- + utils/gdm-screenshot.c | 296 ----------------------------------------- + utils/meson.build | 15 --- + 2 files changed, 311 deletions(-) + delete mode 100644 utils/gdm-screenshot.c + +diff --git a/utils/gdm-screenshot.c b/utils/gdm-screenshot.c +deleted file mode 100644 +index 5d20929a3..000000000 +--- a/utils/gdm-screenshot.c ++++ /dev/null +@@ -1,296 +0,0 @@ +-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- +- * +- * Copyright (C) 2008 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 +- +-#include +-#include +- +-#define SELECTION_NAME "_GDM_SCREENSHOT" +-static GtkWidget *selection_window; +- +-static gboolean debug_in; +- +-/* Keep all config options for compatibility even if they are noops */ +-GOptionEntry options [] = { +- { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug_in, N_("Debugging output"), NULL }, +- { NULL } +-}; +- +-/* To make sure there is only one screenshot taken at a time, +- * (Imagine key repeat for the print screen key) we hold a selection +- * until we are done taking the screenshot +- */ +-/* * Copyright (C) 2001-2006 Jonathan Blandford */ +-static gboolean +-screenshot_grab_lock (void) +-{ +- Atom selection_atom; +- GdkCursor *cursor; +- gboolean result = FALSE; +- +- selection_atom = gdk_x11_get_xatom_by_name (SELECTION_NAME); +- XGrabServer (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); +- if (XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), selection_atom) != None) { +- goto out; +- } +- +- selection_window = gtk_invisible_new (); +- gtk_widget_show (selection_window); +- +- if (!gtk_selection_owner_set (selection_window, +- gdk_atom_intern (SELECTION_NAME, FALSE), +- GDK_CURRENT_TIME)) { +- gtk_widget_destroy (selection_window); +- selection_window = NULL; +- goto out; +- } +- +- cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_WATCH); +- gdk_pointer_grab (gtk_widget_get_window (selection_window), FALSE, 0, NULL, +- cursor, GDK_CURRENT_TIME); +- g_object_unref (cursor); +- +- result = TRUE; +- +- out: +- XUngrabServer (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ())); +- gdk_flush (); +- +- return result; +-} +- +-/* * Copyright (C) 2001-2006 Jonathan Blandford */ +-static void +-screenshot_release_lock (void) +-{ +- if (selection_window != NULL) { +- gtk_widget_destroy (selection_window); +- selection_window = NULL; +- } +- gdk_flush (); +-} +- +-/* * Copyright (C) 2001-2006 Jonathan Blandford */ +-static GdkPixbuf * +-screenshot_get_pixbuf (Window w) +-{ +- GdkWindow *window; +- GdkWindow *root; +- GdkPixbuf *screenshot; +- int x_real_orig; +- int y_real_orig; +- int x_orig; +- int y_orig; +- int real_width; +- int real_height; +- int width; +- int height; +- +- window = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), w); +- if (window == NULL) { +- return NULL; +- } +- +- root = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), GDK_ROOT_WINDOW ()); +- gdk_window_get_geometry (window, NULL, NULL, &real_width, &real_height); +- gdk_window_get_origin (window, &x_real_orig, &y_real_orig); +- +- x_orig = x_real_orig; +- y_orig = y_real_orig; +- width = real_width; +- height = real_height; +- +- if (x_orig < 0) { +- width = width + x_orig; +- x_orig = 0; +- } +- if (y_orig < 0) { +- height = height + y_orig; +- y_orig = 0; +- } +- +- if (x_orig + width > gdk_screen_width ()) { +- width = gdk_screen_width () - x_orig; +- } +- if (y_orig + height > gdk_screen_height ()) { +- height = gdk_screen_height () - y_orig; +- } +- +- screenshot = gdk_pixbuf_get_from_window (root, +- x_orig, +- y_orig, +- width, +- height); +- +- return screenshot; +-} +- +-static char * +-screenshot_save (GdkPixbuf *pixbuf) +-{ +- char *filename; +- gboolean res; +- GError *error; +- +- filename = g_build_filename (GDM_SCREENSHOT_DIR, +- "GDM-Screenshot.png", +- NULL); +- +- error = NULL; +- res = gdk_pixbuf_save (pixbuf, +- filename, +- "png", +- &error, +- "tEXt::CREATOR", "gdm-screenshot", +- NULL); +- if (! res) { +- g_warning ("Unable to save screenshot: %s", error->message); +- g_error_free (error); +- g_free (filename); +- filename = NULL; +- } +- +- return filename; +-} +- +-static void +-sound_effect_finished (ca_context *c, +- uint32_t id, +- int error_code, +- void *userdata) +-{ +-} +- +-static void +-play_sound_effect (Window xid) +-{ +- ca_context *c; +- ca_proplist *p; +- int res; +- +- c = ca_gtk_context_get (); +- +- p = NULL; +- res = ca_proplist_create (&p); +- if (res < 0) { +- goto done; +- } +- +- res = ca_proplist_sets (p, CA_PROP_EVENT_ID, "screen-capture"); +- if (res < 0) { +- goto done; +- } +- +- res = ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Screenshot taken")); +- if (res < 0) { +- goto done; +- } +- +- res = ca_proplist_setf (p, +- CA_PROP_WINDOW_X11_XID, +- "%lu", +- (unsigned long) xid); +- if (res < 0) { +- goto done; +- } +- +- ca_context_play_full (c, 0, p, sound_effect_finished, NULL); +- +- done: +- if (p != NULL) { +- ca_proplist_destroy (p); +- } +- +-} +- +-static void +-prepare_screenshot (void) +-{ +- Window win; +- GdkPixbuf *screenshot; +- char *filename; +- +- if (!screenshot_grab_lock ()) { +- exit (EXIT_SUCCESS); +- } +- +- win = GDK_ROOT_WINDOW (); +- +- screenshot = screenshot_get_pixbuf (win); +- +- screenshot_release_lock (); +- +- if (screenshot == NULL) { +- /* FIXME: dialog? */ +- exit (EXIT_FAILURE); +- } +- +- play_sound_effect (win); +- +- filename = screenshot_save (screenshot); +- if (filename != NULL) { +- g_print ("Wrote %s\n", filename); +- /* FIXME: show a dialog or something */ +- g_free (filename); +- } +-} +- +-int +-main (int argc, char *argv[]) +-{ +- GOptionContext *ctx; +- gboolean res; +- GError *error; +- +- bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); +- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +- textdomain (GETTEXT_PACKAGE); +- setlocale (LC_ALL, ""); +- +- /* Option parsing */ +- ctx = g_option_context_new (N_("Take a picture of the screen")); +- g_option_context_set_translation_domain (ctx, GETTEXT_PACKAGE); +- g_option_context_add_main_entries (ctx, options, NULL); +- g_option_context_add_group (ctx, gtk_get_option_group (TRUE)); +- error = NULL; +- res = g_option_context_parse (ctx, &argc, &argv, &error); +- g_option_context_free (ctx); +- +- if (! res) { +- g_warning ("%s", error->message); +- g_error_free (error); +- exit (EXIT_FAILURE); +- } +- +- prepare_screenshot (); +- +- return 1; +-} +diff --git a/utils/meson.build b/utils/meson.build +index d59f167b0..1edd7bce4 100644 +--- a/utils/meson.build ++++ b/utils/meson.build +@@ -1,41 +1,26 @@ + # gdm-flexiserver + gdm_flexiserver_deps = [ + glib_dep, + libgdmcommon_dep, + ] + + gdm_flexiserver = executable('gdmflexiserver', + 'gdmflexiserver.c', + dependencies: gdm_flexiserver_deps, + include_directories: config_h_dir, + install: true, + ) + +-# gdm-screenshot +-gdm_screenshot_deps = [ +- glib_dep, +- gtk_dep, +- x_deps, +- libcanberra_gtk_dep, +-] +- +-gdm_screenshot = executable('gdm-screenshot', +- 'gdm-screenshot.c', +- dependencies: gdm_screenshot_deps, +- include_directories: config_h_dir, +- install: true, +-) +- + # gdm-runtime-config + gdm_runtime_config_deps = [ + glib_dep, + ] + + gdm_runtime_config = executable('gdm-runtime-config', + 'gdm-runtime-config.c', + dependencies: gdm_runtime_config_deps, + include_directories: config_h_dir, + install: true, + install_dir: get_option('libexecdir'), + ) + +-- +2.31.1 + diff --git a/SOURCES/0001-utils-add-new-gdm-disable-wayland-binary.patch b/SOURCES/0001-utils-add-new-gdm-disable-wayland-binary.patch deleted file mode 100644 index 0171861..0000000 --- a/SOURCES/0001-utils-add-new-gdm-disable-wayland-binary.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 14656db42a6b4d4d48cf74127f3187dfe85607ec Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 21 May 2018 15:03:29 +0000 -Subject: [PATCH] utils: add new gdm-disable-wayland binary - -We currently disable wayland for cirrus by calling printf -from a udev rule. This works, but it's a little too open -coded to easily write SELinux policy for. - -This commit introduces a new program, gdm-disable-wayland, -that does the same thing, but in a dedicated binary. - -A future commit will change the udev rule to use the binary. - -https://bugzilla.gnome.org/show_bug.cgi?id=796315 - - -(cherry picked from commit 2dc57da31781dedfe374ce353b0f5fd6aa9da56f) ---- - utils/Makefile.am | 14 ++++++++++ - utils/gdm-disable-wayland.c | 53 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 67 insertions(+) - create mode 100644 utils/gdm-disable-wayland.c - -diff --git a/utils/Makefile.am b/utils/Makefile.am -index ae3cc01fb..babe890b9 100644 ---- a/utils/Makefile.am -+++ b/utils/Makefile.am -@@ -1,56 +1,70 @@ - NULL = - - AM_CPPFLAGS = \ - -I$(srcdir) \ - -I$(builddir) \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/common \ - -I$(top_builddir)/common \ - -DDATADIR=\"$(datadir)\" \ - -DGDMCONFDIR=\"$(gdmconfdir)\" \ - -DLOCALSTATEDIR=\""$(localstatedir)"\" \ -+ -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ -+ -DGDM_RUNTIME_CONF=\"$(GDM_RUNTIME_CONF)\" \ - -DGDM_SCREENSHOT_DIR=\""$(GDM_SCREENSHOT_DIR)"\"\ - -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ - $(UTILS_CFLAGS) \ - $(CANBERRA_GTK_CFLAGS) \ - $(GTK_CFLAGS) \ - $(XLIB_CFLAGS) \ - $(SYSTEMD_CFLAGS) \ - $(COMMON_CFLAGS) \ - $(NULL) - - edit = sed \ - -e 's|@sbindir[@]|$(sbindir)|g' \ - -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ - -e 's|@localstatedir[@]|$(localstatedir)|g' \ - -e 's|@GDM_PID_FILE[@]|$(GDM_PID_FILE)|g' - - bin_PROGRAMS = \ - gdmflexiserver \ - gdm-screenshot \ - $(NULL) - -+libexec_PROGRAMS = \ -+ gdm-disable-wayland \ -+ $(NULL) -+ - gdmflexiserver_LDADD = \ - $(top_builddir)/common/libgdmcommon.la \ - $(GTK_LIBS) \ - $(COMMON_LIBS) \ - $(SYSTEMD_LIBS) \ - $(NULL) - - gdm_screenshot_SOURCES = \ - gdm-screenshot.c \ - $(NULL) - - gdm_screenshot_LDADD = \ - $(GTK_LIBS) \ - $(CANBERRA_GTK_LIBS) \ - $(XLIB_LIBS) \ - $(COMMON_LIBS) \ - $(NULL) - -+gdm_disable_wayland_LDADD = \ -+ $(COMMON_LIBS) \ -+ $(NULL) -+ -+gdm_disable_wayland_SOURCES = \ -+ gdm-disable-wayland.c \ -+ $(NULL) -+ - CLEANFILES = \ - $(NULL) - - DISTCLEANFILES = \ - $(NULL) -diff --git a/utils/gdm-disable-wayland.c b/utils/gdm-disable-wayland.c -new file mode 100644 -index 000000000..be61c4d8f ---- /dev/null -+++ b/utils/gdm-disable-wayland.c -@@ -0,0 +1,53 @@ -+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- -+ * -+ * Copyright (C) 2018 Red Hat, Inc. -+ * -+ * 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 -+ -+int -+main (int argc, char *argv[]) -+{ -+ g_autoptr(GKeyFile) key_file = NULL; -+ g_autoptr(GError) error = NULL; -+ gboolean saved_okay; -+ -+ setlocale (LC_ALL, ""); -+ -+ key_file = g_key_file_new (); -+ -+ g_key_file_set_boolean (key_file, "daemon", "WaylandEnable", FALSE); -+ -+ g_mkdir_with_parents (GDM_RUN_DIR, 0711); -+ -+ saved_okay = g_key_file_save_to_file (key_file, GDM_RUNTIME_CONF, &error); -+ -+ if (!saved_okay) { -+ g_printerr ("gdm-disable-wayland: unable to disable wayland: %s", -+ error->message); -+ return EX_CANTCREAT; -+ } -+ -+ return EX_OK; -+} --- -2.17.1 - diff --git a/SOURCES/0001-worker-don-t-load-user-settings-for-program-sessions.patch b/SOURCES/0001-worker-don-t-load-user-settings-for-program-sessions.patch index 279384d..3d8c7ce 100644 --- a/SOURCES/0001-worker-don-t-load-user-settings-for-program-sessions.patch +++ b/SOURCES/0001-worker-don-t-load-user-settings-for-program-sessions.patch @@ -1,4 +1,4 @@ -From a45b3f26e1f1f4ffc8870ebf073698d5eecf587b Mon Sep 17 00:00:00 2001 +From 70eb29d5eedc2b66e617745be1dd145aac3e177e Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 15 Aug 2018 10:48:16 -0400 Subject: [PATCH 1/4] worker: don't load user settings for program sessions @@ -6,14 +6,14 @@ Subject: [PATCH 1/4] worker: don't load user settings for program sessions We don't need or want the login greeter to access accountsservice for its session name --- - daemon/gdm-session-worker.c | 38 +++++++++++++++++++++++++------------ - 1 file changed, 26 insertions(+), 12 deletions(-) + daemon/gdm-session-worker.c | 37 ++++++++++++++++++++++++++----------- + 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index c1d89cab2..e79073996 100644 +index 774298b9..88fe36c1 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c -@@ -409,103 +409,108 @@ gdm_session_execute (const char *file, +@@ -400,103 +400,108 @@ gdm_session_execute (const char *file, */ static gboolean gdm_session_worker_get_username (GdmSessionWorker *worker, @@ -124,12 +124,12 @@ index c1d89cab2..e79073996 100644 worker->priv->service, question, answerp, -@@ -2475,87 +2480,89 @@ gdm_session_worker_get_property (GObject *object, - g_value_set_string (value, self->priv->server_address); - break; - case PROP_IS_REAUTH_SESSION: +@@ -2600,87 +2605,89 @@ gdm_session_worker_get_property (GObject *object, g_value_set_boolean (value, self->priv->is_reauth_session); break; + case PROP_STATE: + g_value_set_enum (value, self->priv->state); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -218,7 +218,8 @@ index c1d89cab2..e79073996 100644 g_free (session_name); } -@@ -2634,109 +2641,111 @@ do_authorize (GdmSessionWorker *worker) +@@ -2758,110 +2765,113 @@ do_authorize (GdmSessionWorker *worker) + g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error); } worker->priv->pending_invocation = NULL; } @@ -248,7 +249,8 @@ index c1d89cab2..e79073996 100644 g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED); g_debug ("GdmSessionWorker: saving account details for user %s", worker->priv->username); - worker->priv->state = GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED; ++ + gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED); - if (!gdm_session_settings_save (worker->priv->user_settings, - worker->priv->username)) { - g_warning ("could not save session and language settings"); @@ -334,7 +336,7 @@ index c1d89cab2..e79073996 100644 } gdm_dbus_worker_complete_open (GDM_DBUS_WORKER (worker), worker->priv->pending_invocation, session_id); -@@ -2980,155 +2989,161 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object, +@@ -3105,155 +3115,161 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object, if (g_strcmp0 (key, "service") == 0) { worker->priv->service = g_variant_dup_string (value, NULL); } else if (g_strcmp0 (key, "extensions") == 0) { @@ -496,7 +498,7 @@ index c1d89cab2..e79073996 100644 GDBusMethodInvocation *invocation, const char *service, const char *username, -@@ -3459,98 +3474,97 @@ static void +@@ -3591,61 +3607,60 @@ static void reauthentication_request_free (ReauthenticationRequest *request) { @@ -558,44 +560,6 @@ index c1d89cab2..e79073996 100644 g_return_if_fail (worker->priv != NULL); - gdm_session_worker_unwatch_child (worker); - - if (worker->priv->child_pid > 0) { - gdm_signal_pid (worker->priv->child_pid, SIGTERM); - gdm_wait_on_pid (worker->priv->child_pid); - } - -- g_object_unref (worker->priv->user_settings); -+ g_clear_object (&worker->priv->user_settings); - g_free (worker->priv->service); - g_free (worker->priv->x11_display_name); - g_free (worker->priv->x11_authority_file); - g_free (worker->priv->display_device); - g_free (worker->priv->display_seat_id); - g_free (worker->priv->hostname); - g_free (worker->priv->username); - g_free (worker->priv->server_address); - g_strfreev (worker->priv->arguments); - g_strfreev (worker->priv->extensions); - - g_hash_table_unref (worker->priv->reauthentication_requests); - - G_OBJECT_CLASS (gdm_session_worker_parent_class)->finalize (object); - } - - GdmSessionWorker * - gdm_session_worker_new (const char *address, - gboolean is_reauth_session) - { - GObject *object; - - object = g_object_new (GDM_TYPE_SESSION_WORKER, - "server-address", address, - "is-reauth-session", is_reauth_session, - NULL); - - return GDM_SESSION_WORKER (object); - } -- -2.17.1 +2.27.0 diff --git a/SOURCES/0002-gdm-x-session-run-session-bus-on-non-seat0-seats.patch b/SOURCES/0002-gdm-x-session-run-session-bus-on-non-seat0-seats.patch index df3c8bb..65e60ab 100644 --- a/SOURCES/0002-gdm-x-session-run-session-bus-on-non-seat0-seats.patch +++ b/SOURCES/0002-gdm-x-session-run-session-bus-on-non-seat0-seats.patch @@ -1,7 +1,7 @@ -From 84b823187c8e0b23274cd1a93f4e47a2c585c75b Mon Sep 17 00:00:00 2001 +From 874b26e3674d540df37d7f145df853bcf81e5a26 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 5 Feb 2020 15:20:48 -0500 -Subject: [PATCH 2/2] gdm-x-session: run session bus on non-seat0 seats +Subject: [PATCH 2/3] gdm-x-session: run session bus on non-seat0 seats GNOME doesn't deal very well with multiple sessions running on a multiple seats at the moment. @@ -9,14 +9,14 @@ running on a multiple seats at the moment. Until that's fixed, ensure sessions run on auxillary seats get their own session bus. --- - daemon/gdm-session.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) + daemon/gdm-session.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index a8263ba11..55637b378 100644 +index 418240dc0..77d6b8ff0 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c -@@ -2846,130 +2846,139 @@ on_start_program_cb (GdmDBusWorker *worker, +@@ -2822,119 +2822,128 @@ on_start_program_cb (GdmDBusWorker *worker, if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; @@ -25,8 +25,8 @@ index a8263ba11..55637b378 100644 service_name = conversation->service_name; if (worked) { - self->priv->session_pid = pid; - self->priv->session_conversation = conversation; + self->session_pid = pid; + self->session_conversation = conversation; g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", pid); g_signal_emit (self, signals[SESSION_STARTED], 0, service_name, pid); @@ -50,9 +50,10 @@ index a8263ba11..55637b378 100644 + gboolean run_separate_bus = FALSE; char *command; char *program; + gboolean register_session; g_return_if_fail (GDM_IS_SESSION (self)); - g_return_if_fail (self->priv->session_conversation == NULL); + g_return_if_fail (self->session_conversation == NULL); conversation = find_conversation_by_name (self, service_name); @@ -67,7 +68,7 @@ index a8263ba11..55637b378 100644 display_mode = gdm_session_get_display_mode (self); #ifdef ENABLE_WAYLAND_SUPPORT - is_x11 = g_strcmp0 (self->priv->session_type, "wayland") != 0; + is_x11 = g_strcmp0 (self->session_type, "wayland") != 0; #endif if (display_mode == GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED || @@ -75,18 +76,20 @@ index a8263ba11..55637b378 100644 run_launcher = TRUE; } -+ if (g_strcmp0 (self->priv->display_seat_id, "seat0") != 0 && !run_launcher) { + register_session = !gdm_session_session_registers (self); + ++ if (g_strcmp0 (self->display_seat_id, "seat0") != 0 && !run_launcher) { + run_separate_bus = TRUE; + } + - if (self->priv->selected_program == NULL) { + if (self->selected_program == NULL) { gboolean run_xsession_script; command = get_session_command (self); run_xsession_script = !gdm_session_bypasses_xsession (self); - if (self->priv->display_is_local) { + if (self->display_is_local) { gboolean disallow_tcp = TRUE; gdm_settings_direct_get_boolean (GDM_KEY_DISALLOW_TCP, &disallow_tcp); allow_remote_connections = !disallow_tcp; @@ -96,70 +99,53 @@ index a8263ba11..55637b378 100644 if (run_launcher) { if (is_x11) { - program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s %s\"%s\"", + program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s%s %s\"%s\"", + register_session ? "--register-session " : "", run_xsession_script? "--run-script " : "", allow_remote_connections? "--allow-remote-connections " : "", command); } else { - program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"", + program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"", + register_session ? "--register-session " : "", command); } } else if (run_xsession_script) { - program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); -+ if (run_separate_bus) { -+ program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command); -+ } else { -+ program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); -+ } ++ if (run_separate_bus) { ++ program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command); ++ } else { ++ program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); ++ } } else { program = g_strdup (command); } g_free (command); } else { + /* FIXME: + * Always use a separate DBus bus for each greeter session. + * Firstly, this means that if we run multiple greeter session + * (which we really should not do, but have to currently), then + * each one will get its own DBus session bus. + * But, we also explicitly do this for seat0, because that way + * it cannot make use of systemd to run the GNOME session. This + * prevents the session lookup logic from getting confused. + * This has a similar effect as passing --builtin to gnome-session. + * + * We really should not be doing this. But the fix is to use + * separate dynamically created users and that requires some + * major refactorings. + */ if (run_launcher) { if (is_x11) { -- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"", -- self->priv->selected_program); -+ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"", -+ self->priv->selected_program); + program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"dbus-run-session -- %s\"", + register_session ? "--register-session " : "", + self->selected_program); } else { - program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"", - self->priv->selected_program); + program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"dbus-run-session -- %s\"", + register_session ? "--register-session " : "", + self->selected_program); } - } else { -- if (g_strcmp0 (self->priv->display_seat_id, "seat0") != 0) { -+ if (run_separate_bus) { - program = g_strdup_printf ("dbus-run-session -- %s", - self->priv->selected_program); - } else { - program = g_strdup (self->priv->selected_program); - } - } - } - - set_up_session_environment (self); - send_environment (self, conversation); - - gdm_dbus_worker_call_start_program (conversation->worker_proxy, - program, - conversation->worker_cancellable, - (GAsyncReadyCallback) on_start_program_cb, - conversation); - g_free (program); - } - - static void - stop_all_conversations (GdmSession *self) - { - stop_all_other_conversations (self, NULL, TRUE); - } - - static void - do_reset (GdmSession *self) - { - stop_all_conversations (self); - -- -2.21.1 +2.30.1 diff --git a/SOURCES/0002-libgdm-Sort-session-list.patch b/SOURCES/0002-libgdm-Sort-session-list.patch new file mode 100644 index 0000000..108c85c --- /dev/null +++ b/SOURCES/0002-libgdm-Sort-session-list.patch @@ -0,0 +1,131 @@ +From 677d370e892788635c4086b139d78499510fa86c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 20 Jul 2021 13:36:45 -0400 +Subject: [PATCH 2/2] libgdm: Sort session list + +Right now the session list comes out in hash table order. + +This commit changes the code to sort by description. +--- + libgdm/gdm-sessions.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c +index 97ed5ef3..f078e04b 100644 +--- a/libgdm/gdm-sessions.c ++++ b/libgdm/gdm-sessions.c +@@ -311,92 +311,111 @@ collect_sessions (void) + g_ptr_array_add (wayland_search_array, g_strdup (wayland_search_dirs[i])); + } + #endif + + if (gdm_available_sessions_map == NULL) { + gdm_available_sessions_map = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify)gdm_session_file_free); + } + + if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "x11")) { + for (i = 0; i < xorg_search_array->len; i++) { + collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i)); + } + } + + #ifdef ENABLE_WAYLAND_SUPPORT + #ifdef ENABLE_USER_DISPLAY_SERVER + if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "wayland")) { + for (i = 0; i < wayland_search_array->len; i++) { + collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i)); + } + } + #endif + #endif + + g_hash_table_foreach_remove (gdm_available_sessions_map, + remove_duplicate_sessions, + names_seen_before); + } + ++static gint ++compare_session_ids (gconstpointer a, ++ gconstpointer b) ++{ ++ GdmSessionFile *session_a, *session_b; ++ session_a = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, a); ++ session_b = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, b); ++ ++ if (session_a == NULL) ++ return -1; ++ ++ if (session_b == NULL) ++ return 1; ++ ++ return g_strcmp0 (session_a->translated_name, session_b->translated_name); ++} ++ + /** + * gdm_get_session_ids: + * + * Reads /usr/share/xsessions and other relevant places for possible sessions + * to log into and returns the complete list. + * + * Returns: (transfer full): a %NULL terminated list of session ids + */ + char ** + gdm_get_session_ids (void) + { + GHashTableIter iter; + gpointer key, value; + GPtrArray *array; + + if (!gdm_sessions_map_is_initialized) { + collect_sessions (); + + gdm_sessions_map_is_initialized = TRUE; + } + + array = g_ptr_array_new (); + g_hash_table_iter_init (&iter, gdm_available_sessions_map); + while (g_hash_table_iter_next (&iter, &key, &value)) { + GdmSessionFile *session; + + session = (GdmSessionFile *) value; + + g_ptr_array_add (array, g_strdup (session->id)); + } + g_ptr_array_add (array, NULL); + ++ g_ptr_array_sort (array, compare_session_ids); ++ + return (char **) g_ptr_array_free (array, FALSE); + } + + /** + * gdm_get_session_name_and_description: + * @id: an id from gdm_get_session_ids() + * @description: (out): optional returned session description + * + * Takes an xsession id and returns the name and comment about it. + * + * Returns: The session name if found, or %NULL otherwise + */ + char * + gdm_get_session_name_and_description (const char *id, + char **description) + { + GdmSessionFile *session; + char *name; + + if (!gdm_sessions_map_is_initialized) { + collect_sessions (); + + gdm_sessions_map_is_initialized = TRUE; + } + + session = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, + id); + + if (session == NULL) { + return NULL; +-- +2.27.0 + diff --git a/SOURCES/0002-local-display-factory-Add-gdm_local_display_factory_.patch b/SOURCES/0002-local-display-factory-Add-gdm_local_display_factory_.patch deleted file mode 100644 index b93dbda..0000000 --- a/SOURCES/0002-local-display-factory-Add-gdm_local_display_factory_.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 417f0aed42959719c40f0f8ec65050dcf2510bd1 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 16 May 2018 14:10:34 +0100 -Subject: [PATCH 02/51] local-display-factory: Add - gdm_local_display_factory_use_wayland() helper - -Factor out the code which decides if Xorg or Wayland should be used into -a helper function. ---- - daemon/gdm-local-display-factory.c | 23 +++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 1a9196ee1..b21e3aee0 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -158,60 +158,73 @@ take_next_display_number (GdmLocalDisplayFactory *factory) - ret = num + 1; - break; - } - } - out: - - /* now reserve this number */ - g_debug ("GdmLocalDisplayFactory: Reserving X display: %u", ret); - g_hash_table_insert (factory->priv->used_display_numbers, GUINT_TO_POINTER (ret), NULL); - - return ret; - } - - static void - on_display_disposed (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - g_debug ("GdmLocalDisplayFactory: Display %p disposed", display); - } - - static void - store_display (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - GdmDisplayStore *store; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - gdm_display_store_add (store, display); - } - -+static gboolean -+gdm_local_display_factory_use_wayland (void) -+{ -+#ifdef ENABLE_WAYLAND_SUPPORT -+ gboolean wayland_enabled = FALSE; -+ if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { -+ if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) -+ return TRUE; -+ } -+#endif -+ return FALSE; -+} -+ - /* - Example: - dbus-send --system --dest=org.gnome.DisplayManager \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/gnome/DisplayManager/Manager \ - org.gnome.DisplayManager.Manager.GetDisplays - */ - gboolean - gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory, - char **id, - GError **error) - { - gboolean ret; - GdmDisplay *display = NULL; - - g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); - - ret = FALSE; - - g_debug ("GdmLocalDisplayFactory: Creating transient display"); - - #ifdef ENABLE_USER_DISPLAY_SERVER - display = gdm_local_display_new (); - #else - if (display == NULL) { - guint32 num; - - num = take_next_display_number (factory); - - display = gdm_legacy_display_new (num); -@@ -422,68 +435,62 @@ gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory) - GVariant *array; - GVariantIter iter; - const char *seat; - - result = g_dbus_connection_call_sync (factory->priv->connection, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "ListSeats", - NULL, - G_VARIANT_TYPE ("(a(so))"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, &error); - - if (!result) { - g_warning ("GdmLocalDisplayFactory: Failed to issue method call: %s", error->message); - g_clear_error (&error); - return FALSE; - } - - array = g_variant_get_child_value (result, 0); - g_variant_iter_init (&iter, array); - - while (g_variant_iter_loop (&iter, "(&so)", &seat, NULL)) { - gboolean is_initial; - const char *session_type = NULL; - - if (g_strcmp0 (seat, "seat0") == 0) { - is_initial = TRUE; --#ifdef ENABLE_WAYLAND_SUPPORT -- gboolean wayland_enabled = FALSE; -- if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { -- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) { -- session_type = "wayland"; -- } -- } --#endif -+ if (gdm_local_display_factory_use_wayland ()) -+ session_type = "wayland"; - } else { - is_initial = FALSE; - } - - create_display (factory, seat, session_type, is_initial); - } - - g_variant_unref (result); - g_variant_unref (array); - return TRUE; - } - - static void - on_seat_new (GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) - { - const char *seat; - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - create_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat, NULL, FALSE); - } - - static void - on_seat_removed (GDBusConnection *connection, - const gchar *sender_name, --- -2.27.0 - diff --git a/SOURCES/0002-manager-session-Add-some-debugging-around-starting-r.patch b/SOURCES/0002-manager-session-Add-some-debugging-around-starting-r.patch deleted file mode 100644 index bb217a4..0000000 --- a/SOURCES/0002-manager-session-Add-some-debugging-around-starting-r.patch +++ /dev/null @@ -1,1015 +0,0 @@ -From d3b60b5211d804e23c663d053c5b511dede22a28 Mon Sep 17 00:00:00 2001 -From: Iain Lane -Date: Thu, 31 Jan 2019 10:52:35 +0000 -Subject: [PATCH 2/4] manager,session: Add some debugging around starting - reauthentication - -There's a bug right now dealing with timed login and reauthentication, -but it's not clear what's going on by looking at the logs. - -This commit sprinkles some more logging throughout the code, to make -the bug easier to track. ---- - daemon/gdm-manager.c | 46 ++++++++++++++++++++++++++++++++++++++------ - daemon/gdm-session.c | 25 ++++++++++++++++++++---- - 2 files changed, 61 insertions(+), 10 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index b2d0578f5..0cc06a978 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -340,77 +340,94 @@ session_unlock (GdmManager *manager, - "org.freedesktop.login1.Manager", - "UnlockSession", - g_variant_new ("(s)", ssid), - NULL, /* expected reply */ - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("GdmManager: logind 'UnlockSession' %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 GdmSession * - find_session_for_user_on_seat (GdmManager *manager, - const char *username, - const char *seat_id, - GdmSession *dont_count_session) - { - GList *node; - - for (node = manager->priv->user_sessions; node != NULL; node = node->next) { - GdmSession *candidate_session = node->data; -- const char *candidate_username, *candidate_seat_id; -+ const char *candidate_username, *candidate_seat_id, *candidate_session_id; - -- if (candidate_session == dont_count_session) -+ candidate_session_id = gdm_session_get_session_id (candidate_session); -+ -+ if (candidate_session == dont_count_session) { -+ g_debug ("GdmSession: Ignoring session %s as requested", -+ candidate_session_id); - continue; -+ } - -- if (!gdm_session_is_running (candidate_session)) -+ if (!gdm_session_is_running (candidate_session)) { -+ g_debug ("GdmSession: Ignoring session %s as it isn't running", -+ candidate_session_id); - continue; -+ } - - candidate_username = gdm_session_get_username (candidate_session); - candidate_seat_id = gdm_session_get_display_seat_id (candidate_session); - -+ g_debug ("GdmManager: Considering session %s on seat %s belonging to user %s", -+ candidate_session_id, -+ candidate_seat_id, -+ candidate_username); -+ - if (g_strcmp0 (candidate_username, username) == 0 && - g_strcmp0 (candidate_seat_id, seat_id) == 0) { -+ g_debug ("GdmManager: yes, found session %s", candidate_session_id); - return candidate_session; - } -+ -+ g_debug ("GdmManager: no, will not use session %s", candidate_session_id); - } - -+ g_debug ("GdmManager: no matching sessions found"); - return NULL; - } - - static gboolean - is_remote_session (GdmManager *self, - const char *session_id, - GError **error) - { - char *seat; - int ret; - gboolean is_remote; - - /* FIXME: The next release of logind is going to have explicit api for - * checking remoteness. - */ - seat = NULL; - ret = sd_session_get_seat (session_id, &seat); - - if (ret < 0 && ret != -ENOENT) { - g_debug ("GdmManager: Error while retrieving seat for session %s: %s", - session_id, strerror (-ret)); - } - - if (seat != NULL) { - is_remote = FALSE; - free (seat); - } else { - is_remote = TRUE; - } - -@@ -840,62 +857,66 @@ gdm_manager_handle_open_session (GdmDBusManager *manager, - if (display == NULL) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("No session available")); - - return TRUE; - } - - #ifdef HAVE_LIBXDMCP - if (GDM_IS_XDMCP_CHOOSER_DISPLAY (display)) { - GdmLaunchEnvironment *launch_environment; - - g_object_get (display, "launch-environment", &launch_environment, NULL); - - if (launch_environment != NULL) { - session = gdm_launch_environment_get_session (launch_environment); - } - - if (session == NULL) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("Chooser session unavailable")); - return TRUE; - } - } - #endif - if (session == NULL) { - session = get_user_session_for_display (display); -+ g_debug ("GdmSession: Considering session %s for username %s", -+ gdm_session_get_session_id (session), -+ gdm_session_get_username (session)); - - if (gdm_session_is_running (session)) { -+ g_debug ("GdmSession: the session is running, and therefore can't be used"); - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("Can only be called before user is logged in")); - return TRUE; - } - } - - allowed_user = gdm_session_get_allowed_user (session); - - if (uid != allowed_user) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("Caller not GDM")); - return TRUE; - } - - address = gdm_session_get_server_address (session); - - if (address == NULL) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("Unable to open private communication channel")); - return TRUE; - } - - gdm_dbus_manager_complete_open_session (GDM_DBUS_MANAGER (manager), - invocation, -@@ -1017,60 +1038,64 @@ open_temporary_reauthentication_channel (GdmManager *self, - char *seat_id, - char *session_id, - GPid pid, - uid_t uid, - gboolean is_remote) - { - GdmSession *session; - char **environment; - const char *display, *auth_file; - const char *address; - - /* Note we're just using a minimal environment here rather than the - * session's environment because the caller is unprivileged and the - * associated worker will be privileged */ - environment = g_get_environ (); - display = ""; - auth_file = "/dev/null"; - - session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE, - uid, - display, - NULL, - NULL, - seat_id, - auth_file, - is_remote == FALSE, - (const char * const *) - environment); - g_strfreev (environment); - -+ g_debug ("GdmSession: Created session for temporary reauthentication channel for user %d (seat %s)", -+ (int) uid, -+ seat_id); -+ - g_object_set_data_full (G_OBJECT (session), - "caller-session-id", - g_strdup (session_id), - (GDestroyNotify) - g_free); - g_object_set_data (G_OBJECT (session), - "caller-pid", - GUINT_TO_POINTER (pid)); - g_hash_table_insert (self->priv->transient_sessions, - GINT_TO_POINTER (pid), - session); - - g_signal_connect (session, - "client-connected", - G_CALLBACK (on_reauthentication_client_connected), - self); - g_signal_connect (session, - "client-disconnected", - G_CALLBACK (on_reauthentication_client_disconnected), - self); - g_signal_connect (session, - "client-rejected", - G_CALLBACK (on_reauthentication_client_rejected), - self); - g_signal_connect (session, - "cancelled", - G_CALLBACK (on_reauthentication_cancelled), - self); - g_signal_connect (session, - "conversation-started", -@@ -1096,65 +1121,67 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager - const char *username) - { - GdmManager *self = GDM_MANAGER (manager); - const char *sender; - GdmDisplay *display = NULL; - GdmSession *session; - GDBusConnection *connection; - char *seat_id = NULL; - char *session_id = NULL; - GPid pid = 0; - uid_t uid = (uid_t) -1; - gboolean is_login_screen = FALSE; - gboolean is_remote = FALSE; - - g_debug ("GdmManager: trying to open reauthentication channel for user %s", username); - - sender = g_dbus_method_invocation_get_sender (invocation); - connection = g_dbus_method_invocation_get_connection (invocation); - get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, NULL, &pid, &uid, &is_login_screen, &is_remote); - - if (session_id == NULL || pid == 0 || uid == (uid_t) -1) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("No session available")); - - return TRUE; - } - - if (is_login_screen) { -+ g_debug ("GdmManager: looking for login screen session for user %s on seat %s", username, seat_id); - session = find_session_for_user_on_seat (self, - username, - seat_id, - NULL); - } else { -+ g_debug ("GdmManager: looking for user session on display"); - session = get_user_session_for_display (display); - } - - if (session != NULL && gdm_session_is_running (session)) { - gdm_session_start_reauthentication (session, pid, uid); - g_hash_table_insert (self->priv->open_reauthentication_requests, - GINT_TO_POINTER (pid), - invocation); - } else if (is_login_screen) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - "Login screen only allowed to open reauthentication channels for running sessions"); - return TRUE; - } else { - char *address; - address = open_temporary_reauthentication_channel (self, - seat_id, - session_id, - pid, - uid, - is_remote); - gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), - invocation, - address); - g_free (address); - } - - return TRUE; - } -@@ -2087,107 +2114,107 @@ on_session_client_ready_for_session_to_start (GdmSession *session, - if (client_is_ready) { - g_debug ("GdmManager: Will start session when ready"); - } else { - g_debug ("GdmManager: Will start session when ready and told"); - } - - waiting_to_start_user_session = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), - "waiting-to-start")); - - g_object_set_data (G_OBJECT (session), - "start-when-ready", - GINT_TO_POINTER (client_is_ready)); - - if (client_is_ready && waiting_to_start_user_session) { - start_user_session_if_ready (manager, session, service_name); - } - } - - static void - on_session_client_connected (GdmSession *session, - GCredentials *credentials, - GPid pid_of_client, - GdmManager *manager) - { - GdmDisplay *display; - char *username; - int delay; - gboolean enabled; - gboolean allow_timed_login = FALSE; - -- g_debug ("GdmManager: client connected"); -+ g_debug ("GdmManager: client with pid %d connected", (int) pid_of_client); - - display = get_display_for_user_session (session); - - if (display == NULL) { - return; - } - - if (!display_is_on_seat0 (display)) { - return; - } - - #ifdef WITH_PLYMOUTH - if (manager->priv->plymouth_is_running) { - plymouth_quit_with_transition (); - manager->priv->plymouth_is_running = FALSE; - } - #endif - - g_object_get (G_OBJECT (display), "allow-timed-login", &allow_timed_login, NULL); - - if (!allow_timed_login) { - return; - } - - enabled = get_timed_login_details (manager, &username, &delay); - - if (! enabled) { - return; - } - - gdm_session_set_timed_login_details (session, username, delay); - - g_debug ("GdmManager: Starting automatic login conversation (for timed login)"); - gdm_session_start_conversation (session, "gdm-autologin"); - - g_free (username); - - } - - static void - on_session_client_disconnected (GdmSession *session, - GCredentials *credentials, - GPid pid_of_client, - GdmManager *manager) - { -- g_debug ("GdmManager: client disconnected"); -+ g_debug ("GdmManager: client with pid %d disconnected", (int) pid_of_client); - } - - typedef struct - { - GdmManager *manager; - GdmSession *session; - guint idle_id; - } ResetSessionOperation; - - static void - destroy_reset_session_operation (ResetSessionOperation *operation) - { - g_object_set_data (G_OBJECT (operation->session), - "reset-session-operation", - NULL); - g_object_unref (operation->session); - g_slice_free (ResetSessionOperation, operation); - } - - static gboolean - on_reset_session (ResetSessionOperation *operation) - { - gdm_session_reset (operation->session); - - destroy_reset_session_operation (operation); - - return G_SOURCE_REMOVE; - } - - static void -@@ -2200,63 +2227,64 @@ queue_session_reset (GdmManager *manager, - - if (operation != NULL) { - return; - } - - operation = g_slice_new0 (ResetSessionOperation); - operation->manager = manager; - operation->session = g_object_ref (session); - operation->idle_id = g_idle_add ((GSourceFunc) on_reset_session, operation); - - g_object_set_data (G_OBJECT (session), "reset-session-operation", operation); - } - - static void - on_session_cancelled (GdmSession *session, - GdmManager *manager) - { - g_debug ("GdmManager: Session was cancelled"); - queue_session_reset (manager, session); - } - - static void - on_session_conversation_started (GdmSession *session, - const char *service_name, - GdmManager *manager) - { - GdmDisplay *display; - gboolean enabled; - char *username; - -- g_debug ("GdmManager: session conversation started for service %s", service_name); -+ g_debug ("GdmManager: session conversation started for service %s on session", service_name); - - if (g_strcmp0 (service_name, "gdm-autologin") != 0) { -+ g_debug ("GdmManager: ignoring session conversation since its not automatic login conversation"); - return; - } - - display = get_display_for_user_session (session); - - if (display == NULL) { - g_debug ("GdmManager: conversation has no associated display"); - return; - } - - if (!display_is_on_seat0 (display)) { - return; - } - - enabled = get_automatic_login_details (manager, &username); - - if (! enabled) { - return; - } - - g_debug ("GdmManager: begin auto login for user '%s'", username); - - /* service_name will be "gdm-autologin" - */ - gdm_session_setup_for_user (session, service_name, username); - - g_free (username); - } - - static void -@@ -2312,60 +2340,66 @@ create_user_session_for_display (GdmManager *manager, - char *display_auth_file = NULL; - char *display_seat_id = NULL; - char *display_id = NULL; - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - char *display_session_type = NULL; - gboolean greeter_is_wayland; - #endif - - g_object_get (G_OBJECT (display), - "id", &display_id, - "x11-display-name", &display_name, - "is-local", &display_is_local, - "remote-hostname", &remote_hostname, - "x11-authority-file", &display_auth_file, - "seat-id", &display_seat_id, - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - "session-type", &display_session_type, - #endif - NULL); - display_device = get_display_device (manager, display); - - session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN, - allowed_user, - display_name, - remote_hostname, - display_device, - display_seat_id, - display_auth_file, - display_is_local, - NULL); -+ -+ g_debug ("GdmSession: Created user session for user %d on display %s (seat %s)", -+ (int) allowed_user, -+ display_id, -+ display_seat_id); -+ - g_free (display_name); - g_free (remote_hostname); - g_free (display_auth_file); - g_free (display_seat_id); - - g_signal_connect (session, - "reauthentication-started", - G_CALLBACK (on_session_reauthentication_started), - manager); - g_signal_connect (session, - "reauthenticated", - G_CALLBACK (on_session_reauthenticated), - manager); - g_signal_connect (session, - "client-ready-for-session-to-start", - G_CALLBACK (on_session_client_ready_for_session_to_start), - manager); - g_signal_connect (session, - "client-connected", - G_CALLBACK (on_session_client_connected), - manager); - g_signal_connect (session, - "client-disconnected", - G_CALLBACK (on_session_client_disconnected), - manager); - g_signal_connect (session, - "cancelled", - G_CALLBACK (on_session_cancelled), - manager); - g_signal_connect (session, -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 0f821e390..f23a83c5e 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -624,61 +624,64 @@ get_fallback_session_name (GdmSession *self) - - static const char * - get_default_session_name (GdmSession *self) - { - if (self->priv->saved_session != NULL) { - return self->priv->saved_session; - } - - return get_fallback_session_name (self); - } - - static void - gdm_session_defaults_changed (GdmSession *self) - { - - update_session_type (self); - - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface, - get_default_language_name (self)); - gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface, - get_default_session_name (self)); - } - } - - void - gdm_session_select_user (GdmSession *self, - const char *text) - { - -- g_debug ("GdmSession: Setting user: '%s'", text); -+ g_debug ("GdmSession: selecting user '%s' for session '%s' (%p)", -+ text, -+ gdm_session_get_session_id (self), -+ self); - - g_free (self->priv->selected_user); - self->priv->selected_user = g_strdup (text); - - g_free (self->priv->saved_session); - self->priv->saved_session = NULL; - - g_free (self->priv->saved_session_type); - self->priv->saved_session_type = NULL; - - g_free (self->priv->saved_language); - self->priv->saved_language = NULL; - } - - static void - cancel_pending_query (GdmSessionConversation *conversation) - { - if (conversation->pending_invocation == NULL) { - return; - } - - g_debug ("GdmSession: Cancelling pending query"); - - g_dbus_method_invocation_return_dbus_error (conversation->pending_invocation, - GDM_SESSION_DBUS_ERROR_CANCEL, - "Operation cancelled"); - conversation->pending_invocation = NULL; - } - - static void -@@ -1416,117 +1419,121 @@ gdm_session_handle_client_cancel (GdmDBusUserVerifier *user_verifier_interfac - gdm_dbus_user_verifier_complete_cancel (user_verifier_interface, - invocation); - gdm_session_cancel (self); - return TRUE; - } - - static gboolean - gdm_session_handle_client_select_session (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *session, - GdmSession *self) - { - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_select_session (greeter_interface, - invocation); - } - gdm_session_select_session (self, session); - return TRUE; - } - - static gboolean - gdm_session_handle_client_select_user (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *username, - GdmSession *self) - { - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_select_user (greeter_interface, - invocation); - } -+ g_debug ("GdmSession: client selected user '%s' on session (%p)", username, self); - gdm_session_select_user (self, username); - return TRUE; - } - - static gboolean - gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *service_name, - gboolean client_is_ready, - GdmSession *self) - { - - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_start_session_when_ready (greeter_interface, - invocation); - } - g_signal_emit (G_OBJECT (self), - signals [CLIENT_READY_FOR_SESSION_TO_START], - 0, - service_name, - client_is_ready); - return TRUE; - } - - static gboolean - gdm_session_handle_get_timed_login_details (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - GdmSession *self) - { - - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface, - invocation, - self->priv->timed_login_username != NULL, - self->priv->timed_login_username != NULL? self->priv->timed_login_username : "", - self->priv->timed_login_delay); - if (self->priv->timed_login_username != NULL) { - gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface, - self->priv->timed_login_username, - self->priv->timed_login_delay); - } - } - return TRUE; - } - - static gboolean - gdm_session_handle_client_begin_auto_login (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *username, - GdmSession *self) - { - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_begin_auto_login (greeter_interface, - invocation); - } - -- g_debug ("GdmSession: begin auto login for user '%s'", username); -+ g_debug ("GdmSession: client requesting automatic login for user '%s' on session '%s' (%p)", -+ username, -+ gdm_session_get_session_id (self), -+ self); - - gdm_session_setup_for_user (self, "gdm-autologin", username); - - return TRUE; - } - - static void - export_user_verifier_interface (GdmSession *self, - GDBusConnection *connection) - { - GdmDBusUserVerifier *user_verifier_interface; - user_verifier_interface = GDM_DBUS_USER_VERIFIER (gdm_dbus_user_verifier_skeleton_new ()); - - g_object_set_data (G_OBJECT (connection), "gdm-session", self); - - g_signal_connect (user_verifier_interface, - "handle-enable-extensions", - G_CALLBACK (gdm_session_handle_client_enable_extensions), - connection); - g_signal_connect (user_verifier_interface, - "handle-begin-verification", - G_CALLBACK (gdm_session_handle_client_begin_verification), - self); - g_signal_connect (user_verifier_interface, - "handle-begin-verification-for-user", - G_CALLBACK (gdm_session_handle_client_begin_verification_for_user), - self); - g_signal_connect (user_verifier_interface, - "handle-answer-query", - G_CALLBACK (gdm_session_handle_client_answer_query), -@@ -1775,61 +1782,63 @@ allow_user_function (GDBusAuthObserver *observer, - { - uid_t client_uid; - GPid pid_of_client; - - client_uid = g_credentials_get_unix_user (credentials, NULL); - if (client_uid == self->priv->allowed_user) { - return TRUE; - } - - g_debug ("GdmSession: User not allowed"); - - pid_of_client = g_credentials_get_unix_pid (credentials, NULL); - g_signal_emit (G_OBJECT (self), - signals [CLIENT_REJECTED], - 0, - credentials, - (guint) - pid_of_client); - - - return FALSE; - } - - static void - setup_outside_server (GdmSession *self) - { - GDBusAuthObserver *observer; - GDBusServer *server; - GError *error = NULL; - -- g_debug ("GdmSession: Creating D-Bus server for greeters and such"); -+ g_debug ("GdmSession: Creating D-Bus server for greeters and such for session %s (%p)", -+ gdm_session_get_session_id (self), -+ self); - - observer = g_dbus_auth_observer_new (); - g_signal_connect_object (observer, - "authorize-authenticated-peer", - G_CALLBACK (allow_user_function), - self, - 0); - - server = gdm_dbus_setup_private_server (observer, &error); - g_object_unref (observer); - - if (server == NULL) { - g_warning ("Cannot create greeter D-Bus server for the session: %s", - error->message); - return; - } - - g_signal_connect_object (server, - "new-connection", - G_CALLBACK (handle_connection_from_outside), - self, - 0); - self->priv->outside_server = server; - - g_dbus_server_start (server); - - g_debug ("GdmSession: D-Bus server for greeters listening on %s", - g_dbus_server_get_client_address (self->priv->outside_server)); - } - -@@ -2160,61 +2169,61 @@ stop_conversation_now (GdmSessionConversation *conversation) - void - gdm_session_set_ignore_wayland (GdmSession *self, - gboolean ignore_wayland) - { - self->priv->ignore_wayland = ignore_wayland; - } - #endif - - gboolean - gdm_session_start_conversation (GdmSession *self, - const char *service_name) - { - GdmSessionConversation *conversation; - - g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); - - conversation = g_hash_table_lookup (self->priv->conversations, - service_name); - - if (conversation != NULL) { - if (!conversation->is_stopping) { - g_warning ("GdmSession: conversation %s started more than once", service_name); - return FALSE; - } - g_debug ("GdmSession: stopping old conversation %s", service_name); - gdm_session_worker_job_stop_now (conversation->job); - g_object_unref (conversation->job); - conversation->job = NULL; - } - -- g_debug ("GdmSession: starting conversation %s", service_name); -+ g_debug ("GdmSession: starting conversation %s for session (%p)", service_name, self); - - conversation = start_conversation (self, service_name); - - g_hash_table_insert (self->priv->conversations, - g_strdup (service_name), conversation); - return TRUE; - } - - void - gdm_session_stop_conversation (GdmSession *self, - const char *service_name) - { - GdmSessionConversation *conversation; - - g_return_if_fail (GDM_IS_SESSION (self)); - - g_debug ("GdmSession: stopping conversation %s", service_name); - - conversation = find_conversation_by_name (self, service_name); - - if (conversation != NULL) { - stop_conversation (conversation); - } - } - - static void - on_initialization_complete_cb (GdmDBusWorker *proxy, - GAsyncResult *res, - gpointer user_data) - { -@@ -2319,60 +2328,64 @@ initialize (GdmSession *self, - } - - 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); - -+ g_debug ("GdmSession: Set up service %s for username %s on session (%p)", -+ service_name, -+ username, -+ 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) { -@@ -2968,60 +2981,64 @@ gdm_session_set_timed_login_details (GdmSession *self, - - gboolean - gdm_session_is_running (GdmSession *self) - { - return self->priv->session_pid > 0; - } - - gboolean - gdm_session_client_is_connected (GdmSession *self) - { - g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); - - return self->priv->outside_connections != NULL; - } - - uid_t - gdm_session_get_allowed_user (GdmSession *self) - { - return self->priv->allowed_user; - } - - void - gdm_session_start_reauthentication (GdmSession *session, - GPid pid_of_caller, - uid_t uid_of_caller) - { - GdmSessionConversation *conversation = session->priv->session_conversation; - - g_return_if_fail (conversation != NULL); - -+ g_debug ("GdmSession: starting reauthentication for session %s for client with pid %d", -+ conversation->session_id, -+ (int) uid_of_caller); -+ - conversation->reauth_pid_of_caller = pid_of_caller; - - gdm_dbus_worker_call_start_reauthentication (conversation->worker_proxy, - (int) pid_of_caller, - (int) uid_of_caller, - conversation->worker_cancellable, - (GAsyncReadyCallback) on_reauthentication_started_cb, - conversation); - } - - const char * - gdm_session_get_server_address (GdmSession *self) - { - g_return_val_if_fail (GDM_IS_SESSION (self), NULL); - - return g_dbus_server_get_client_address (self->priv->outside_server); - } - - const char * - gdm_session_get_username (GdmSession *self) - { - g_return_val_if_fail (GDM_IS_SESSION (self), NULL); - - return self->priv->selected_user; - } - - const char * - gdm_session_get_display_device (GdmSession *self) - { - g_return_val_if_fail (GDM_IS_SESSION (self), NULL); --- -2.21.0 - diff --git a/SOURCES/0002-session-Don-t-leak-remote-greeter-interface.patch b/SOURCES/0002-session-Don-t-leak-remote-greeter-interface.patch deleted file mode 100644 index b3e80dd..0000000 --- a/SOURCES/0002-session-Don-t-leak-remote-greeter-interface.patch +++ /dev/null @@ -1,87 +0,0 @@ -From aeb88313c2110389ec530c8c7d5d816bac24d254 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 15 Sep 2020 00:41:00 -0400 -Subject: [PATCH 2/3] session: Don't leak remote greeter interface - -XDMCP login screens get a "Remote Geeter Interface" exported over -the bus connection (so the login window can provide a Disconnect -button). - -This interface is getting leaked when the session object is disposed, -leaving the bus connection itself undisposed, which causes an fd -leak. - -This commit plugs the interface leak, and thus the fd leak. ---- - daemon/gdm-session.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 540a2534d..d6d8f128a 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -3602,60 +3602,61 @@ gdm_session_get_property (GObject *object, - break; - #ifdef ENABLE_WAYLAND_SUPPORT - case PROP_IGNORE_WAYLAND: - g_value_set_boolean (value, self->priv->ignore_wayland); - break; - #endif - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - gdm_session_dispose (GObject *object) - { - GdmSession *self; - - self = GDM_SESSION (object); - - g_debug ("GdmSession: Disposing session"); - - gdm_session_close (self); - - g_clear_pointer (&self->priv->conversations, - g_hash_table_unref); - - g_clear_object (&self->priv->user_verifier_interface); - g_clear_pointer (&self->priv->user_verifier_extensions, - g_hash_table_unref); - g_clear_object (&self->priv->greeter_interface); -+ g_clear_object (&self->priv->remote_greeter_interface); - g_clear_object (&self->priv->chooser_interface); - - g_free (self->priv->display_name); - self->priv->display_name = NULL; - - g_free (self->priv->display_hostname); - self->priv->display_hostname = NULL; - - g_free (self->priv->display_device); - self->priv->display_device = NULL; - - g_free (self->priv->display_seat_id); - self->priv->display_seat_id = NULL; - - g_free (self->priv->display_x11_authority_file); - self->priv->display_x11_authority_file = NULL; - - g_strfreev (self->priv->conversation_environment); - self->priv->conversation_environment = NULL; - - if (self->priv->worker_server != NULL) { - g_dbus_server_stop (self->priv->worker_server); - g_clear_object (&self->priv->worker_server); - } - - if (self->priv->outside_server != NULL) { - g_dbus_server_stop (self->priv->outside_server); - g_clear_object (&self->priv->outside_server); - } - --- -2.26.2 - diff --git a/SOURCES/0002-session-support-new-accountsservice-Session-and-Sess.patch b/SOURCES/0002-session-support-new-accountsservice-Session-and-Sess.patch index 1269f41..21ea92a 100644 --- a/SOURCES/0002-session-support-new-accountsservice-Session-and-Sess.patch +++ b/SOURCES/0002-session-support-new-accountsservice-Session-and-Sess.patch @@ -1,4 +1,4 @@ -From e625a214d531635db1e48b2dc51ed0e09ef8005b Mon Sep 17 00:00:00 2001 +From 96e78f519a4d5ce2e5b708035ae1f43eb7c1bbd2 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 14 Aug 2018 14:52:41 -0400 Subject: [PATCH 2/4] session: support new accountsservice Session and @@ -12,15 +12,15 @@ a related "SessionType" property to replace "XSession". This commit switches GDM over to use the new properties. --- - daemon/gdm-session-settings.c | 61 ++++++++++++++++++++++++--- + daemon/gdm-session-settings.c | 61 ++++++++++++++++++++++-- daemon/gdm-session-settings.h | 3 ++ - daemon/gdm-session-worker.c | 28 +++++++++++++ + daemon/gdm-session-worker.c | 28 +++++++++++ daemon/gdm-session-worker.xml | 3 ++ - daemon/gdm-session.c | 78 ++++++++++++++++++++++++++--------- - 5 files changed, 148 insertions(+), 25 deletions(-) + daemon/gdm-session.c | 87 +++++++++++++++++++++++++---------- + 5 files changed, 153 insertions(+), 29 deletions(-) diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c -index 933f095bc..8463fad32 100644 +index 484a3b5b..f2b1addd 100644 --- a/daemon/gdm-session-settings.c +++ b/daemon/gdm-session-settings.c @@ -12,114 +12,121 @@ @@ -79,7 +79,9 @@ index 933f095bc..8463fad32 100644 PROP_IS_LOADED }; - G_DEFINE_TYPE (GdmSessionSettings, gdm_session_settings, G_TYPE_OBJECT) + G_DEFINE_TYPE_WITH_PRIVATE (GdmSessionSettings, + gdm_session_settings, + G_TYPE_OBJECT) static void gdm_session_settings_class_init (GdmSessionSettingsClass *settings_class) @@ -91,8 +93,6 @@ index 933f095bc..8463fad32 100644 object_class->finalize = gdm_session_settings_finalize; gdm_session_settings_class_install_properties (settings_class); - - g_type_class_add_private (settings_class, sizeof (GdmSessionSettingsPrivate)); } static void @@ -107,7 +107,7 @@ index 933f095bc..8463fad32 100644 param_spec = g_param_spec_string ("session-name", "Session Name", "The name of the session", - NULL, G_PARAM_READWRITE); + NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_SESSION_NAME, param_spec); + param_spec = g_param_spec_string ("session-type", "Session Type", @@ -118,11 +118,11 @@ index 933f095bc..8463fad32 100644 param_spec = g_param_spec_string ("language-name", "Language Name", "The name of the language", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec); param_spec = g_param_spec_boolean ("is-loaded", NULL, NULL, - FALSE, G_PARAM_READABLE); + FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_IS_LOADED, param_spec); } @@ -305,14 +305,14 @@ index 933f095bc..8463fad32 100644 - session_name = act_user_get_x_session (settings->priv->user); - g_debug ("GdmSessionSettings: saved session is %s", session_name); -+ /* if the user doesn't have saved state, they don't have any settings worth reading */ -+ if (!act_user_get_saved (settings->priv->user)) -+ goto out; + +- if (session_name != NULL) { ++ ++ + + session_type = act_user_get_session_type (settings->priv->user); + session_name = act_user_get_session (settings->priv->user); - -- if (session_name != NULL) { ++ + g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type); + + if (session_type != NULL && session_type[0] != '\0') { @@ -409,7 +409,7 @@ index 933f095bc..8463fad32 100644 return TRUE; } diff --git a/daemon/gdm-session-settings.h b/daemon/gdm-session-settings.h -index 20946bff1..db38ffc72 100644 +index 20946bff..db38ffc7 100644 --- a/daemon/gdm-session-settings.h +++ b/daemon/gdm-session-settings.h @@ -33,37 +33,40 @@ G_BEGIN_DECLS @@ -454,10 +454,10 @@ index 20946bff1..db38ffc72 100644 G_END_DECLS #endif /* GDM_SESSION_SETTINGS_H */ diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index e79073996..ae86d28ac 100644 +index 88fe36c1..c1201b70 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c -@@ -2539,60 +2539,74 @@ gdm_session_worker_handle_set_language_name (GdmDBusWorker *object, +@@ -2664,60 +2664,74 @@ gdm_session_worker_handle_set_language_name (GdmDBusWorker *object, gdm_dbus_worker_complete_set_language_name (object, invocation); return TRUE; } @@ -532,7 +532,7 @@ index e79073996..ae86d28ac 100644 static void do_authenticate (GdmSessionWorker *worker) { -@@ -3001,158 +3015,172 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object, +@@ -3127,158 +3141,172 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object, } else if (g_strcmp0 (key, "x11-authority-file") == 0) { worker->priv->x11_authority_file = g_variant_dup_string (value, NULL); } else if (g_strcmp0 (key, "console") == 0) { @@ -706,7 +706,7 @@ index e79073996..ae86d28ac 100644 const char *log_file) { diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml -index 4280fe095..a215779c8 100644 +index 4280fe09..a215779c 100644 --- a/daemon/gdm-session-worker.xml +++ b/daemon/gdm-session-worker.xml @@ -51,40 +51,43 @@ @@ -754,12 +754,10 @@ index 4280fe095..a215779c8 100644 diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 19d26c92e..e6640aac7 100644 +index 29459346..43da024f 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c -@@ -59,60 +59,61 @@ - - #define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel" +@@ -61,60 +61,61 @@ #define GDM_SESSION_DBUS_OBJECT_PATH "/org/gnome/DisplayManager/Session" #define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker" @@ -782,8 +780,10 @@ index 19d26c92e..e6640aac7 100644 GPid reauth_pid_of_caller; } GdmSessionConversation; - struct _GdmSessionPrivate + struct _GdmSession { + GObject parent; + /* per open scope */ char *selected_program; char *selected_session; @@ -819,25 +819,14 @@ index 19d26c92e..e6640aac7 100644 char *display_name; char *display_hostname; char *display_device; -@@ -312,295 +313,310 @@ on_establish_credentials_cb (GdmDBusWorker *proxy, - return; - - self = g_object_ref (conversation->session); - service_name = g_strdup (conversation->service_name); - - if (worked) { - if (self->priv->user_verifier_interface != NULL) { - gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface, - service_name); - g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name); - } - - switch (self->priv->verification_mode) { - case GDM_SESSION_VERIFICATION_MODE_LOGIN: - case GDM_SESSION_VERIFICATION_MODE_CHOOSER: - gdm_session_open_session (self, service_name); - break; +@@ -328,309 +329,325 @@ on_establish_credentials_cb (GdmDBusWorker *proxy, case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE: + if (self->user_verifier_interface != NULL) { + gdm_dbus_user_verifier_emit_verification_complete (self->user_verifier_interface, + service_name); + g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name); + } + break; default: break; } @@ -849,6 +838,17 @@ index 19d26c92e..e6640aac7 100644 g_object_unref (self); } + static gboolean + supports_session_type (GdmSession *self, + const char *session_type) + { + if (session_type == NULL) + return TRUE; + + return g_strv_contains ((const char * const *) self->supported_session_types, + session_type); + } + static char ** -get_system_session_dirs (GdmSession *self) +get_system_session_dirs (GdmSession *self, @@ -856,6 +856,8 @@ index 19d26c92e..e6640aac7 100644 { GArray *search_array = NULL; char **search_dirs; + int i, j; + const gchar * const *system_data_dirs = g_get_system_data_dirs (); static const char *x_search_dirs[] = { "/etc/X11/sessions/", @@ -868,20 +870,33 @@ index 19d26c92e..e6640aac7 100644 search_array = g_array_new (TRUE, TRUE, sizeof (char *)); -- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); -+ if (type == NULL || strcmp (type, "x11") == 0) -+ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); + for (j = 0; self->supported_session_types[j] != NULL; j++) { + const char *supported_type = self->supported_session_types[j]; + +- if (g_str_equal (supported_type, "x11")) { ++ if (g_str_equal (supported_type, "x11") || ++ (type == NULL || g_str_equal (type, supported_type))) { + for (i = 0; system_data_dirs[i]; i++) { + gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL); + g_array_append_val (search_array, dir); + } + + g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); + } #ifdef ENABLE_WAYLAND_SUPPORT -- if (!self->priv->ignore_wayland) { -+ if ((!self->priv->ignore_wayland && type == NULL) || g_strcmp0 (type, "wayland") == 0) { - #ifdef ENABLE_USER_DISPLAY_SERVER - g_array_prepend_val (search_array, wayland_search_dir); - #else - g_array_append_val (search_array, wayland_search_dir); +- if (g_str_equal (supported_type, "wayland")) { ++ if (g_str_equal (supported_type, "wayland") || ++ (type == NULL || g_str_equal (type, supported_type))) { + for (i = 0; system_data_dirs[i]; i++) { + gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); + g_array_append_val (search_array, dir); + } + + g_array_append_val (search_array, wayland_search_dir); + } #endif } - #endif search_dirs = g_strdupv ((char **) search_array->data); @@ -961,9 +976,9 @@ index 19d26c92e..e6640aac7 100644 *command = NULL; } -+ if (self->priv->ignore_wayland && g_strcmp0 (type, "wayland") == 0) { -+ g_debug ("GdmSession: ignoring wayland session command request for file '%s'", -+ file); ++ if (!supports_session_type (self, type)) { ++ g_debug ("GdmSession: ignoring %s session command request for file '%s'", ++ type, file); + goto out; + } + @@ -1046,11 +1061,11 @@ index 19d26c92e..e6640aac7 100644 { const char *default_language; - if (self->priv->saved_language != NULL) { - return self->priv->saved_language; + if (self->saved_language != NULL) { + return self->saved_language; } - default_language = g_hash_table_lookup (self->priv->environment, + default_language = g_hash_table_lookup (self->environment, "LANG"); if (default_language != NULL) { @@ -1069,10 +1084,10 @@ index 19d26c92e..e6640aac7 100644 GSequence *sessions; GSequenceIter *session; - if (self->priv->fallback_session_name != NULL) { + if (self->fallback_session_name != NULL) { /* verify that the cached version still exists */ -- if (get_session_command_for_name (self, self->priv->fallback_session_name, NULL)) { -+ if (get_session_command_for_name (self, self->priv->fallback_session_name, NULL, NULL)) { +- if (get_session_command_for_name (self, self->fallback_session_name, NULL)) { ++ if (get_session_command_for_name (self, self->fallback_session_name, NULL, NULL)) { goto out; } } @@ -1080,8 +1095,8 @@ index 19d26c92e..e6640aac7 100644 name = g_strdup ("gnome"); - if (get_session_command_for_name (self, name, NULL)) { + if (get_session_command_for_name (self, name, NULL, NULL)) { - g_free (self->priv->fallback_session_name); - self->priv->fallback_session_name = name; + g_free (self->fallback_session_name); + self->fallback_session_name = name; goto out; } g_free (name); @@ -1136,27 +1151,24 @@ index 19d26c92e..e6640aac7 100644 session = g_sequence_iter_next (session); } while (!g_sequence_iter_is_end (session)); - g_free (self->priv->fallback_session_name); - self->priv->fallback_session_name = g_strdup (name); + g_free (self->fallback_session_name); + self->fallback_session_name = g_strdup (name); g_sequence_free (sessions); out: - return self->priv->fallback_session_name; -@@ -616,60 +632,63 @@ get_default_session_name (GdmSession *self) - return get_fallback_session_name (self); - } - + return self->fallback_session_name; +@@ -649,60 +666,63 @@ get_default_session_name (GdmSession *self) static void gdm_session_defaults_changed (GdmSession *self) { update_session_type (self); - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface, + if (self->greeter_interface != NULL) { + gdm_dbus_greeter_emit_default_language_name_changed (self->greeter_interface, get_default_language_name (self)); - gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface, + gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface, get_default_session_name (self)); } } @@ -1166,19 +1178,22 @@ index 19d26c92e..e6640aac7 100644 const char *text) { - g_debug ("GdmSession: Setting user: '%s'", text); + g_debug ("GdmSession: selecting user '%s' for session '%s' (%p)", + text, + gdm_session_get_session_id (self), + self); - g_free (self->priv->selected_user); - self->priv->selected_user = g_strdup (text); + g_free (self->selected_user); + self->selected_user = g_strdup (text); - g_free (self->priv->saved_session); - self->priv->saved_session = NULL; + g_free (self->saved_session); + self->saved_session = NULL; -+ g_free (self->priv->saved_session_type); -+ self->priv->saved_session_type = NULL; ++ g_free (self->saved_session_type); ++ self->saved_session_type = NULL; + - g_free (self->priv->saved_language); - self->priv->saved_language = NULL; + g_free (self->saved_language); + self->saved_language = NULL; } static void @@ -1207,7 +1222,7 @@ index 19d26c92e..e6640aac7 100644 static void set_pending_query (GdmSessionConversation *conversation, -@@ -936,80 +955,91 @@ worker_on_reauthenticated (GdmDBusWorker *worker, +@@ -969,83 +989,94 @@ worker_on_reauthenticated (GdmDBusWorker *worker, GdmSession *self = conversation->session; g_debug ("GdmSession: Emitting 'reauthenticated' signal "); g_signal_emit (self, signals[REAUTHENTICATED], 0, service_name); @@ -1221,11 +1236,11 @@ index 19d26c92e..e6640aac7 100644 GdmSession *self = conversation->session; if (strlen (language_name) > 0) { - g_free (self->priv->saved_language); - self->priv->saved_language = g_strdup (language_name); + g_free (self->saved_language); + self->saved_language = g_strdup (language_name); - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface, + if (self->greeter_interface != NULL) { + gdm_dbus_greeter_emit_default_language_name_changed (self->greeter_interface, language_name); } } @@ -1239,24 +1254,27 @@ index 19d26c92e..e6640aac7 100644 GdmSession *self = conversation->session; - if (! get_session_command_for_name (self, session_name, NULL)) { -+ if (! get_session_command_for_name (self, session_name, self->priv->saved_session_type, NULL)) { ++ if (! get_session_command_for_name (self, session_name, self->saved_session_type, NULL)) { /* ignore sessions that don't exist */ g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name); - g_free (self->priv->saved_session); - self->priv->saved_session = NULL; - } else if (strcmp (session_name, - get_default_session_name (self)) != 0) { - g_free (self->priv->saved_session); - self->priv->saved_session = g_strdup (session_name); + g_free (self->saved_session); + self->saved_session = NULL; + update_session_type (self); + } else { + if (strcmp (session_name, + get_default_session_name (self)) != 0) { + g_free (self->saved_session); + self->saved_session = g_strdup (session_name); - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface, - session_name); + if (self->greeter_interface != NULL) { + gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface, + session_name); + } } + if (self->saved_session_type != NULL) + set_session_type (self, self->saved_session_type); } - update_session_type (self); - } +static void @@ -1266,8 +1284,8 @@ index 19d26c92e..e6640aac7 100644 +{ + GdmSession *self = conversation->session; + -+ g_free (self->priv->saved_session_type); -+ self->priv->saved_session_type = g_strdup (session_type); ++ g_free (self->saved_session_type); ++ self->saved_session_type = g_strdup (session_type); +} + static GdmSessionConversation * @@ -1277,7 +1295,7 @@ index 19d26c92e..e6640aac7 100644 GHashTableIter iter; gpointer key, value; - g_hash_table_iter_init (&iter, self->priv->conversations); + g_hash_table_iter_init (&iter, self->conversations); while (g_hash_table_iter_next (&iter, &key, &value)) { GdmSessionConversation *conversation; @@ -1300,7 +1318,7 @@ index 19d26c92e..e6640aac7 100644 uid_t connecting_user; connecting_user = g_credentials_get_unix_user (credentials, NULL); -@@ -1089,60 +1119,63 @@ register_worker (GdmDBusWorkerManager *worker_manager_interface, +@@ -1125,60 +1156,63 @@ register_worker (GdmDBusWorkerManager *worker_manager_interface, g_dbus_method_invocation_return_value (invocation, NULL); conversation->worker_proxy = gdm_dbus_worker_proxy_new_sync (connection, @@ -1344,8 +1362,8 @@ index 19d26c92e..e6640aac7 100644 g_debug ("GdmSession: Emitting conversation-started signal"); g_signal_emit (self, signals[CONVERSATION_STARTED], 0, conversation->service_name); - if (self->priv->user_verifier_interface != NULL) { - gdm_dbus_user_verifier_emit_conversation_started (self->priv->user_verifier_interface, + if (self->user_verifier_interface != NULL) { + gdm_dbus_user_verifier_emit_conversation_started (self->user_verifier_interface, conversation->service_name); } @@ -1364,9 +1382,9 @@ index 19d26c92e..e6640aac7 100644 g_debug ("GdmSession: Conversation started"); return TRUE; -@@ -1804,60 +1837,63 @@ static void - free_conversation (GdmSessionConversation *conversation) - { +@@ -1921,60 +1955,63 @@ free_conversation (GdmSessionConversation *conversation) + close_conversation (conversation); + if (conversation->job != NULL) { g_warning ("Freeing conversation '%s' with active job", conversation->service_name); } @@ -1428,7 +1446,7 @@ index 19d26c92e..e6640aac7 100644 error = NULL; if (!g_file_get_contents (config_file, &contents, &length, &error)) { g_debug ("Failed to parse '%s': %s", -@@ -2412,83 +2448,83 @@ gdm_session_send_environment (GdmSession *self, +@@ -2533,83 +2570,83 @@ gdm_session_send_environment (GdmSession *self, g_return_if_fail (GDM_IS_SESSION (self)); conversation = find_conversation_by_name (self, service_name); @@ -1442,8 +1460,8 @@ index 19d26c92e..e6640aac7 100644 { /* FIXME: test the session names before we use them? */ - if (self->priv->selected_session != NULL) { - return self->priv->selected_session; + if (self->selected_session != NULL) { + return self->selected_session; } return get_default_session_name (self); @@ -1476,7 +1494,7 @@ index 19d26c92e..e6640aac7 100644 GKeyFile *keyfile; gchar *desktop_names = NULL; - if (self->priv->selected_program != NULL) { + if (self->selected_program != NULL) { return g_strdup ("GNOME-Greeter:GNOME"); } @@ -1509,13 +1527,12 @@ index 19d26c92e..e6640aac7 100644 g_return_if_fail (key != NULL); g_return_if_fail (value != NULL); - g_hash_table_replace (self->priv->environment, + g_hash_table_replace (self->environment, g_strdup (key), g_strdup (value)); } -@@ -3008,115 +3044,117 @@ gdm_session_get_conversation_session_id (GdmSession *self, - +@@ -3179,148 +3216,150 @@ gdm_session_get_conversation_session_id (GdmSession *self, conversation = find_conversation_by_name (self, service_name); if (conversation == NULL) { @@ -1545,11 +1562,16 @@ index 19d26c92e..e6640aac7 100644 filename = get_session_filename (self); -- key_file = load_key_file_for_file (self, filename, &full_path); -+ key_file = load_key_file_for_file (self, filename, "wayland", &full_path); + if (supports_session_type (self, "wayland")) { +- key_file = load_key_file_for_file (self, filename, &full_path); ++ key_file = load_key_file_for_file (self, filename, NULL, &full_path); - if (key_file == NULL) { - goto out; +- if (key_file == NULL) { +- goto out; +- } ++ if (key_file == NULL) { ++ goto out; ++ } } if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { @@ -1558,7 +1580,7 @@ index 19d26c92e..e6640aac7 100644 g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); out: - g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free); + g_clear_pointer (&key_file, g_key_file_free); g_free (filename); return is_wayland_session; } @@ -1571,7 +1593,7 @@ index 19d26c92e..e6640aac7 100644 - gboolean is_wayland_session; + gboolean is_wayland_session = FALSE; + -+ if (!self->priv->ignore_wayland) ++ if (supports_session_type (self, "wayland")) + is_wayland_session = gdm_session_is_wayland_session (self); - is_wayland_session = gdm_session_is_wayland_session (self); @@ -1583,6 +1605,39 @@ index 19d26c92e..e6640aac7 100644 #endif } + gboolean + gdm_session_session_registers (GdmSession *self) + { + g_autoptr(GError) error = NULL; + g_autoptr(GKeyFile) key_file = NULL; + gboolean session_registers = FALSE; + g_autofree char *filename = NULL; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); + + filename = get_session_filename (self); + +- key_file = load_key_file_for_file (self, filename, NULL); ++ key_file = load_key_file_for_file (self, filename, NULL, NULL); + + session_registers = g_key_file_get_boolean (key_file, + G_KEY_FILE_DESKTOP_GROUP, + "X-GDM-SessionRegisters", + &error); + if (!session_registers && + error != NULL && + !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { + g_warning ("GdmSession: Couldn't read session file '%s'", filename); + return FALSE; + } + + g_debug ("GdmSession: '%s' %s self", filename, + session_registers ? "registers" : "does not register"); + + return session_registers; + } + gboolean gdm_session_bypasses_xsession (GdmSession *self) { @@ -1632,10 +1687,10 @@ index 19d26c92e..e6640aac7 100644 gdm_session_get_display_mode (GdmSession *self) { g_debug ("GdmSession: type %s, program? %s, seat %s", - self->priv->session_type, - self->priv->is_program_session? "yes" : "no", - self->priv->display_seat_id); + self->session_type, + self->is_program_session? "yes" : "no", + self->display_seat_id); -- -2.17.1 +2.27.0 diff --git a/SOURCES/0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch b/SOURCES/0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch deleted file mode 100644 index 85175ea..0000000 --- a/SOURCES/0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch +++ /dev/null @@ -1,922 +0,0 @@ -From 4db5bf628396a7191f2392e7d09ab9bbd7c2b533 Mon Sep 17 00:00:00 2001 -From: Xiaoguang Wang -Date: Thu, 16 May 2019 13:26:16 +0800 -Subject: [PATCH 2/3] session-worker: kill user sessions when stop gdm service - -At the moment the session worker exits as soon as it gets SIGTERM. -That means it may fail to stop the user session (which only happens -in the orderly shutdown path). - -This commit sets up a SIGTERM handler that integrates with and -quits the main loop after the session is started. - -It still retains the _exit-on-SIGTERM behavior before the session -is started, to ensure a stuck pam module doesn't prevent the -process from dying. - -Some small changes to commit by Ray Strode. - -Closes #400 ---- - daemon/gdm-session-worker.c | 39 +++++++++++++++++++++++++++--------- - daemon/session-worker-main.c | 33 ++++++++++++++++++++++++++++++ - 2 files changed, 63 insertions(+), 9 deletions(-) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index f6935ab1d..aa288ac8e 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -159,60 +159,61 @@ struct GdmSessionWorkerPrivate - guint32 display_is_initial : 1; - guint state_change_idle_id; - GdmSessionDisplayMode display_mode; - - char *server_address; - GDBusConnection *connection; - GdmDBusWorkerManager *manager; - - GHashTable *reauthentication_requests; - - GdmSessionAuditor *auditor; - GdmSessionSettings *user_settings; - - GDBusMethodInvocation *pending_invocation; - }; - - #ifdef SUPPORTS_PAM_EXTENSIONS - static char gdm_pam_extension_environment_block[_POSIX_ARG_MAX]; - - static const char * const - gdm_supported_pam_extensions[] = { - GDM_PAM_EXTENSION_CHOICE_LIST, - NULL - }; - #endif - - enum { - PROP_0, - PROP_SERVER_ADDRESS, - PROP_IS_REAUTH_SESSION, -+ PROP_STATE, - }; - - static void gdm_session_worker_class_init (GdmSessionWorkerClass *klass); - static void gdm_session_worker_init (GdmSessionWorker *session_worker); - static void gdm_session_worker_finalize (GObject *object); - - static void gdm_session_worker_set_environment_variable (GdmSessionWorker *worker, - const char *key, - const char *value); - - static void queue_state_change (GdmSessionWorker *worker); - - static void worker_interface_init (GdmDBusWorkerIface *iface); - - - typedef int (* GdmSessionWorkerPamNewMessagesFunc) (int, - const struct pam_message **, - struct pam_response **, - gpointer); - - G_DEFINE_TYPE_WITH_CODE (GdmSessionWorker, - gdm_session_worker, - GDM_DBUS_TYPE_WORKER_SKELETON, - G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_WORKER, - worker_interface_init)) - - /* adapted from glib script_execute */ - static void - script_execute (const gchar *file, - char **argv, -@@ -971,100 +972,111 @@ jump_to_vt (GdmSessionWorker *worker, - - g_debug ("GdmSessionWorker: first setting graphics mode to prevent flicker"); - if (ioctl (fd, KDSETMODE, KD_GRAPHICS) < 0) { - g_debug ("GdmSessionWorker: couldn't set graphics mode: %m"); - } - - /* It's possible that the current VT was left in a broken - * combination of states (KD_GRAPHICS with VT_AUTO), that - * can't be switched away from. This call makes sure things - * are set in a way that VT_ACTIVATE should work and - * VT_WAITACTIVE shouldn't hang. - */ - fix_terminal_vt_mode (worker, active_vt_tty_fd); - } else { - fd = active_vt_tty_fd; - } - - handle_terminal_vt_switches (worker, fd); - - if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) { - g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m", - vt_number); - } else if (ioctl (fd, VT_WAITACTIVE, vt_number) < 0) { - g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m", - vt_number); - } - - close (active_vt_tty_fd); - } - -+static void -+gdm_session_worker_set_state (GdmSessionWorker *worker, -+ GdmSessionWorkerState state) -+{ -+ if (worker->priv->state == state) -+ return; -+ -+ worker->priv->state = state; -+ g_object_notify (G_OBJECT (worker), "state"); -+} -+ - static void - gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, - int status) - { - g_debug ("GdmSessionWorker: uninitializing PAM"); - - if (worker->priv->pam_handle == NULL) - return; - - gdm_session_worker_get_username (worker, NULL); - - if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { - pam_close_session (worker->priv->pam_handle, 0); - gdm_session_auditor_report_logout (worker->priv->auditor); - } else { - gdm_session_auditor_report_login_failure (worker->priv->auditor, - status, - pam_strerror (worker->priv->pam_handle, status)); - } - - if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) { - pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED); - } - - pam_end (worker->priv->pam_handle, status); - worker->priv->pam_handle = NULL; - - gdm_session_worker_stop_auditor (worker); - - if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) { - if (worker->priv->login_vt != worker->priv->session_vt) { - jump_to_vt (worker, worker->priv->login_vt); - } - } - - worker->priv->login_vt = 0; - worker->priv->session_vt = 0; - - g_debug ("GdmSessionWorker: state NONE"); -- worker->priv->state = GDM_SESSION_WORKER_STATE_NONE; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE); - } - - static char * - _get_tty_for_pam (const char *x11_display_name, - const char *display_device) - { - #ifdef __sun - return g_strdup (display_device); - #else - return g_strdup (x11_display_name); - #endif - } - - #ifdef PAM_XAUTHDATA - static struct pam_xauth_data * - _get_xauth_for_pam (const char *x11_authority_file) - { - FILE *fh; - Xauth *auth = NULL; - struct pam_xauth_data *retval = NULL; - gsize len = sizeof (*retval) + 1; - - fh = fopen (x11_authority_file, "r"); - if (fh) { - auth = XauReadAuth (fh); - fclose (fh); - } - if (auth) { - len += auth->name_length + auth->data_length; - retval = g_malloc0 (len); -@@ -1173,61 +1185,61 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, - goto out; - } - } - - /* set RHOST */ - if (hostname != NULL && hostname[0] != '\0') { - error_code = pam_set_item (worker->priv->pam_handle, PAM_RHOST, hostname); - g_debug ("error informing authentication system of user's hostname %s: %s", - hostname, - pam_strerror (worker->priv->pam_handle, error_code)); - - if (error_code != PAM_SUCCESS) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_AUTHENTICATING, - "%s", ""); - goto out; - } - } - - /* set seat ID */ - if (seat_id != NULL && seat_id[0] != '\0') { - gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id); - } - - if (strcmp (service, "gdm-launch-environment") == 0) { - gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter"); - } - - g_debug ("GdmSessionWorker: state SETUP_COMPLETE"); -- worker->priv->state = GDM_SESSION_WORKER_STATE_SETUP_COMPLETE; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE); - - /* Temporarily set PAM_TTY with the currently active VT (login screen) - PAM_TTY will be reset with the users VT right before the user session is opened */ - ensure_login_vt (worker); - g_snprintf (tty_string, 256, "/dev/tty%d", worker->priv->login_vt); - pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string); - if (!display_is_local) - worker->priv->password_is_required = TRUE; - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - return TRUE; - } - - static gboolean - gdm_session_worker_authenticate_user (GdmSessionWorker *worker, - gboolean password_is_required, - GError **error) - { - int error_code; - int authentication_flags; - - g_debug ("GdmSessionWorker: authenticating user %s", worker->priv->username); - - authentication_flags = 0; - -@@ -1238,61 +1250,61 @@ gdm_session_worker_authenticate_user (GdmSessionWorker *worker, - /* blocking call, does the actual conversation */ - error_code = pam_authenticate (worker->priv->pam_handle, authentication_flags); - - if (error_code == PAM_AUTHINFO_UNAVAIL) { - g_debug ("GdmSessionWorker: authentication service unavailable"); - - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_SERVICE_UNAVAILABLE, - "%s", ""); - goto out; - } else if (error_code != PAM_SUCCESS) { - g_debug ("GdmSessionWorker: authentication returned %d: %s", error_code, pam_strerror (worker->priv->pam_handle, error_code)); - - /* - * Do not display a different message for user unknown versus - * a failed password for a valid user. - */ - if (error_code == PAM_USER_UNKNOWN) { - error_code = PAM_AUTH_ERR; - } - - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_AUTHENTICATING, - "%s", get_friendly_error_message (error_code)); - goto out; - } - - g_debug ("GdmSessionWorker: state AUTHENTICATED"); -- worker->priv->state = GDM_SESSION_WORKER_STATE_AUTHENTICATED; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_AUTHENTICATED); - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - return TRUE; - } - - static gboolean - gdm_session_worker_authorize_user (GdmSessionWorker *worker, - gboolean password_is_required, - GError **error) - { - int error_code; - int authentication_flags; - - g_debug ("GdmSessionWorker: determining if authenticated user (password required:%d) is authorized to session", - password_is_required); - - authentication_flags = 0; - - if (password_is_required) { - authentication_flags |= PAM_DISALLOW_NULL_AUTHTOK; - } - - /* check that the account isn't disabled or expired - */ - error_code = pam_acct_mgmt (worker->priv->pam_handle, authentication_flags); -@@ -1303,61 +1315,61 @@ gdm_session_worker_authorize_user (GdmSessionWorker *worker, - g_debug ("GdmSessionWorker: authenticated user requires new auth token"); - error_code = pam_chauthtok (worker->priv->pam_handle, PAM_CHANGE_EXPIRED_AUTHTOK); - - gdm_session_worker_get_username (worker, NULL); - - if (error_code != PAM_SUCCESS) { - gdm_session_auditor_report_password_change_failure (worker->priv->auditor); - } else { - gdm_session_auditor_report_password_changed (worker->priv->auditor); - } - } - - /* If the user is reauthenticating, then authorization isn't required to - * proceed, the user is already logged in after all. - */ - if (worker->priv->is_reauth_session) { - error_code = PAM_SUCCESS; - } - - if (error_code != PAM_SUCCESS) { - g_debug ("GdmSessionWorker: user is not authorized to log in: %s", - pam_strerror (worker->priv->pam_handle, error_code)); - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_AUTHORIZING, - "%s", get_friendly_error_message (error_code)); - goto out; - } - - g_debug ("GdmSessionWorker: state AUTHORIZED"); -- worker->priv->state = GDM_SESSION_WORKER_STATE_AUTHORIZED; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_AUTHORIZED); - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - return TRUE; - } - - static void - gdm_session_worker_set_environment_variable (GdmSessionWorker *worker, - const char *key, - const char *value) - { - int error_code; - char *environment_entry; - - if (value != NULL) { - environment_entry = g_strdup_printf ("%s=%s", key, value); - } else { - /* empty value means "remove from environment" */ - environment_entry = g_strdup (key); - } - - error_code = pam_putenv (worker->priv->pam_handle, - environment_entry); - - if (error_code != PAM_SUCCESS) { - g_warning ("cannot put %s in pam environment: %s\n", -@@ -1716,61 +1728,61 @@ gdm_session_worker_accredit_user (GdmSessionWorker *worker, - - /* If the user is reauthenticating and they've made it this far, then there - * is no reason we should lock them out of their session. They've already - * proved they are they same person who logged in, and that's all we care - * about. - */ - if (worker->priv->is_reauth_session) { - error_code = PAM_SUCCESS; - } - - if (error_code != PAM_SUCCESS) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_GIVING_CREDENTIALS, - "%s", - pam_strerror (worker->priv->pam_handle, error_code)); - goto out; - } - - ret = TRUE; - - out: - g_free (home); - g_free (shell); - if (ret) { - g_debug ("GdmSessionWorker: state ACCREDITED"); - ret = TRUE; - - gdm_session_worker_get_username (worker, NULL); - gdm_session_auditor_report_user_accredited (worker->priv->auditor); -- worker->priv->state = GDM_SESSION_WORKER_STATE_ACCREDITED; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCREDITED); - } else { - gdm_session_worker_uninitialize_pam (worker, error_code); - } - - return ret; - } - - static const char * const * - gdm_session_worker_get_environment (GdmSessionWorker *worker) - { - return (const char * const *) pam_getenvlist (worker->priv->pam_handle); - } - - static gboolean - run_script (GdmSessionWorker *worker, - const char *dir) - { - /* scripts are for non-program sessions only */ - if (worker->priv->is_program_session) { - return TRUE; - } - - return gdm_run_script (dir, - worker->priv->username, - worker->priv->x11_display_name, - worker->priv->display_is_local? NULL : worker->priv->hostname, - worker->priv->x11_authority_file); - } - - static void -@@ -2145,61 +2157,61 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, - (char **) - environment, - TRUE); - - gdm_log_init (); - g_debug ("GdmSessionWorker: child '%s' could not be started: %s", - worker->priv->arguments[0], - g_strerror (errno)); - - _exit (EXIT_FAILURE); - } - - if (worker->priv->session_tty_fd > 0) { - close (worker->priv->session_tty_fd); - worker->priv->session_tty_fd = -1; - } - - /* If we end up execing again, make sure we don't use the executable context set up - * by pam_selinux durin pam_open_session - */ - #ifdef HAVE_SELINUX - setexeccon (NULL); - #endif - - worker->priv->child_pid = session_pid; - - g_debug ("GdmSessionWorker: session opened creating reply..."); - g_assert (sizeof (GPid) <= sizeof (int)); - - g_debug ("GdmSessionWorker: state SESSION_STARTED"); -- worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_STARTED; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_STARTED); - - gdm_session_worker_watch_child (worker); - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - return TRUE; - } - - static gboolean - set_up_for_new_vt (GdmSessionWorker *worker) - { - int fd; - char vt_string[256], tty_string[256]; - int session_vt = 0; - - fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); - - if (fd < 0) { - g_debug ("GdmSessionWorker: couldn't open VT master: %m"); - return FALSE; - } - - if (worker->priv->display_is_initial) { - session_vt = atoi (GDM_INITIAL_VT); - } else { - if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) { -@@ -2368,61 +2380,61 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, - break; - case GDM_SESSION_DISPLAY_MODE_NEW_VT: - case GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED: - if (!set_up_for_new_vt (worker)) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_OPENING_SESSION, - "Unable to open VT"); - return FALSE; - } - break; - } - - flags = 0; - - if (worker->priv->is_program_session) { - flags |= PAM_SILENT; - } - - error_code = pam_open_session (worker->priv->pam_handle, flags); - - if (error_code != PAM_SUCCESS) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_OPENING_SESSION, - "%s", pam_strerror (worker->priv->pam_handle, error_code)); - goto out; - } - - g_debug ("GdmSessionWorker: state SESSION_OPENED"); -- worker->priv->state = GDM_SESSION_WORKER_STATE_SESSION_OPENED; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_OPENED); - - session_id = gdm_session_worker_get_environment_variable (worker, "XDG_SESSION_ID"); - - if (session_id != NULL) { - g_free (worker->priv->session_id); - worker->priv->session_id = session_id; - } - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - gdm_session_worker_get_username (worker, NULL); - gdm_session_auditor_report_login (worker->priv->auditor); - - return TRUE; - } - - static void - gdm_session_worker_set_server_address (GdmSessionWorker *worker, - const char *address) - { - g_free (worker->priv->server_address); - worker->priv->server_address = g_strdup (address); - } - - static void - gdm_session_worker_set_is_reauth_session (GdmSessionWorker *worker, -@@ -2445,61 +2457,61 @@ gdm_session_worker_set_property (GObject *object, - case PROP_SERVER_ADDRESS: - gdm_session_worker_set_server_address (self, g_value_get_string (value)); - break; - case PROP_IS_REAUTH_SESSION: - gdm_session_worker_set_is_reauth_session (self, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - gdm_session_worker_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) - { - GdmSessionWorker *self; - - self = GDM_SESSION_WORKER (object); - - switch (prop_id) { - case PROP_SERVER_ADDRESS: - g_value_set_string (value, self->priv->server_address); - break; - case PROP_IS_REAUTH_SESSION: - g_value_set_boolean (value, self->priv->is_reauth_session); - break; - case PROP_STATE: -- g_value_set_int (value, self->priv->state); -+ g_value_set_enum (value, self->priv->state); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static gboolean - gdm_session_worker_handle_set_environment_variable (GdmDBusWorker *object, - GDBusMethodInvocation *invocation, - const char *key, - const char *value) - { - GdmSessionWorker *worker = GDM_SESSION_WORKER (object); - gdm_session_worker_set_environment_variable (worker, key, value); - gdm_dbus_worker_complete_set_environment_variable (object, invocation); - return TRUE; - } - - static gboolean - gdm_session_worker_handle_set_session_name (GdmDBusWorker *object, - GDBusMethodInvocation *invocation, - const char *session_name) - { - GdmSessionWorker *worker = GDM_SESSION_WORKER (object); - g_debug ("GdmSessionWorker: session name set to %s", session_name); - if (worker->priv->user_settings != NULL) - gdm_session_settings_set_session_name (worker->priv->user_settings, - session_name); - gdm_dbus_worker_complete_set_session_name (object, invocation); -@@ -2646,61 +2658,61 @@ do_authorize (GdmSessionWorker *worker) - g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error); - } - worker->priv->pending_invocation = NULL; - } - - static void - do_accredit (GdmSessionWorker *worker) - { - GError *error; - gboolean res; - - /* get kerberos tickets, setup group lists, etc - */ - error = NULL; - res = gdm_session_worker_accredit_user (worker, &error); - - if (res) { - gdm_dbus_worker_complete_establish_credentials (GDM_DBUS_WORKER (worker), worker->priv->pending_invocation); - } else { - g_dbus_method_invocation_take_error (worker->priv->pending_invocation, error); - } - worker->priv->pending_invocation = NULL; - } - - static void - save_account_details_now (GdmSessionWorker *worker) - { - g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED); - - g_debug ("GdmSessionWorker: saving account details for user %s", worker->priv->username); -- worker->priv->state = GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED; -+ gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED); - if (worker->priv->user_settings != NULL) { - if (!gdm_session_settings_save (worker->priv->user_settings, - worker->priv->username)) { - g_warning ("could not save session and language settings"); - } - } - queue_state_change (worker); - } - - static void - on_settings_is_loaded_changed (GdmSessionSettings *user_settings, - GParamSpec *pspec, - GdmSessionWorker *worker) - { - if (!gdm_session_settings_is_loaded (worker->priv->user_settings)) { - return; - } - - /* These signal handlers should be disconnected after the loading, - * so that gdm_session_settings_set_* APIs don't cause the emitting - * of Saved*NameRead D-Bus signals any more. - */ - g_signal_handlers_disconnect_by_func (worker->priv->user_settings, - G_CALLBACK (on_saved_session_name_read), - worker); - - g_signal_handlers_disconnect_by_func (worker->priv->user_settings, - G_CALLBACK (on_saved_language_name_read), - worker); - -@@ -3461,60 +3473,69 @@ worker_interface_init (GdmDBusWorkerIface *interface) - interface->handle_start_reauthentication = gdm_session_worker_handle_start_reauthentication; - } - - static void - gdm_session_worker_class_init (GdmSessionWorkerClass *klass) - { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_session_worker_get_property; - object_class->set_property = gdm_session_worker_set_property; - object_class->constructor = gdm_session_worker_constructor; - object_class->finalize = gdm_session_worker_finalize; - - g_type_class_add_private (klass, sizeof (GdmSessionWorkerPrivate)); - - g_object_class_install_property (object_class, - PROP_SERVER_ADDRESS, - g_param_spec_string ("server-address", - "server address", - "server address", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (object_class, - PROP_IS_REAUTH_SESSION, - g_param_spec_boolean ("is-reauth-session", - "is reauth session", - "is reauth session", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); -+ -+ g_object_class_install_property (object_class, -+ PROP_STATE, -+ g_param_spec_enum ("state", -+ "state", -+ "state", -+ GDM_TYPE_SESSION_WORKER_STATE, -+ GDM_SESSION_WORKER_STATE_NONE, -+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - } - - static void - reauthentication_request_free (ReauthenticationRequest *request) - { - - g_signal_handlers_disconnect_by_func (request->session, - G_CALLBACK (on_reauthentication_client_connected), - request); - g_signal_handlers_disconnect_by_func (request->session, - G_CALLBACK (on_reauthentication_client_disconnected), - request); - g_signal_handlers_disconnect_by_func (request->session, - G_CALLBACK (on_reauthentication_cancelled), - request); - g_signal_handlers_disconnect_by_func (request->session, - G_CALLBACK (on_reauthentication_conversation_started), - request); - g_signal_handlers_disconnect_by_func (request->session, - G_CALLBACK (on_reauthentication_conversation_stopped), - request); - g_signal_handlers_disconnect_by_func (request->session, - G_CALLBACK (on_reauthentication_verification_complete), - request); - g_clear_object (&request->session); - g_slice_free (ReauthenticationRequest, request); - } - - static void - gdm_session_worker_init (GdmSessionWorker *worker) -diff --git a/daemon/session-worker-main.c b/daemon/session-worker-main.c -index 4a3a8ebbe..d96844d2d 100644 ---- a/daemon/session-worker-main.c -+++ b/daemon/session-worker-main.c -@@ -37,104 +37,137 @@ - #include - - #include "gdm-common.h" - #include "gdm-log.h" - #include "gdm-session-worker.h" - - #include "gdm-settings.h" - #include "gdm-settings-direct.h" - #include "gdm-settings-keys.h" - - static GdmSettings *settings = NULL; - - static gboolean - on_sigusr1_cb (gpointer user_data) - { - g_debug ("Got USR1 signal"); - - gdm_log_toggle_debug (); - - return TRUE; - } - - static gboolean - is_debug_set (void) - { - gboolean debug; - gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); - return debug; - } - -+static gboolean -+on_shutdown_signal_cb (gpointer user_data) -+{ -+ GMainLoop *mainloop = user_data; -+ -+ g_main_loop_quit (mainloop); -+ -+ return FALSE; -+} -+ -+static void -+on_state_changed (GdmSessionWorker *worker, -+ GParamSpec *pspec, -+ GMainLoop *main_loop) -+{ -+ GdmSessionWorkerState state; -+ -+ g_object_get (G_OBJECT (worker), "state", &state, NULL); -+ -+ if (state != GDM_SESSION_WORKER_STATE_SESSION_STARTED) -+ return; -+ -+ g_unix_signal_add (SIGTERM, on_shutdown_signal_cb, main_loop); -+} -+ - static void - on_sigterm_cb (int signal_number) - { - _exit (EXIT_SUCCESS); - } - - int - main (int argc, - char **argv) - { - GMainLoop *main_loop; - GOptionContext *context; - GdmSessionWorker *worker; - const char *address; - gboolean is_for_reauth; - static GOptionEntry entries [] = { - { NULL } - }; - - signal (SIGTERM, on_sigterm_cb); - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - /* Translators: worker is a helper process that does the work - of starting up a session */ - context = g_option_context_new (_("GNOME Display Manager Session Worker")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - gdm_log_init (); - - settings = gdm_settings_new (); - if (settings == NULL) { - g_warning ("Unable to initialize settings"); - exit (EXIT_FAILURE); - } - - if (! gdm_settings_direct_init (settings, DATADIR "/gdm/gdm.schemas", "/")) { - g_warning ("Unable to initialize settings"); - exit (EXIT_FAILURE); - } - - gdm_log_set_debug (is_debug_set ()); - - address = g_getenv ("GDM_SESSION_DBUS_ADDRESS"); - if (address == NULL) { - g_warning ("GDM_SESSION_DBUS_ADDRESS not set"); - exit (EXIT_FAILURE); - } - - is_for_reauth = g_getenv ("GDM_SESSION_FOR_REAUTH") != NULL; - - worker = gdm_session_worker_new (address, is_for_reauth); - - main_loop = g_main_loop_new (NULL, FALSE); - -+ g_signal_connect (G_OBJECT (worker), -+ "notify::state", -+ G_CALLBACK (on_state_changed), -+ main_loop); -+ - g_unix_signal_add (SIGUSR1, on_sigusr1_cb, NULL); - - g_main_loop_run (main_loop); - - if (worker != NULL) { -+ g_signal_handlers_disconnect_by_func (worker, -+ G_CALLBACK (on_state_changed), -+ main_loop); - g_object_unref (worker); - } - - g_main_loop_unref (main_loop); - - g_debug ("Worker finished"); - - return 0; - } --- -2.18.1 - diff --git a/SOURCES/0003-daemon-save-os-release-in-accountsservice.patch b/SOURCES/0003-daemon-save-os-release-in-accountsservice.patch index d41e6c3..b670407 100644 --- a/SOURCES/0003-daemon-save-os-release-in-accountsservice.patch +++ b/SOURCES/0003-daemon-save-os-release-in-accountsservice.patch @@ -1,4 +1,4 @@ -From f12d17a6f4f76ba037e9126113684777a070a8f4 Mon Sep 17 00:00:00 2001 +From bd5153305b576f29ea3b8835bd2740a5eda2db0f Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 20 Aug 2018 14:30:59 -0400 Subject: [PATCH 3/4] daemon: save os-release in accountsservice @@ -8,167 +8,31 @@ when they logged in (to detect upgrades). This commit saves that information in accountsservice. --- - daemon/Makefile.am | 10 ++ - daemon/gdm-session-settings.c | 98 +++++++++++++++++++ - data/Makefile.am | 2 + .../com.redhat.AccountsServiceUser.System.xml | 10 ++ - 4 files changed, 120 insertions(+) - create mode 100644 data/com.redhat.AccountsServiceUser.System.xml + daemon/gdm-session-settings.c | 98 +++++++++++++++++++ + daemon/gdm-session.c | 4 +- + daemon/meson.build | 8 ++ + 4 files changed, 118 insertions(+), 2 deletions(-) + create mode 100644 daemon/com.redhat.AccountsServiceUser.System.xml -diff --git a/daemon/Makefile.am b/daemon/Makefile.am -index 3b1b15122..b77c9276e 100644 ---- a/daemon/Makefile.am -+++ b/daemon/Makefile.am -@@ -14,137 +14,147 @@ AM_CPPFLAGS = \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -DLOCALSTATEDIR=\"$(localstatedir)\" \ - -DLOGDIR=\"$(logdir)\" \ - -DSBINDIR=\"$(sbindir)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ - -DGDM_RUN_DIR=\"$(GDM_RUN_DIR)\" \ - -DGDM_XAUTH_DIR=\"$(GDM_XAUTH_DIR)\" \ - -DGDM_SCREENSHOT_DIR=\"$(GDM_SCREENSHOT_DIR)\" \ - -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ - -DGDM_SESSION_DEFAULT_PATH=\"$(GDM_SESSION_DEFAULT_PATH)\" \ - $(DISABLE_DEPRECATED_CFLAGS) \ - $(DAEMON_CFLAGS) \ - $(XLIB_CFLAGS) \ - $(WARN_CFLAGS) \ - $(DEBUG_CFLAGS) \ - $(SYSTEMD_CFLAGS) \ - $(JOURNALD_CFLAGS) \ - $(LIBSELINUX_CFLAGS) \ - -DLANG_CONFIG_FILE=\"$(LANG_CONFIG_FILE)\" \ - $(NULL) - - BUILT_SOURCES = \ - gdm-display-glue.h \ - gdm-manager-glue.h \ - gdm-local-display-glue.h \ - gdm-local-display-factory-glue.h \ - gdm-session-glue.h \ - gdm-session-worker-glue.h \ - gdm-session-enum-types.h \ -+ com.redhat.AccountsServiceUser.System.h \ - $(NULL) - - gdm-session-enum-types.h: gdm-session-enum-types.h.in gdm-session.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - - gdm-session-enum-types.c: gdm-session-enum-types.c.in gdm-session.h - $(AM_V_GEN) glib-mkenums --template $^ > $@ - - gdm-display-glue.c gdm-display-glue.h: gdm-display.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-display-glue \ - $(srcdir)/gdm-display.xml - - gdm-local-display-glue.c gdm-local-display-glue.h: gdm-local-display.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-local-display-glue \ - $(srcdir)/gdm-local-display.xml - - gdm-local-display-factory-glue.c gdm-local-display-factory-glue.h : gdm-local-display-factory.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-local-display-factory-glue \ - $(srcdir)/gdm-local-display-factory.xml - - gdm-manager-glue.c gdm-manager-glue.h : gdm-manager.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-manager-glue \ - $(srcdir)/gdm-manager.xml - - gdm-session-glue.c gdm-session-glue.h : gdm-session.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-session-glue \ - $(srcdir)/gdm-session.xml - - gdm-session-worker-glue.c gdm-session-worker-glue.h : gdm-session-worker.xml Makefile.am - $(AM_V_GEN)gdbus-codegen \ - --c-namespace=GdmDBus \ - --interface-prefix=org.gnome.DisplayManager \ - --generate-c-code=gdm-session-worker-glue \ - $(srcdir)/gdm-session-worker.xml - -+com.redhat.AccountsServiceUser.System.c com.redhat.AccountsServiceUser.System.h: $(top_srcdir)/data/com.redhat.AccountsServiceUser.System.xml Makefile.am -+ $(AM_V_GEN)gdbus-codegen \ -+ --c-namespace=Gdm \ -+ --interface-prefix=com.redhat \ -+ --generate-c-code=com.redhat.AccountsServiceUser.System \ -+ $(top_srcdir)/data/com.redhat.AccountsServiceUser.System.xml +diff --git a/daemon/com.redhat.AccountsServiceUser.System.xml b/daemon/com.redhat.AccountsServiceUser.System.xml +new file mode 100644 +index 00000000..67f5f302 +--- /dev/null ++++ b/daemon/com.redhat.AccountsServiceUser.System.xml +@@ -0,0 +1,10 @@ ++ ++ + - noinst_PROGRAMS = \ - test-session-client \ - $(NULL) - - test_session_client_SOURCES = \ - test-session-client.c \ - $(NULL) - - nodist_test_session_client_SOURCES = \ - gdm-session-glue.h \ - gdm-session-glue.c \ - gdm-manager-glue.h \ - gdm-manager-glue.c \ - $(NULL) - - test_session_client_LDADD = \ - $(DAEMON_LIBS) \ - $(NULL) - - libexec_PROGRAMS = \ - gdm-session-worker \ - gdm-wayland-session \ - gdm-x-session \ - $(NULL) - - gdm_session_worker_SOURCES = \ - session-worker-main.c \ -+ com.redhat.AccountsServiceUser.System.h \ -+ com.redhat.AccountsServiceUser.System.c \ - gdm-session.c \ - gdm-session.h \ - gdm-session-settings.h \ - gdm-session-settings.c \ - gdm-session-auditor.h \ - gdm-session-auditor.c \ - gdm-session-record.c \ - gdm-session-record.h \ - gdm-session-worker.h \ - gdm-session-worker.c \ - gdm-session-worker-job.c \ - gdm-session-worker-common.c \ - gdm-session-worker-common.h \ - gdm-dbus-util.c \ - gdm-dbus-util.h \ - $(NULL) - - if SUPPORTS_PAM_EXTENSIONS - gdm_session_worker_SOURCES += $(top_srcdir)/pam-extensions/gdm-pam-extensions.h - endif - - nodist_gdm_session_worker_SOURCES = \ - gdm-session-glue.h \ - gdm-session-glue.c \ - gdm-session-worker-glue.c \ - gdm-session-worker-glue.h \ - gdm-session-enum-types.c \ - gdm-session-enum-types.h \ - $(NULL) - ++ ++ ++ ++ ++ ++ ++ diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c -index 8463fad32..921e4d501 100644 +index f2b1addd..a4b7f1a6 100644 --- a/daemon/gdm-session-settings.c +++ b/daemon/gdm-session-settings.c @@ -1,70 +1,77 @@ @@ -245,15 +109,15 @@ index 8463fad32..921e4d501 100644 PROP_IS_LOADED }; - G_DEFINE_TYPE (GdmSessionSettings, gdm_session_settings, G_TYPE_OBJECT) + G_DEFINE_TYPE_WITH_PRIVATE (GdmSessionSettings, + gdm_session_settings, + G_TYPE_OBJECT) - static void - gdm_session_settings_class_init (GdmSessionSettingsClass *settings_class) @@ -107,60 +114,62 @@ gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec); param_spec = g_param_spec_boolean ("is-loaded", NULL, NULL, - FALSE, G_PARAM_READABLE); + FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_IS_LOADED, param_spec); } @@ -369,9 +233,9 @@ index 8463fad32..921e4d501 100644 + } + } + - /* if the user doesn't have saved state, they don't have any settings worth reading */ - if (!act_user_get_saved (settings->priv->user)) - goto out; + + + session_type = act_user_get_session_type (settings->priv->user); session_name = act_user_get_session (settings->priv->user); @@ -536,89 +400,212 @@ index 8463fad32..921e4d501 100644 return TRUE; } -diff --git a/data/Makefile.am b/data/Makefile.am -index 192dfa052..d69021985 100644 ---- a/data/Makefile.am -+++ b/data/Makefile.am -@@ -8,60 +8,62 @@ SUBDIRS = \ - $(NULL) +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index 43da024f..c8e04c1b 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -351,72 +351,72 @@ supports_session_type (GdmSession *self, + if (session_type == NULL) + return TRUE; - initdir = $(gdmconfdir)/Init - postdir = $(gdmconfdir)/PostSession - predir = $(gdmconfdir)/PreSession - postlogindir = $(gdmconfdir)/PostLogin - workingdir = $(GDM_WORKING_DIR) - xauthdir = $(GDM_XAUTH_DIR) - screenshotdir = $(GDM_SCREENSHOT_DIR) - cachedir = $(localstatedir)/cache/gdm + return g_strv_contains ((const char * const *) self->supported_session_types, + session_type); + } - Init: $(srcdir)/Init.in - sed -e 's,[@]X_PATH[@],$(X_PATH),g' \ - <$(srcdir)/Init.in >Init + static char ** + get_system_session_dirs (GdmSession *self, + const char *type) + { + GArray *search_array = NULL; + char **search_dirs; + int i, j; + const gchar * const *system_data_dirs = g_get_system_data_dirs (); - PreSession: $(srcdir)/PreSession.in - sed -e 's,[@]X_PATH[@],$(X_PATH),g' \ - <$(srcdir)/PreSession.in >PreSession - PostSession: $(srcdir)/PostSession.in - sed -e 's,[@]X_PATH[@],$(X_PATH),g' \ - <$(srcdir)/PostSession.in >PostSession + static const char *x_search_dirs[] = { + "/etc/X11/sessions/", + DMCONFDIR "/Sessions/", + DATADIR "/gdm/BuiltInSessions/", + DATADIR "/xsessions/", + }; - gdm.conf-custom: $(srcdir)/gdm.conf-custom.in - sed -e 's,[@]GDM_DEFAULTS_CONF[@],$(GDM_DEFAULTS_CONF),g' \ - <$(srcdir)/gdm.conf-custom.in >gdm.conf-custom + static const char *wayland_search_dir = DATADIR "/wayland-sessions/"; - dbusconfdir = $(DBUS_SYS_DIR) - dbusconf_in_files = gdm.conf.in - dbusconf_DATA = $(dbusconf_in_files:.conf.in=.conf) + search_array = g_array_new (TRUE, TRUE, sizeof (char *)); -+EXTRA_DIST += com.redhat.AccountsServiceUser.System.xml + for (j = 0; self->supported_session_types[j] != NULL; j++) { + const char *supported_type = self->supported_session_types[j]; + +- if (g_str_equal (supported_type, "x11") || ++ if (g_str_equal (supported_type, "x11") && + (type == NULL || g_str_equal (type, supported_type))) { + for (i = 0; system_data_dirs[i]; i++) { + gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL); + g_array_append_val (search_array, dir); + } + + g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); + } + + #ifdef ENABLE_WAYLAND_SUPPORT +- if (g_str_equal (supported_type, "wayland") || ++ if (g_str_equal (supported_type, "wayland") && + (type == NULL || g_str_equal (type, supported_type))) { + for (i = 0; system_data_dirs[i]; i++) { + gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); + g_array_append_val (search_array, dir); + } + + g_array_append_val (search_array, wayland_search_dir); + } + #endif + } + + search_dirs = g_strdupv ((char **) search_array->data); + + g_array_free (search_array, TRUE); + + return search_dirs; + } + + static gboolean + is_prog_in_path (const char *prog) + { + char *f; + gboolean ret; + + f = g_find_program_in_path (prog); + ret = (f != NULL); + g_free (f); + return ret; + } + +diff --git a/daemon/meson.build b/daemon/meson.build +index 2e61b644..71c65039 100644 +--- a/daemon/meson.build ++++ b/daemon/meson.build +@@ -15,114 +15,122 @@ local_display_dbus_gen = gnome.gdbus_codegen('gdm-local-display-glue', + 'gdm-local-display.xml', + namespace: 'GdmDBus', + interface_prefix: 'org.gnome.DisplayManager', + autocleanup: 'all', + ) + local_display_factory_dbus_gen = gnome.gdbus_codegen('gdm-local-display-factory-glue', + 'gdm-local-display-factory.xml', + namespace: 'GdmDBus', + interface_prefix: 'org.gnome.DisplayManager', + autocleanup: 'all', + ) + manager_dbus_gen = gnome.gdbus_codegen('gdm-manager-glue', + 'gdm-manager.xml', + namespace: 'GdmDBus', + interface_prefix: 'org.gnome.DisplayManager', + autocleanup: 'all', + ) + session_dbus_gen = gnome.gdbus_codegen('gdm-session-glue', + 'gdm-session.xml', + namespace: 'GdmDBus', + interface_prefix: 'org.gnome.DisplayManager', + autocleanup: 'all', + ) + session_worker_dbus_gen = gnome.gdbus_codegen('gdm-session-worker-glue', + 'gdm-session-worker.xml', + namespace: 'GdmDBus', + interface_prefix: 'org.gnome.DisplayManager', + autocleanup: 'all', + ) + ++accountsservice_system_user_dbus_gen = gnome.gdbus_codegen('com.redhat.AccountsServiceUser.System', ++ 'com.redhat.AccountsServiceUser.System.xml', ++ namespace: 'Gdm', ++ interface_prefix: 'com.redhat', ++ autocleanup: 'all', ++) + - @INTLTOOL_SCHEMAS_RULE@ - @INTLTOOL_XML_NOMERGE_RULE@ + gdm_session_enums = gnome.mkenums('gdm-session-enum-types', + h_template: 'gdm-session-enum-types.h.in', + c_template: 'gdm-session-enum-types.c.in', + sources: 'gdm-session.h', + ) + gdm_session_worker_enums = gnome.mkenums('gdm-session-worker-enum-types', + h_template: 'gdm-session-worker-enum-types.h.in', + c_template: 'gdm-session-worker-enum-types.c.in', + sources: 'gdm-session-worker.h', + ) - # dconf database and profile - dconf_db_files = \ - dconf/defaults/00-upstream-settings \ - dconf/defaults/locks/00-upstream-settings-locks + # Daemons deps + gdm_daemon_deps = [ + libgdmcommon_dep, + accountsservice_dep, + gobject_dep, + gio_dep, + gio_unix_dep, + libpam_dep, + x_deps, + xcb_dep, + ] - dconfdbdir = $(pkgdatadir) - dconfdb_DATA = greeter-dconf-defaults - greeter-dconf-defaults: $(dconf_db_files) - $(AM_V_GEN) dconf compile $@ $(srcdir)/dconf/defaults + if xdmcp_dep.found() and get_option('tcp-wrappers') + gdm_daemon_deps += libwrap_dep + endif - dconfprofiledir = $(DATADIR)/dconf/profile - dconfprofile_DATA = dconf/gdm + # test-session-client + test_session_client_src = [ + 'test-session-client.c', + session_dbus_gen, + manager_dbus_gen, + ] - gsettings_SCHEMAS = org.gnome.login-screen.gschema.xml - @GSETTINGS_RULES@ + test_session_client = executable('test-session-client', + test_session_client_src, + dependencies: gdm_daemon_deps, + include_directories: config_h_dir, + ) - schemasdir = $(pkgdatadir) - schemas_in_files = gdm.schemas.in - schemas_DATA = $(schemas_in_files:.schemas.in=.schemas) + # Session worker + gdm_session_worker_src = [ + 'session-worker-main.c', + 'gdm-session.c', + 'gdm-session-settings.c', + 'gdm-session-auditor.c', + 'gdm-session-record.c', + 'gdm-session-worker.c', + 'gdm-session-worker-job.c', + 'gdm-session-worker-common.c', + 'gdm-dbus-util.c', + dbus_gen, + session_dbus_gen, + session_worker_dbus_gen, ++ accountsservice_system_user_dbus_gen, + gdm_session_enums, + gdm_session_worker_enums, + ] - gdm.schemas.in: $(srcdir)/gdm.schemas.in.in - sed -e 's,[@]GDMPREFETCHCMD[@],$(GDMPREFETCHCMD),g' \ - -e 's,[@]GDM_CUSTOM_CONF[@],$(GDM_CUSTOM_CONF),g' \ - -e 's,[@]GDM_USER_PATH[@],$(GDM_USER_PATH),g' \ - -e 's,[@]GDM_USERNAME[@],$(GDM_USERNAME),g' \ - -e 's,[@]GDM_GROUPNAME[@],$(GDM_GROUPNAME),g' \ - -e 's,[@]HALT_COMMAND[@],$(HALT_COMMAND),g' \ -diff --git a/data/com.redhat.AccountsServiceUser.System.xml b/data/com.redhat.AccountsServiceUser.System.xml -new file mode 100644 -index 000000000..67f5f302c ---- /dev/null -+++ b/data/com.redhat.AccountsServiceUser.System.xml -@@ -0,0 +1,10 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ + gdm_session_worker_deps = [ + gdm_daemon_deps, + ] + + gdm_session_worker_includes = [ + config_h_dir, + ] + + if pam_extensions_supported + gdm_session_worker_src += '../pam-extensions/gdm-pam-extensions.h' + gdm_session_worker_includes += pam_extensions_inc + endif + + if libaudit_dep.found() + gdm_session_worker_deps += libaudit_dep + + gdm_session_worker_src += [ + 'gdm-session-linux-auditor.c', + ] + endif + + if have_adt + gdm_session_worker_src += 'gdm-session-solaris-auditor.c' + endif + + gdm_session_worker = executable('gdm-session-worker', -- -2.17.1 +2.27.0 diff --git a/SOURCES/0003-local-display-factory-Use-correct-session-type-for-n.patch b/SOURCES/0003-local-display-factory-Use-correct-session-type-for-n.patch deleted file mode 100644 index 3bc4336..0000000 --- a/SOURCES/0003-local-display-factory-Use-correct-session-type-for-n.patch +++ /dev/null @@ -1,83 +0,0 @@ -From db47f4de3aab9f4cd6b381ecd9341c94add59bf9 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 16 May 2018 18:36:50 +0100 -Subject: [PATCH 03/51] local-display-factory: Use correct session-type for new - transient displays - -Use the new gdm_local_display_factory_use_wayland() helper to correctly -set the session-type properties for displays created through -gdm_local_display_factory_create_transient_display(). ---- - daemon/gdm-local-display-factory.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index b21e3aee0..e52360a56 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -194,60 +194,62 @@ gdm_local_display_factory_use_wayland (void) - if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) - return TRUE; - } - #endif - return FALSE; - } - - /* - Example: - dbus-send --system --dest=org.gnome.DisplayManager \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/gnome/DisplayManager/Manager \ - org.gnome.DisplayManager.Manager.GetDisplays - */ - gboolean - gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory, - char **id, - GError **error) - { - gboolean ret; - GdmDisplay *display = NULL; - - g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); - - ret = FALSE; - - g_debug ("GdmLocalDisplayFactory: Creating transient display"); - - #ifdef ENABLE_USER_DISPLAY_SERVER - display = gdm_local_display_new (); -+ if (gdm_local_display_factory_use_wayland ()) -+ g_object_set (G_OBJECT (display), "session-type", "wayland", NULL); - #else - if (display == NULL) { - guint32 num; - - num = take_next_display_number (factory); - - display = gdm_legacy_display_new (num); - } - #endif - - g_object_set (display, - "seat-id", "seat0", - "allow-timed-login", FALSE, - NULL); - - 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 */ --- -2.27.0 - diff --git a/SOURCES/0003-session-Don-t-allow-greeter-operations-on-an-running.patch b/SOURCES/0003-session-Don-t-allow-greeter-operations-on-an-running.patch deleted file mode 100644 index cc60c6f..0000000 --- a/SOURCES/0003-session-Don-t-allow-greeter-operations-on-an-running.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 7b83c1dc9645cabadfeb253d7eca427f6a26d10f Mon Sep 17 00:00:00 2001 -From: Iain Lane -Date: Thu, 31 Jan 2019 17:51:52 +0000 -Subject: [PATCH 3/4] session: Don't allow greeter operations on an running - session - -If a client has a reference to a session that starts running, -refuse to allow further operations on the session. - -CVE-2019-3825 ---- - daemon/gdm-session.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 75 insertions(+) - -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index f23a83c5e..a8263ba11 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -1401,130 +1401,205 @@ gdm_session_handle_client_begin_verification_for_user (GdmDBusUserVerifier *u - static gboolean - gdm_session_handle_client_answer_query (GdmDBusUserVerifier *user_verifier_interface, - GDBusMethodInvocation *invocation, - const char *service_name, - const char *answer, - GdmSession *self) - { - gdm_dbus_user_verifier_complete_answer_query (user_verifier_interface, - invocation); - gdm_session_answer_query (self, service_name, answer); - return TRUE; - } - - static gboolean - gdm_session_handle_client_cancel (GdmDBusUserVerifier *user_verifier_interface, - GDBusMethodInvocation *invocation, - GdmSession *self) - { - gdm_dbus_user_verifier_complete_cancel (user_verifier_interface, - invocation); - gdm_session_cancel (self); - return TRUE; - } - - static gboolean - gdm_session_handle_client_select_session (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *session, - GdmSession *self) - { -+ if (gdm_session_is_running (self)) { -+ const char *username; -+ -+ username = gdm_session_get_username (self); -+ g_debug ("GdmSession: refusing to select session %s since it's already running (for user %s)", -+ session, -+ username); -+ g_dbus_method_invocation_return_error (invocation, -+ G_DBUS_ERROR, -+ G_DBUS_ERROR_INVALID_ARGS, -+ "Session already running for user %s", -+ username); -+ return TRUE; -+ } -+ - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_select_session (greeter_interface, - invocation); - } - gdm_session_select_session (self, session); - return TRUE; - } - - static gboolean - gdm_session_handle_client_select_user (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *username, - GdmSession *self) - { -+ if (gdm_session_is_running (self)) { -+ const char *session_username; -+ -+ session_username = gdm_session_get_username (self); -+ g_debug ("GdmSession: refusing to select user %s, since session (%p) already running (for user %s)", -+ username, -+ self, -+ session_username); -+ g_dbus_method_invocation_return_error (invocation, -+ G_DBUS_ERROR, -+ G_DBUS_ERROR_INVALID_ARGS, -+ "Session already running for user %s", -+ session_username); -+ return TRUE; -+ } -+ - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_select_user (greeter_interface, - invocation); - } - g_debug ("GdmSession: client selected user '%s' on session (%p)", username, self); - gdm_session_select_user (self, username); - return TRUE; - } - - static gboolean - gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *service_name, - gboolean client_is_ready, - GdmSession *self) - { -+ if (gdm_session_is_running (self)) { -+ const char *username; -+ -+ username = gdm_session_get_username (self); -+ g_debug ("GdmSession: refusing to start session (%p), since it's already running (for user %s)", -+ self, -+ username); -+ g_dbus_method_invocation_return_error (invocation, -+ G_DBUS_ERROR, -+ G_DBUS_ERROR_INVALID_ARGS, -+ "Session already running for user %s", -+ username); -+ return TRUE; -+ } - - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_start_session_when_ready (greeter_interface, - invocation); - } - g_signal_emit (G_OBJECT (self), - signals [CLIENT_READY_FOR_SESSION_TO_START], - 0, - service_name, - client_is_ready); - return TRUE; - } - - static gboolean - gdm_session_handle_get_timed_login_details (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - GdmSession *self) - { -+ if (gdm_session_is_running (self)) { -+ const char *username; -+ -+ username = gdm_session_get_username (self); -+ g_debug ("GdmSession: refusing to give timed login details, session (%p) already running (for user %s)", -+ self, -+ username); -+ g_dbus_method_invocation_return_error (invocation, -+ G_DBUS_ERROR, -+ G_DBUS_ERROR_INVALID_ARGS, -+ "Session already running for user %s", -+ username); -+ return TRUE; -+ } - - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface, - invocation, - self->priv->timed_login_username != NULL, - self->priv->timed_login_username != NULL? self->priv->timed_login_username : "", - self->priv->timed_login_delay); - if (self->priv->timed_login_username != NULL) { - gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface, - self->priv->timed_login_username, - self->priv->timed_login_delay); - } - } - return TRUE; - } - - static gboolean - gdm_session_handle_client_begin_auto_login (GdmDBusGreeter *greeter_interface, - GDBusMethodInvocation *invocation, - const char *username, - GdmSession *self) - { -+ const char *session_username; -+ -+ if (gdm_session_is_running (self)) { -+ session_username = gdm_session_get_username (self); -+ g_debug ("GdmSession: refusing auto login operation, session (%p) already running for user %s (%s requested)", -+ self, -+ session_username, -+ username); -+ g_dbus_method_invocation_return_error (invocation, -+ G_DBUS_ERROR, -+ G_DBUS_ERROR_INVALID_ARGS, -+ "Session already owned by user %s", -+ session_username); -+ return TRUE; -+ } -+ - if (self->priv->greeter_interface != NULL) { - gdm_dbus_greeter_complete_begin_auto_login (greeter_interface, - invocation); - } - - g_debug ("GdmSession: client requesting automatic login for user '%s' on session '%s' (%p)", - username, - gdm_session_get_session_id (self), - self); - - gdm_session_setup_for_user (self, "gdm-autologin", username); - - return TRUE; - } - - static void - export_user_verifier_interface (GdmSession *self, - GDBusConnection *connection) - { - GdmDBusUserVerifier *user_verifier_interface; - user_verifier_interface = GDM_DBUS_USER_VERIFIER (gdm_dbus_user_verifier_skeleton_new ()); - - g_object_set_data (G_OBJECT (connection), "gdm-session", self); - - g_signal_connect (user_verifier_interface, - "handle-enable-extensions", - G_CALLBACK (gdm_session_handle_client_enable_extensions), - connection); - g_signal_connect (user_verifier_interface, - "handle-begin-verification", --- -2.21.0 - diff --git a/SOURCES/0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch b/SOURCES/0003-session-ensure-login-screen-over-XDMCP-connects-to-i.patch similarity index 91% rename from SOURCES/0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch rename to SOURCES/0003-session-ensure-login-screen-over-XDMCP-connects-to-i.patch index bf19d59..79b75d0 100644 --- a/SOURCES/0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch +++ b/SOURCES/0003-session-ensure-login-screen-over-XDMCP-connects-to-i.patch @@ -1,7 +1,7 @@ -From b8c942b5f191eaa39ac1e578fa019b32a516cd5c Mon Sep 17 00:00:00 2001 +From 64e8db8432158e5115df18a03bb87ecc1d58ae63 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 11 Feb 2019 10:32:55 -0500 -Subject: [PATCH] session: ensure login screen over XDMCP connects to its +Subject: [PATCH 3/3] session: ensure login screen over XDMCP connects to its session Right now GTK preferentially picks the wayland display over an @@ -17,10 +17,10 @@ the session is X11. 1 file changed, 19 insertions(+) diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index e6640aac7..0f821e390 100644 +index 77d6b8ff0..357e4a297 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c -@@ -2614,60 +2614,79 @@ set_up_session_environment (GdmSession *self) +@@ -2697,60 +2697,79 @@ set_up_session_environment (GdmSession *self) } static void @@ -42,8 +42,8 @@ index e6640aac7..0f821e390 100644 { const char *session_type = "x11"; - if (self->priv->session_type != NULL) { - session_type = self->priv->session_type; + if (self->session_type != NULL) { + session_type = self->session_type; } gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy, @@ -101,5 +101,5 @@ index e6640aac7..0f821e390 100644 gpointer key, value; -- -2.18.1 +2.30.1 diff --git a/SOURCES/0003-session-worker-uninitialize-pam-if-worker-is-killed.patch b/SOURCES/0003-session-worker-uninitialize-pam-if-worker-is-killed.patch deleted file mode 100644 index e79e546..0000000 --- a/SOURCES/0003-session-worker-uninitialize-pam-if-worker-is-killed.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 1987a539495f38ade3efc561f65b56316080356e Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 24 Jun 2019 16:21:59 -0400 -Subject: [PATCH 3/3] session-worker: uninitialize pam if worker is killed - -Right nowe don't uninitialize pam or switch back to the -starting VT if the worker is killed before the session. - -This commit fixes that. ---- - daemon/gdm-session-worker.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index aa288ac8e..0322037e0 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -3552,60 +3552,64 @@ gdm_session_worker_init (GdmSessionWorker *worker) - static void - gdm_session_worker_unwatch_child (GdmSessionWorker *worker) - { - if (worker->priv->child_watch_id == 0) - return; - - g_source_remove (worker->priv->child_watch_id); - worker->priv->child_watch_id = 0; - } - - - static void - gdm_session_worker_finalize (GObject *object) - { - GdmSessionWorker *worker; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_SESSION_WORKER (object)); - - worker = GDM_SESSION_WORKER (object); - - g_return_if_fail (worker->priv != NULL); - - gdm_session_worker_unwatch_child (worker); - - if (worker->priv->child_pid > 0) { - gdm_signal_pid (worker->priv->child_pid, SIGTERM); - gdm_wait_on_pid (worker->priv->child_pid); - } - -+ if (worker->priv->pam_handle != NULL) { -+ gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); -+ } -+ - g_clear_object (&worker->priv->user_settings); - g_free (worker->priv->service); - g_free (worker->priv->x11_display_name); - g_free (worker->priv->x11_authority_file); - g_free (worker->priv->display_device); - g_free (worker->priv->display_seat_id); - g_free (worker->priv->hostname); - g_free (worker->priv->username); - g_free (worker->priv->server_address); - g_strfreev (worker->priv->arguments); - g_strfreev (worker->priv->extensions); - - g_hash_table_unref (worker->priv->reauthentication_requests); - - G_OBJECT_CLASS (gdm_session_worker_parent_class)->finalize (object); - } - - GdmSessionWorker * - gdm_session_worker_new (const char *address, - gboolean is_reauth_session) - { - GObject *object; - - object = g_object_new (GDM_TYPE_SESSION_WORKER, - "server-address", address, - "is-reauth-session", is_reauth_session, - NULL); - - return GDM_SESSION_WORKER (object); - } --- -2.18.1 - diff --git a/SOURCES/0003-xdmcp-display-factory-Clear-launch-environment-when-.patch b/SOURCES/0003-xdmcp-display-factory-Clear-launch-environment-when-.patch deleted file mode 100644 index 2ff5c46..0000000 --- a/SOURCES/0003-xdmcp-display-factory-Clear-launch-environment-when-.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 7c9e236f9015aae2ea5868b67ff8036766cb7099 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 15 Sep 2020 11:28:48 -0400 -Subject: [PATCH 3/3] xdmcp-display-factory: Clear launch environment when done - with it - -The XDMCP disply factory examines the sessions of its displays' -launch environments when the displays change status. - -Unfortunately it leaks a reference to the launch environment when -doing that. - -This commit fixes the reference leak which leads to an fd leak. ---- - daemon/gdm-xdmcp-display-factory.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c -index 2e14beab4..98232113f 100644 ---- a/daemon/gdm-xdmcp-display-factory.c -+++ b/daemon/gdm-xdmcp-display-factory.c -@@ -2091,60 +2091,62 @@ on_display_status_changed (GdmDisplay *display, - gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - break; - case GDM_DISPLAY_FAILED: - gdm_display_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - break; - case GDM_DISPLAY_UNMANAGED: - if (session != NULL) { - g_signal_handlers_disconnect_by_func (G_OBJECT (session), - G_CALLBACK (on_client_disconnected), - display); - } - break; - case GDM_DISPLAY_PREPARED: - break; - case GDM_DISPLAY_MANAGED: - if (session != NULL) { - g_signal_connect_object (G_OBJECT (session), - "client-disconnected", - G_CALLBACK (on_client_disconnected), - display, G_CONNECT_SWAPPED); - g_signal_connect_object (G_OBJECT (session), - "disconnected", - G_CALLBACK (on_client_disconnected), - display, G_CONNECT_SWAPPED); - } - break; - default: - g_assert_not_reached (); - break; - } -+ -+ g_clear_object (&launch_environment); - } - - static GdmDisplay * - gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory, - const char *hostname, - GdmAddress *address, - int displaynum) - { - GdmDisplay *display; - GdmDisplayStore *store; - gboolean use_chooser; - - g_debug ("GdmXdmcpDisplayFactory: Creating xdmcp display for %s:%d", - hostname ? hostname : "(null)", displaynum); - - use_chooser = FALSE; - if (factory->priv->honor_indirect) { - IndirectClient *ic; - - ic = indirect_client_lookup (factory, address); - - /* This was an indirect thingie and nothing was yet chosen, - * use a chooser */ - if (ic != NULL && ic->chosen_address == NULL) { - use_chooser = TRUE; - } - } - - if (use_chooser) { - display = gdm_xdmcp_chooser_display_new (hostname, --- -2.26.2 - diff --git a/SOURCES/0003-xdmcp-display-factory-Set-supported-session-types-fo.patch b/SOURCES/0003-xdmcp-display-factory-Set-supported-session-types-fo.patch new file mode 100644 index 0000000..8e5eb3e --- /dev/null +++ b/SOURCES/0003-xdmcp-display-factory-Set-supported-session-types-fo.patch @@ -0,0 +1,122 @@ +From e3a7ca44c0153ffa895786eabb020810b138eea2 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 14 Sep 2021 11:00:33 -0400 +Subject: [PATCH 3/3] xdmcp-display-factory: Set supported session types for + XDMCP displays + +The lower levels of GDM now expect the session types supported by a +display to be specified up front. + +This commit makes sure XDMCP displays do that. +--- + daemon/gdm-xdmcp-display-factory.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c +index ce8f026e1..558458f1c 100644 +--- a/daemon/gdm-xdmcp-display-factory.c ++++ b/daemon/gdm-xdmcp-display-factory.c +@@ -2104,94 +2104,100 @@ on_display_status_changed (GdmDisplay *display, + break; + case GDM_DISPLAY_MANAGED: + if (session != NULL) { + g_signal_connect_object (G_OBJECT (session), + "client-disconnected", + G_CALLBACK (on_client_disconnected), + display, G_CONNECT_SWAPPED); + g_signal_connect_object (G_OBJECT (session), + "disconnected", + G_CALLBACK (on_client_disconnected), + display, G_CONNECT_SWAPPED); + } + break; + default: + g_assert_not_reached (); + break; + } + + g_clear_object (&launch_environment); + } + + static GdmDisplay * + gdm_xdmcp_display_create (GdmXdmcpDisplayFactory *factory, + const char *hostname, + GdmAddress *address, + int displaynum) + { + GdmDisplay *display; + GdmDisplayStore *store; + gboolean use_chooser; ++ const char *session_types[] = { "x11", NULL }; + + g_debug ("GdmXdmcpDisplayFactory: Creating xdmcp display for %s:%d", + hostname ? hostname : "(null)", displaynum); + + use_chooser = FALSE; + if (factory->honor_indirect) { + IndirectClient *ic; + + ic = indirect_client_lookup (factory, address); + + /* This was an indirect thingie and nothing was yet chosen, + * use a chooser */ + if (ic != NULL && ic->chosen_address == NULL) { + use_chooser = TRUE; + } + } + + if (use_chooser) { + display = gdm_xdmcp_chooser_display_new (hostname, + displaynum, + address, + get_next_session_serial (factory)); + g_signal_connect (display, "hostname-selected", G_CALLBACK (on_hostname_selected), factory); + } else { + display = gdm_xdmcp_display_new (hostname, + displaynum, + address, + get_next_session_serial (factory)); + } + + if (display == NULL) { + goto out; + } + ++ g_object_set (G_OBJECT (display), ++ "session-type", session_types[0], ++ "supported-session-types", session_types, ++ NULL); ++ + if (! gdm_display_prepare (display)) { + gdm_display_unmanage (display); + g_object_unref (display); + display = NULL; + goto out; + } + + g_signal_connect_after (display, + "notify::status", + G_CALLBACK (on_display_status_changed), + factory); + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + gdm_display_store_add (store, display); + + factory->num_pending_sessions++; + out: + + return display; + } + + static void + gdm_xdmcp_send_accept (GdmXdmcpDisplayFactory *factory, + GdmAddress *address, + CARD32 session_id, + ARRAY8Ptr authentication_name, + ARRAY8Ptr authentication_data, + ARRAY8Ptr authorization_name, + ARRAY8Ptr authorization_data) + { +-- +2.31.1 + diff --git a/SOURCES/0004-GdmManager-Don-t-perform-timed-login-if-session-gets.patch b/SOURCES/0004-GdmManager-Don-t-perform-timed-login-if-session-gets.patch deleted file mode 100644 index 158e15a..0000000 --- a/SOURCES/0004-GdmManager-Don-t-perform-timed-login-if-session-gets.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 15a19ac7856c539aa9cfbf76997d18b0275aae35 Mon Sep 17 00:00:00 2001 -From: Iain Lane -Date: Mon, 4 Feb 2019 15:12:38 +0000 -Subject: [PATCH 4/4] GdmManager: Don't perform timed login if session gets - started - -At the moment it's possible for the login screen to initiate -a timed login operation shortly after a user successfully starts -their session. - -GDM won't complete the timed login operation, since a session is -already running, but will erroneously overwrite the username -associated with the session, misattributing the users session -to the timed login user. - -Later, attempts to log in as the timed user will instead unlock the -session for the other user, since that session is now associated -with the timed login user. - -This commit refuses timed login requests on sessions that are -already running, so the username doesn't get corrupted. - -CVE-2019-3825 - -Closes https://gitlab.gnome.org/GNOME/gdm/issues/460 ---- - daemon/gdm-manager.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 0cc06a978..056560b20 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -2116,60 +2116,68 @@ on_session_client_ready_for_session_to_start (GdmSession *session, - } else { - g_debug ("GdmManager: Will start session when ready and told"); - } - - waiting_to_start_user_session = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), - "waiting-to-start")); - - g_object_set_data (G_OBJECT (session), - "start-when-ready", - GINT_TO_POINTER (client_is_ready)); - - if (client_is_ready && waiting_to_start_user_session) { - start_user_session_if_ready (manager, session, service_name); - } - } - - static void - on_session_client_connected (GdmSession *session, - GCredentials *credentials, - GPid pid_of_client, - GdmManager *manager) - { - GdmDisplay *display; - char *username; - int delay; - gboolean enabled; - gboolean allow_timed_login = FALSE; - - g_debug ("GdmManager: client with pid %d connected", (int) pid_of_client); - -+ if (gdm_session_is_running (session)) { -+ const char *session_username; -+ session_username = gdm_session_get_username (session); -+ g_debug ("GdmManager: ignoring connection, since session already running (for user %s)", -+ session_username); -+ return; -+ } -+ - display = get_display_for_user_session (session); - - if (display == NULL) { - return; - } - - if (!display_is_on_seat0 (display)) { - return; - } - - #ifdef WITH_PLYMOUTH - if (manager->priv->plymouth_is_running) { - plymouth_quit_with_transition (); - manager->priv->plymouth_is_running = FALSE; - } - #endif - - g_object_get (G_OBJECT (display), "allow-timed-login", &allow_timed_login, NULL); - - if (!allow_timed_login) { - return; - } - - enabled = get_timed_login_details (manager, &username, &delay); - - if (! enabled) { - return; - } - - gdm_session_set_timed_login_details (session, username, delay); --- -2.21.0 - diff --git a/SOURCES/0004-daemon-handle-upgrades-from-RHEL-7.patch b/SOURCES/0004-daemon-handle-upgrades-from-RHEL-7.patch index cad7650..6d56e3c 100644 --- a/SOURCES/0004-daemon-handle-upgrades-from-RHEL-7.patch +++ b/SOURCES/0004-daemon-handle-upgrades-from-RHEL-7.patch @@ -1,4 +1,4 @@ -From c673a7dd781da5ae0d64e13eb83c17e130231931 Mon Sep 17 00:00:00 2001 +From b7c0541ffccf43994a3e418c4012b17a6dd8b630 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 20 Aug 2018 14:30:59 -0400 Subject: [PATCH 4/4] daemon: handle upgrades from RHEL 7 @@ -12,10 +12,11 @@ or not they were using RHEL 7 and in the event they were try to get the right settings. --- daemon/gdm-session-settings.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) + daemon/gdm-session.c | 19 ++++++++----------- + 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c -index 921e4d501..0ce2e7de2 100644 +index a4b7f1a6..a84b2ffa 100644 --- a/daemon/gdm-session-settings.c +++ b/daemon/gdm-session-settings.c @@ -270,95 +270,114 @@ gdm_session_settings_get_property (GObject *object, @@ -79,9 +80,9 @@ index 921e4d501..0ce2e7de2 100644 } } - /* if the user doesn't have saved state, they don't have any settings worth reading */ - if (!act_user_get_saved (settings->priv->user)) - goto out; + + + session_type = act_user_get_session_type (settings->priv->user); session_name = act_user_get_session (settings->priv->user); @@ -133,6 +134,117 @@ index 921e4d501..0ce2e7de2 100644 G_CALLBACK (on_user_is_loaded_changed), settings); } +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index c8e04c1b..3103e9df 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -3205,98 +3205,95 @@ gdm_session_get_session_id (GdmSession *self) + return conversation->session_id; + } + + const char * + gdm_session_get_conversation_session_id (GdmSession *self, + const char *service_name) + { + GdmSessionConversation *conversation; + + g_return_val_if_fail (GDM_IS_SESSION (self), NULL); + + conversation = find_conversation_by_name (self, service_name); + + if (conversation == NULL) { + return NULL; + } + + return conversation->session_id; + } + + static char * + get_session_filename (GdmSession *self) + { + return g_strdup_printf ("%s.desktop", get_session_name (self)); + } + + #ifdef ENABLE_WAYLAND_SUPPORT + static gboolean + gdm_session_is_wayland_session (GdmSession *self) + { +- GKeyFile *key_file; ++ g_autoptr (GKeyFile) key_file = NULL; + gboolean is_wayland_session = FALSE; +- char *filename; +- char *full_path = NULL; ++ g_autofree char *filename = NULL; ++ g_autofree char *full_path = NULL; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); + + filename = get_session_filename (self); + + if (supports_session_type (self, "wayland")) { + key_file = load_key_file_for_file (self, filename, NULL, &full_path); + + if (key_file == NULL) { + goto out; + } +- } + +- if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { +- is_wayland_session = TRUE; ++ if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { ++ is_wayland_session = TRUE; ++ } + } +- g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); + + out: +- g_clear_pointer (&key_file, g_key_file_free); +- g_free (filename); ++ g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); + return is_wayland_session; + } + #endif + + static void + update_session_type (GdmSession *self) + { + #ifdef ENABLE_WAYLAND_SUPPORT + gboolean is_wayland_session = FALSE; + +- if (supports_session_type (self, "wayland")) +- is_wayland_session = gdm_session_is_wayland_session (self); ++ is_wayland_session = gdm_session_is_wayland_session (self); + + if (is_wayland_session) { + set_session_type (self, "wayland"); + } else { + set_session_type (self, NULL); + } + #endif + } + + gboolean + gdm_session_session_registers (GdmSession *self) + { + g_autoptr(GError) error = NULL; + g_autoptr(GKeyFile) key_file = NULL; + gboolean session_registers = FALSE; + g_autofree char *filename = NULL; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); + + filename = get_session_filename (self); + + key_file = load_key_file_for_file (self, filename, NULL, NULL); + + session_registers = g_key_file_get_boolean (key_file, + G_KEY_FILE_DESKTOP_GROUP, + "X-GDM-SessionRegisters", + &error); + if (!session_registers && + error != NULL && -- -2.17.1 +2.27.0 diff --git a/SOURCES/0004-data-reap-gdm-sessions-on-shutdown.patch b/SOURCES/0004-data-reap-gdm-sessions-on-shutdown.patch deleted file mode 100644 index d0c0451..0000000 --- a/SOURCES/0004-data-reap-gdm-sessions-on-shutdown.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f32adbe9bf26d502cb055b3a6cb98fc57e06bf13 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 26 Jul 2019 14:06:16 -0400 -Subject: [PATCH 4/4] data: reap gdm sessions on shutdown - -If GDM gets shutdown we should make sure all sessions get shutdown too. - -This is a bit of a safety net in case any processes in the session are -lingering after the orderly shutdown. ---- - data/gdm.service.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/data/gdm.service.in b/data/gdm.service.in -index 72201c1fd..202ab6753 100644 ---- a/data/gdm.service.in -+++ b/data/gdm.service.in -@@ -21,6 +21,7 @@ OnFailure=plymouth-quit.service - - [Service] - ExecStart=@sbindir@/gdm -+ExecStopPost=-/usr/bin/bash -c 'for f in /run/systemd/sessions/*; do [ -f $f ] && /usr/bin/fgrep -q SERVICE=gdm $f && loginctl terminate-session $(basename $f); done' - KillMode=mixed - Restart=always - IgnoreSIGPIPE=no --- -2.18.1 - 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 deleted file mode 100644 index 5f95b3b..0000000 --- a/SOURCES/0004-manager-make-get_login_window_session_id-fail-if-no-.patch +++ /dev/null @@ -1,137 +0,0 @@ -From e2e5d2a7d73baa7c24d1f14b276cb653c06dd82f Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 1 Aug 2018 15:46:11 -0400 -Subject: [PATCH 04/51] 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 e44b94373..a9d5628ea 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1372,113 +1372,113 @@ 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) { - 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) { - 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) { - 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.27.0 - diff --git a/SOURCES/0005-manager-avoid-leaking-session_id.patch b/SOURCES/0005-manager-avoid-leaking-session_id.patch deleted file mode 100644 index c287705..0000000 --- a/SOURCES/0005-manager-avoid-leaking-session_id.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 34238a9e845455ae2b92159c71b75b7abedc2eb9 Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Mon, 18 Jun 2018 12:33:42 +0200 -Subject: [PATCH 05/51] manager: avoid leaking session_id - -get_login_window_session_id() duplicates the session id. ---- - daemon/gdm-manager.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index a9d5628ea..71f55ec65 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1449,60 +1449,61 @@ get_login_window_session_id (const char *seat_id, - - 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); -+ g_free (session_id); - } - - static void - maybe_activate_other_session (GdmManager *self, - GdmDisplay *old_display) - { - char *seat_id = NULL; - char *session_id; - 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 (seat_id); - } --- -2.27.0 - diff --git a/SOURCES/0006-manager-gracefully-handle-the-case-of-no-session-for.patch b/SOURCES/0006-manager-gracefully-handle-the-case-of-no-session-for.patch deleted file mode 100644 index f3dc218..0000000 --- a/SOURCES/0006-manager-gracefully-handle-the-case-of-no-session-for.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 454a3daad5148a8ef30cb298af82aa0713e73af7 Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Mon, 18 Jun 2018 12:33:51 +0200 -Subject: [PATCH 06/51] manager: gracefully handle the case of no session for - login window - -get_login_window_session_id() will return TRUE with session_id=NULL when -there's no session. This restults in an assertion failure on -constructing the o.fd.login1.Manager.ActivateSessionOnSeat() arguments: - - GLib: g_variant_new_string: assertion 'string != NULL' failed ---- - daemon/gdm-manager.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 71f55ec65..7a5554e9d 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1448,62 +1448,64 @@ get_login_window_session_id (const char *seat_id, - } - - 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); -- g_free (session_id); -+ if (session_id) { -+ activate_session_id (self, seat_id, session_id); -+ g_free (session_id); -+ } - } - - static void - maybe_activate_other_session (GdmManager *self, - GdmDisplay *old_display) - { - char *seat_id = NULL; - char *session_id; - 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 (seat_id); - } --- -2.27.0 - diff --git a/SOURCES/0007-common-dedupe-gdm_get_login_window_session_id.patch b/SOURCES/0007-common-dedupe-gdm_get_login_window_session_id.patch deleted file mode 100644 index b2c2e03..0000000 --- a/SOURCES/0007-common-dedupe-gdm_get_login_window_session_id.patch +++ /dev/null @@ -1,432 +0,0 @@ -From 2fc9a5f9db7c9d2ab828bcff4ee5dec9c3cf3d3c Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Wed, 1 Aug 2018 16:34:30 -0400 -Subject: [PATCH 07/51] common: dedupe gdm_get_login_window_session_id - -Right now there are two slightly different cut-and-pastes of -the function to get the session id of the login session in -the code. - -This commit deduplicates them. ---- - common/gdm-common.c | 47 ++++++++++++++++++++++++++++++++------------ - common/gdm-common.h | 2 ++ - daemon/gdm-manager.c | 4 ++-- - 3 files changed, 38 insertions(+), 15 deletions(-) - -diff --git a/common/gdm-common.c b/common/gdm-common.c -index c44fa998d..00daf0df8 100644 ---- a/common/gdm-common.c -+++ b/common/gdm-common.c -@@ -364,186 +364,207 @@ create_transient_display (GDBusConnection *connection, - - static gboolean - activate_session_id (GDBusConnection *connection, - const char *seat_id, - const char *session_id) - { - GError *local_error = NULL; - GVariant *reply; - - reply = g_dbus_connection_call_sync (connection, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "ActivateSessionOnSeat", - g_variant_new ("(ss)", session_id, seat_id), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, &local_error); - if (reply == NULL) { - g_warning ("Unable to activate session: %s", local_error->message); - g_error_free (local_error); - return FALSE; - } - - g_variant_unref (reply); - - return TRUE; - } - --static gboolean --get_login_window_session_id (const char *seat_id, -- char **session_id) -+gboolean -+gdm_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) { -+ free (service_class); -+ 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) { - 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); - -- *session_id = g_strdup (sessions[i]); -- ret = TRUE; -- break; -+ res = sd_session_get_service (sessions[i], &service_id); -+ if (res < 0) { -+ 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: -- for (i = 0; sessions[i]; i ++) { -- free (sessions[i]); -- } -+ if (sessions) { -+ for (i = 0; sessions[i]; i ++) { -+ free (sessions[i]); -+ } - -- free (sessions); -+ free (sessions); -+ } - - return ret; - } - - static gboolean - goto_login_session (GDBusConnection *connection, - GError **error) - { - gboolean ret; - int res; - char *our_session; - char *session_id; - char *seat_id; - - ret = FALSE; - session_id = NULL; - seat_id = NULL; - - /* First look for any existing LoginWindow sessions on the seat. - If none are found, create a new one. */ - - /* Note that we mostly use free () here, instead of g_free () - * since the data allocated is from libsystemd-logind, which - * does not use GLib's g_malloc (). */ - - res = sd_pid_get_session (0, &our_session); - if (res < 0) { - g_debug ("failed to determine own session: %s", strerror (-res)); - g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current session.")); - - return FALSE; - } - - res = sd_session_get_seat (our_session, &seat_id); - free (our_session); - if (res < 0) { - g_debug ("failed to determine own seat: %s", strerror (-res)); - g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current seat.")); - - return FALSE; - } - - res = sd_seat_can_multi_session (seat_id); - if (res < 0) { - free (seat_id); - - g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res)); - g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to determine whether to switch to an existing login screen or start up a new login screen.")); - - return FALSE; - } - - if (res == 0) { - free (seat_id); - - g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to start up a new login screen.")); - - return FALSE; - } - -- res = get_login_window_session_id (seat_id, &session_id); -+ res = gdm_get_login_window_session_id (seat_id, &session_id); - if (res && session_id != NULL) { - res = activate_session_id (connection, seat_id, session_id); - - if (res) { - ret = TRUE; - } - } - - if (! ret && g_strcmp0 (seat_id, "seat0") == 0) { - res = create_transient_display (connection, error); - if (res) { - ret = TRUE; - } - } - - free (seat_id); - g_free (session_id); - - return ret; - } - - gboolean - gdm_goto_login_session (GError **error) - { - GError *local_error; - GDBusConnection *connection; - - local_error = NULL; - connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error); - if (connection == NULL) { -diff --git a/common/gdm-common.h b/common/gdm-common.h -index 8d83a1246..c9cbd9c48 100644 ---- a/common/gdm-common.h -+++ b/common/gdm-common.h -@@ -26,51 +26,53 @@ - #include - - #define VE_IGNORE_EINTR(expr) \ - do { \ - errno = 0; \ - expr; \ - } while G_UNLIKELY (errno == EINTR); - - GQuark gdm_common_error_quark (void); - #define GDM_COMMON_ERROR gdm_common_error_quark() - - typedef char * (*GdmExpandVarFunc) (const char *var, - gpointer user_data); - - G_BEGIN_DECLS - - int gdm_wait_on_pid (int pid); - int gdm_wait_on_and_disown_pid (int pid, - int timeout); - int gdm_signal_pid (int pid, - int signal); - gboolean gdm_get_pwent_for_name (const char *name, - struct passwd **pwentp); - - gboolean gdm_clear_close_on_exec_flag (int fd); - - const char * gdm_make_temp_dir (char *template); - - char *gdm_generate_random_bytes (gsize size, - GError **error); -+gboolean gdm_get_login_window_session_id (const char *seat_id, -+ char **session_id); - gboolean gdm_goto_login_session (GError **error); - - GPtrArray *gdm_get_script_environment (const char *username, - const char *display_name, - const char *display_hostname, - const char *display_x11_authority_file); - gboolean gdm_run_script (const char *dir, - const char *username, - const char *display_name, - const char *display_hostname, - const char *display_x11_authority_file); - - gboolean gdm_shell_var_is_valid_char (char c, - gboolean first); - char * gdm_shell_expand (const char *str, - GdmExpandVarFunc expand_func, - gpointer user_data); - - G_END_DECLS - - #endif /* _GDM_COMMON_H */ -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 7a5554e9d..375ef6f80 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1444,61 +1444,61 @@ get_login_window_session_id (const char *seat_id, - 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)) { -+ if (!gdm_get_login_window_session_id (seat_id, &session_id)) { - return; - } - - if (session_id) { - activate_session_id (self, seat_id, session_id); - g_free (session_id); - } - } - - static void - maybe_activate_other_session (GdmManager *self, - GdmDisplay *old_display) - { - char *seat_id = NULL; - char *session_id; - 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); - -@@ -2082,61 +2082,61 @@ on_user_session_exited (GdmSession *session, - - static void - on_user_session_died (GdmSession *session, - int signal_number, - GdmManager *manager) - { - g_debug ("GdmManager: session died with signal %s", strsignal (signal_number)); - remove_user_session (manager, session); - } - - static char * - get_display_device (GdmManager *manager, - GdmDisplay *display) - { - /* systemd finds the display device out on its own based on the display */ - return NULL; - } - - static void - on_session_reauthenticated (GdmSession *session, - const char *service_name, - GdmManager *manager) - { - gboolean fail_if_already_switched = FALSE; - - if (gdm_session_get_display_mode (session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - const char *seat_id; - char *session_id; - - seat_id = gdm_session_get_display_seat_id (session); -- if (get_login_window_session_id (seat_id, &session_id)) { -+ if (gdm_get_login_window_session_id (seat_id, &session_id)) { - GdmDisplay *display = gdm_display_store_find (manager->priv->display_store, - lookup_by_session_id, - (gpointer) session_id); - - if (display != NULL) { - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - } - g_free (session_id); - } - } - - /* There should already be a session running, so jump to its - * VT. In the event we're already on the right VT, (i.e. user - * used an unlock screen instead of a user switched login screen), - * then silently succeed and unlock the session. - */ - switch_to_compatible_user_session (manager, session, fail_if_already_switched); - } - - static void - on_session_client_ready_for_session_to_start (GdmSession *session, - const char *service_name, - gboolean client_is_ready, - GdmManager *manager) - { - gboolean waiting_to_start_user_session; - - if (client_is_ready) { --- -2.27.0 - diff --git a/SOURCES/0008-common-dedupe-activate_session_id.patch b/SOURCES/0008-common-dedupe-activate_session_id.patch deleted file mode 100644 index 3e99665..0000000 --- a/SOURCES/0008-common-dedupe-activate_session_id.patch +++ /dev/null @@ -1,401 +0,0 @@ -From 9d8e72ea9171566e9d74caaf28c8b5933ef34874 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 2 Aug 2018 14:00:46 -0400 -Subject: [PATCH 08/51] common: dedupe activate_session_id - -Right now there are three copies of activate_session_id. - -This commit consolidates the code to gdm-common.c ---- - common/gdm-common.c | 10 +++++----- - common/gdm-common.h | 6 ++++++ - daemon/gdm-manager.c | 33 +-------------------------------- - 3 files changed, 12 insertions(+), 37 deletions(-) - -diff --git a/common/gdm-common.c b/common/gdm-common.c -index 00daf0df8..59317a889 100644 ---- a/common/gdm-common.c -+++ b/common/gdm-common.c -@@ -335,64 +335,64 @@ static gboolean - create_transient_display (GDBusConnection *connection, - GError **error) - { - GError *local_error = NULL; - GVariant *reply; - const char *value; - - reply = g_dbus_connection_call_sync (connection, - GDM_DBUS_NAME, - GDM_DBUS_LOCAL_DISPLAY_FACTORY_PATH, - GDM_DBUS_LOCAL_DISPLAY_FACTORY_INTERFACE, - "CreateTransientDisplay", - NULL, /* parameters */ - G_VARIANT_TYPE ("(o)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, &local_error); - if (reply == NULL) { - g_warning ("Unable to create transient display: %s", local_error->message); - g_propagate_error (error, local_error); - return FALSE; - } - - g_variant_get (reply, "(&o)", &value); - g_debug ("Started %s", value); - - g_variant_unref (reply); - return TRUE; - } - --static gboolean --activate_session_id (GDBusConnection *connection, -- const char *seat_id, -- const char *session_id) -+gboolean -+gdm_activate_session_by_id (GDBusConnection *connection, -+ const char *seat_id, -+ const char *session_id) - { - GError *local_error = NULL; - GVariant *reply; - - reply = g_dbus_connection_call_sync (connection, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "ActivateSessionOnSeat", - g_variant_new ("(ss)", session_id, seat_id), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, &local_error); - if (reply == NULL) { - g_warning ("Unable to activate session: %s", local_error->message); - g_error_free (local_error); - return FALSE; - } - - g_variant_unref (reply); - - return TRUE; - } - - gboolean - gdm_get_login_window_session_id (const char *seat_id, - char **session_id) - { - gboolean ret; -@@ -512,61 +512,61 @@ goto_login_session (GDBusConnection *connection, - - res = sd_session_get_seat (our_session, &seat_id); - free (our_session); - if (res < 0) { - g_debug ("failed to determine own seat: %s", strerror (-res)); - g_set_error (error, GDM_COMMON_ERROR, 0, _("Could not identify the current seat.")); - - return FALSE; - } - - res = sd_seat_can_multi_session (seat_id); - if (res < 0) { - free (seat_id); - - g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res)); - g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to determine whether to switch to an existing login screen or start up a new login screen.")); - - return FALSE; - } - - if (res == 0) { - free (seat_id); - - g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to start up a new login screen.")); - - return FALSE; - } - - res = gdm_get_login_window_session_id (seat_id, &session_id); - if (res && session_id != NULL) { -- res = activate_session_id (connection, seat_id, session_id); -+ res = gdm_activate_session_by_id (connection, seat_id, session_id); - - if (res) { - ret = TRUE; - } - } - - if (! ret && g_strcmp0 (seat_id, "seat0") == 0) { - res = create_transient_display (connection, error); - if (res) { - ret = TRUE; - } - } - - free (seat_id); - g_free (session_id); - - return ret; - } - - gboolean - gdm_goto_login_session (GError **error) - { - GError *local_error; - GDBusConnection *connection; - - local_error = NULL; - connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &local_error); - if (connection == NULL) { - g_debug ("Failed to connect to the D-Bus daemon: %s", local_error->message); - g_propagate_error (error, local_error); -diff --git a/common/gdm-common.h b/common/gdm-common.h -index c9cbd9c48..3fbf07653 100644 ---- a/common/gdm-common.h -+++ b/common/gdm-common.h -@@ -1,78 +1,84 @@ - /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - - #ifndef _GDM_COMMON_H - #define _GDM_COMMON_H - - #include -+#include -+ - #include - #include - - #define VE_IGNORE_EINTR(expr) \ - do { \ - errno = 0; \ - expr; \ - } while G_UNLIKELY (errno == EINTR); - - GQuark gdm_common_error_quark (void); - #define GDM_COMMON_ERROR gdm_common_error_quark() - - typedef char * (*GdmExpandVarFunc) (const char *var, - gpointer user_data); - - G_BEGIN_DECLS - - int gdm_wait_on_pid (int pid); - int gdm_wait_on_and_disown_pid (int pid, - int timeout); - int gdm_signal_pid (int pid, - int signal); - gboolean gdm_get_pwent_for_name (const char *name, - struct passwd **pwentp); - - gboolean gdm_clear_close_on_exec_flag (int fd); - - const char * gdm_make_temp_dir (char *template); - - char *gdm_generate_random_bytes (gsize size, - GError **error); - gboolean gdm_get_login_window_session_id (const char *seat_id, - char **session_id); - gboolean gdm_goto_login_session (GError **error); - - GPtrArray *gdm_get_script_environment (const char *username, - const char *display_name, - const char *display_hostname, - const char *display_x11_authority_file); - gboolean gdm_run_script (const char *dir, - const char *username, - const char *display_name, - const char *display_hostname, - const char *display_x11_authority_file); - - gboolean gdm_shell_var_is_valid_char (char c, - gboolean first); - char * gdm_shell_expand (const char *str, - GdmExpandVarFunc expand_func, - gpointer user_data); - -+gboolean gdm_activate_session_by_id (GDBusConnection *connection, -+ const char *seat_id, -+ const char *session_id); -+ - G_END_DECLS - - #endif /* _GDM_COMMON_H */ -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 375ef6f80..617ee36f0 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -267,91 +267,60 @@ lookup_by_session_id (const char *id, - - static gboolean - is_login_session (GdmManager *self, - const char *session_id, - GError **error) - { - char *session_class = NULL; - int ret; - - ret = sd_session_get_class (session_id, &session_class); - - if (ret < 0) { - g_set_error (error, - GDM_DISPLAY_ERROR, - GDM_DISPLAY_ERROR_GETTING_SESSION_INFO, - "Error getting class for session id %s from systemd: %s", - session_id, - g_strerror (-ret)); - return FALSE; - } - - if (g_strcmp0 (session_class, "greeter") != 0) { - g_free (session_class); - return FALSE; - } - - g_free (session_class); - return TRUE; - } - --static gboolean --activate_session_id (GdmManager *manager, -- const char *seat_id, -- const char *session_id) --{ -- GError *error = NULL; -- GVariant *reply; -- -- reply = g_dbus_connection_call_sync (manager->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 - session_unlock (GdmManager *manager, - const char *ssid) - { - GError *error = NULL; - GVariant *reply; - - g_debug ("Unlocking session %s", ssid); - - reply = g_dbus_connection_call_sync (manager->priv->connection, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "UnlockSession", - g_variant_new ("(s)", ssid), - NULL, /* expected reply */ - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (reply == NULL) { - g_debug ("GdmManager: logind 'UnlockSession' %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; -@@ -627,61 +596,61 @@ switch_to_compatible_user_session (GdmManager *manager, - ret = FALSE; - - username = gdm_session_get_username (session); - seat_id = gdm_session_get_display_seat_id (session); - - if (!fail_if_already_switched) - ssid_to_activate = gdm_session_get_session_id (session); - - if (ssid_to_activate == NULL) { - if (!seat_id || !sd_seat_can_multi_session (seat_id)) { - g_debug ("GdmManager: unable to activate existing sessions from login screen unless on seat0"); - goto out; - } - - if (!fail_if_already_switched) { - session = NULL; - } - - existing_session = find_session_for_user_on_seat (manager, username, seat_id, session); - - if (existing_session != NULL) { - ssid_to_activate = gdm_session_get_session_id (existing_session); - } - } - - if (ssid_to_activate == NULL) { - goto out; - } - - if (seat_id != NULL) { -- res = activate_session_id (manager, seat_id, ssid_to_activate); -+ res = gdm_activate_session_by_id (manager->priv->connection, seat_id, ssid_to_activate); - if (! res) { - g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate); - goto out; - } - } - - res = session_unlock (manager, ssid_to_activate); - if (!res) { - /* this isn't fatal */ - g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate); - } - - ret = TRUE; - - out: - return ret; - } - - static GdmDisplay * - get_display_for_user_session (GdmSession *session) - { - return g_object_get_data (G_OBJECT (session), "gdm-display"); - } - - static GdmSession * - get_user_session_for_display (GdmDisplay *display) - { - if (display == NULL) { - return NULL; - } --- -2.27.0 - diff --git a/SOURCES/0009-manager-plug-leak-in-maybe_activate_other_session.patch b/SOURCES/0009-manager-plug-leak-in-maybe_activate_other_session.patch deleted file mode 100644 index f3236f8..0000000 --- a/SOURCES/0009-manager-plug-leak-in-maybe_activate_other_session.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 5bc19a4eb6de02ba549252026911dcce86e0fc21 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 22 Jun 2018 14:44:11 -0400 -Subject: [PATCH 09/51] 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 617ee36f0..a4dad92ee 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1428,79 +1428,81 @@ out: - 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 (!gdm_get_login_window_session_id (seat_id, &session_id)) { - return; - } - - if (session_id) { - activate_session_id (self, seat_id, session_id); - g_free (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.27.0 - diff --git a/SOURCES/0010-manager-start-login-screen-if-old-one-is-finished.patch b/SOURCES/0010-manager-start-login-screen-if-old-one-is-finished.patch deleted file mode 100644 index 090b728..0000000 --- a/SOURCES/0010-manager-start-login-screen-if-old-one-is-finished.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 2ec1b65c7bc2cefeabbd9a7a3a50436e1233804c Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 22 Jun 2018 14:55:39 -0400 -Subject: [PATCH 10/51] 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 a4dad92ee..a6f13dec7 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1444,61 +1444,61 @@ activate_login_window_session_on_seat (GdmManager *self, - return; - } - - if (session_id) { - activate_session_id (self, seat_id, session_id); - g_free (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.27.0 - diff --git a/SOURCES/0011-manager-don-t-bail-if-session-disappears-out-from-un.patch b/SOURCES/0011-manager-don-t-bail-if-session-disappears-out-from-un.patch deleted file mode 100644 index b843be7..0000000 --- a/SOURCES/0011-manager-don-t-bail-if-session-disappears-out-from-un.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 67d29b19ff4e53d58879b14c2e79a3bda419576f Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 22 Jun 2018 15:26:03 -0400 -Subject: [PATCH 11/51] 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 | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index a6f13dec7..ede22e771 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1349,87 +1349,97 @@ 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) { -+ free (service_class); -+ 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) -+ 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) -+ 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; - } --- -2.27.0 - diff --git a/SOURCES/0012-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch b/SOURCES/0012-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch deleted file mode 100644 index 55868c2..0000000 --- a/SOURCES/0012-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch +++ /dev/null @@ -1,563 +0,0 @@ -From 9a3e9cb9a6bbf68ed6eb9f13d143a63af940f3ae Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 30 Jul 2018 16:21:29 -0400 -Subject: [PATCH 12/51] 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 GdmLocalDisplyFactory 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 | 36 +++++++- - daemon/gdm-manager.c | 143 ----------------------------- - 2 files changed, 31 insertions(+), 148 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index e52360a56..0e454c880 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; -@@ -240,174 +242,198 @@ 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; - 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); - - 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_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - - /* 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_factory_queue_purge_displays (GDM_DISPLAY_FACTORY (factory)); - - /* 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; - - /* workaround logind race for now - * bug 1643874 - */ - g_usleep (2 * G_USEC_PER_SEC); - } - - #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 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 (gdm_get_login_window_session_id (seat_id, &login_session_id)) { -+ if (g_strcmp0 (active_session_id, login_session_id) != 0) { -+ gdm_activate_session_by_id (factory->priv->connection, 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 ede22e771..80f60d24c 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1322,202 +1322,60 @@ maybe_start_pending_initial_login (GdmManager *manager, - char *user_session_seat_id = NULL; - - /* There may be a user session waiting to be started. - * This would happen if we couldn't start it earlier because - * the login screen X server was coming up and two X servers - * can't be started on the same seat at the same time. - */ - - if (manager->priv->initial_login_operation == NULL) { - return; - } - - operation = manager->priv->initial_login_operation; - - g_object_get (G_OBJECT (greeter_display), - "seat-id", &greeter_seat_id, - NULL); - g_object_get (G_OBJECT (operation->session), - "display-seat-id", &user_session_seat_id, - 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 = FALSE; -- goto out; -- } -- -- for (i = 0; sessions[i]; i ++) { -- -- res = sd_session_get_class (sessions[i], &service_class); -- if (res < 0) { -- if (res == -ENOENT) { -- free (service_class); -- 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) -- 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) -- 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 (!gdm_get_login_window_session_id (seat_id, &session_id)) { -- return; -- } -- -- if (session_id) { -- activate_session_id (self, seat_id, session_id); -- g_free (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); - -@@ -1709,61 +1567,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, - GdmDisplay *display, - GdmManager *manager) - { - char *id; - - gdm_display_get_id (display, &id, NULL); - g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); - g_free (id); - - g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); - - g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, display); - } - - static void - destroy_start_user_session_operation (StartUserSessionOperation *operation) - { - g_object_set_data (G_OBJECT (operation->session), - "start-user-session-operation", - NULL); - g_object_unref (operation->session); --- -2.27.0 - diff --git a/SOURCES/0013-local-display-factory-ensure-non-seat0-codepath-does.patch b/SOURCES/0013-local-display-factory-ensure-non-seat0-codepath-does.patch deleted file mode 100644 index 34f4120..0000000 --- a/SOURCES/0013-local-display-factory-ensure-non-seat0-codepath-does.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 299a0981f4e9fc02716d64abf5e5e692e2ad2951 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 3 Aug 2018 16:50:36 -0400 -Subject: [PATCH 13/51] local-display-factory: ensure non-seat0 codepath - doesn't affect seat0 - -create_display currently bails in some cases if any display is running -on the seat. That's the right thing to do on seats other than seat0, -but wrong for seat0 (which an have multiple sessions at the same -time). - -To ensure we never hit the case for seat0, add a call to check if -the passed seat is multi-session capable. ---- - daemon/gdm-local-display-factory.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 0e454c880..7f7735ca1 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -373,61 +373,61 @@ lookup_by_seat_id (const char *id, - } - - 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; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - 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 (gdm_get_login_window_session_id (seat_id, &login_session_id)) { - if (g_strcmp0 (active_session_id, login_session_id) != 0) { - gdm_activate_session_by_id (factory->priv->connection, 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 { -+ } else if (!sd_seat_can_multi_session (seat_id)) { - /* 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); - --- -2.27.0 - diff --git a/SOURCES/0014-daemon-kill-and-restart-greeter-on-demand-under-wayl.patch b/SOURCES/0014-daemon-kill-and-restart-greeter-on-demand-under-wayl.patch deleted file mode 100644 index 84b33da..0000000 --- a/SOURCES/0014-daemon-kill-and-restart-greeter-on-demand-under-wayl.patch +++ /dev/null @@ -1,369 +0,0 @@ -From 08f5f88ca6fb0edfc94af4c85912484b6048691b Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 2 Aug 2018 15:06:09 -0400 -Subject: [PATCH 14/51] daemon: kill and restart greeter on demand under - wayland - -Right now we leave the greeter alive after the user logs in. -This is for two reasons: - -1) When the greeter is running Xorg, there's no way to kill -it when it's running on an inactive VT (X jumps to the foreground -when being killed) - -2) The greeter, in a way, provides a securepath for unlock. -Users in theory could know that by hitting ctrl-alt-f1 to secure -attention, the login screen presented is not spoofed. - -Since we use wayland by default, 1 isn't that much of a concern, -and 2 is a bit of niche feature that most users probably haven't -considered. - -And there's a huge downside to keeping the greeter alive: it uses -a very large amount of memory. - -This commit changes GDM to kill the login screen when switching -away from the login screen's VT and restarting it when switching -back. - -Based heavily on work by Hans de Goede - -Closes: https://gitlab.gnome.org/GNOME/gdm/issues/222 ---- - daemon/gdm-local-display-factory.c | 167 +++++++++++++++++++++++++++++ - 1 file changed, 167 insertions(+) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 7f7735ca1..4ae656ab3 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -34,60 +34,65 @@ - #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; - guint seat_removed_id; -+ -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ char *tty_of_active_vt; -+ guint active_vt_watch_id; -+#endif - }; - - enum { - PROP_0, - }; - - static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); - static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); - static void gdm_local_display_factory_finalize (GObject *object); - - static GdmDisplay *create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial_display); - - static void on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmLocalDisplayFactory *factory); - - static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); - static gpointer local_display_factory_object = NULL; - - G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) - - GQuark - gdm_local_display_factory_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_local_display_factory_error"); -@@ -507,98 +512,260 @@ gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory) - static void - on_seat_new (GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) - { - const char *seat; - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - create_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat, NULL, FALSE); - } - - static void - on_seat_removed (GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) - { - const char *seat; - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); - } - -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+static gboolean -+lookup_by_session_id (const char *id, -+ GdmDisplay *display, -+ gpointer user_data) -+{ -+ const char *looking_for = user_data; -+ const char *current; -+ -+ current = gdm_display_get_session_id (display); -+ return g_strcmp0 (current, looking_for) == 0; -+} -+ -+static void -+maybe_stop_greeter_display (GdmDisplay *display) -+{ -+ g_autofree char *display_session_type = NULL; -+ -+ if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) -+ return; -+ -+ g_object_get (G_OBJECT (display), -+ "session-type", &display_session_type, -+ NULL); -+ -+ /* we can only stop greeter for wayland sessions, since -+ * X server would jump back on exit */ -+ if (g_strcmp0 (display_session_type, "wayland") != 0) -+ return; -+ -+ gdm_display_stop_greeter_session (display); -+ gdm_display_unmanage (display); -+ gdm_display_finish (display); -+} -+ -+static gboolean -+on_vt_changed (GIOChannel *source, -+ GIOCondition condition, -+ GdmLocalDisplayFactory *factory) -+{ -+ GIOStatus status; -+ static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT; -+ g_autofree char *tty_of_previous_vt = NULL; -+ g_autofree char *tty_of_active_vt = NULL; -+ g_autofree char *login_session_id = NULL; -+ g_autofree char *active_session_id = NULL; -+ const char *session_type = NULL; -+ int ret; -+ -+ g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL); -+ -+ if (condition & G_IO_PRI) { -+ g_autoptr (GError) error = NULL; -+ status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error); -+ -+ if (error != NULL) { -+ g_warning ("could not read active VT from kernel: %s", error->message); -+ } -+ switch (status) { -+ case G_IO_STATUS_ERROR: -+ return G_SOURCE_REMOVE; -+ case G_IO_STATUS_EOF: -+ return G_SOURCE_REMOVE; -+ case G_IO_STATUS_AGAIN: -+ return G_SOURCE_CONTINUE; -+ case G_IO_STATUS_NORMAL: -+ break; -+ } -+ } -+ -+ if ((condition & G_IO_ERR) || (condition & G_IO_HUP)) -+ return G_SOURCE_REMOVE; -+ -+ if (tty_of_active_vt == NULL) -+ return G_SOURCE_CONTINUE; -+ -+ g_strchomp (tty_of_active_vt); -+ -+ /* don't do anything if we're on the same VT we were before */ -+ if (g_strcmp0 (tty_of_active_vt, factory->priv->tty_of_active_vt) == 0) -+ return G_SOURCE_CONTINUE; -+ -+ tty_of_previous_vt = g_steal_pointer (&factory->priv->tty_of_active_vt); -+ factory->priv->tty_of_active_vt = g_steal_pointer (&tty_of_active_vt); -+ -+ /* if the old VT was running a wayland login screen kill it -+ */ -+ if (gdm_get_login_window_session_id ("seat0", &login_session_id)) { -+ unsigned int vt; -+ -+ ret = sd_session_get_vt (login_session_id, &vt); -+ if (ret == 0 && vt != 0) { -+ g_autofree char *tty_of_login_window_vt = NULL; -+ -+ tty_of_login_window_vt = g_strdup_printf ("tty%u", vt); -+ -+ if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { -+ GdmDisplayStore *store; -+ GdmDisplay *display; -+ -+ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); -+ display = gdm_display_store_find (store, -+ lookup_by_session_id, -+ (gpointer) login_session_id); -+ -+ if (display != NULL) -+ maybe_stop_greeter_display (display); -+ } -+ } -+ } -+ -+ /* if user jumped back to initial vt and it's empty put a login screen -+ * on it (unless a login screen is already running elsewhere, then -+ * jump to that login screen) -+ */ -+ if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) { -+ return G_SOURCE_CONTINUE; -+ } -+ -+ ret = sd_seat_get_active ("seat0", &active_session_id, NULL); -+ -+ if (ret == 0) { -+ g_autofree char *state = NULL; -+ ret = sd_session_get_state (active_session_id, &state); -+ -+ /* if there's something already running on the active VT then bail */ -+ if (ret == 0 && g_strcmp0 (state, "closing") != 0) -+ return G_SOURCE_CONTINUE; -+ } -+ -+ if (gdm_local_display_factory_use_wayland ()) -+ session_type = "wayland"; -+ -+ create_display (factory, "seat0", session_type, TRUE); -+ -+ return G_SOURCE_CONTINUE; -+} -+#endif -+ - static void - gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) - { -+ g_autoptr (GIOChannel) io_channel = NULL; -+ - factory->priv->seat_new_id = g_dbus_connection_signal_subscribe (factory->priv->connection, - "org.freedesktop.login1", - "org.freedesktop.login1.Manager", - "SeatNew", - "/org/freedesktop/login1", - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - on_seat_new, - g_object_ref (factory), - g_object_unref); - factory->priv->seat_removed_id = g_dbus_connection_signal_subscribe (factory->priv->connection, - "org.freedesktop.login1", - "org.freedesktop.login1.Manager", - "SeatRemoved", - "/org/freedesktop/login1", - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - on_seat_removed, - g_object_ref (factory), - g_object_unref); -+ -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ io_channel = g_io_channel_new_file ("/sys/class/tty/tty0/active", "r", NULL); -+ -+ if (io_channel != NULL) { -+ factory->priv->active_vt_watch_id = -+ g_io_add_watch (io_channel, -+ G_IO_PRI, -+ (GIOFunc) -+ on_vt_changed, -+ factory); -+ } -+#endif - } - - static void - gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory) - { - if (factory->priv->seat_new_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_new_id); - factory->priv->seat_new_id = 0; - } - if (factory->priv->seat_removed_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_removed_id); - factory->priv->seat_removed_id = 0; - } -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ if (factory->priv->active_vt_watch_id) { -+ g_source_remove (factory->priv->active_vt_watch_id); -+ factory->priv->active_vt_watch_id = 0; -+ } -+ -+ g_clear_pointer (&factory->priv->tty_of_active_vt, g_free); -+#endif - } - - static void - on_display_added (GdmDisplayStore *display_store, - const char *id, - GdmLocalDisplayFactory *factory) - { - GdmDisplay *display; - - display = gdm_display_store_lookup (display_store, id); - - if (display != NULL) { - g_signal_connect_object (display, "notify::status", - G_CALLBACK (on_display_status_changed), - factory, - 0); - - g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); - } - } - - static void - on_display_removed (GdmDisplayStore *display_store, - GdmDisplay *display, - GdmLocalDisplayFactory *factory) - { - g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), factory); - g_object_weak_unref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); - } - --- -2.27.0 - diff --git a/SOURCES/0015-local-display-factory-add-more-debug-messages-to-new.patch b/SOURCES/0015-local-display-factory-add-more-debug-messages-to-new.patch deleted file mode 100644 index 456bc34..0000000 --- a/SOURCES/0015-local-display-factory-add-more-debug-messages-to-new.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 59533722f1749d4e71360c5d717a18006c1f64c0 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 7 Aug 2018 13:55:06 -0400 -Subject: [PATCH 15/51] local-display-factory: add more debug messages to new - vt handling code - -commit c0188a7030 added some complex code for starting and stopping -the login screen based on VT changes. - -That code currently has zero debug statements in it making it trickier -than necessary to debug. - -This commit sprinkles some g_debug's throughout the function. ---- - daemon/gdm-local-display-factory.c | 44 ++++++++++++++++++++++++------ - 1 file changed, 35 insertions(+), 9 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 4ae656ab3..2a2259f2a 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -530,175 +530,201 @@ on_seat_removed (GDBusConnection *connection, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) - { - const char *seat; - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); - } - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - static gboolean - lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - const char *looking_for = user_data; - const char *current; - - current = gdm_display_get_session_id (display); - return g_strcmp0 (current, looking_for) == 0; - } - - static void - maybe_stop_greeter_display (GdmDisplay *display) - { - g_autofree char *display_session_type = NULL; - -- if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) -+ if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) { -+ g_debug ("GdmLocalDisplayFactory: login window not in managed state, so ignoring"); - return; -+ } - - g_object_get (G_OBJECT (display), - "session-type", &display_session_type, - NULL); - - /* we can only stop greeter for wayland sessions, since - * X server would jump back on exit */ -- if (g_strcmp0 (display_session_type, "wayland") != 0) -+ if (g_strcmp0 (display_session_type, "wayland") != 0) { -+ g_debug ("GdmLocalDisplayFactory: login window is running on Xorg, so ignoring"); - return; -+ } - -+ g_debug ("GdmLocalDisplayFactory: killing login window since its now unused"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - } - - static gboolean - on_vt_changed (GIOChannel *source, - GIOCondition condition, - GdmLocalDisplayFactory *factory) - { - GIOStatus status; - static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT; - g_autofree char *tty_of_previous_vt = NULL; - g_autofree char *tty_of_active_vt = NULL; - g_autofree char *login_session_id = NULL; - g_autofree char *active_session_id = NULL; - const char *session_type = NULL; - int ret; - -+ g_debug ("GdmLocalDisplayFactory: received VT change event"); - g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL); - - if (condition & G_IO_PRI) { - g_autoptr (GError) error = NULL; - status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error); - - if (error != NULL) { - g_warning ("could not read active VT from kernel: %s", error->message); - } - switch (status) { - case G_IO_STATUS_ERROR: - return G_SOURCE_REMOVE; - case G_IO_STATUS_EOF: - return G_SOURCE_REMOVE; - case G_IO_STATUS_AGAIN: - return G_SOURCE_CONTINUE; - case G_IO_STATUS_NORMAL: - break; - } - } - -- if ((condition & G_IO_ERR) || (condition & G_IO_HUP)) -+ if ((condition & G_IO_ERR) || (condition & G_IO_HUP)) { -+ g_debug ("GdmLocalDisplayFactory: kernel hung up active vt watch"); - return G_SOURCE_REMOVE; -+ } - -- if (tty_of_active_vt == NULL) -+ if (tty_of_active_vt == NULL) { -+ g_debug ("GdmLocalDisplayFactory: unable to read active VT from kernel"); - return G_SOURCE_CONTINUE; -+ } - - g_strchomp (tty_of_active_vt); - -- /* don't do anything if we're on the same VT we were before */ -- if (g_strcmp0 (tty_of_active_vt, factory->priv->tty_of_active_vt) == 0) -- return G_SOURCE_CONTINUE; -- - tty_of_previous_vt = g_steal_pointer (&factory->priv->tty_of_active_vt); - factory->priv->tty_of_active_vt = g_steal_pointer (&tty_of_active_vt); - -+ /* don't do anything at start up */ -+ if (tty_of_previous_vt == NULL) { -+ g_debug ("GdmLocalDisplayFactory: VT is %s at startup", -+ factory->priv->tty_of_active_vt); -+ return G_SOURCE_CONTINUE; -+ } -+ -+ g_debug ("GdmLocalDisplayFactory: VT changed from %s to %s", -+ tty_of_previous_vt, factory->priv->tty_of_active_vt); -+ - /* if the old VT was running a wayland login screen kill it - */ - if (gdm_get_login_window_session_id ("seat0", &login_session_id)) { - unsigned int vt; - - ret = sd_session_get_vt (login_session_id, &vt); - if (ret == 0 && vt != 0) { - g_autofree char *tty_of_login_window_vt = NULL; - - tty_of_login_window_vt = g_strdup_printf ("tty%u", vt); - -+ g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt); - if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { - GdmDisplayStore *store; - GdmDisplay *display; - -+ g_debug ("GdmLocalDisplayFactory: VT switched from login window"); -+ - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - - if (display != NULL) - maybe_stop_greeter_display (display); -+ } else { -+ g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); - } - } - } - - /* if user jumped back to initial vt and it's empty put a login screen - * on it (unless a login screen is already running elsewhere, then - * jump to that login screen) - */ - if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) { -+ g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring"); - return G_SOURCE_CONTINUE; - } - - ret = sd_seat_get_active ("seat0", &active_session_id, NULL); - - if (ret == 0) { - g_autofree char *state = NULL; - ret = sd_session_get_state (active_session_id, &state); - - /* if there's something already running on the active VT then bail */ -- if (ret == 0 && g_strcmp0 (state, "closing") != 0) -+ if (ret == 0 && g_strcmp0 (state, "closing") != 0) { -+ g_debug ("GdmLocalDisplayFactory: initial VT is in use, so ignoring"); - return G_SOURCE_CONTINUE; -+ } - } - - if (gdm_local_display_factory_use_wayland ()) - session_type = "wayland"; - -+ g_debug ("GdmLocalDisplayFactory: creating new display on seat0 because of VT change"); -+ - create_display (factory, "seat0", session_type, TRUE); - - return G_SOURCE_CONTINUE; - } - #endif - - static void - gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) - { - g_autoptr (GIOChannel) io_channel = NULL; - - factory->priv->seat_new_id = g_dbus_connection_signal_subscribe (factory->priv->connection, - "org.freedesktop.login1", - "org.freedesktop.login1.Manager", - "SeatNew", - "/org/freedesktop/login1", - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - on_seat_new, - g_object_ref (factory), - g_object_unref); - factory->priv->seat_removed_id = g_dbus_connection_signal_subscribe (factory->priv->connection, - "org.freedesktop.login1", - "org.freedesktop.login1.Manager", - "SeatRemoved", - "/org/freedesktop/login1", - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - on_seat_removed, - g_object_ref (factory), --- -2.27.0 - diff --git a/SOURCES/0016-local-display-factory-don-t-start-two-greeters-at-st.patch b/SOURCES/0016-local-display-factory-don-t-start-two-greeters-at-st.patch deleted file mode 100644 index dc9b1b7..0000000 --- a/SOURCES/0016-local-display-factory-don-t-start-two-greeters-at-st.patch +++ /dev/null @@ -1,97 +0,0 @@ -From e5bf6d78ff8f54bbb74e572f05ccbf1c0df24017 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 7 Aug 2018 13:55:06 -0400 -Subject: [PATCH 16/51] local-display-factory: don't start two greeters at - startup - -commit c0188a7030 added some complex code for starting -the login screen when the user switches to the initial -VT if nothing is running on that VT. - -The problem is, we get a VT change event on that VT as -part of the start up process. - -This leads to an additional greeter getting started. - -This commit adds a check to side step the new code during -startup. - -Closes: https://gitlab.gnome.org/GNOME/gdm/issues/409 ---- - daemon/gdm-local-display-factory.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 2a2259f2a..9f377ba9a 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -600,60 +600,66 @@ on_vt_changed (GIOChannel *source, - g_autoptr (GError) error = NULL; - status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error); - - if (error != NULL) { - g_warning ("could not read active VT from kernel: %s", error->message); - } - switch (status) { - case G_IO_STATUS_ERROR: - return G_SOURCE_REMOVE; - case G_IO_STATUS_EOF: - return G_SOURCE_REMOVE; - case G_IO_STATUS_AGAIN: - return G_SOURCE_CONTINUE; - case G_IO_STATUS_NORMAL: - break; - } - } - - if ((condition & G_IO_ERR) || (condition & G_IO_HUP)) { - g_debug ("GdmLocalDisplayFactory: kernel hung up active vt watch"); - return G_SOURCE_REMOVE; - } - - if (tty_of_active_vt == NULL) { - g_debug ("GdmLocalDisplayFactory: unable to read active VT from kernel"); - return G_SOURCE_CONTINUE; - } - - g_strchomp (tty_of_active_vt); - -+ /* don't do anything if we're on the same VT we were before */ -+ if (g_strcmp0 (tty_of_active_vt, factory->priv->tty_of_active_vt) == 0) { -+ g_debug ("GdmLocalDisplayFactory: VT changed to the same VT, ignoring"); -+ return G_SOURCE_CONTINUE; -+ } -+ - tty_of_previous_vt = g_steal_pointer (&factory->priv->tty_of_active_vt); - factory->priv->tty_of_active_vt = g_steal_pointer (&tty_of_active_vt); - - /* don't do anything at start up */ - if (tty_of_previous_vt == NULL) { - g_debug ("GdmLocalDisplayFactory: VT is %s at startup", - factory->priv->tty_of_active_vt); - return G_SOURCE_CONTINUE; - } - - g_debug ("GdmLocalDisplayFactory: VT changed from %s to %s", - tty_of_previous_vt, factory->priv->tty_of_active_vt); - - /* if the old VT was running a wayland login screen kill it - */ - if (gdm_get_login_window_session_id ("seat0", &login_session_id)) { - unsigned int vt; - - ret = sd_session_get_vt (login_session_id, &vt); - if (ret == 0 && vt != 0) { - g_autofree char *tty_of_login_window_vt = NULL; - - tty_of_login_window_vt = g_strdup_printf ("tty%u", vt); - - g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt); - if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { - GdmDisplayStore *store; - GdmDisplay *display; - - g_debug ("GdmLocalDisplayFactory: VT switched from login window"); --- -2.27.0 - diff --git a/SOURCES/0017-session-worker-don-t-switch-VTs-if-we-re-already-on-.patch b/SOURCES/0017-session-worker-don-t-switch-VTs-if-we-re-already-on-.patch deleted file mode 100644 index 76ab241..0000000 --- a/SOURCES/0017-session-worker-don-t-switch-VTs-if-we-re-already-on-.patch +++ /dev/null @@ -1,128 +0,0 @@ -From de4b24f63e62a39b2cb10a8c58c54d86559f7f26 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 7 Aug 2018 14:04:44 -0400 -Subject: [PATCH 17/51] session-worker: don't switch VTs if we're already on - the right VT - -commit 5b5dccbd shows that switching VTs to the same VT isn't -exactly a no-op. In order to prevent unnecessary wakeups, avoid -switching VTs if the worker is already on the correct VT. ---- - daemon/gdm-session-worker.c | 22 ++++++++++++++++------ - 1 file changed, 16 insertions(+), 6 deletions(-) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index 0322037e0..fd6470bab 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -936,91 +936,101 @@ fix_terminal_vt_mode (GdmSessionWorker *worker, - if (ioctl (tty_fd, KDGETMODE, &kernel_display_mode) < 0) { - g_debug ("GdmSessionWorker: couldn't query kernel display mode: %m"); - succeeded = FALSE; - } - - if (kernel_display_mode == KD_TEXT) { - goto out; - } - - /* VT is in the anti-social state of VT_AUTO + KD_GRAPHICS, - * fix it. - */ - succeeded = handle_terminal_vt_switches (worker, tty_fd); - mode_fixed = TRUE; - out: - if (!succeeded) { - g_error ("GdmSessionWorker: couldn't set up terminal, aborting..."); - return; - } - - g_debug ("GdmSessionWorker: VT mode did %sneed to be fixed", - mode_fixed? "" : "not "); - } - - static void - jump_to_vt (GdmSessionWorker *worker, - int vt_number) - { - int fd; - int active_vt_tty_fd; -+ int active_vt = -1; -+ struct vt_stat vt_state = { 0 }; - - g_debug ("GdmSessionWorker: jumping to VT %d", vt_number); - active_vt_tty_fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); - - if (worker->priv->session_tty_fd != -1) { - fd = worker->priv->session_tty_fd; - - g_debug ("GdmSessionWorker: first setting graphics mode to prevent flicker"); - if (ioctl (fd, KDSETMODE, KD_GRAPHICS) < 0) { - g_debug ("GdmSessionWorker: couldn't set graphics mode: %m"); - } - - /* It's possible that the current VT was left in a broken - * combination of states (KD_GRAPHICS with VT_AUTO), that - * can't be switched away from. This call makes sure things - * are set in a way that VT_ACTIVATE should work and - * VT_WAITACTIVE shouldn't hang. - */ - fix_terminal_vt_mode (worker, active_vt_tty_fd); - } else { - fd = active_vt_tty_fd; - } - - handle_terminal_vt_switches (worker, fd); - -- if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) { -- g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m", -- vt_number); -- } else if (ioctl (fd, VT_WAITACTIVE, vt_number) < 0) { -- g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m", -- vt_number); -+ if (ioctl (fd, VT_GETSTATE, &vt_state) <= 0) { -+ g_debug ("GdmSessionWorker: couldn't get current VT: %m"); -+ } else { -+ active_vt = vt_state.v_active; -+ } -+ -+ if (active_vt != vt_number) { -+ if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) { -+ g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m", -+ vt_number); -+ } else if (ioctl (fd, VT_WAITACTIVE, vt_number) < 0) { -+ g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m", -+ vt_number); -+ } - } - - close (active_vt_tty_fd); - } - - static void - gdm_session_worker_set_state (GdmSessionWorker *worker, - GdmSessionWorkerState state) - { - if (worker->priv->state == state) - return; - - worker->priv->state = state; - g_object_notify (G_OBJECT (worker), "state"); - } - - static void - gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, - int status) - { - g_debug ("GdmSessionWorker: uninitializing PAM"); - - if (worker->priv->pam_handle == NULL) - return; - - gdm_session_worker_get_username (worker, NULL); - - if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { - pam_close_session (worker->priv->pam_handle, 0); - gdm_session_auditor_report_logout (worker->priv->auditor); --- -2.27.0 - diff --git a/SOURCES/0018-session-worker-fix-current-vt-detection-short-circui.patch b/SOURCES/0018-session-worker-fix-current-vt-detection-short-circui.patch deleted file mode 100644 index c9a114c..0000000 --- a/SOURCES/0018-session-worker-fix-current-vt-detection-short-circui.patch +++ /dev/null @@ -1,87 +0,0 @@ -From b9e5a2879a410b6a85be6c01c6f49cd7eb24c800 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 31 Aug 2018 15:20:39 -0400 -Subject: [PATCH 18/51] session-worker: fix current vt detection short-circuit - logic - -commit 8169cd4 attempts to avoid changing VTs if the active VT -is the same as the VT getting jumped to. - -It fails to work, however, because accidentally treats a 0 return -code to the VT_GETSTATE ioctl as failure. - -this commit fixes that. ---- - daemon/gdm-session-worker.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index fd6470bab..391969d96 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -963,61 +963,61 @@ jump_to_vt (GdmSessionWorker *worker, - { - int fd; - int active_vt_tty_fd; - int active_vt = -1; - struct vt_stat vt_state = { 0 }; - - g_debug ("GdmSessionWorker: jumping to VT %d", vt_number); - active_vt_tty_fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); - - if (worker->priv->session_tty_fd != -1) { - fd = worker->priv->session_tty_fd; - - g_debug ("GdmSessionWorker: first setting graphics mode to prevent flicker"); - if (ioctl (fd, KDSETMODE, KD_GRAPHICS) < 0) { - g_debug ("GdmSessionWorker: couldn't set graphics mode: %m"); - } - - /* It's possible that the current VT was left in a broken - * combination of states (KD_GRAPHICS with VT_AUTO), that - * can't be switched away from. This call makes sure things - * are set in a way that VT_ACTIVATE should work and - * VT_WAITACTIVE shouldn't hang. - */ - fix_terminal_vt_mode (worker, active_vt_tty_fd); - } else { - fd = active_vt_tty_fd; - } - - handle_terminal_vt_switches (worker, fd); - -- if (ioctl (fd, VT_GETSTATE, &vt_state) <= 0) { -+ if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) { - g_debug ("GdmSessionWorker: couldn't get current VT: %m"); - } else { - active_vt = vt_state.v_active; - } - - if (active_vt != vt_number) { - if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) { - g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m", - vt_number); - } else if (ioctl (fd, VT_WAITACTIVE, vt_number) < 0) { - g_debug ("GdmSessionWorker: couldn't finalize jump to VT %d: %m", - vt_number); - } - } - - close (active_vt_tty_fd); - } - - static void - gdm_session_worker_set_state (GdmSessionWorker *worker, - GdmSessionWorkerState state) - { - if (worker->priv->state == state) - return; - - worker->priv->state = state; - g_object_notify (G_OBJECT (worker), "state"); - } - - static void --- -2.27.0 - diff --git a/SOURCES/0019-local-display-factory-don-t-jump-to-failed-display.patch b/SOURCES/0019-local-display-factory-don-t-jump-to-failed-display.patch deleted file mode 100644 index 45148f2..0000000 --- a/SOURCES/0019-local-display-factory-don-t-jump-to-failed-display.patch +++ /dev/null @@ -1,168 +0,0 @@ -From fe680d77cff9272843cb171c7e590c239f7afe5a Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 9 Aug 2018 12:32:31 -0400 -Subject: [PATCH 19/51] local-display-factory: don't jump to failed display - -Since commit 5e737a57 `create_display` will jump to any -already running login screen if it can find one. - -Right now if a display fails we call `create_display` to -create a new one. It will look for any already running -login screen and find the recently failed display. - -This commit make sure we never jump to a display that isn't -in good working order. ---- - daemon/gdm-local-display-factory.c | 19 +++++++++++++++---- - 1 file changed, 15 insertions(+), 4 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 9f377ba9a..c58de9c17 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -60,60 +60,63 @@ struct GdmLocalDisplayFactoryPrivate - guint num_failures; - - guint seat_new_id; - guint seat_removed_id; - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - char *tty_of_active_vt; - guint active_vt_watch_id; - #endif - }; - - enum { - PROP_0, - }; - - static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); - static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); - static void gdm_local_display_factory_finalize (GObject *object); - - static GdmDisplay *create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial_display); - - static void on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmLocalDisplayFactory *factory); - - static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); - static gpointer local_display_factory_object = NULL; -+static gboolean lookup_by_session_id (const char *id, -+ GdmDisplay *display, -+ gpointer user_data); - - G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) - - GQuark - gdm_local_display_factory_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_local_display_factory_error"); - } - - return ret; - } - - static void - listify_hash (gpointer key, - GdmDisplay *display, - GList **list) - { - *list = g_list_prepend (*list, key); - } - - static int - sort_nums (gpointer a, - gpointer b) - { - guint32 num_a; - guint32 num_b; - - num_a = GPOINTER_TO_UINT (a); -@@ -370,66 +373,74 @@ lookup_by_seat_id (const char *id, - - g_object_get (G_OBJECT (display), "seat-id", ¤t, NULL); - - res = g_strcmp0 (current, looking_for) == 0; - - g_free(current); - - return res; - } - - 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; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - 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 (gdm_get_login_window_session_id (seat_id, &login_session_id)) { -- if (g_strcmp0 (active_session_id, login_session_id) != 0) { -- gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id); -+ GdmDisplay *display; -+ -+ display = gdm_display_store_find (store, -+ lookup_by_session_id, -+ (gpointer) login_session_id); -+ if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { -+ if (g_strcmp0 (active_session_id, login_session_id) != 0) { -+ gdm_activate_session_by_id (factory->priv->connection, 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 (&login_session_id, g_free); -- g_clear_pointer (&active_session_id, g_free); -- return NULL; - } - g_clear_pointer (&active_session_id, g_free); - } else if (!sd_seat_can_multi_session (seat_id)) { - /* 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); - } - --- -2.27.0 - diff --git a/SOURCES/0020-local-display-factory-add-some-more-debug-statements.patch b/SOURCES/0020-local-display-factory-add-some-more-debug-statements.patch deleted file mode 100644 index 31d91a0..0000000 --- a/SOURCES/0020-local-display-factory-add-some-more-debug-statements.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 94207dd5699f1cd2fe7d516c20e1de2b2e2778fb Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 9 Aug 2018 12:48:25 -0400 -Subject: [PATCH 20/51] local-display-factory: add some more debug statements - -This commit just sprinkles in a few more `g_debug`'s for -log file clarity. ---- - daemon/gdm-local-display-factory.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index c58de9c17..6f3a4c391 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -364,76 +364,80 @@ on_display_status_changed (GdmDisplay *display, - - 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 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; - -+ g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", -+ session_type? : "X11", seat_id); - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - 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 (gdm_get_login_window_session_id (seat_id, &login_session_id)) { - GdmDisplay *display; - - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { - if (g_strcmp0 (active_session_id, login_session_id) != 0) { -+ g_debug ("GdmLocalDisplayFactory: session %s found, activating.", -+ login_session_id); - gdm_activate_session_by_id (factory->priv->connection, 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 (&login_session_id, g_free); - } - g_clear_pointer (&active_session_id, g_free); - } else if (!sd_seat_can_multi_session (seat_id)) { - /* 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) { -@@ -453,60 +457,61 @@ create_display (GdmLocalDisplayFactory *factory, - g_object_unref (display); - - if (! gdm_display_manage (display)) { - gdm_display_unmanage (display); - } - - return display; - } - - static void - delete_display (GdmLocalDisplayFactory *factory, - const char *seat_id) { - - GdmDisplayStore *store; - - g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id); - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id); - } - - static gboolean - gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory) - { - GError *error = NULL; - GVariant *result; - GVariant *array; - GVariantIter iter; - const char *seat; - -+ g_debug ("GdmLocalDisplayFactory: enumerating seats from logind"); - result = g_dbus_connection_call_sync (factory->priv->connection, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "ListSeats", - NULL, - G_VARIANT_TYPE ("(a(so))"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, &error); - - if (!result) { - g_warning ("GdmLocalDisplayFactory: Failed to issue method call: %s", error->message); - g_clear_error (&error); - return FALSE; - } - - array = g_variant_get_child_value (result, 0); - g_variant_iter_init (&iter, array); - - while (g_variant_iter_loop (&iter, "(&so)", &seat, NULL)) { - gboolean is_initial; - const char *session_type = NULL; - - if (g_strcmp0 (seat, "seat0") == 0) { - is_initial = TRUE; - if (gdm_local_display_factory_use_wayland ()) - session_type = "wayland"; - } else { - is_initial = FALSE; --- -2.27.0 - diff --git a/SOURCES/0021-local-display-factory-ignore-spurios-SeatNew-signal-.patch b/SOURCES/0021-local-display-factory-ignore-spurios-SeatNew-signal-.patch deleted file mode 100644 index f605db9..0000000 --- a/SOURCES/0021-local-display-factory-ignore-spurios-SeatNew-signal-.patch +++ /dev/null @@ -1,162 +0,0 @@ -From abd8e1ef71d093a3ab5c110aea5fa2012d59d5e2 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 14 Aug 2018 10:21:17 -0400 -Subject: [PATCH 21/51] local-display-factory: ignore spurios SeatNew signal at - start up - -Sometimes during startup, logind will send a `SeatNew` signal for -seat0 after GDM has already called `ListSeats` and processed `seat0`. - -That `SeatNew` signal leads to GDM calling `create_display` twice in -quick succession. - -This commit changes GDM to avoid such double processing, by ignoring -the `create_display` requests for seats that already have a prepared -display ("prepared" means "starting up"). - -Closes: https://gitlab.gnome.org/GNOME/gdm/issues/410 ---- - daemon/gdm-local-display-factory.c | 33 +++++++++++++++++++++++------- - 1 file changed, 26 insertions(+), 7 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 6f3a4c391..127127005 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -353,107 +353,126 @@ on_display_status_changed (GdmDisplay *display, - 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 -+lookup_prepared_display_by_seat_id (const char *id, -+ GdmDisplay *display, -+ gpointer user_data) -+{ -+ int status; -+ -+ status = gdm_display_get_status (display); -+ -+ if (status != GDM_DISPLAY_PREPARED) -+ return FALSE; -+ -+ return lookup_by_seat_id (id, display, user_data); -+} -+ - static GdmDisplay * - create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial) - { - GdmDisplayStore *store; - GdmDisplay *display = NULL; - char *active_session_id = NULL; - int ret; - - g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", - session_type? : "X11", seat_id); - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - -+ if (sd_seat_can_multi_session (seat_id)) -+ display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); -+ else -+ display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); -+ -+ /* Ensure we don't create the same display more than once */ -+ if (display != NULL) { -+ g_debug ("GdmLocalDisplayFactory: display already created"); -+ return NULL; -+ } -+ - 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 (gdm_get_login_window_session_id (seat_id, &login_session_id)) { - GdmDisplay *display; - - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { - if (g_strcmp0 (active_session_id, login_session_id) != 0) { - g_debug ("GdmLocalDisplayFactory: session %s found, activating.", - login_session_id); - gdm_activate_session_by_id (factory->priv->connection, 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 (&login_session_id, g_free); - } - g_clear_pointer (&active_session_id, g_free); -- } else if (!sd_seat_can_multi_session (seat_id)) { -- /* 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)) { --- -2.27.0 - diff --git a/SOURCES/0022-common-remove-unnecessary-free.patch b/SOURCES/0022-common-remove-unnecessary-free.patch deleted file mode 100644 index 5c78e7d..0000000 --- a/SOURCES/0022-common-remove-unnecessary-free.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 9b8c21080286f943d0a19431bc8c0061f4833443 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 30 Aug 2018 13:04:56 -0400 -Subject: [PATCH 22/51] common: remove unnecessary free - -This commit drops an erroneous free call, that would -potentially free a dangling pointer. - -Luckily the error condition can never occur because the -error code checked is never returned, so the free call -is dead code. - -This commit removes the free call. A subsequent commit -will fix the error code checking. ---- - common/gdm-common.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/common/gdm-common.c b/common/gdm-common.c -index 59317a889..c909aceee 100644 ---- a/common/gdm-common.c -+++ b/common/gdm-common.c -@@ -391,64 +391,62 @@ gdm_activate_session_by_id (GDBusConnection *connection, - return TRUE; - } - - gboolean - gdm_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) { -- free (service_class); -+ if (res == -ENOENT) - 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) { - 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) { - g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res)); - ret = FALSE; --- -2.27.0 - diff --git a/SOURCES/0023-common-don-t-bail-if-session-disappears-out-from-und.patch b/SOURCES/0023-common-don-t-bail-if-session-disappears-out-from-und.patch deleted file mode 100644 index c27d5bf..0000000 --- a/SOURCES/0023-common-don-t-bail-if-session-disappears-out-from-und.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 4a948e4b203fdf5fcd9b5e53dd4a80ef2786c0cd Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 30 Aug 2018 13:06:54 -0400 -Subject: [PATCH 23/51] common: 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. - -This commit is very similar to commit 155ee7eca which got -accidentally reverted during code consolidation. The main -difference is this commit checks the correct error code -of -ENXIO instead of -ENOENT, so it might actually fix -what it's ostensibly supposed to fix. ---- - common/gdm-common.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/common/gdm-common.c b/common/gdm-common.c -index c909aceee..59b8dfc44 100644 ---- a/common/gdm-common.c -+++ b/common/gdm-common.c -@@ -391,90 +391,96 @@ gdm_activate_session_by_id (GDBusConnection *connection, - return TRUE; - } - - gboolean - gdm_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) -+ if (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 == -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 == -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; - } --- -2.27.0 - diff --git a/SOURCES/0024-manager-better-logind-handling.patch b/SOURCES/0024-manager-better-logind-handling.patch deleted file mode 100644 index 194c156..0000000 --- a/SOURCES/0024-manager-better-logind-handling.patch +++ /dev/null @@ -1,138 +0,0 @@ -From fac23cfa3e8e9fe21563733c0c1b739ddecead8a Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 30 Aug 2018 14:01:55 -0400 -Subject: [PATCH 24/51] manager: better logind handling - -commit 9ee68d5c8 highlights we've incorrectly -used ENOENT instead of ENXIO when checking for -non-existing sessions/seats with logind. - -This commit mops up all the other cases. ---- - daemon/gdm-manager.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 80f60d24c..367a731cc 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -361,113 +361,113 @@ find_session_for_user_on_seat (GdmManager *manager, - candidate_username); - - if (g_strcmp0 (candidate_username, username) == 0 && - g_strcmp0 (candidate_seat_id, seat_id) == 0) { - g_debug ("GdmManager: yes, found session %s", candidate_session_id); - return candidate_session; - } - - g_debug ("GdmManager: no, will not use session %s", candidate_session_id); - } - - g_debug ("GdmManager: no matching sessions found"); - return NULL; - } - - static gboolean - is_remote_session (GdmManager *self, - const char *session_id, - GError **error) - { - char *seat; - int ret; - gboolean is_remote; - - /* FIXME: The next release of logind is going to have explicit api for - * checking remoteness. - */ - seat = NULL; - ret = sd_session_get_seat (session_id, &seat); - -- if (ret < 0 && ret != -ENOENT) { -+ if (ret < 0 && ret != -ENXIO) { - g_debug ("GdmManager: Error while retrieving seat for session %s: %s", - session_id, strerror (-ret)); - } - - if (seat != NULL) { - is_remote = FALSE; - free (seat); - } else { - is_remote = TRUE; - } - - return is_remote; - } - - static char * - get_seat_id_for_session_id (const char *session_id, - GError **error) - { - int ret; - char *seat, *out_seat; - - seat = NULL; - ret = sd_session_get_seat (session_id, &seat); - -- if (ret == -ENOENT) { -+ if (ret == -ENXIO) { - out_seat = NULL; - } else if (ret < 0) { - g_set_error (error, - GDM_DISPLAY_ERROR, - GDM_DISPLAY_ERROR_GETTING_SESSION_INFO, - "Error getting uid for session id %s from systemd: %s", - session_id, - g_strerror (-ret)); - out_seat = NULL; - } else { - out_seat = g_strdup (seat); - free (seat); - } - - return out_seat; - } - - static char * - get_tty_for_session_id (const char *session_id, - GError **error) - { - int ret; - char *tty, *out_tty; - - ret = sd_session_get_tty (session_id, &tty); - -- if (ret == -ENOENT) { -+ if (ret == -ENXIO) { - out_tty = NULL; - } else if (ret < 0) { - g_set_error (error, - GDM_DISPLAY_ERROR, - GDM_DISPLAY_ERROR_GETTING_SESSION_INFO, - "Error getting tty for session id %s from systemd: %s", - session_id, - g_strerror (-ret)); - out_tty = NULL; - } else { - out_tty = g_strdup (tty); - free (tty); - } - - return out_tty; - } - - static void - get_display_and_details_for_bus_sender (GdmManager *self, - GDBusConnection *connection, - const char *sender, - GdmDisplay **out_display, - char **out_seat_id, - char **out_session_id, - char **out_tty, - GPid *out_pid, - uid_t *out_uid, - gboolean *out_is_login_screen, - gboolean *out_is_remote) - { --- -2.27.0 - diff --git a/SOURCES/0025-session-worker-clear-VT-before-jumping-to-it.patch b/SOURCES/0025-session-worker-clear-VT-before-jumping-to-it.patch deleted file mode 100644 index cc3744a..0000000 --- a/SOURCES/0025-session-worker-clear-VT-before-jumping-to-it.patch +++ /dev/null @@ -1,90 +0,0 @@ -From cabcd21c17ca98e517a3eea7c9d5ce269445e3e0 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 31 Aug 2018 15:46:55 -0400 -Subject: [PATCH 25/51] session-worker: clear VT before jumping to it - -If we're going to jump to a new VT we should make sure it's free -of residual console text. That way if there's flicker the user -will be less likely to notice it. - -This commit sends a clear screen escape sequence to the tty -before jumping to it. ---- - daemon/gdm-session-worker.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index 391969d96..7ed2789da 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -943,60 +943,67 @@ fix_terminal_vt_mode (GdmSessionWorker *worker, - } - - /* VT is in the anti-social state of VT_AUTO + KD_GRAPHICS, - * fix it. - */ - succeeded = handle_terminal_vt_switches (worker, tty_fd); - mode_fixed = TRUE; - out: - if (!succeeded) { - g_error ("GdmSessionWorker: couldn't set up terminal, aborting..."); - return; - } - - g_debug ("GdmSessionWorker: VT mode did %sneed to be fixed", - mode_fixed? "" : "not "); - } - - static void - jump_to_vt (GdmSessionWorker *worker, - int vt_number) - { - int fd; - int active_vt_tty_fd; - int active_vt = -1; - struct vt_stat vt_state = { 0 }; - - g_debug ("GdmSessionWorker: jumping to VT %d", vt_number); - active_vt_tty_fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); - - if (worker->priv->session_tty_fd != -1) { -+ static const char *clear_screen_escape_sequence = "\33[H\33[2J"; -+ -+ /* let's make sure the new VT is clear */ -+ write (worker->priv->session_tty_fd, -+ clear_screen_escape_sequence, -+ sizeof (clear_screen_escape_sequence)); -+ - fd = worker->priv->session_tty_fd; - - g_debug ("GdmSessionWorker: first setting graphics mode to prevent flicker"); - if (ioctl (fd, KDSETMODE, KD_GRAPHICS) < 0) { - g_debug ("GdmSessionWorker: couldn't set graphics mode: %m"); - } - - /* It's possible that the current VT was left in a broken - * combination of states (KD_GRAPHICS with VT_AUTO), that - * can't be switched away from. This call makes sure things - * are set in a way that VT_ACTIVATE should work and - * VT_WAITACTIVE shouldn't hang. - */ - fix_terminal_vt_mode (worker, active_vt_tty_fd); - } else { - fd = active_vt_tty_fd; - } - - handle_terminal_vt_switches (worker, fd); - - if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) { - g_debug ("GdmSessionWorker: couldn't get current VT: %m"); - } else { - active_vt = vt_state.v_active; - } - - if (active_vt != vt_number) { - if (ioctl (fd, VT_ACTIVATE, vt_number) < 0) { - g_debug ("GdmSessionWorker: couldn't initiate jump to VT %d: %m", - vt_number); --- -2.27.0 - diff --git a/SOURCES/0026-manager-don-t-set-ran_once-after-running-initial-set.patch b/SOURCES/0026-manager-don-t-set-ran_once-after-running-initial-set.patch deleted file mode 100644 index 5a98652..0000000 --- a/SOURCES/0026-manager-don-t-set-ran_once-after-running-initial-set.patch +++ /dev/null @@ -1,133 +0,0 @@ -From b773eb570d8c5f9d2222ee39eecbc6a622d108d8 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 30 Aug 2018 16:04:41 -0400 -Subject: [PATCH 26/51] manager: don't set ran_once after running initial-setup - -GdmManager tracks whether or not the user session has ran -once, so it won't autologin a user again after logout. - -Unfortunately the initial-setup session was counting toward the -ran_once count preventing initial-setup from logging the user -in afterward. - -This commit prevents ran_once from getting set in that case. ---- - 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 367a731cc..c8197a043 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1519,105 +1519,107 @@ set_up_session (GdmManager *manager, - operation->username = username; - - g_signal_connect (user, - "notify::is-loaded", - G_CALLBACK (on_user_is_loaded_changed), - operation); - } - } - - static void - greeter_display_started (GdmManager *manager, - GdmDisplay *display) - { - if (manager->priv->ran_once) { - return; - } - - maybe_start_pending_initial_login (manager, display); - } - - static void - on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmManager *manager) - { - int status; - int display_number = -1; - char *session_type = NULL; - #ifdef WITH_PLYMOUTH - gboolean display_is_local = FALSE; -+ gboolean doing_initial_setup = FALSE; - gboolean quit_plymouth = FALSE; - - g_object_get (display, - "is-local", &display_is_local, -+ "doing-initial-setup", &doing_initial_setup, - NULL); - quit_plymouth = display_is_local && manager->priv->plymouth_is_running; - #endif - - g_object_get (display, - "x11-display-number", &display_number, - "session-type", &session_type, - NULL); - - status = gdm_display_get_status (display); - - switch (status) { - case GDM_DISPLAY_PREPARED: - case GDM_DISPLAY_MANAGED: - 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) { -+ if (!doing_initial_setup && (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0)) { - manager->priv->ran_once = TRUE; - } - maybe_start_pending_initial_login (manager, display); - break; - default: - break; - } - - } - - static void - on_display_removed (GdmDisplayStore *display_store, - GdmDisplay *display, - GdmManager *manager) - { - char *id; - - gdm_display_get_id (display, &id, NULL); - g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); - g_free (id); - - g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); - - g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, display); - } - - static void - destroy_start_user_session_operation (StartUserSessionOperation *operation) - { - g_object_set_data (G_OBJECT (operation->session), --- -2.27.0 - diff --git a/SOURCES/0027-manager-start-initial-setup-right-away.patch b/SOURCES/0027-manager-start-initial-setup-right-away.patch deleted file mode 100644 index b16bcfb..0000000 --- a/SOURCES/0027-manager-start-initial-setup-right-away.patch +++ /dev/null @@ -1,418 +0,0 @@ -From 3d4199f82136e7046b5b08fc7c583e3fce2d04a2 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 31 Aug 2018 14:33:58 -0400 -Subject: [PATCH 27/51] manager: start initial setup right away - -We no longer restart the greeter as soon as it dies, since we -start the greeter on demand. This means, we no longer need to -defer starting initial setup until after the greeter respawns. - -Furthermore, it doesn't work anymore since it relied on the -respawn to trigger. - -This commit removes that code and scaffolding and just starts -initial setup directly. - -https://gitlab.gnome.org/GNOME/gdm/issues/415 ---- - daemon/gdm-manager.c | 66 +------------------------------------------- - 1 file changed, 1 insertion(+), 65 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index c8197a043..fb7b1ec4b 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -62,62 +62,60 @@ - #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays" - - #define INITIAL_SETUP_USERNAME "gnome-initial-setup" - - typedef struct - { - GdmManager *manager; - GdmSession *session; - char *service_name; - guint idle_id; - } StartUserSessionOperation; - - struct GdmManagerPrivate - { - GdmDisplayStore *display_store; - GdmLocalDisplayFactory *local_factory; - #ifdef HAVE_LIBXDMCP - GdmXdmcpDisplayFactory *xdmcp_factory; - #endif - GList *user_sessions; - GHashTable *transient_sessions; - GHashTable *open_reauthentication_requests; - gboolean xdmcp_enabled; - - gboolean started; - gboolean show_local_greeter; - - GDBusConnection *connection; - GDBusObjectManagerServer *object_manager; - -- StartUserSessionOperation *initial_login_operation; -- - #ifdef WITH_PLYMOUTH - guint plymouth_is_running : 1; - #endif - guint ran_once : 1; - }; - - enum { - PROP_0, - PROP_XDMCP_ENABLED, - PROP_SHOW_LOCAL_GREETER - }; - - enum { - DISPLAY_ADDED, - DISPLAY_REMOVED, - LAST_SIGNAL - }; - - typedef enum { - SESSION_RECORD_LOGIN, - SESSION_RECORD_LOGOUT, - SESSION_RECORD_FAILED, - } SessionRecord; - - static guint signals [LAST_SIGNAL] = { 0, }; - - static void gdm_manager_class_init (GdmManagerClass *klass); - static void gdm_manager_init (GdmManager *manager); - static void gdm_manager_dispose (GObject *object); - -@@ -1286,96 +1284,60 @@ get_automatic_login_details (GdmManager *manager, - if (res && enabled) { - res = gdm_settings_direct_get_string (GDM_KEY_AUTO_LOGIN_USER, &username); - } - - if (enabled && res && username != NULL && username[0] != '\0') { - goto out; - } - - g_free (username); - username = NULL; - enabled = FALSE; - - out: - if (enabled) { - g_debug ("GdmDisplay: Got automatic login details for display: %d %s", - enabled, - username); - } else { - g_debug ("GdmDisplay: Got automatic login details for display: 0"); - } - - if (usernamep != NULL) { - *usernamep = username; - } else { - g_free (username); - } - - return enabled; - } - --static void --maybe_start_pending_initial_login (GdmManager *manager, -- GdmDisplay *greeter_display) --{ -- StartUserSessionOperation *operation; -- char *greeter_seat_id = NULL; -- char *user_session_seat_id = NULL; -- -- /* There may be a user session waiting to be started. -- * This would happen if we couldn't start it earlier because -- * the login screen X server was coming up and two X servers -- * can't be started on the same seat at the same time. -- */ -- -- if (manager->priv->initial_login_operation == NULL) { -- return; -- } -- -- operation = manager->priv->initial_login_operation; -- -- g_object_get (G_OBJECT (greeter_display), -- "seat-id", &greeter_seat_id, -- NULL); -- g_object_get (G_OBJECT (operation->session), -- "display-seat-id", &user_session_seat_id, -- 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 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); - -@@ -1498,131 +1460,115 @@ set_up_session (GdmManager *manager, - return; - } - #endif - - set_up_greeter_session (manager, display); - return; - } - - /* Check whether the user really exists before committing to autologin. */ - user_manager = act_user_manager_get_default (); - user = act_user_manager_get_user (user_manager, username); - g_object_get (user_manager, "is-loaded", &loaded, NULL); - - if (loaded) { - set_up_automatic_login_session_if_user_exists (manager, display, user); - } else { - UsernameLookupOperation *operation; - - operation = g_new (UsernameLookupOperation, 1); - operation->manager = g_object_ref (manager); - operation->display = g_object_ref (display); - operation->username = username; - - g_signal_connect (user, - "notify::is-loaded", - G_CALLBACK (on_user_is_loaded_changed), - operation); - } - } - --static void --greeter_display_started (GdmManager *manager, -- GdmDisplay *display) --{ -- if (manager->priv->ran_once) { -- return; -- } -- -- maybe_start_pending_initial_login (manager, display); --} -- - static void - on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmManager *manager) - { - int status; - int display_number = -1; - char *session_type = NULL; - #ifdef WITH_PLYMOUTH - gboolean display_is_local = FALSE; - gboolean doing_initial_setup = FALSE; - gboolean quit_plymouth = FALSE; - - g_object_get (display, - "is-local", &display_is_local, - "doing-initial-setup", &doing_initial_setup, - NULL); - quit_plymouth = display_is_local && manager->priv->plymouth_is_running; - #endif - - g_object_get (display, - "x11-display-number", &display_number, - "session-type", &session_type, - NULL); - - status = gdm_display_get_status (display); - - switch (status) { - case GDM_DISPLAY_PREPARED: - case GDM_DISPLAY_MANAGED: - 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 (!doing_initial_setup && (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0)) { - manager->priv->ran_once = TRUE; - } -- maybe_start_pending_initial_login (manager, display); - break; - default: - break; - } - - } - - static void - on_display_removed (GdmDisplayStore *display_store, - GdmDisplay *display, - GdmManager *manager) - { - char *id; - - gdm_display_get_id (display, &id, NULL); - g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); - g_free (id); - - g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); - - g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, display); - } - - static void - destroy_start_user_session_operation (StartUserSessionOperation *operation) - { - g_object_set_data (G_OBJECT (operation->session), - "start-user-session-operation", - NULL); - g_object_unref (operation->session); -@@ -1723,97 +1669,87 @@ on_start_user_session (StartUserSessionOperation *operation) - gdm_session_reset (operation->session); - destroy_start_user_session_operation (operation); - goto out; - } - - display = get_display_for_user_session (operation->session); - - g_object_get (G_OBJECT (display), "doing-initial-setup", &doing_initial_setup, NULL); - - session_id = gdm_session_get_conversation_session_id (operation->session, - operation->service_name); - - if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - /* In this case, the greeter's display is morphing into - * the user session display. Kill the greeter on this session - * and let the user session follow the same display. */ - gdm_display_stop_greeter_session (display); - g_object_set (G_OBJECT (display), - "session-class", "user", - "session-id", session_id, - NULL); - } else { - uid_t allowed_uid; - - g_object_ref (display); - if (doing_initial_setup) { - g_debug ("GdmManager: closing down initial setup display"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); -- -- /* We can't start the user session until the finished display -- * starts to respawn (since starting an X server and bringing -- * one down at the same time is a no go) -- */ -- g_assert (self->priv->initial_login_operation == NULL); -- self->priv->initial_login_operation = operation; -- starting_user_session_right_away = FALSE; - } else { - g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); - } - - /* The user session is going to follow the session worker - * into the new display. Untie it from this display and - * create a new session for a future user login. */ - allowed_uid = gdm_session_get_allowed_user (operation->session); - g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); - g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); - create_user_session_for_display (operation->manager, display, allowed_uid); - - if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) && - !gdm_session_client_is_connected (operation->session)) { - /* remove the unused prepared greeter display since we're not going - * to have a greeter */ - gdm_display_store_remove (self->priv->display_store, display); - g_object_unref (display); - } - - /* Give the user session a new display object for bookkeeping purposes */ - create_display_for_user_session (operation->manager, - operation->session, - session_id); - } - -- if (starting_user_session_right_away) { -- start_user_session (operation->manager, operation); -- } -+ start_user_session (operation->manager, operation); - - out: - return G_SOURCE_REMOVE; - } - - static void - queue_start_user_session (GdmManager *manager, - GdmSession *session, - const char *service_name) - { - StartUserSessionOperation *operation; - - operation = g_slice_new0 (StartUserSessionOperation); - operation->manager = manager; - operation->session = g_object_ref (session); - operation->service_name = g_strdup (service_name); - - operation->idle_id = g_idle_add ((GSourceFunc) on_start_user_session, operation); - g_object_set_data (G_OBJECT (session), "start-user-session-operation", operation); - } - - static void - start_user_session_if_ready (GdmManager *manager, - GdmSession *session, - const char *service_name) - { - gboolean start_when_ready; - - start_when_ready = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (session), "start-when-ready")); - if (start_when_ready) { --- -2.27.0 - diff --git a/SOURCES/0028-gdm-wayland-session-gdm-x-session-register-after-del.patch b/SOURCES/0028-gdm-wayland-session-gdm-x-session-register-after-del.patch deleted file mode 100644 index 67ee336..0000000 --- a/SOURCES/0028-gdm-wayland-session-gdm-x-session-register-after-del.patch +++ /dev/null @@ -1,309 +0,0 @@ -From 3073c23c673ede5093c1f93fb0775c2cd3203d7f Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 30 Aug 2018 16:09:02 -0400 -Subject: [PATCH 28/51] gdm-wayland-session,gdm-x-session: register after delay - -Right now gdm-x-session registers with GDM as soon as the -X server is started, and gdm-wayland-session registers as -soon as the session is started. - -Ideally registration wouldn't happen until the session -says things started successfully. - -This commit inches us toward that ideal but adding a little -timeout before proceeding with registration. - -A future commit will add a new xsession file key to allow -us to know whether or not the session manager of the session -supports doing registration. ---- - daemon/gdm-wayland-session.c | 23 ++++++++++++++++------- - daemon/gdm-x-session.c | 25 +++++++++++++++++-------- - 2 files changed, 33 insertions(+), 15 deletions(-) - -diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c -index 94f49e19c..de1991b34 100644 ---- a/daemon/gdm-wayland-session.c -+++ b/daemon/gdm-wayland-session.c -@@ -427,60 +427,75 @@ init_state (State **state) - static State state_allocation; - - *state = &state_allocation; - } - - static void - clear_state (State **out_state) - { - State *state = *out_state; - - g_clear_object (&state->cancellable); - g_clear_object (&state->bus_connection); - g_clear_object (&state->session_subprocess); - g_clear_pointer (&state->environment, g_strfreev); - g_clear_pointer (&state->main_loop, g_main_loop_unref); - *out_state = NULL; - } - - static gboolean - on_sigterm (State *state) - { - g_cancellable_cancel (state->cancellable); - - if (g_main_loop_is_running (state->main_loop)) { - g_main_loop_quit (state->main_loop); - } - - return G_SOURCE_CONTINUE; - } - -+static gboolean -+on_registration_delay_complete (State *state) -+{ -+ gboolean ret; -+ -+ ret = register_display (state, state->cancellable); -+ -+ if (!ret) { -+ g_printerr ("Unable to register display with display manager\n"); -+ g_main_loop_quit (state->main_loop); -+ } -+ -+ return G_SOURCE_REMOVE; -+} -+ - int - main (int argc, - char **argv) - { - State *state = NULL; - GOptionContext *context = NULL; - static char **args = NULL; - gboolean debug = FALSE; - gboolean ret; - int exit_status = EX_OK; - static GOptionEntry entries [] = { - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - gdm_log_init (); - - context = g_option_context_new (_("GNOME Display Manager Wayland Session Launcher")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - if (args == NULL || args[0] == NULL || args[1] != NULL) { - g_warning ("gdm-wayland-session takes one argument (the session)"); - exit_status = EX_USAGE; -@@ -501,55 +516,49 @@ main (int argc, - } - - gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); - state->debug_enabled = debug; - - gdm_log_set_debug (debug); - - state->main_loop = g_main_loop_new (NULL, FALSE); - state->cancellable = g_cancellable_new (); - - g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state); - - ret = spawn_bus (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session message bus\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - import_environment (state, state->cancellable); - - ret = spawn_session (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -- ret = register_display (state, state->cancellable); -- -- if (!ret) { -- g_printerr ("Unable to register display with display manager\n"); -- exit_status = EX_SOFTWARE; -- goto out; -- } -+ g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state); - - g_main_loop_run (state->main_loop); - - /* Only use exit status of session if we're here because it exit */ - - if (state->session_subprocess == NULL) { - exit_status = state->session_exit_status; - } - - out: - if (state != NULL) { - signal_subprocesses (state); - wait_on_subprocesses (state); - clear_state (&state); - } - - return exit_status; - } -diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c -index 3b2fcef47..412999cf5 100644 ---- a/daemon/gdm-x-session.c -+++ b/daemon/gdm-x-session.c -@@ -783,60 +783,75 @@ init_state (State **state) - } - - static void - clear_state (State **out_state) - { - State *state = *out_state; - - g_clear_object (&state->cancellable); - g_clear_object (&state->bus_connection); - g_clear_object (&state->session_subprocess); - g_clear_object (&state->x_subprocess); - g_clear_pointer (&state->environment, g_strfreev); - g_clear_pointer (&state->auth_file, g_free); - g_clear_pointer (&state->display_name, g_free); - g_clear_pointer (&state->main_loop, g_main_loop_unref); - *out_state = NULL; - } - - static gboolean - on_sigterm (State *state) - { - g_cancellable_cancel (state->cancellable); - - if (g_main_loop_is_running (state->main_loop)) { - g_main_loop_quit (state->main_loop); - } - - return G_SOURCE_CONTINUE; - } - -+static gboolean -+on_registration_delay_complete (State *state) -+{ -+ gboolean ret; -+ -+ ret = register_display (state, state->cancellable); -+ -+ if (!ret) { -+ g_printerr ("Unable to register display with display manager\n"); -+ g_main_loop_quit (state->main_loop); -+ } -+ -+ return G_SOURCE_REMOVE; -+} -+ - int - main (int argc, - char **argv) - { - State *state = NULL; - GOptionContext *context = NULL; - static char **args = NULL; - static gboolean run_script = FALSE; - static gboolean allow_remote_connections = FALSE; - gboolean debug = FALSE; - gboolean ret; - int exit_status = EX_OK; - static GOptionEntry entries [] = { - { "run-script", 'r', 0, G_OPTION_ARG_NONE, &run_script, N_("Run program through /etc/gdm/Xsession wrapper script"), NULL }, - { "allow-remote-connections", 'a', 0, G_OPTION_ARG_NONE, &allow_remote_connections, N_("Listen on TCP socket"), NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - gdm_log_init (); - - context = g_option_context_new (_("GNOME Display Manager X Session Launcher")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); -@@ -869,63 +884,57 @@ main (int argc, - state->cancellable = g_cancellable_new (); - - g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state); - - ret = spawn_x_server (state, allow_remote_connections, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run X server\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - ret = spawn_bus (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session message bus\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - import_environment (state, state->cancellable); - - ret = update_bus_environment (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to update bus environment\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -- ret = register_display (state, state->cancellable); -- -- if (!ret) { -- g_printerr ("Unable to register display with display manager\n"); -- exit_status = EX_SOFTWARE; -- goto out; -- } -- - ret = spawn_session (state, run_script, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -+ g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state); -+ - g_main_loop_run (state->main_loop); - - /* Only use exit status of session if we're here because it exit */ - - if (state->session_subprocess == NULL) { - exit_status = state->session_exit_status; - } - - out: - if (state != NULL) { - signal_subprocesses (state); - wait_on_subprocesses (state); - clear_state (&state); - } - - return exit_status; - } --- -2.27.0 - diff --git a/SOURCES/0029-local-display-factory-defer-killing-greeter-until-ne.patch b/SOURCES/0029-local-display-factory-defer-killing-greeter-until-ne.patch deleted file mode 100644 index df23fbd..0000000 --- a/SOURCES/0029-local-display-factory-defer-killing-greeter-until-ne.patch +++ /dev/null @@ -1,399 +0,0 @@ -From d85448e2e523deb1487e7e405a480e1c4e6a5f6f Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 31 Aug 2018 15:33:00 -0400 -Subject: [PATCH 29/51] local-display-factory: defer killing greeter until new - session registers - -At the moment we kill the greeter the second the VT change to the new -session happens. - -That can cause flicker if the new session doesn't take over the display -quickly enough. - -This commit defers killing the greeter until the new display registers. - -Closes https://gitlab.gnome.org/GNOME/gdm/issues/413 ---- - daemon/gdm-display.h | 1 + - daemon/gdm-local-display-factory.c | 43 +++++++++++++++++++++++++----- - 2 files changed, 38 insertions(+), 6 deletions(-) - -diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h -index 6d5e88df9..33dc3be41 100644 ---- a/daemon/gdm-display.h -+++ b/daemon/gdm-display.h -@@ -13,60 +13,61 @@ - * 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. - * - */ - - - #ifndef __GDM_DISPLAY_H - #define __GDM_DISPLAY_H - - #include - #include - - G_BEGIN_DECLS - - #define GDM_TYPE_DISPLAY (gdm_display_get_type ()) - #define GDM_DISPLAY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_DISPLAY, GdmDisplay)) - #define GDM_DISPLAY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_DISPLAY, GdmDisplayClass)) - #define GDM_IS_DISPLAY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_DISPLAY)) - #define GDM_IS_DISPLAY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_DISPLAY)) - #define GDM_DISPLAY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_DISPLAY, GdmDisplayClass)) - - typedef struct GdmDisplayPrivate GdmDisplayPrivate; - - typedef enum { - GDM_DISPLAY_UNMANAGED = 0, - GDM_DISPLAY_PREPARED, - GDM_DISPLAY_MANAGED, -+ GDM_DISPLAY_WAITING_TO_FINISH, - GDM_DISPLAY_FINISHED, - GDM_DISPLAY_FAILED, - } GdmDisplayStatus; - - typedef struct - { - GObject parent; - GdmDisplayPrivate *priv; - } GdmDisplay; - - typedef struct - { - GObjectClass parent_class; - - /* methods */ - gboolean (*prepare) (GdmDisplay *display); - void (*manage) (GdmDisplay *self); - } GdmDisplayClass; - - typedef enum - { - GDM_DISPLAY_ERROR_GENERAL, - GDM_DISPLAY_ERROR_GETTING_USER_INFO, - GDM_DISPLAY_ERROR_GETTING_SESSION_INFO, - } GdmDisplayError; - - #define GDM_DISPLAY_ERROR gdm_display_error_quark () - - GQuark gdm_display_error_quark (void); - GType gdm_display_get_type (void); -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 127127005..bc6ac6855 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -241,60 +241,90 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact - - display = gdm_legacy_display_new (num); - } - #endif - - g_object_set (display, - "seat-id", "seat0", - "allow-timed-login", FALSE, - NULL); - - 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 gboolean -+finish_display_on_seat_if_waiting (GdmDisplayStore *display_store, -+ GdmDisplay *display, -+ const char *seat_id) -+{ -+ if (gdm_display_get_status (display) != GDM_DISPLAY_WAITING_TO_FINISH) -+ return FALSE; -+ -+ g_debug ("GdmLocalDisplayFactory: finish background display\n"); -+ gdm_display_stop_greeter_session (display); -+ gdm_display_unmanage (display); -+ gdm_display_finish (display); -+ -+ return FALSE; -+} -+ -+static void -+finish_waiting_displays_on_seat (GdmLocalDisplayFactory *factory, -+ const char *seat_id) -+{ -+ GdmDisplayStore *store; -+ -+ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); -+ -+ gdm_display_store_foreach (store, -+ (GdmDisplayStoreFunc) finish_display_on_seat_if_waiting, -+ (gpointer) -+ seat_id); -+} -+ - static void - on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmLocalDisplayFactory *factory) - { - int status; - 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); - - 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 -@@ -324,60 +354,63 @@ on_display_status_changed (GdmDisplay *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; - - /* workaround logind race for now - * bug 1643874 - */ - g_usleep (2 * G_USEC_PER_SEC); - } - - #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: -+ finish_waiting_displays_on_seat (factory, seat_id); -+ break; -+ case GDM_DISPLAY_WAITING_TO_FINISH: - 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 -@@ -561,84 +594,82 @@ on_seat_new (GDBusConnection *connection, - - static void - on_seat_removed (GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) - { - const char *seat; - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); - } - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - static gboolean - lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - const char *looking_for = user_data; - const char *current; - - current = gdm_display_get_session_id (display); - return g_strcmp0 (current, looking_for) == 0; - } - - static void --maybe_stop_greeter_display (GdmDisplay *display) -+maybe_stop_greeter_in_background (GdmDisplay *display) - { - g_autofree char *display_session_type = NULL; - - if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) { - g_debug ("GdmLocalDisplayFactory: login window not in managed state, so ignoring"); - return; - } - - g_object_get (G_OBJECT (display), - "session-type", &display_session_type, - NULL); - - /* we can only stop greeter for wayland sessions, since - * X server would jump back on exit */ - if (g_strcmp0 (display_session_type, "wayland") != 0) { - g_debug ("GdmLocalDisplayFactory: login window is running on Xorg, so ignoring"); - return; - } - -- g_debug ("GdmLocalDisplayFactory: killing login window since its now unused"); -- gdm_display_stop_greeter_session (display); -- gdm_display_unmanage (display); -- gdm_display_finish (display); -+ g_debug ("GdmLocalDisplayFactory: killing login window once its unused"); -+ g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); - } - - static gboolean - on_vt_changed (GIOChannel *source, - GIOCondition condition, - GdmLocalDisplayFactory *factory) - { - GIOStatus status; - static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT; - g_autofree char *tty_of_previous_vt = NULL; - g_autofree char *tty_of_active_vt = NULL; - g_autofree char *login_session_id = NULL; - g_autofree char *active_session_id = NULL; - const char *session_type = NULL; - int ret; - - g_debug ("GdmLocalDisplayFactory: received VT change event"); - g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL); - - if (condition & G_IO_PRI) { - g_autoptr (GError) error = NULL; - status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error); - - if (error != NULL) { - g_warning ("could not read active VT from kernel: %s", error->message); - } - switch (status) { - case G_IO_STATUS_ERROR: - return G_SOURCE_REMOVE; - case G_IO_STATUS_EOF: -@@ -678,61 +709,61 @@ on_vt_changed (GIOChannel *source, - return G_SOURCE_CONTINUE; - } - - g_debug ("GdmLocalDisplayFactory: VT changed from %s to %s", - tty_of_previous_vt, factory->priv->tty_of_active_vt); - - /* if the old VT was running a wayland login screen kill it - */ - if (gdm_get_login_window_session_id ("seat0", &login_session_id)) { - unsigned int vt; - - ret = sd_session_get_vt (login_session_id, &vt); - if (ret == 0 && vt != 0) { - g_autofree char *tty_of_login_window_vt = NULL; - - tty_of_login_window_vt = g_strdup_printf ("tty%u", vt); - - g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt); - if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { - GdmDisplayStore *store; - GdmDisplay *display; - - g_debug ("GdmLocalDisplayFactory: VT switched from login window"); - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - - if (display != NULL) -- maybe_stop_greeter_display (display); -+ maybe_stop_greeter_in_background (display); - } else { - g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); - } - } - } - - /* if user jumped back to initial vt and it's empty put a login screen - * on it (unless a login screen is already running elsewhere, then - * jump to that login screen) - */ - if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) { - g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring"); - return G_SOURCE_CONTINUE; - } - - ret = sd_seat_get_active ("seat0", &active_session_id, NULL); - - if (ret == 0) { - g_autofree char *state = NULL; - ret = sd_session_get_state (active_session_id, &state); - - /* if there's something already running on the active VT then bail */ - if (ret == 0 && g_strcmp0 (state, "closing") != 0) { - g_debug ("GdmLocalDisplayFactory: initial VT is in use, so ignoring"); - return G_SOURCE_CONTINUE; - } - } - - if (gdm_local_display_factory_use_wayland ()) - session_type = "wayland"; --- -2.27.0 - diff --git a/SOURCES/0030-daemon-Move-the-waiting-the-session-to-have-taken-ov.patch b/SOURCES/0030-daemon-Move-the-waiting-the-session-to-have-taken-ov.patch deleted file mode 100644 index 889088d..0000000 --- a/SOURCES/0030-daemon-Move-the-waiting-the-session-to-have-taken-ov.patch +++ /dev/null @@ -1,708 +0,0 @@ -From 0ff911467265831006aac6216060dbecff84c1cb Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 4 Sep 2018 10:56:45 +0200 -Subject: [PATCH 30/51] daemon: Move the waiting the session to have taken over - the fb to gdm-local-display-factory - -Commit 708618746683 ("gdm-wayland-session,gdm-x-session: register after -delay") delayed displays changing their status from PREPARED to MANAGED -so that their status would not change until the session has had a change -to install its own framebuffer and tell the GPU to scanout this new fb. - -Commit 74ee77717df7 ("local-display-factory: defer killing greeter until -new session registers") uses this to avoid a flicker when transitioning -from the greeter to the user-session by deferring the stopping of the -greeter-session until the new display moves to the MANAGED state. - -But this only works when transitioning to a new user-session, when moving -to an existing user-session (fast user switching) the display already -is in MANAGED state and instead of deferring the stopping of the greeter -commit 74ee77717df7 causes us to now never stop the greeter-session. - -This commit fixes this by starting a timeout when switching away from -the initial-vt and letting that timeout stop the greeter-session. - -This commit removes the finish_waiting_displays_on_seat() call when the -display's status changes to MANAGED, so that we still only have one code -path stopping the greeter and not two. - -This means we also no longer need to delay registering the display. So this -commit removes the code adding the delay (reverts commit 74ee77717df7). - -Note this commit uses a delay of 10 seconds, rather then 2 seconds. The -transition to a new user-session takes about 8 seconds on my budget -Apollo Lake based laptop (with SSD). - -Note this all really is a workaround, the proper solution for this would -be able to tell the kernel to keep the greeter framebuffer around until -a new framebuffer is installed. There is a patch to add a new unref_fb -ioctl for this: https://www.spinics.net/lists/dri-devel/msg140912.html . -We need to get this patch upstream and teach mutter to use it. ---- - daemon/gdm-local-display-factory.c | 29 ++++++++++++++++++++++++++--- - daemon/gdm-wayland-session.c | 23 +++++++---------------- - daemon/gdm-x-session.c | 25 ++++++++----------------- - 3 files changed, 41 insertions(+), 36 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index bc6ac6855..be6b377be 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -22,76 +22,78 @@ - - #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 -+#define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */ - - struct GdmLocalDisplayFactoryPrivate - { - GdmDBusLocalDisplayFactory *skeleton; - GDBusConnection *connection; - GHashTable *used_display_numbers; - - /* FIXME: this needs to be per seat? */ - guint num_failures; - - guint seat_new_id; - guint seat_removed_id; - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - char *tty_of_active_vt; - guint active_vt_watch_id; -+ guint wait_to_finish_timeout_id; - #endif - }; - - enum { - PROP_0, - }; - - static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); - static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); - static void gdm_local_display_factory_finalize (GObject *object); - - static GdmDisplay *create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial_display); - - static void on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmLocalDisplayFactory *factory); - - static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); - static gpointer local_display_factory_object = NULL; - static gboolean lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data); - - G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) - - GQuark - gdm_local_display_factory_error_quark (void) -@@ -354,61 +356,60 @@ on_display_status_changed (GdmDisplay *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; - - /* workaround logind race for now - * bug 1643874 - */ - g_usleep (2 * G_USEC_PER_SEC); - } - - #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: -- finish_waiting_displays_on_seat (factory, seat_id); - break; - case GDM_DISPLAY_WAITING_TO_FINISH: - 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; - } -@@ -593,83 +594,101 @@ on_seat_new (GDBusConnection *connection, - } - - static void - on_seat_removed (GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) - { - const char *seat; - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); - } - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - static gboolean - lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - const char *looking_for = user_data; - const char *current; - - current = gdm_display_get_session_id (display); - return g_strcmp0 (current, looking_for) == 0; - } - -+static gboolean -+wait_to_finish_timeout (GdmLocalDisplayFactory *factory) -+{ -+ finish_waiting_displays_on_seat (factory, "seat0"); -+ factory->priv->wait_to_finish_timeout_id = 0; -+ return G_SOURCE_REMOVE; -+} -+ - static void --maybe_stop_greeter_in_background (GdmDisplay *display) -+maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory, -+ GdmDisplay *display) - { - g_autofree char *display_session_type = NULL; - - if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) { - g_debug ("GdmLocalDisplayFactory: login window not in managed state, so ignoring"); - return; - } - - g_object_get (G_OBJECT (display), - "session-type", &display_session_type, - NULL); - - /* we can only stop greeter for wayland sessions, since - * X server would jump back on exit */ - if (g_strcmp0 (display_session_type, "wayland") != 0) { - g_debug ("GdmLocalDisplayFactory: login window is running on Xorg, so ignoring"); - return; - } - - g_debug ("GdmLocalDisplayFactory: killing login window once its unused"); - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); -+ -+ /* We stop the greeter after a timeout to avoid flicker */ -+ if (factory->priv->wait_to_finish_timeout_id != 0) -+ g_source_remove (factory->priv->wait_to_finish_timeout_id); -+ -+ factory->priv->wait_to_finish_timeout_id = -+ g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT, -+ (GSourceFunc)wait_to_finish_timeout, -+ factory); - } - - static gboolean - on_vt_changed (GIOChannel *source, - GIOCondition condition, - GdmLocalDisplayFactory *factory) - { - GIOStatus status; - static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT; - g_autofree char *tty_of_previous_vt = NULL; - g_autofree char *tty_of_active_vt = NULL; - g_autofree char *login_session_id = NULL; - g_autofree char *active_session_id = NULL; - const char *session_type = NULL; - int ret; - - g_debug ("GdmLocalDisplayFactory: received VT change event"); - g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL); - - if (condition & G_IO_PRI) { - g_autoptr (GError) error = NULL; - status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error); - - if (error != NULL) { - g_warning ("could not read active VT from kernel: %s", error->message); - } - switch (status) { - case G_IO_STATUS_ERROR: - return G_SOURCE_REMOVE; - case G_IO_STATUS_EOF: -@@ -709,61 +728,61 @@ on_vt_changed (GIOChannel *source, - return G_SOURCE_CONTINUE; - } - - g_debug ("GdmLocalDisplayFactory: VT changed from %s to %s", - tty_of_previous_vt, factory->priv->tty_of_active_vt); - - /* if the old VT was running a wayland login screen kill it - */ - if (gdm_get_login_window_session_id ("seat0", &login_session_id)) { - unsigned int vt; - - ret = sd_session_get_vt (login_session_id, &vt); - if (ret == 0 && vt != 0) { - g_autofree char *tty_of_login_window_vt = NULL; - - tty_of_login_window_vt = g_strdup_printf ("tty%u", vt); - - g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt); - if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { - GdmDisplayStore *store; - GdmDisplay *display; - - g_debug ("GdmLocalDisplayFactory: VT switched from login window"); - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - - if (display != NULL) -- maybe_stop_greeter_in_background (display); -+ maybe_stop_greeter_in_background (factory, display); - } else { - g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); - } - } - } - - /* if user jumped back to initial vt and it's empty put a login screen - * on it (unless a login screen is already running elsewhere, then - * jump to that login screen) - */ - if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) { - g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring"); - return G_SOURCE_CONTINUE; - } - - ret = sd_seat_get_active ("seat0", &active_session_id, NULL); - - if (ret == 0) { - g_autofree char *state = NULL; - ret = sd_session_get_state (active_session_id, &state); - - /* if there's something already running on the active VT then bail */ - if (ret == 0 && g_strcmp0 (state, "closing") != 0) { - g_debug ("GdmLocalDisplayFactory: initial VT is in use, so ignoring"); - return G_SOURCE_CONTINUE; - } - } - - if (gdm_local_display_factory_use_wayland ()) - session_type = "wayland"; -@@ -803,60 +822,64 @@ gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) - g_object_unref); - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - io_channel = g_io_channel_new_file ("/sys/class/tty/tty0/active", "r", NULL); - - if (io_channel != NULL) { - factory->priv->active_vt_watch_id = - g_io_add_watch (io_channel, - G_IO_PRI, - (GIOFunc) - on_vt_changed, - factory); - } - #endif - } - - static void - gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory) - { - if (factory->priv->seat_new_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_new_id); - factory->priv->seat_new_id = 0; - } - if (factory->priv->seat_removed_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_removed_id); - factory->priv->seat_removed_id = 0; - } - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ if (factory->priv->wait_to_finish_timeout_id != 0) { -+ g_source_remove (factory->priv->wait_to_finish_timeout_id); -+ factory->priv->wait_to_finish_timeout_id = 0; -+ } - if (factory->priv->active_vt_watch_id) { - g_source_remove (factory->priv->active_vt_watch_id); - factory->priv->active_vt_watch_id = 0; - } - - g_clear_pointer (&factory->priv->tty_of_active_vt, g_free); - #endif - } - - static void - on_display_added (GdmDisplayStore *display_store, - const char *id, - GdmLocalDisplayFactory *factory) - { - GdmDisplay *display; - - display = gdm_display_store_lookup (display_store, id); - - if (display != NULL) { - g_signal_connect_object (display, "notify::status", - G_CALLBACK (on_display_status_changed), - factory, - 0); - - g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); - } - } - - static void - on_display_removed (GdmDisplayStore *display_store, -diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c -index de1991b34..94f49e19c 100644 ---- a/daemon/gdm-wayland-session.c -+++ b/daemon/gdm-wayland-session.c -@@ -427,75 +427,60 @@ init_state (State **state) - static State state_allocation; - - *state = &state_allocation; - } - - static void - clear_state (State **out_state) - { - State *state = *out_state; - - g_clear_object (&state->cancellable); - g_clear_object (&state->bus_connection); - g_clear_object (&state->session_subprocess); - g_clear_pointer (&state->environment, g_strfreev); - g_clear_pointer (&state->main_loop, g_main_loop_unref); - *out_state = NULL; - } - - static gboolean - on_sigterm (State *state) - { - g_cancellable_cancel (state->cancellable); - - if (g_main_loop_is_running (state->main_loop)) { - g_main_loop_quit (state->main_loop); - } - - return G_SOURCE_CONTINUE; - } - --static gboolean --on_registration_delay_complete (State *state) --{ -- gboolean ret; -- -- ret = register_display (state, state->cancellable); -- -- if (!ret) { -- g_printerr ("Unable to register display with display manager\n"); -- g_main_loop_quit (state->main_loop); -- } -- -- return G_SOURCE_REMOVE; --} -- - int - main (int argc, - char **argv) - { - State *state = NULL; - GOptionContext *context = NULL; - static char **args = NULL; - gboolean debug = FALSE; - gboolean ret; - int exit_status = EX_OK; - static GOptionEntry entries [] = { - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - gdm_log_init (); - - context = g_option_context_new (_("GNOME Display Manager Wayland Session Launcher")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - if (args == NULL || args[0] == NULL || args[1] != NULL) { - g_warning ("gdm-wayland-session takes one argument (the session)"); - exit_status = EX_USAGE; -@@ -516,49 +501,55 @@ main (int argc, - } - - gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); - state->debug_enabled = debug; - - gdm_log_set_debug (debug); - - state->main_loop = g_main_loop_new (NULL, FALSE); - state->cancellable = g_cancellable_new (); - - g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state); - - ret = spawn_bus (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session message bus\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - import_environment (state, state->cancellable); - - ret = spawn_session (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -- g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state); -+ ret = register_display (state, state->cancellable); -+ -+ if (!ret) { -+ g_printerr ("Unable to register display with display manager\n"); -+ exit_status = EX_SOFTWARE; -+ goto out; -+ } - - g_main_loop_run (state->main_loop); - - /* Only use exit status of session if we're here because it exit */ - - if (state->session_subprocess == NULL) { - exit_status = state->session_exit_status; - } - - out: - if (state != NULL) { - signal_subprocesses (state); - wait_on_subprocesses (state); - clear_state (&state); - } - - return exit_status; - } -diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c -index 412999cf5..3b2fcef47 100644 ---- a/daemon/gdm-x-session.c -+++ b/daemon/gdm-x-session.c -@@ -783,75 +783,60 @@ init_state (State **state) - } - - static void - clear_state (State **out_state) - { - State *state = *out_state; - - g_clear_object (&state->cancellable); - g_clear_object (&state->bus_connection); - g_clear_object (&state->session_subprocess); - g_clear_object (&state->x_subprocess); - g_clear_pointer (&state->environment, g_strfreev); - g_clear_pointer (&state->auth_file, g_free); - g_clear_pointer (&state->display_name, g_free); - g_clear_pointer (&state->main_loop, g_main_loop_unref); - *out_state = NULL; - } - - static gboolean - on_sigterm (State *state) - { - g_cancellable_cancel (state->cancellable); - - if (g_main_loop_is_running (state->main_loop)) { - g_main_loop_quit (state->main_loop); - } - - return G_SOURCE_CONTINUE; - } - --static gboolean --on_registration_delay_complete (State *state) --{ -- gboolean ret; -- -- ret = register_display (state, state->cancellable); -- -- if (!ret) { -- g_printerr ("Unable to register display with display manager\n"); -- g_main_loop_quit (state->main_loop); -- } -- -- return G_SOURCE_REMOVE; --} -- - int - main (int argc, - char **argv) - { - State *state = NULL; - GOptionContext *context = NULL; - static char **args = NULL; - static gboolean run_script = FALSE; - static gboolean allow_remote_connections = FALSE; - gboolean debug = FALSE; - gboolean ret; - int exit_status = EX_OK; - static GOptionEntry entries [] = { - { "run-script", 'r', 0, G_OPTION_ARG_NONE, &run_script, N_("Run program through /etc/gdm/Xsession wrapper script"), NULL }, - { "allow-remote-connections", 'a', 0, G_OPTION_ARG_NONE, &allow_remote_connections, N_("Listen on TCP socket"), NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - gdm_log_init (); - - context = g_option_context_new (_("GNOME Display Manager X Session Launcher")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); -@@ -884,57 +869,63 @@ main (int argc, - state->cancellable = g_cancellable_new (); - - g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state); - - ret = spawn_x_server (state, allow_remote_connections, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run X server\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - ret = spawn_bus (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session message bus\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - import_environment (state, state->cancellable); - - ret = update_bus_environment (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to update bus environment\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -+ ret = register_display (state, state->cancellable); -+ -+ if (!ret) { -+ g_printerr ("Unable to register display with display manager\n"); -+ exit_status = EX_SOFTWARE; -+ goto out; -+ } -+ - ret = spawn_session (state, run_script, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -- g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state); -- - g_main_loop_run (state->main_loop); - - /* Only use exit status of session if we're here because it exit */ - - if (state->session_subprocess == NULL) { - exit_status = state->session_exit_status; - } - - out: - if (state != NULL) { - signal_subprocesses (state); - wait_on_subprocesses (state); - clear_state (&state); - } - - return exit_status; - } --- -2.27.0 - diff --git a/SOURCES/0031-local-display-factory-don-t-autoreap-initial-setup.patch b/SOURCES/0031-local-display-factory-don-t-autoreap-initial-setup.patch deleted file mode 100644 index 5605385..0000000 --- a/SOURCES/0031-local-display-factory-don-t-autoreap-initial-setup.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 59b3b809400dfac25410cf99dbc15cb5f66f85a3 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 25 Sep 2018 14:52:15 -0400 -Subject: [PATCH 31/51] local-display-factory: don't autoreap initial-setup - -We automatically kill the login screen when switching VTs away -from it, but we should never kill the initial-setup screen in -that situation. - -This commit adds a check to prevent that from happening. ---- - daemon/gdm-local-display-factory.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index be6b377be..13d56dcff 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -607,70 +607,78 @@ on_seat_removed (GDBusConnection *connection, - g_variant_get (parameters, "(&s&o)", &seat, NULL); - delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); - } - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - static gboolean - lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - const char *looking_for = user_data; - const char *current; - - current = gdm_display_get_session_id (display); - return g_strcmp0 (current, looking_for) == 0; - } - - static gboolean - wait_to_finish_timeout (GdmLocalDisplayFactory *factory) - { - finish_waiting_displays_on_seat (factory, "seat0"); - factory->priv->wait_to_finish_timeout_id = 0; - return G_SOURCE_REMOVE; - } - - static void - maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - g_autofree char *display_session_type = NULL; -+ gboolean doing_initial_setup = FALSE; - - if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) { - g_debug ("GdmLocalDisplayFactory: login window not in managed state, so ignoring"); - return; - } - - g_object_get (G_OBJECT (display), - "session-type", &display_session_type, -+ "doing-initial-setup", &doing_initial_setup, - NULL); - -+ /* we don't ever stop initial-setup implicitly */ -+ if (doing_initial_setup) { -+ g_debug ("GdmLocalDisplayFactory: login window is performing initial-setup, so ignoring"); -+ return; -+ } -+ - /* we can only stop greeter for wayland sessions, since - * X server would jump back on exit */ - if (g_strcmp0 (display_session_type, "wayland") != 0) { - g_debug ("GdmLocalDisplayFactory: login window is running on Xorg, so ignoring"); - return; - } - - g_debug ("GdmLocalDisplayFactory: killing login window once its unused"); - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); - - /* We stop the greeter after a timeout to avoid flicker */ - if (factory->priv->wait_to_finish_timeout_id != 0) - g_source_remove (factory->priv->wait_to_finish_timeout_id); - - factory->priv->wait_to_finish_timeout_id = - g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT, - (GSourceFunc)wait_to_finish_timeout, - factory); - } - - static gboolean - on_vt_changed (GIOChannel *source, - GIOCondition condition, - GdmLocalDisplayFactory *factory) - { - GIOStatus status; - static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT; - g_autofree char *tty_of_previous_vt = NULL; - g_autofree char *tty_of_active_vt = NULL; - g_autofree char *login_session_id = NULL; --- -2.27.0 - diff --git a/SOURCES/0032-manager-rework-how-autologin-is-figured-out.patch b/SOURCES/0032-manager-rework-how-autologin-is-figured-out.patch deleted file mode 100644 index adf484e..0000000 --- a/SOURCES/0032-manager-rework-how-autologin-is-figured-out.patch +++ /dev/null @@ -1,460 +0,0 @@ -From 566720ce07db8745c0ae6780ff289292dc0a9b60 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 25 Sep 2018 10:59:37 -0400 -Subject: [PATCH 32/51] manager: rework how autologin is figured out - -At the moment we decide whether or not to perform autologin, by -looking at if the display is the initial VT display and if autologin -hasn't been started before. - -That isn't going to work in the future when autologin is started -on a non-initial vt. - -This commit changes GDM to instead check if the seat is seat0, and -if autologin hasn't run before, before deciding to do autologin. ---- - daemon/gdm-manager.c | 46 ++++++++++++++++++++++++++++++++------------ - 1 file changed, 34 insertions(+), 12 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index fb7b1ec4b..228cec6ff 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -51,75 +51,76 @@ - #include "gdm-session.h" - #include "gdm-session-record.h" - #include "gdm-settings-direct.h" - #include "gdm-settings-keys.h" - #include "gdm-xdmcp-display-factory.h" - #include "gdm-xdmcp-chooser-display.h" - - #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate)) - - #define GDM_DBUS_PATH "/org/gnome/DisplayManager" - #define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager" - #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays" - - #define INITIAL_SETUP_USERNAME "gnome-initial-setup" - - typedef struct - { - GdmManager *manager; - GdmSession *session; - char *service_name; - guint idle_id; - } StartUserSessionOperation; - - struct GdmManagerPrivate - { - GdmDisplayStore *display_store; - GdmLocalDisplayFactory *local_factory; - #ifdef HAVE_LIBXDMCP - GdmXdmcpDisplayFactory *xdmcp_factory; - #endif -+ GdmDisplay *automatic_login_display; - GList *user_sessions; - GHashTable *transient_sessions; - GHashTable *open_reauthentication_requests; - gboolean xdmcp_enabled; - - gboolean started; - gboolean show_local_greeter; - - GDBusConnection *connection; - GDBusObjectManagerServer *object_manager; - - #ifdef WITH_PLYMOUTH - guint plymouth_is_running : 1; - #endif -- guint ran_once : 1; -+ guint did_automatic_login : 1; - }; - - enum { - PROP_0, - PROP_XDMCP_ENABLED, - PROP_SHOW_LOCAL_GREETER - }; - - enum { - DISPLAY_ADDED, - DISPLAY_REMOVED, - LAST_SIGNAL - }; - - typedef enum { - SESSION_RECORD_LOGIN, - SESSION_RECORD_LOGOUT, - SESSION_RECORD_FAILED, - } SessionRecord; - - static guint signals [LAST_SIGNAL] = { 0, }; - - static void gdm_manager_class_init (GdmManagerClass *klass); - static void gdm_manager_init (GdmManager *manager); - static void gdm_manager_dispose (GObject *object); - - static GdmSession *create_user_session_for_display (GdmManager *manager, - GdmDisplay *display, - uid_t allowed_user); - static void start_user_session (GdmManager *manager, -@@ -1415,67 +1416,74 @@ typedef struct { - static void - destroy_username_lookup_operation (UsernameLookupOperation *operation) - { - g_object_unref (operation->manager); - g_object_unref (operation->display); - g_free (operation->username); - g_free (operation); - } - - static void - on_user_is_loaded_changed (ActUser *user, - GParamSpec *pspec, - UsernameLookupOperation *operation) - { - if (act_user_is_loaded (user)) { - set_up_automatic_login_session_if_user_exists (operation->manager, operation->display, user); - g_signal_handlers_disconnect_by_func (G_OBJECT (user), - G_CALLBACK (on_user_is_loaded_changed), - operation); - destroy_username_lookup_operation (operation); - } - } - - static void - set_up_session (GdmManager *manager, - GdmDisplay *display) - { - ActUserManager *user_manager; - ActUser *user; - gboolean loaded; -- gboolean is_initial_display = FALSE; -+ gboolean seat_can_autologin = FALSE, seat_did_autologin = FALSE; - gboolean autologin_enabled = FALSE; -+ g_autofree char *seat_id = NULL; - char *username = NULL; - -- g_object_get (G_OBJECT (display), "is-initial", &is_initial_display, NULL); -+ g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL); -+ -+ if (g_strcmp0 (seat_id, "seat0") == 0) -+ seat_can_autologin = TRUE; -+ -+ if (manager->priv->did_automatic_login || manager->priv->automatic_login_display != NULL) -+ seat_did_autologin = TRUE; - -- if (!manager->priv->ran_once && is_initial_display) -+ if (seat_can_autologin && !seat_did_autologin) - autologin_enabled = get_automatic_login_details (manager, &username); - - if (!autologin_enabled) { - g_free (username); - - #ifdef HAVE_LIBXDMCP - if (GDM_IS_XDMCP_CHOOSER_DISPLAY (display)) { - set_up_chooser_session (manager, display); - return; - } - #endif - - set_up_greeter_session (manager, display); - return; - } - - /* Check whether the user really exists before committing to autologin. */ - user_manager = act_user_manager_get_default (); - user = act_user_manager_get_user (user_manager, username); - g_object_get (user_manager, "is-loaded", &loaded, NULL); - - if (loaded) { - set_up_automatic_login_session_if_user_exists (manager, display, user); - } else { - UsernameLookupOperation *operation; - - operation = g_new (UsernameLookupOperation, 1); - operation->manager = g_object_ref (manager); - operation->display = g_object_ref (display); - operation->username = username; -@@ -1512,62 +1520,72 @@ on_display_status_changed (GdmDisplay *display, - "session-type", &session_type, - NULL); - - status = gdm_display_get_status (display); - - switch (status) { - case GDM_DISPLAY_PREPARED: - case GDM_DISPLAY_MANAGED: - 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); - } - 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 (!doing_initial_setup && (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0)) { -- manager->priv->ran_once = TRUE; -+ if (display == manager->priv->automatic_login_display) { -+ g_clear_weak_pointer (&manager->priv->automatic_login_display); -+ -+ manager->priv->did_automatic_login = TRUE; -+ -+#ifdef ENABLE_WAYLAND_SUPPORT -+ if (g_strcmp0 (session_type, "wayland") != 0 && status == GDM_DISPLAY_FAILED) { -+ /* we're going to fall back to X11, so try to autologin again -+ */ -+ manager->priv->did_automatic_login = FALSE; -+ } -+#endif - } - break; - default: - break; - } - - } - - static void - on_display_removed (GdmDisplayStore *display_store, - GdmDisplay *display, - GdmManager *manager) - { - char *id; - - gdm_display_get_id (display, &id, NULL); - g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); - g_free (id); - - g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); - - g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, display); - } - - static void - destroy_start_user_session_operation (StartUserSessionOperation *operation) - { - g_object_set_data (G_OBJECT (operation->session), - "start-user-session-operation", - NULL); -@@ -1621,132 +1639,134 @@ create_display_for_user_session (GdmManager *self, - const char *session_id) - { - GdmDisplay *display; - /* at the moment we only create GdmLocalDisplay objects on seat0 */ - const char *seat_id = "seat0"; - - display = gdm_local_display_new (); - - g_object_set (G_OBJECT (display), - "session-class", "user", - "seat-id", seat_id, - "session-id", session_id, - NULL); - gdm_display_store_add (self->priv->display_store, - display); - g_object_set_data (G_OBJECT (session), "gdm-display", display); - g_object_set_data_full (G_OBJECT (display), - "gdm-user-session", - g_object_ref (session), - (GDestroyNotify) - clean_user_session); - } - - static gboolean - on_start_user_session (StartUserSessionOperation *operation) - { - GdmManager *self = operation->manager; - gboolean migrated; - gboolean fail_if_already_switched = TRUE; - gboolean doing_initial_setup = FALSE; -- gboolean starting_user_session_right_away = TRUE; - GdmDisplay *display; - const char *session_id; - - g_debug ("GdmManager: start or jump to session"); - - /* If there's already a session running, jump to it. - * If the only session running is the one we just opened, - * start a session on it. - */ - migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched); - - g_debug ("GdmManager: migrated: %d", migrated); - if (migrated) { - /* We don't stop the manager here because - when Xorg exits it switches to the VT it was - started from. That interferes with fast - user switching. */ - gdm_session_reset (operation->session); - destroy_start_user_session_operation (operation); - goto out; - } - - display = get_display_for_user_session (operation->session); - - g_object_get (G_OBJECT (display), "doing-initial-setup", &doing_initial_setup, NULL); - - session_id = gdm_session_get_conversation_session_id (operation->session, - operation->service_name); - - if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - /* In this case, the greeter's display is morphing into - * the user session display. Kill the greeter on this session - * and let the user session follow the same display. */ - gdm_display_stop_greeter_session (display); - g_object_set (G_OBJECT (display), - "session-class", "user", - "session-id", session_id, - NULL); - } else { - uid_t allowed_uid; - - g_object_ref (display); - if (doing_initial_setup) { - g_debug ("GdmManager: closing down initial setup display"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - } else { - g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); - } - - /* The user session is going to follow the session worker - * into the new display. Untie it from this display and - * create a new session for a future user login. */ - allowed_uid = gdm_session_get_allowed_user (operation->session); - g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); - g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); - create_user_session_for_display (operation->manager, display, allowed_uid); - -+ /* Give the user session a new display object for bookkeeping purposes */ -+ create_display_for_user_session (operation->manager, -+ operation->session, -+ session_id); -+ - if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) && - !gdm_session_client_is_connected (operation->session)) { - /* remove the unused prepared greeter display since we're not going - * to have a greeter */ - gdm_display_store_remove (self->priv->display_store, display); - g_object_unref (display); -- } - -- /* Give the user session a new display object for bookkeeping purposes */ -- create_display_for_user_session (operation->manager, -- operation->session, -- session_id); -+ self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display"); -+ g_object_add_weak_pointer (G_OBJECT (display), (gpointer *) &self->priv->automatic_login_display); -+ } - } - - start_user_session (operation->manager, operation); - - out: - return G_SOURCE_REMOVE; - } - - static void - queue_start_user_session (GdmManager *manager, - GdmSession *session, - const char *service_name) - { - StartUserSessionOperation *operation; - - operation = g_slice_new0 (StartUserSessionOperation); - operation->manager = manager; - operation->session = g_object_ref (session); - operation->service_name = g_strdup (service_name); - - operation->idle_id = g_idle_add ((GSourceFunc) on_start_user_session, operation); - g_object_set_data (G_OBJECT (session), "start-user-session-operation", operation); - } - - static void - start_user_session_if_ready (GdmManager *manager, - GdmSession *session, - const char *service_name) - { - gboolean start_when_ready; -@@ -2601,60 +2621,62 @@ unexport_display (const char *id, - GdmDisplay *display, - GdmManager *manager) - { - if (!g_dbus_connection_is_closed (manager->priv->connection)) - g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); - } - - static void - finish_display (const char *id, - GdmDisplay *display, - GdmManager *manager) - { - gdm_display_stop_greeter_session (display); - if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) - gdm_display_unmanage (display); - gdm_display_finish (display); - } - - static void - gdm_manager_dispose (GObject *object) - { - GdmManager *manager; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_MANAGER (object)); - - manager = GDM_MANAGER (object); - - g_return_if_fail (manager->priv != NULL); - -+ g_clear_weak_pointer (&manager->priv->automatic_login_display); -+ - #ifdef HAVE_LIBXDMCP - g_clear_object (&manager->priv->xdmcp_factory); - #endif - g_clear_object (&manager->priv->local_factory); - g_clear_pointer (&manager->priv->open_reauthentication_requests, - (GDestroyNotify) - g_hash_table_unref); - g_clear_pointer (&manager->priv->transient_sessions, - (GDestroyNotify) - g_hash_table_unref); - - g_list_foreach (manager->priv->user_sessions, - (GFunc) gdm_session_close, - NULL); - g_list_free_full (manager->priv->user_sessions, (GDestroyNotify) g_object_unref); - manager->priv->user_sessions = NULL; - - g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), - G_CALLBACK (on_display_added), - manager); - g_signal_handlers_disconnect_by_func (G_OBJECT (manager->priv->display_store), - G_CALLBACK (on_display_removed), - manager); - - if (!g_dbus_connection_is_closed (manager->priv->connection)) { - gdm_display_store_foreach (manager->priv->display_store, - (GdmDisplayStoreFunc)unexport_display, - manager); - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (manager)); - } --- -2.27.0 - diff --git a/SOURCES/0033-manager-correct-display-confusion.patch b/SOURCES/0033-manager-correct-display-confusion.patch deleted file mode 100644 index a898d87..0000000 --- a/SOURCES/0033-manager-correct-display-confusion.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 05e49542a9de81731fce68614babe22d437e8fff Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 1 Oct 2018 11:05:57 -0400 -Subject: [PATCH 33/51] manager: correct display confusion - -commit c5c5bf1f reworked autologin and broke it. - -This commit addresses the breakage by accessing -the proper display variable. - -Closes https://gitlab.gnome.org/GNOME/gdm/issues/426 ---- - daemon/gdm-manager.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 228cec6ff..4c81dac7f 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1711,61 +1711,61 @@ on_start_user_session (StartUserSessionOperation *operation) - if (doing_initial_setup) { - g_debug ("GdmManager: closing down initial setup display"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - } else { - g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); - } - - /* The user session is going to follow the session worker - * into the new display. Untie it from this display and - * create a new session for a future user login. */ - allowed_uid = gdm_session_get_allowed_user (operation->session); - g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); - g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); - create_user_session_for_display (operation->manager, display, allowed_uid); - - /* Give the user session a new display object for bookkeeping purposes */ - create_display_for_user_session (operation->manager, - operation->session, - session_id); - - if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) && - !gdm_session_client_is_connected (operation->session)) { - /* remove the unused prepared greeter display since we're not going - * to have a greeter */ - gdm_display_store_remove (self->priv->display_store, display); - g_object_unref (display); - - self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display"); -- g_object_add_weak_pointer (G_OBJECT (display), (gpointer *) &self->priv->automatic_login_display); -+ g_object_add_weak_pointer (G_OBJECT (self->priv->automatic_login_display), (gpointer *) &self->priv->automatic_login_display); - } - } - - start_user_session (operation->manager, operation); - - out: - return G_SOURCE_REMOVE; - } - - static void - queue_start_user_session (GdmManager *manager, - GdmSession *session, - const char *service_name) - { - StartUserSessionOperation *operation; - - operation = g_slice_new0 (StartUserSessionOperation); - operation->manager = manager; - operation->session = g_object_ref (session); - operation->service_name = g_strdup (service_name); - - operation->idle_id = g_idle_add ((GSourceFunc) on_start_user_session, operation); - g_object_set_data (G_OBJECT (session), "start-user-session-operation", operation); - } - - static void - start_user_session_if_ready (GdmManager *manager, - GdmSession *session, - const char *service_name) - { --- -2.27.0 - diff --git a/SOURCES/0034-manager-don-t-run-autologin-display-on-tty1.patch b/SOURCES/0034-manager-don-t-run-autologin-display-on-tty1.patch deleted file mode 100644 index 757ec9e..0000000 --- a/SOURCES/0034-manager-don-t-run-autologin-display-on-tty1.patch +++ /dev/null @@ -1,99 +0,0 @@ -From e4c9a998f89d429d31b02997f146c8218c0742bc Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 24 Sep 2018 14:45:38 -0400 -Subject: [PATCH 34/51] manager: don't run autologin display on tty1 - -tty1 is really meant for the login screen. -If a user autologins on it and we need a login -screen later, then the login screen has to go -in some auxiliary VT which isn't very nice. - -This commit changes autologin to not use the -initial vt. ---- - daemon/gdm-manager.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 4c81dac7f..e896c8945 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1308,74 +1308,72 @@ get_automatic_login_details (GdmManager *manager, - } else { - g_free (username); - } - - return enabled; - } - - static const char * - get_username_for_greeter_display (GdmManager *manager, - GdmDisplay *display) - { - gboolean doing_initial_setup = FALSE; - - g_object_get (G_OBJECT (display), - "doing-initial-setup", &doing_initial_setup, - NULL); - - if (doing_initial_setup) { - return INITIAL_SETUP_USERNAME; - } else { - return GDM_USERNAME; - } - } - - static void - set_up_automatic_login_session (GdmManager *manager, - GdmDisplay *display) - { - 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); - - g_object_get (G_OBJECT (display), -- "is-initial", &is_initial, - "session-type", &display_session_type, - NULL); - - g_object_set (G_OBJECT (session), -- "display-is-initial", is_initial, -+ "display-is-initial", FALSE, - NULL); - - g_debug ("GdmManager: Starting automatic login conversation"); - gdm_session_start_conversation (session, "gdm-autologin"); - } - - static void - set_up_chooser_session (GdmManager *manager, - GdmDisplay *display) - { - const char *allowed_user; - struct passwd *passwd_entry; - - allowed_user = get_username_for_greeter_display (manager, display); - - if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) { - g_warning ("GdmManager: couldn't look up username %s", - allowed_user); - gdm_display_unmanage (display); - gdm_display_finish (display); - return; - } - - gdm_display_start_greeter_session (display); - } - - static void - set_up_greeter_session (GdmManager *manager, - GdmDisplay *display) - { --- -2.27.0 - diff --git a/SOURCES/0035-local-display-factory-Remove-initial-VT-is-in-use-ch.patch b/SOURCES/0035-local-display-factory-Remove-initial-VT-is-in-use-ch.patch deleted file mode 100644 index e53ccef..0000000 --- a/SOURCES/0035-local-display-factory-Remove-initial-VT-is-in-use-ch.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 2843a951ef826afd01fa3c7340780b1929db38c7 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 4 Sep 2018 08:12:34 +0200 -Subject: [PATCH 35/51] local-display-factory: Remove initial VT is in use - check - -The initial VT is in use check in on_vt_changed() is racy, when switching -to VT1 from an active session, on_vt_changed() may run before logind has -processed the VT change and then sd_seat_get_active() will return the -active session which we are switching away from. This results in the greeter -not being started on VT1. - -On my system gdm reliably wins the race resulting in not getting a greeter -when manually switching from an active session to VT1. - -gdm already starts the greeter unconditionally from -gdm_local_display_factory_sync_seats() on both startup and when an user -session exits. gdm also starts it unconditionally when selecting -"Switch user" from an user session. - -Now autologin sessions avoid the initial VT as well. - -So we now can assume that the initial VT is free for the login screen's -use. And create_display already checks for and re-uses -an existing greeter, so we can safely remove the racy check. ---- - daemon/gdm-local-display-factory.c | 13 ------------- - 1 file changed, 13 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 13d56dcff..8e46dbca2 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -752,73 +752,60 @@ on_vt_changed (GIOChannel *source, - - g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt); - if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { - GdmDisplayStore *store; - GdmDisplay *display; - - g_debug ("GdmLocalDisplayFactory: VT switched from login window"); - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - - if (display != NULL) - maybe_stop_greeter_in_background (factory, display); - } else { - g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); - } - } - } - - /* if user jumped back to initial vt and it's empty put a login screen - * on it (unless a login screen is already running elsewhere, then - * jump to that login screen) - */ - if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) { - g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring"); - return G_SOURCE_CONTINUE; - } - -- ret = sd_seat_get_active ("seat0", &active_session_id, NULL); -- -- if (ret == 0) { -- g_autofree char *state = NULL; -- ret = sd_session_get_state (active_session_id, &state); -- -- /* if there's something already running on the active VT then bail */ -- if (ret == 0 && g_strcmp0 (state, "closing") != 0) { -- g_debug ("GdmLocalDisplayFactory: initial VT is in use, so ignoring"); -- return G_SOURCE_CONTINUE; -- } -- } -- - if (gdm_local_display_factory_use_wayland ()) - session_type = "wayland"; - - g_debug ("GdmLocalDisplayFactory: creating new display on seat0 because of VT change"); - - create_display (factory, "seat0", session_type, TRUE); - - return G_SOURCE_CONTINUE; - } - #endif - - static void - gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) - { - g_autoptr (GIOChannel) io_channel = NULL; - - factory->priv->seat_new_id = g_dbus_connection_signal_subscribe (factory->priv->connection, - "org.freedesktop.login1", - "org.freedesktop.login1.Manager", - "SeatNew", - "/org/freedesktop/login1", - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - on_seat_new, - g_object_ref (factory), - g_object_unref); - factory->priv->seat_removed_id = g_dbus_connection_signal_subscribe (factory->priv->connection, - "org.freedesktop.login1", - "org.freedesktop.login1.Manager", - "SeatRemoved", --- -2.27.0 - diff --git a/SOURCES/0036-local-display-factory-Remove-same-VT-so-don-t-switch.patch b/SOURCES/0036-local-display-factory-Remove-same-VT-so-don-t-switch.patch deleted file mode 100644 index 85f9af9..0000000 --- a/SOURCES/0036-local-display-factory-Remove-same-VT-so-don-t-switch.patch +++ /dev/null @@ -1,140 +0,0 @@ -From f5acee2766c05403235c06da6b1bb68af744da79 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 25 Sep 2018 14:30:16 -0400 -Subject: [PATCH 36/51] local-display-factory: Remove same VT so don't switch - check - -We avoid changing to the login screen vt if we're already on it, -but the call is racy since we react to vt changes concurrently -with logind (who we query for the active vt). - -This check drops the active vt check since it's pointless and -getting in the way. ---- - daemon/gdm-local-display-factory.c | 39 ++++++++++-------------------- - 1 file changed, 13 insertions(+), 26 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 8e46dbca2..be7b43cff 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -410,103 +410,90 @@ lookup_by_seat_id (const char *id, - res = g_strcmp0 (current, looking_for) == 0; - - g_free(current); - - return res; - } - - static gboolean - lookup_prepared_display_by_seat_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - int status; - - status = gdm_display_get_status (display); - - if (status != GDM_DISPLAY_PREPARED) - return FALSE; - - return lookup_by_seat_id (id, display, user_data); - } - - static GdmDisplay * - create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial) - { - GdmDisplayStore *store; - GdmDisplay *display = NULL; -- char *active_session_id = NULL; -- int ret; -+ g_autofree char *login_session_id = NULL; - - g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", - session_type? : "X11", seat_id); - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - if (sd_seat_can_multi_session (seat_id)) - display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); - else - display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); - - /* Ensure we don't create the same display more than once */ - if (display != NULL) { - g_debug ("GdmLocalDisplayFactory: display already created"); - return NULL; - } - -- 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 (gdm_get_login_window_session_id (seat_id, &login_session_id)) { -- GdmDisplay *display; -- -- display = gdm_display_store_find (store, -- lookup_by_session_id, -- (gpointer) login_session_id); -- if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { -- if (g_strcmp0 (active_session_id, login_session_id) != 0) { -- g_debug ("GdmLocalDisplayFactory: session %s found, activating.", -- login_session_id); -- gdm_activate_session_by_id (factory->priv->connection, 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 (&login_session_id, g_free); -+ /* If we already have a login window, switch to it */ -+ if (gdm_get_login_window_session_id (seat_id, &login_session_id)) { -+ GdmDisplay *display; -+ -+ display = gdm_display_store_find (store, -+ lookup_by_session_id, -+ (gpointer) login_session_id); -+ if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { -+ g_debug ("GdmLocalDisplayFactory: session %s found, activating.", -+ login_session_id); -+ gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id); -+ return NULL; - } -- g_clear_pointer (&active_session_id, g_free); - } - - 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)) { --- -2.27.0 - diff --git a/SOURCES/0037-local-display-factory-handle-reviving-displays-that-.patch b/SOURCES/0037-local-display-factory-handle-reviving-displays-that-.patch deleted file mode 100644 index 35639e9..0000000 --- a/SOURCES/0037-local-display-factory-handle-reviving-displays-that-.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 59a4538e335362a92186217be03529f3694697e1 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 25 Sep 2018 14:39:42 -0400 -Subject: [PATCH 37/51] local-display-factory: handle reviving displays that - are waiting to die - -We may end up re-using a display in waiting-to-finish state before it gets -finished in this case reset its state to managed to avoid it getting -finished while it is being used. - -Closes https://gitlab.gnome.org/GNOME/gdm/merge_requests/45 ---- - daemon/gdm-local-display-factory.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index be7b43cff..d999596b5 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -434,61 +434,64 @@ create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial) - { - GdmDisplayStore *store; - GdmDisplay *display = NULL; - g_autofree char *login_session_id = NULL; - - g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", - session_type? : "X11", seat_id); - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - if (sd_seat_can_multi_session (seat_id)) - display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); - else - display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); - - /* Ensure we don't create the same display more than once */ - if (display != NULL) { - g_debug ("GdmLocalDisplayFactory: display already created"); - return NULL; - } - - /* If we already have a login window, switch to it */ - if (gdm_get_login_window_session_id (seat_id, &login_session_id)) { - GdmDisplay *display; - - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); -- if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { -+ if (display != NULL && -+ (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED || -+ gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) { -+ g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); - g_debug ("GdmLocalDisplayFactory: session %s found, activating.", - login_session_id); - gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id); - return NULL; - } - } - - 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); --- -2.27.0 - diff --git a/SOURCES/0038-manager-don-t-kill-initial-setup-before-starting-use.patch b/SOURCES/0038-manager-don-t-kill-initial-setup-before-starting-use.patch deleted file mode 100644 index 1925cab..0000000 --- a/SOURCES/0038-manager-don-t-kill-initial-setup-before-starting-use.patch +++ /dev/null @@ -1,151 +0,0 @@ -From c65a0dbd195be52f0db0c49ea0355fe1b5eb4c09 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 31 Aug 2018 15:48:38 -0400 -Subject: [PATCH 38/51] manager: don't kill initial-setup before starting user - session on wayland - -Right now we kill initial-setup before starting the session for the user -initial-setup created. This is the right thing to do for Xorg, since -Xorg can't be killed in the background, but it adds unncessary flicker -for wayland. - -This commit checks if it's wayland and avoids killing it right away -in that case. ---- - daemon/gdm-manager.c | 26 +++++++++++++++++++++----- - 1 file changed, 21 insertions(+), 5 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index e896c8945..0823e8638 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1639,105 +1639,121 @@ create_display_for_user_session (GdmManager *self, - GdmDisplay *display; - /* at the moment we only create GdmLocalDisplay objects on seat0 */ - const char *seat_id = "seat0"; - - display = gdm_local_display_new (); - - g_object_set (G_OBJECT (display), - "session-class", "user", - "seat-id", seat_id, - "session-id", session_id, - NULL); - gdm_display_store_add (self->priv->display_store, - display); - g_object_set_data (G_OBJECT (session), "gdm-display", display); - g_object_set_data_full (G_OBJECT (display), - "gdm-user-session", - g_object_ref (session), - (GDestroyNotify) - clean_user_session); - } - - static gboolean - on_start_user_session (StartUserSessionOperation *operation) - { - GdmManager *self = operation->manager; - gboolean migrated; - gboolean fail_if_already_switched = TRUE; - gboolean doing_initial_setup = FALSE; - GdmDisplay *display; - const char *session_id; -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ g_autofree char *display_session_type = NULL; -+#endif - - g_debug ("GdmManager: start or jump to session"); - - /* If there's already a session running, jump to it. - * If the only session running is the one we just opened, - * start a session on it. - */ - migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched); - - g_debug ("GdmManager: migrated: %d", migrated); - if (migrated) { - /* We don't stop the manager here because - when Xorg exits it switches to the VT it was - started from. That interferes with fast - user switching. */ - gdm_session_reset (operation->session); - destroy_start_user_session_operation (operation); - goto out; - } - - display = get_display_for_user_session (operation->session); - -- g_object_get (G_OBJECT (display), "doing-initial-setup", &doing_initial_setup, NULL); -+ g_object_get (G_OBJECT (display), -+ "doing-initial-setup", &doing_initial_setup, -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ "session-type", &display_session_type, -+#endif -+ NULL); - - session_id = gdm_session_get_conversation_session_id (operation->session, - operation->service_name); - - if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - /* In this case, the greeter's display is morphing into - * the user session display. Kill the greeter on this session - * and let the user session follow the same display. */ - gdm_display_stop_greeter_session (display); - g_object_set (G_OBJECT (display), - "session-class", "user", - "session-id", session_id, - NULL); - } else { - uid_t allowed_uid; - - g_object_ref (display); - if (doing_initial_setup) { -- g_debug ("GdmManager: closing down initial setup display"); -- gdm_display_stop_greeter_session (display); -- gdm_display_unmanage (display); -- gdm_display_finish (display); -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ if (g_strcmp0 (display_session_type, "wayland") == 0) { -+ g_debug ("GdmManager: closing down initial setup display in background"); -+ g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); -+ } -+#endif -+ if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { -+ g_debug ("GdmManager: closing down initial setup display"); -+ gdm_display_stop_greeter_session (display); -+ gdm_display_unmanage (display); -+ gdm_display_finish (display); -+ } - } else { - g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); - } - - /* The user session is going to follow the session worker - * into the new display. Untie it from this display and - * create a new session for a future user login. */ - allowed_uid = gdm_session_get_allowed_user (operation->session); - g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); - g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); - create_user_session_for_display (operation->manager, display, allowed_uid); - - /* Give the user session a new display object for bookkeeping purposes */ - create_display_for_user_session (operation->manager, - operation->session, - session_id); - - if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) && - !gdm_session_client_is_connected (operation->session)) { - /* remove the unused prepared greeter display since we're not going - * to have a greeter */ - gdm_display_store_remove (self->priv->display_store, display); - g_object_unref (display); - - self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display"); - g_object_add_weak_pointer (G_OBJECT (self->priv->automatic_login_display), (gpointer *) &self->priv->automatic_login_display); - } - } - - start_user_session (operation->manager, operation); --- -2.27.0 - diff --git a/SOURCES/0039-manager-do-initial-setup-post-work-in-manager-code.patch b/SOURCES/0039-manager-do-initial-setup-post-work-in-manager-code.patch deleted file mode 100644 index dff5a1f..0000000 --- a/SOURCES/0039-manager-do-initial-setup-post-work-in-manager-code.patch +++ /dev/null @@ -1,694 +0,0 @@ -From c08afca0807d8820030c19a40e7590f72878c788 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 6 Sep 2018 19:31:50 -0400 -Subject: [PATCH 39/51] manager: do initial-setup post work in manager code - -Right now we do the initial-setup related post work -when stopping the greeter, but the problem is we delay -stopping the greeter now until after the user session -is started. - -That post-work needs to be done before the user session -is started. - -This commit moves the code to a more logical place. ---- - daemon/gdm-display.c | 132 ------------------------------------------- - daemon/gdm-manager.c | 132 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 132 insertions(+), 132 deletions(-) - -diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 875534272..1cef8c7c1 100644 ---- a/daemon/gdm-display.c -+++ b/daemon/gdm-display.c -@@ -22,61 +22,60 @@ - - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include - - #include - #include - - #include "gdm-common.h" - #include "gdm-display.h" - #include "gdm-display-glue.h" - #include "gdm-display-access-file.h" - #include "gdm-launch-environment.h" - - #include "gdm-settings-direct.h" - #include "gdm-settings-keys.h" - - #include "gdm-launch-environment.h" - #include "gdm-dbus-util.h" - --#define INITIAL_SETUP_USERNAME "gnome-initial-setup" - #define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions" - - #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate)) - - struct GdmDisplayPrivate - { - char *id; - char *seat_id; - char *session_id; - char *session_class; - char *session_type; - - char *remote_hostname; - int x11_display_number; - char *x11_display_name; - int status; - time_t creation_time; - GTimer *server_timer; - - char *x11_cookie; - gsize x11_cookie_size; - GdmDisplayAccessFile *access_file; - - guint finish_idle_id; - - xcb_connection_t *xcb_connection; - int xcb_screen_number; - - GDBusConnection *connection; - GdmDisplayAccessFile *user_access_file; -@@ -98,131 +97,60 @@ enum { - PROP_0, - PROP_ID, - PROP_STATUS, - PROP_SEAT_ID, - PROP_SESSION_ID, - PROP_SESSION_CLASS, - PROP_SESSION_TYPE, - PROP_REMOTE_HOSTNAME, - PROP_X11_DISPLAY_NUMBER, - PROP_X11_DISPLAY_NAME, - PROP_X11_COOKIE, - PROP_X11_AUTHORITY_FILE, - PROP_IS_CONNECTED, - PROP_IS_LOCAL, - PROP_LAUNCH_ENVIRONMENT, - PROP_IS_INITIAL, - PROP_ALLOW_TIMED_LOGIN, - PROP_HAVE_EXISTING_USER_ACCOUNTS, - PROP_DOING_INITIAL_SETUP, - }; - - static void gdm_display_class_init (GdmDisplayClass *klass); - static void gdm_display_init (GdmDisplay *self); - static void gdm_display_finalize (GObject *object); - static void queue_finish (GdmDisplay *self); - static void _gdm_display_set_status (GdmDisplay *self, - int status); - static gboolean wants_initial_setup (GdmDisplay *self); - G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT) - --static gboolean --chown_file (GFile *file, -- uid_t uid, -- gid_t gid, -- GError **error) --{ -- if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid, -- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, -- NULL, error)) { -- return FALSE; -- } -- if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid, -- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, -- NULL, error)) { -- return FALSE; -- } -- return TRUE; --} -- --static gboolean --chown_recursively (GFile *dir, -- uid_t uid, -- gid_t gid, -- GError **error) --{ -- GFile *file = NULL; -- GFileInfo *info = NULL; -- GFileEnumerator *enumerator = NULL; -- gboolean retval = FALSE; -- -- if (chown_file (dir, uid, gid, error) == FALSE) { -- goto out; -- } -- -- enumerator = g_file_enumerate_children (dir, -- G_FILE_ATTRIBUTE_STANDARD_TYPE"," -- G_FILE_ATTRIBUTE_STANDARD_NAME, -- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, -- NULL, error); -- if (!enumerator) { -- goto out; -- } -- -- while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) { -- file = g_file_get_child (dir, g_file_info_get_name (info)); -- -- if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { -- if (chown_recursively (file, uid, gid, error) == FALSE) { -- goto out; -- } -- } else if (chown_file (file, uid, gid, error) == FALSE) { -- goto out; -- } -- -- g_clear_object (&file); -- g_clear_object (&info); -- } -- -- if (*error) { -- goto out; -- } -- -- retval = TRUE; --out: -- g_clear_object (&file); -- g_clear_object (&info); -- g_clear_object (&enumerator); -- -- return retval; --} -- - GQuark - gdm_display_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_display_error"); - } - - return ret; - } - - time_t - gdm_display_get_creation_time (GdmDisplay *self) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); - - return self->priv->creation_time; - } - - int - gdm_display_get_status (GdmDisplay *self) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); - - return self->priv->status; - } - - const char * - gdm_display_get_session_id (GdmDisplay *self) - { -@@ -1649,145 +1577,85 @@ gdm_display_start_greeter_session (GdmDisplay *self) - G_CALLBACK (on_launch_environment_session_stopped), - self, 0); - g_signal_connect_object (self->priv->launch_environment, - "exited", - G_CALLBACK (on_launch_environment_session_exited), - self, 0); - g_signal_connect_object (self->priv->launch_environment, - "died", - G_CALLBACK (on_launch_environment_session_died), - self, 0); - - if (auth_file != NULL) { - g_object_set (self->priv->launch_environment, - "x11-authority-file", auth_file, - NULL); - } - - gdm_launch_environment_start (self->priv->launch_environment); - - session = gdm_launch_environment_get_session (self->priv->launch_environment); - g_object_set (G_OBJECT (session), - "display-is-initial", self->priv->is_initial, - NULL); - - g_free (display_name); - g_free (seat_id); - g_free (hostname); - g_free (auth_file); - } - --static void --chown_initial_setup_home_dir (void) --{ -- GFile *dir; -- GError *error; -- char *gis_dir_path; -- char *gis_uid_path; -- char *gis_uid_contents; -- struct passwd *pwe; -- uid_t uid; -- -- if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) { -- g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME); -- return; -- } -- -- gis_dir_path = g_strdup (pwe->pw_dir); -- -- gis_uid_path = g_build_filename (gis_dir_path, -- "gnome-initial-setup-uid", -- NULL); -- if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) { -- g_warning ("Unable to read %s", gis_uid_path); -- goto out; -- } -- -- uid = (uid_t) atoi (gis_uid_contents); -- pwe = getpwuid (uid); -- if (uid == 0 || pwe == NULL) { -- g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path); -- goto out; -- } -- -- error = NULL; -- dir = g_file_new_for_path (gis_dir_path); -- if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) { -- g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message); -- g_error_free (error); -- } -- g_object_unref (dir); --out: -- g_free (gis_uid_contents); -- g_free (gis_uid_path); -- g_free (gis_dir_path); --} -- - void - gdm_display_stop_greeter_session (GdmDisplay *self) - { - GError *error = NULL; - - if (self->priv->launch_environment != NULL) { - - g_signal_handlers_disconnect_by_func (self->priv->launch_environment, - G_CALLBACK (on_launch_environment_session_opened), - self); - g_signal_handlers_disconnect_by_func (self->priv->launch_environment, - G_CALLBACK (on_launch_environment_session_started), - self); - g_signal_handlers_disconnect_by_func (self->priv->launch_environment, - G_CALLBACK (on_launch_environment_session_stopped), - self); - g_signal_handlers_disconnect_by_func (self->priv->launch_environment, - G_CALLBACK (on_launch_environment_session_exited), - self); - g_signal_handlers_disconnect_by_func (self->priv->launch_environment, - G_CALLBACK (on_launch_environment_session_died), - self); - gdm_launch_environment_stop (self->priv->launch_environment); - g_clear_object (&self->priv->launch_environment); - } -- -- if (self->priv->doing_initial_setup) { -- chown_initial_setup_home_dir (); -- -- if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT, -- "1", -- 1, -- &error)) { -- g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s", -- ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT, -- error->message); -- g_clear_error (&error); -- } -- } - } - - static xcb_window_t - get_root_window (xcb_connection_t *connection, - int screen_number) - { - xcb_screen_t *screen = NULL; - xcb_screen_iterator_t iter; - - iter = xcb_setup_roots_iterator (xcb_get_setup (connection)); - while (iter.rem) { - if (screen_number == 0) - screen = iter.data; - screen_number--; - xcb_screen_next (&iter); - } - - if (screen != NULL) { - return screen->root; - } - - return XCB_WINDOW_NONE; - } - - static void - gdm_display_set_windowpath (GdmDisplay *self) - { - /* setting WINDOWPATH for clients */ - xcb_intern_atom_cookie_t atom_cookie; - xcb_intern_atom_reply_t *atom_reply = NULL; -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 0823e8638..cf982870c 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -35,60 +35,61 @@ - #include - - #include - - #include - - #include "gdm-common.h" - - #include "gdm-dbus-util.h" - #include "gdm-manager.h" - #include "gdm-manager-glue.h" - #include "gdm-display-store.h" - #include "gdm-display-factory.h" - #include "gdm-launch-environment.h" - #include "gdm-local-display.h" - #include "gdm-local-display-factory.h" - #include "gdm-session.h" - #include "gdm-session-record.h" - #include "gdm-settings-direct.h" - #include "gdm-settings-keys.h" - #include "gdm-xdmcp-display-factory.h" - #include "gdm-xdmcp-chooser-display.h" - - #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate)) - - #define GDM_DBUS_PATH "/org/gnome/DisplayManager" - #define GDM_MANAGER_PATH GDM_DBUS_PATH "/Manager" - #define GDM_MANAGER_DISPLAYS_PATH GDM_DBUS_PATH "/Displays" - - #define INITIAL_SETUP_USERNAME "gnome-initial-setup" -+#define ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT GDM_RUN_DIR "/gdm.ran-initial-setup" - - typedef struct - { - GdmManager *manager; - GdmSession *session; - char *service_name; - guint idle_id; - } StartUserSessionOperation; - - struct GdmManagerPrivate - { - GdmDisplayStore *display_store; - GdmLocalDisplayFactory *local_factory; - #ifdef HAVE_LIBXDMCP - GdmXdmcpDisplayFactory *xdmcp_factory; - #endif - GdmDisplay *automatic_login_display; - GList *user_sessions; - GHashTable *transient_sessions; - GHashTable *open_reauthentication_requests; - gboolean xdmcp_enabled; - - gboolean started; - gboolean show_local_greeter; - - GDBusConnection *connection; - GDBusObjectManagerServer *object_manager; - - #ifdef WITH_PLYMOUTH - guint plymouth_is_running : 1; -@@ -1630,130 +1631,261 @@ start_user_session (GdmManager *manager, - - destroy_start_user_session_operation (operation); - } - - static void - create_display_for_user_session (GdmManager *self, - GdmSession *session, - const char *session_id) - { - GdmDisplay *display; - /* at the moment we only create GdmLocalDisplay objects on seat0 */ - const char *seat_id = "seat0"; - - display = gdm_local_display_new (); - - g_object_set (G_OBJECT (display), - "session-class", "user", - "seat-id", seat_id, - "session-id", session_id, - NULL); - gdm_display_store_add (self->priv->display_store, - display); - g_object_set_data (G_OBJECT (session), "gdm-display", display); - g_object_set_data_full (G_OBJECT (display), - "gdm-user-session", - g_object_ref (session), - (GDestroyNotify) - clean_user_session); - } - -+static gboolean -+chown_file (GFile *file, -+ uid_t uid, -+ gid_t gid, -+ GError **error) -+{ -+ if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_UID, uid, -+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, -+ NULL, error)) { -+ return FALSE; -+ } -+ if (!g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_GID, gid, -+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, -+ NULL, error)) { -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+static gboolean -+chown_recursively (GFile *dir, -+ uid_t uid, -+ gid_t gid, -+ GError **error) -+{ -+ GFile *file = NULL; -+ GFileInfo *info = NULL; -+ GFileEnumerator *enumerator = NULL; -+ gboolean retval = FALSE; -+ -+ if (chown_file (dir, uid, gid, error) == FALSE) { -+ goto out; -+ } -+ -+ enumerator = g_file_enumerate_children (dir, -+ G_FILE_ATTRIBUTE_STANDARD_TYPE"," -+ G_FILE_ATTRIBUTE_STANDARD_NAME, -+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, -+ NULL, error); -+ if (!enumerator) { -+ goto out; -+ } -+ -+ while ((info = g_file_enumerator_next_file (enumerator, NULL, error)) != NULL) { -+ file = g_file_get_child (dir, g_file_info_get_name (info)); -+ -+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { -+ if (chown_recursively (file, uid, gid, error) == FALSE) { -+ goto out; -+ } -+ } else if (chown_file (file, uid, gid, error) == FALSE) { -+ goto out; -+ } -+ -+ g_clear_object (&file); -+ g_clear_object (&info); -+ } -+ -+ if (*error) { -+ goto out; -+ } -+ -+ retval = TRUE; -+out: -+ g_clear_object (&file); -+ g_clear_object (&info); -+ g_clear_object (&enumerator); -+ -+ return retval; -+} -+ -+static void -+chown_initial_setup_home_dir (void) -+{ -+ GFile *dir; -+ GError *error; -+ char *gis_dir_path; -+ char *gis_uid_path; -+ char *gis_uid_contents; -+ struct passwd *pwe; -+ uid_t uid; -+ -+ if (!gdm_get_pwent_for_name (INITIAL_SETUP_USERNAME, &pwe)) { -+ g_warning ("Unknown user %s", INITIAL_SETUP_USERNAME); -+ return; -+ } -+ -+ gis_dir_path = g_strdup (pwe->pw_dir); -+ -+ gis_uid_path = g_build_filename (gis_dir_path, -+ "gnome-initial-setup-uid", -+ NULL); -+ if (!g_file_get_contents (gis_uid_path, &gis_uid_contents, NULL, NULL)) { -+ g_warning ("Unable to read %s", gis_uid_path); -+ goto out; -+ } -+ -+ uid = (uid_t) atoi (gis_uid_contents); -+ pwe = getpwuid (uid); -+ if (uid == 0 || pwe == NULL) { -+ g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path); -+ goto out; -+ } -+ -+ error = NULL; -+ dir = g_file_new_for_path (gis_dir_path); -+ if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) { -+ g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message); -+ g_error_free (error); -+ } -+ g_object_unref (dir); -+out: -+ g_free (gis_uid_contents); -+ g_free (gis_uid_path); -+ g_free (gis_dir_path); -+} -+ - static gboolean - on_start_user_session (StartUserSessionOperation *operation) - { - GdmManager *self = operation->manager; - gboolean migrated; - gboolean fail_if_already_switched = TRUE; - gboolean doing_initial_setup = FALSE; - GdmDisplay *display; - const char *session_id; - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - g_autofree char *display_session_type = NULL; - #endif - - g_debug ("GdmManager: start or jump to session"); - - /* If there's already a session running, jump to it. - * If the only session running is the one we just opened, - * start a session on it. - */ - migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched); - - g_debug ("GdmManager: migrated: %d", migrated); - if (migrated) { - /* We don't stop the manager here because - when Xorg exits it switches to the VT it was - started from. That interferes with fast - user switching. */ - gdm_session_reset (operation->session); - destroy_start_user_session_operation (operation); - goto out; - } - - display = get_display_for_user_session (operation->session); - - g_object_get (G_OBJECT (display), - "doing-initial-setup", &doing_initial_setup, - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - "session-type", &display_session_type, - #endif - NULL); - - session_id = gdm_session_get_conversation_session_id (operation->session, - operation->service_name); - - if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - /* In this case, the greeter's display is morphing into - * the user session display. Kill the greeter on this session - * and let the user session follow the same display. */ - gdm_display_stop_greeter_session (display); - g_object_set (G_OBJECT (display), - "session-class", "user", - "session-id", session_id, - NULL); - } else { - uid_t allowed_uid; - - g_object_ref (display); - if (doing_initial_setup) { -+ g_autoptr(GError) error = NULL; -+ - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - if (g_strcmp0 (display_session_type, "wayland") == 0) { - g_debug ("GdmManager: closing down initial setup display in background"); - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); - } - #endif - if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { - g_debug ("GdmManager: closing down initial setup display"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - } -+ -+ chown_initial_setup_home_dir (); -+ -+ if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT, -+ "1", -+ 1, -+ &error)) { -+ g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s", -+ ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT, -+ error->message); -+ g_clear_error (&error); -+ } - } else { - g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); - } - - /* The user session is going to follow the session worker - * into the new display. Untie it from this display and - * create a new session for a future user login. */ - allowed_uid = gdm_session_get_allowed_user (operation->session); - g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); - g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); - create_user_session_for_display (operation->manager, display, allowed_uid); - - /* Give the user session a new display object for bookkeeping purposes */ - create_display_for_user_session (operation->manager, - operation->session, - session_id); - - if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) && - !gdm_session_client_is_connected (operation->session)) { - /* remove the unused prepared greeter display since we're not going - * to have a greeter */ - gdm_display_store_remove (self->priv->display_store, display); - g_object_unref (display); - - self->priv->automatic_login_display = g_object_get_data (G_OBJECT (operation->session), "gdm-display"); - g_object_add_weak_pointer (G_OBJECT (self->priv->automatic_login_display), (gpointer *) &self->priv->automatic_login_display); - } - } - - start_user_session (operation->manager, operation); --- -2.27.0 - diff --git a/SOURCES/0040-display-store-make-foreach-ignore-callback-return-va.patch b/SOURCES/0040-display-store-make-foreach-ignore-callback-return-va.patch deleted file mode 100644 index 622db0c..0000000 --- a/SOURCES/0040-display-store-make-foreach-ignore-callback-return-va.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 49383786d96414e7204ea50ca5ea0263be97b581 Mon Sep 17 00:00:00 2001 -From: xiaoguang wang -Date: Wed, 20 Feb 2019 09:26:02 +0800 -Subject: [PATCH 40/51] display-store: make foreach ignore callback return - value - -gdm_display_store_foreach is designed to iterate through all -displays in the display store. Under the hood, it currently -uses gdm_display_store_find, though, so will prematurely stop -it's loop if a callback returns TRUE. Callers are getting this -wrong. Some return TRUE with the expectation it goes on, and -some fail to return a value at all. - -This commit changes gdm_display_store_foreach to use -g_hash_table_foreach instead, so the callback return values no -longer matter. ---- - daemon/gdm-display-store.c | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/daemon/gdm-display-store.c b/daemon/gdm-display-store.c -index fd24334eb..910468cd7 100644 ---- a/daemon/gdm-display-store.c -+++ b/daemon/gdm-display-store.c -@@ -119,76 +119,86 @@ remove_display (char *id, - } - - gboolean - gdm_display_store_remove (GdmDisplayStore *store, - GdmDisplay *display) - { - g_return_val_if_fail (store != NULL, FALSE); - - gdm_display_store_foreach_remove (store, - (GdmDisplayStoreFunc)remove_display, - display); - return FALSE; - } - - typedef struct - { - GdmDisplayStoreFunc predicate; - gpointer user_data; - } FindClosure; - - static gboolean - find_func (const char *id, - StoredDisplay *stored_display, - FindClosure *closure) - { - return closure->predicate (id, - stored_display->display, - closure->user_data); - } - -+static void -+foreach_func (const char *id, -+ StoredDisplay *stored_display, -+ FindClosure *closure) -+{ -+ (void) closure->predicate (id, -+ stored_display->display, -+ closure->user_data); -+} -+ - void - gdm_display_store_foreach (GdmDisplayStore *store, - GdmDisplayStoreFunc func, - gpointer user_data) - { - FindClosure closure; - - g_return_if_fail (store != NULL); - g_return_if_fail (func != NULL); - - closure.predicate = func; - closure.user_data = user_data; - -- g_hash_table_find (store->priv->displays, -- (GHRFunc) find_func, -- &closure); -+ g_hash_table_foreach (store->priv->displays, -+ (GHFunc) foreach_func, -+ &closure); - } - - GdmDisplay * - gdm_display_store_lookup (GdmDisplayStore *store, - const char *id) - { - StoredDisplay *stored_display; - - g_return_val_if_fail (store != NULL, NULL); - g_return_val_if_fail (id != NULL, NULL); - - stored_display = g_hash_table_lookup (store->priv->displays, - id); - if (stored_display == NULL) { - return NULL; - } - - return stored_display->display; - } - - GdmDisplay * - gdm_display_store_find (GdmDisplayStore *store, - GdmDisplayStoreFunc predicate, - gpointer user_data) - { - StoredDisplay *stored_display; - FindClosure closure; - - g_return_val_if_fail (store != NULL, NULL); - g_return_val_if_fail (predicate != NULL, NULL); --- -2.27.0 - diff --git a/SOURCES/0041-xdmcp-display-factory-don-t-return-value-from-foreac.patch b/SOURCES/0041-xdmcp-display-factory-don-t-return-value-from-foreac.patch deleted file mode 100644 index 7b8cf5c..0000000 --- a/SOURCES/0041-xdmcp-display-factory-don-t-return-value-from-foreac.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 323358ef61d969588ea048d5b0eba6fd102d3dcf Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 21 Feb 2019 15:20:01 -0500 -Subject: [PATCH 41/51] xdmcp-display-factory: don't return value from foreach - funcs - -The xdmcp code is returning TRUE from its display store foreach -functions, which is useless since commit 47d01abe and wrong -before that. - -This commit makes it return void instead. ---- - daemon/gdm-xdmcp-display-factory.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/daemon/gdm-xdmcp-display-factory.c b/daemon/gdm-xdmcp-display-factory.c -index 5b5786c6f..2e14beab4 100644 ---- a/daemon/gdm-xdmcp-display-factory.c -+++ b/daemon/gdm-xdmcp-display-factory.c -@@ -639,76 +639,74 @@ gdm_xdmcp_host_allow (GdmAddress *address) - { - #ifdef HAVE_TCPWRAPPERS - char *client; - char *host; - gboolean ret; - - host = NULL; - client = NULL; - - /* Find client hostname */ - gdm_address_get_hostname (address, &client); - gdm_address_get_numeric_info (address, &host, NULL); - - /* Check with tcp_wrappers if client is allowed to access */ - ret = hosts_ctl ("gdm", client, host, ""); - - g_free (host); - g_free (client); - - return ret; - #else /* HAVE_TCPWRAPPERS */ - return (TRUE); - #endif /* HAVE_TCPWRAPPERS */ - } - - typedef struct { - GdmAddress *address; - int count; - } CountDisplayData; - --static gboolean -+static void - count_displays_from_host (const char *id, - GdmDisplay *display, - CountDisplayData *data) - { - GdmAddress *address; - - if (GDM_IS_XDMCP_DISPLAY (display)) { - address = gdm_xdmcp_display_get_remote_address (GDM_XDMCP_DISPLAY (display)); - - if (gdm_address_equal (address, data->address)) { - data->count++; - } - } -- -- return TRUE; - } - - static int - gdm_xdmcp_num_displays_from_host (GdmXdmcpDisplayFactory *factory, - GdmAddress *address) - { - CountDisplayData data; - GdmDisplayStore *store; - - data.count = 0; - data.address = address; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - gdm_display_store_foreach (store, - (GdmDisplayStoreFunc)count_displays_from_host, - &data); - - return data.count; - } - - typedef struct { - GdmAddress *address; - int display_num; - } LookupHostData; - - static gboolean - lookup_by_host (const char *id, - GdmDisplay *display, - LookupHostData *data) - { -@@ -1780,78 +1778,76 @@ gdm_xdmcp_send_managed_forward (GdmXdmcpDisplayFactory *factory, - - static void - gdm_xdmcp_send_got_managed_forward (GdmXdmcpDisplayFactory *factory, - GdmAddress *address, - GdmAddress *origin) - { - ARRAY8 addr; - XdmcpHeader header; - char *host; - - host = NULL; - gdm_address_get_numeric_info (address, &host, NULL); - g_debug ("GdmXdmcpDisplayFactory: Sending GOT_MANAGED_FORWARD to %s", - host ? host : "(null)"); - g_free (host); - - set_address_for_request (origin, &addr); - - header.opcode = (CARD16) GDM_XDMCP_GOT_MANAGED_FORWARD; - header.length = 4 + addr.length; - header.version = GDM_XDMCP_PROTOCOL_VERSION; - XdmcpWriteHeader (&factory->priv->buf, &header); - - XdmcpWriteARRAY8 (&factory->priv->buf, &addr); - XdmcpFlush (factory->priv->socket_fd, - &factory->priv->buf, - (XdmcpNetaddr)gdm_address_peek_sockaddr_storage (address), - (int)gdm_sockaddr_len (gdm_address_peek_sockaddr_storage (address))); - } - --static gboolean -+static void - count_sessions (const char *id, - GdmDisplay *display, - GdmXdmcpDisplayFactory *factory) - { - if (GDM_IS_XDMCP_DISPLAY (display)) { - int status; - - status = gdm_display_get_status (display); - - if (status == GDM_DISPLAY_MANAGED) { - factory->priv->num_sessions++; - } else if (status == GDM_DISPLAY_UNMANAGED) { - factory->priv->num_pending_sessions++; - } - } -- -- return TRUE; - } - - static void - gdm_xdmcp_recount_sessions (GdmXdmcpDisplayFactory *factory) - { - GdmDisplayStore *store; - - factory->priv->num_sessions = 0; - factory->priv->num_pending_sessions = 0; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - gdm_display_store_foreach (store, - (GdmDisplayStoreFunc)count_sessions, - factory); - } - - static gboolean - purge_displays (const char *id, - GdmDisplay *display, - GdmXdmcpDisplayFactory *factory) - { - if (GDM_IS_XDMCP_DISPLAY (display)) { - int status; - time_t currtime; - time_t acctime; - - currtime = time (NULL); - status = gdm_display_get_status (display); - acctime = gdm_display_get_creation_time (display); - --- -2.27.0 - diff --git a/SOURCES/0042-GdmLocalDisplayFactory-Store-VT-number-not-tty-ident.patch b/SOURCES/0042-GdmLocalDisplayFactory-Store-VT-number-not-tty-ident.patch deleted file mode 100644 index c03b87f..0000000 --- a/SOURCES/0042-GdmLocalDisplayFactory-Store-VT-number-not-tty-ident.patch +++ /dev/null @@ -1,538 +0,0 @@ -From 3cf5b4b12d3d39fa858ff593adeecfe711cdddaf Mon Sep 17 00:00:00 2001 -From: Iain Lane -Date: Tue, 7 May 2019 15:35:23 +0100 -Subject: [PATCH 42/51] GdmLocalDisplayFactory: Store VT number, not tty - identifier - -This makes the code a fair bit simpler. ---- - configure.ac | 6 ++-- - daemon/gdm-local-display-factory.c | 50 ++++++++++++++++-------------- - daemon/gdm-server.c | 2 +- - daemon/gdm-session-worker.c | 2 +- - 4 files changed, 31 insertions(+), 29 deletions(-) - -diff --git a/configure.ac b/configure.ac -index c549146ce..0c138ab38 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1477,66 +1477,66 @@ fi - AC_SUBST(DEBUG_CFLAGS) - - # - # Enable Profiling - # - AC_ARG_ENABLE(profiling, - AS_HELP_STRING([--enable-profiling], - [turn on profiling]),, - enable_profiling=yes) - - if test "$enable_profiling" = "yes"; then - AC_DEFINE(ENABLE_PROFILING,1,[enable profiling]) - fi - - # - # Set SHELL to use in scripts. - # - if test x$os_solaris = xyes ; then - XSESSION_SHELL=/bin/ksh - else - XSESSION_SHELL=/bin/sh - fi - - # - # Set VT to use for initial server - # - AC_ARG_WITH(initial-vt, - AS_HELP_STRING([--with-initial-vt=], - [Initial virtual terminal to use])) - if ! test -z "$with_initial_vt"; then -- GDM_INITIAL_VT="$with_initial_vt" -+ GDM_INITIAL_VT=$with_initial_vt - else -- GDM_INITIAL_VT="1" -+ GDM_INITIAL_VT=1 - fi - AC_SUBST(GDM_INITIAL_VT) --AC_DEFINE_UNQUOTED(GDM_INITIAL_VT, "$GDM_INITIAL_VT", [Initial Virtual Terminal]) -+AC_DEFINE_UNQUOTED(GDM_INITIAL_VT, $GDM_INITIAL_VT, [Initial Virtual Terminal]) - - # Set configuration choices. - # - AC_SUBST(XSESSION_SHELL) - AC_DEFINE_UNQUOTED(XSESSION_SHELL,"$XSESSION_SHELL",[xsession shell]) - AC_SUBST(SOUND_PROGRAM) - AC_DEFINE_UNQUOTED(SOUND_PROGRAM,"$SOUND_PROGRAM",[]) - - AC_SUBST(X_PATH) - AC_SUBST(X_SERVER) - AC_SUBST(X_SERVER_PATH) - AC_DEFINE_UNQUOTED(X_SERVER,"$X_SERVER",[]) - AC_DEFINE_UNQUOTED(X_SERVER_PATH,"$X_SERVER_PATH",[]) - - ## Stuff for debian/changelog.in - #if test -e "debian/changelog"; then - # DEBIAN_DATESTAMP=`head -1 debian/changelog| sed -e 's/.*cvs.//' -e 's/).*//'` - # DEBIAN_DATE=`grep '^ --' debian/changelog | head -1 | sed -e 's/.* //'` - #else - # DEBIAN_DATESTAMP=`date +%Y%m%d%H%M%s` - # DEBIAN_DATE=`date -R` - #fi - # - #AC_SUBST(DEBIAN_DATESTAMP) - #AC_SUBST(DEBIAN_DATE) - - AC_CONFIG_FILES([ - Makefile - pam-extensions/Makefile - pam-extensions/gdm-pam-extensions.pc -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index d999596b5..7a013c694 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -37,61 +37,61 @@ - #include "gdm-local-display-factory-glue.h" - - #include "gdm-settings-keys.h" - #include "gdm-settings-direct.h" - #include "gdm-display-store.h" - #include "gdm-local-display.h" - #include "gdm-legacy-display.h" - - #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate)) - - #define GDM_DBUS_PATH "/org/gnome/DisplayManager" - #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory" - #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory" - - #define MAX_DISPLAY_FAILURES 5 - #define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */ - - struct GdmLocalDisplayFactoryPrivate - { - GdmDBusLocalDisplayFactory *skeleton; - GDBusConnection *connection; - GHashTable *used_display_numbers; - - /* FIXME: this needs to be per seat? */ - guint num_failures; - - guint seat_new_id; - guint seat_removed_id; - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -- char *tty_of_active_vt; -+ unsigned int active_vt; - guint active_vt_watch_id; - guint wait_to_finish_timeout_id; - #endif - }; - - enum { - PROP_0, - }; - - static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); - static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); - static void gdm_local_display_factory_finalize (GObject *object); - - static GdmDisplay *create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial_display); - - static void on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmLocalDisplayFactory *factory); - - static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); - static gpointer local_display_factory_object = NULL; - static gboolean lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data); - - G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) - -@@ -641,157 +641,161 @@ maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory, - g_debug ("GdmLocalDisplayFactory: login window is performing initial-setup, so ignoring"); - return; - } - - /* we can only stop greeter for wayland sessions, since - * X server would jump back on exit */ - if (g_strcmp0 (display_session_type, "wayland") != 0) { - g_debug ("GdmLocalDisplayFactory: login window is running on Xorg, so ignoring"); - return; - } - - g_debug ("GdmLocalDisplayFactory: killing login window once its unused"); - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); - - /* We stop the greeter after a timeout to avoid flicker */ - if (factory->priv->wait_to_finish_timeout_id != 0) - g_source_remove (factory->priv->wait_to_finish_timeout_id); - - factory->priv->wait_to_finish_timeout_id = - g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT, - (GSourceFunc)wait_to_finish_timeout, - factory); - } - - static gboolean - on_vt_changed (GIOChannel *source, - GIOCondition condition, - GdmLocalDisplayFactory *factory) - { - GIOStatus status; -- static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT; -- g_autofree char *tty_of_previous_vt = NULL; - g_autofree char *tty_of_active_vt = NULL; - g_autofree char *login_session_id = NULL; - g_autofree char *active_session_id = NULL; -+ unsigned int previous_vt, new_vt; - const char *session_type = NULL; -- int ret; -+ int ret, n_returned; - - g_debug ("GdmLocalDisplayFactory: received VT change event"); - g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL); - - if (condition & G_IO_PRI) { - g_autoptr (GError) error = NULL; - status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error); - - if (error != NULL) { - g_warning ("could not read active VT from kernel: %s", error->message); - } - switch (status) { - case G_IO_STATUS_ERROR: - return G_SOURCE_REMOVE; - case G_IO_STATUS_EOF: - return G_SOURCE_REMOVE; - case G_IO_STATUS_AGAIN: - return G_SOURCE_CONTINUE; - case G_IO_STATUS_NORMAL: - break; - } - } - - if ((condition & G_IO_ERR) || (condition & G_IO_HUP)) { - g_debug ("GdmLocalDisplayFactory: kernel hung up active vt watch"); - return G_SOURCE_REMOVE; - } - - if (tty_of_active_vt == NULL) { - g_debug ("GdmLocalDisplayFactory: unable to read active VT from kernel"); - return G_SOURCE_CONTINUE; - } - - g_strchomp (tty_of_active_vt); - -+ errno = 0; -+ n_returned = sscanf (tty_of_active_vt, "tty%u", &new_vt); -+ -+ if (n_returned != 1 || errno != 0) { -+ g_critical ("GdmLocalDisplayFactory: Couldn't read active VT (got '%s')", -+ tty_of_active_vt); -+ return G_SOURCE_CONTINUE; -+ } -+ - /* don't do anything if we're on the same VT we were before */ -- if (g_strcmp0 (tty_of_active_vt, factory->priv->tty_of_active_vt) == 0) { -+ if (new_vt == factory->priv->active_vt) { - g_debug ("GdmLocalDisplayFactory: VT changed to the same VT, ignoring"); - return G_SOURCE_CONTINUE; - } - -- tty_of_previous_vt = g_steal_pointer (&factory->priv->tty_of_active_vt); -- factory->priv->tty_of_active_vt = g_steal_pointer (&tty_of_active_vt); -+ previous_vt = factory->priv->active_vt; -+ factory->priv->active_vt = new_vt; - - /* don't do anything at start up */ -- if (tty_of_previous_vt == NULL) { -- g_debug ("GdmLocalDisplayFactory: VT is %s at startup", -- factory->priv->tty_of_active_vt); -+ if (previous_vt == 0) { -+ g_debug ("GdmLocalDisplayFactory: VT is %u at startup", -+ factory->priv->active_vt); - return G_SOURCE_CONTINUE; - } - -- g_debug ("GdmLocalDisplayFactory: VT changed from %s to %s", -- tty_of_previous_vt, factory->priv->tty_of_active_vt); -+ g_debug ("GdmLocalDisplayFactory: VT changed from %u to %u", -+ previous_vt, factory->priv->active_vt); - - /* if the old VT was running a wayland login screen kill it - */ - if (gdm_get_login_window_session_id ("seat0", &login_session_id)) { -- unsigned int vt; -+ unsigned int login_window_vt; - -- ret = sd_session_get_vt (login_session_id, &vt); -- if (ret == 0 && vt != 0) { -- g_autofree char *tty_of_login_window_vt = NULL; -- -- tty_of_login_window_vt = g_strdup_printf ("tty%u", vt); -- -- g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt); -- if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) { -+ ret = sd_session_get_vt (login_session_id, &login_window_vt); -+ if (ret == 0 && login_window_vt != 0) { -+ g_debug ("GdmLocalDisplayFactory: VT of login window is %u", login_window_vt); -+ if (login_window_vt == previous_vt) { - GdmDisplayStore *store; - GdmDisplay *display; - - g_debug ("GdmLocalDisplayFactory: VT switched from login window"); - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - - if (display != NULL) - maybe_stop_greeter_in_background (factory, display); - } else { - g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); - } - } - } - - /* if user jumped back to initial vt and it's empty put a login screen - * on it (unless a login screen is already running elsewhere, then - * jump to that login screen) - */ -- if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) { -+ if (factory->priv->active_vt != GDM_INITIAL_VT) { - g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring"); - return G_SOURCE_CONTINUE; - } - - if (gdm_local_display_factory_use_wayland ()) - session_type = "wayland"; - - g_debug ("GdmLocalDisplayFactory: creating new display on seat0 because of VT change"); - - create_display (factory, "seat0", session_type, TRUE); - - return G_SOURCE_CONTINUE; - } - #endif - - static void - gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) - { - g_autoptr (GIOChannel) io_channel = NULL; - - factory->priv->seat_new_id = g_dbus_connection_signal_subscribe (factory->priv->connection, - "org.freedesktop.login1", - "org.freedesktop.login1.Manager", - "SeatNew", - "/org/freedesktop/login1", - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - on_seat_new, - g_object_ref (factory), - g_object_unref); -@@ -815,62 +819,60 @@ gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) - G_IO_PRI, - (GIOFunc) - on_vt_changed, - factory); - } - #endif - } - - static void - gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory) - { - if (factory->priv->seat_new_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_new_id); - factory->priv->seat_new_id = 0; - } - if (factory->priv->seat_removed_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_removed_id); - factory->priv->seat_removed_id = 0; - } - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - if (factory->priv->wait_to_finish_timeout_id != 0) { - g_source_remove (factory->priv->wait_to_finish_timeout_id); - factory->priv->wait_to_finish_timeout_id = 0; - } - if (factory->priv->active_vt_watch_id) { - g_source_remove (factory->priv->active_vt_watch_id); - factory->priv->active_vt_watch_id = 0; - } -- -- g_clear_pointer (&factory->priv->tty_of_active_vt, g_free); - #endif - } - - static void - on_display_added (GdmDisplayStore *display_store, - const char *id, - GdmLocalDisplayFactory *factory) - { - GdmDisplay *display; - - display = gdm_display_store_lookup (display_store, id); - - if (display != NULL) { - g_signal_connect_object (display, "notify::status", - G_CALLBACK (on_display_status_changed), - factory, - 0); - - g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); - } - } - - static void - on_display_removed (GdmDisplayStore *display_store, - GdmDisplay *display, - GdmLocalDisplayFactory *factory) - { - g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), factory); - g_object_weak_unref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); - } -diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c -index 83fba99c8..04406a61a 100644 ---- a/daemon/gdm-server.c -+++ b/daemon/gdm-server.c -@@ -726,61 +726,61 @@ gdm_server_spawn (GdmServer *server, - (GChildWatchFunc)server_child_watch, - server); - - ret = TRUE; - out: - g_strfreev (argv); - if (env) { - g_ptr_array_foreach (env, (GFunc)g_free, NULL); - g_ptr_array_free (env, TRUE); - } - return ret; - } - - /** - * gdm_server_start: - * @disp: Pointer to a GdmDisplay structure - * - * Starts a local X server. Handles retries and fatal errors properly. - */ - - gboolean - gdm_server_start (GdmServer *server) - { - gboolean res = FALSE; - const char *vtarg = NULL; - GError *local_error = NULL; - GError **error = &local_error; - - /* Hardcode the VT for the initial X server, but nothing else */ - if (server->priv->is_initial) { -- vtarg = "vt" GDM_INITIAL_VT; -+ vtarg = "vt" G_STRINGIFY (GDM_INITIAL_VT); - } - - /* fork X server process */ - if (!gdm_server_spawn (server, vtarg, error)) { - goto out; - } - - res = TRUE; - out: - if (local_error) { - g_printerr ("%s\n", local_error->message); - g_clear_error (&local_error); - } - return res; - } - - static void - server_died (GdmServer *server) - { - int exit_status; - - g_debug ("GdmServer: Waiting on process %d", server->priv->pid); - exit_status = gdm_wait_on_pid (server->priv->pid); - - if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) { - g_debug ("GdmServer: Wait on child process failed"); - } else { - /* exited normally */ - } - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index 7ed2789da..b4befaa83 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -2202,61 +2202,61 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, - - g_debug ("GdmSessionWorker: state SESSION_STARTED"); - gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_STARTED); - - gdm_session_worker_watch_child (worker); - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - return TRUE; - } - - static gboolean - set_up_for_new_vt (GdmSessionWorker *worker) - { - int fd; - char vt_string[256], tty_string[256]; - int session_vt = 0; - - fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); - - if (fd < 0) { - g_debug ("GdmSessionWorker: couldn't open VT master: %m"); - return FALSE; - } - - if (worker->priv->display_is_initial) { -- session_vt = atoi (GDM_INITIAL_VT); -+ session_vt = GDM_INITIAL_VT; - } else { - if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) { - g_debug ("GdmSessionWorker: couldn't open new VT: %m"); - goto fail; - } - } - - worker->priv->session_vt = session_vt; - - close (fd); - fd = -1; - - g_assert (session_vt > 0); - - g_snprintf (vt_string, sizeof (vt_string), "%d", session_vt); - - /* Set the VTNR. This is used by logind to configure a session in - * the logind-managed case, but it doesn't hurt to set it always. - * When logind gains support for XDG_VTNR=auto, we can make the - * OPENQRY and this whole path only used by the new VT code. */ - gdm_session_worker_set_environment_variable (worker, - "XDG_VTNR", - vt_string); - - g_snprintf (tty_string, 256, "/dev/tty%d", session_vt); - worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY); - pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string); - - return TRUE; - --- -2.27.0 - diff --git a/SOURCES/0043-gdm-session-worker-Drop-login_vt-assuming-it-is-GDM_.patch b/SOURCES/0043-gdm-session-worker-Drop-login_vt-assuming-it-is-GDM_.patch deleted file mode 100644 index ea5f20c..0000000 --- a/SOURCES/0043-gdm-session-worker-Drop-login_vt-assuming-it-is-GDM_.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 476230f7b721781c682d26983c9a2fd82afc45e1 Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Wed, 25 Sep 2019 14:51:40 +0200 -Subject: [PATCH 43/51] gdm-session-worker: Drop login_vt assuming it is - GDM_INITIAL_VT - -When a session ends, its "session worker" is closed. Since -3e8220921bb608afd06ed677104fd2244b901a28 (3.33.4), we uninitialise PAM -when this happens. As part of this procedure, we jump back to the login -screen, if the screen being killed is not itself the login screen. - -This has broken fast user switching. It goes like this - this -explanation is a bit complicated, bear with us: - -We want to jump back to the login screen when a normal user session -ends, so that people can log in again. We do not want to do this when a -login screen itself ends. When session workers start up, they query for -the *currently active VT* and save this in `login_vt`. Then later on, we -check if our session ID is the same as `login_vt`, and jump to -`login_vt` if they are different - this means that it was a user session -not a login session. Querying the currently active VT is fine for the -first greeter, but when initiating a user switch it's wrong as this -gives the user VT. - -GDM greeters are killed once they have spawned a session. They are -associated with a logind session, and therefore a PAM session. There are -some actions performed when unregistering PAM sessions, including the -previously mentioned VT jump. Before -3e8220921bb608afd06ed677104fd2244b901a28 we only uninitialised PAM when -the session itself exited so the bug was masked, but now (since this -commit), if the login screen's *worker* exits first - as happens in the -normal case when GDM kills it - we also do this uninitialisation. Since -we falsely recorded the login screen as the first user's VT, this means -that checking `login_vt != session_vt` returns `TRUE` and we jump back -to the previous user's session immediately after logging into the new -session: fast user switching is broken. - -Since the work on shutting down the GDM session has been finished, we -can assume that the login_vt is always on GDM_INITIAL_VT (see -example c71bc5d6c3bc2ec448b5c72ce9a811d9c0c7905e -"local-display-factory: Remove initial VT is in use check" and -39fb4ff64e6a0653e70a3bfab31da47b49227d59 "manager: don't run autologin -display on tty1"). So simply replace all usages of login_vt with -GDM_INITIAL_VT to solve the above problem. - -Note that in the case where ENABLE_USER_DISPLAY_SERVER is not enabled, -the login_vt is always the same as the session_vt. We can simply remove -the VT switching magic there and everything should be working as -expected. - -This is a simpler version of the patch by Iain Lane , -taking into account that we can make the assumption about the login_vt. - -Closes #515 ---- - daemon/gdm-session-worker.c | 43 +++++++++---------------------------- - 1 file changed, 10 insertions(+), 33 deletions(-) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index b4befaa83..0bd78cfaf 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -119,61 +119,60 @@ typedef struct - - } ReauthenticationRequest; - - struct GdmSessionWorkerPrivate - { - GdmSessionWorkerState state; - - int exit_code; - - pam_handle_t *pam_handle; - - GPid child_pid; - guint child_watch_id; - - /* from Setup */ - char *service; - char *x11_display_name; - char *x11_authority_file; - char *display_device; - char *display_seat_id; - char *hostname; - char *username; - char *log_file; - char *session_id; - uid_t uid; - gid_t gid; - gboolean password_is_required; - char **extensions; - - int cred_flags; -- int login_vt; - int session_vt; - int session_tty_fd; - - char **arguments; - guint32 cancelled : 1; - guint32 timed_out : 1; - guint32 is_program_session : 1; - guint32 is_reauth_session : 1; - guint32 display_is_local : 1; - guint32 display_is_initial : 1; - guint state_change_idle_id; - GdmSessionDisplayMode display_mode; - - char *server_address; - GDBusConnection *connection; - GdmDBusWorkerManager *manager; - - GHashTable *reauthentication_requests; - - GdmSessionAuditor *auditor; - GdmSessionSettings *user_settings; - - GDBusMethodInvocation *pending_invocation; - }; - - #ifdef SUPPORTS_PAM_EXTENSIONS - static char gdm_pam_extension_environment_block[_POSIX_ARG_MAX]; - - static const char * const - gdm_supported_pam_extensions[] = { -@@ -1029,141 +1028,120 @@ gdm_session_worker_set_state (GdmSessionWorker *worker, - - static void - gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, - int status) - { - g_debug ("GdmSessionWorker: uninitializing PAM"); - - if (worker->priv->pam_handle == NULL) - return; - - gdm_session_worker_get_username (worker, NULL); - - if (worker->priv->state >= GDM_SESSION_WORKER_STATE_SESSION_OPENED) { - pam_close_session (worker->priv->pam_handle, 0); - gdm_session_auditor_report_logout (worker->priv->auditor); - } else { - gdm_session_auditor_report_login_failure (worker->priv->auditor, - status, - pam_strerror (worker->priv->pam_handle, status)); - } - - if (worker->priv->state >= GDM_SESSION_WORKER_STATE_ACCREDITED) { - pam_setcred (worker->priv->pam_handle, PAM_DELETE_CRED); - } - - pam_end (worker->priv->pam_handle, status); - worker->priv->pam_handle = NULL; - - gdm_session_worker_stop_auditor (worker); - -+ /* If user-display-server is not enabled the login_vt is always -+ * identical to the session_vt. So in that case we never need to -+ * do a VT switch. */ -+#ifdef ENABLE_USER_DISPLAY_SERVER - if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) { -- if (worker->priv->login_vt != worker->priv->session_vt) { -- jump_to_vt (worker, worker->priv->login_vt); -+ /* Switch to the login VT if we are not the login screen. */ -+ if (worker->priv->session_vt != GDM_INITIAL_VT) { -+ jump_to_vt (worker, GDM_INITIAL_VT); - } - } -+#endif - -- worker->priv->login_vt = 0; - worker->priv->session_vt = 0; - - g_debug ("GdmSessionWorker: state NONE"); - gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE); - } - - static char * - _get_tty_for_pam (const char *x11_display_name, - const char *display_device) - { - #ifdef __sun - return g_strdup (display_device); - #else - return g_strdup (x11_display_name); - #endif - } - - #ifdef PAM_XAUTHDATA - static struct pam_xauth_data * - _get_xauth_for_pam (const char *x11_authority_file) - { - FILE *fh; - Xauth *auth = NULL; - struct pam_xauth_data *retval = NULL; - gsize len = sizeof (*retval) + 1; - - fh = fopen (x11_authority_file, "r"); - if (fh) { - auth = XauReadAuth (fh); - fclose (fh); - } - if (auth) { - len += auth->name_length + auth->data_length; - retval = g_malloc0 (len); - } - if (retval) { - retval->namelen = auth->name_length; - retval->name = (char *) (retval + 1); - memcpy (retval->name, auth->name, auth->name_length); - retval->datalen = auth->data_length; - retval->data = retval->name + auth->name_length + 1; - memcpy (retval->data, auth->data, auth->data_length); - } - XauDisposeAuth (auth); - return retval; - } - #endif - --static gboolean --ensure_login_vt (GdmSessionWorker *worker) --{ -- int fd; -- struct vt_stat vt_state = { 0 }; -- gboolean got_login_vt = FALSE; -- -- fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); -- -- if (fd < 0) { -- g_debug ("GdmSessionWorker: couldn't open VT master: %m"); -- return FALSE; -- } -- -- if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) { -- g_debug ("GdmSessionWorker: couldn't get current VT: %m"); -- goto out; -- } -- -- worker->priv->login_vt = vt_state.v_active; -- got_login_vt = TRUE; --out: -- close (fd); -- return got_login_vt; --} -- - static gboolean - gdm_session_worker_initialize_pam (GdmSessionWorker *worker, - const char *service, - const char * const *extensions, - const char *username, - const char *hostname, - gboolean display_is_local, - const char *x11_display_name, - const char *x11_authority_file, - const char *display_device, - const char *seat_id, - GError **error) - { - struct pam_conv pam_conversation; - int error_code; - char tty_string[256]; - - g_assert (worker->priv->pam_handle == NULL); - - g_debug ("GdmSessionWorker: initializing PAM; service=%s username=%s seat=%s", - service ? service : "(null)", - username ? username : "(null)", - seat_id ? seat_id : "(null)"); - - #ifdef SUPPORTS_PAM_EXTENSIONS - if (extensions != NULL) { - GDM_PAM_EXTENSION_ADVERTISE_SUPPORTED_EXTENSIONS (gdm_pam_extension_environment_block, extensions); - } - #endif - -@@ -1204,64 +1182,63 @@ gdm_session_worker_initialize_pam (GdmSessionWorker *worker, - } - - /* set RHOST */ - if (hostname != NULL && hostname[0] != '\0') { - error_code = pam_set_item (worker->priv->pam_handle, PAM_RHOST, hostname); - g_debug ("error informing authentication system of user's hostname %s: %s", - hostname, - pam_strerror (worker->priv->pam_handle, error_code)); - - if (error_code != PAM_SUCCESS) { - g_set_error (error, - GDM_SESSION_WORKER_ERROR, - GDM_SESSION_WORKER_ERROR_AUTHENTICATING, - "%s", ""); - goto out; - } - } - - /* set seat ID */ - if (seat_id != NULL && seat_id[0] != '\0') { - gdm_session_worker_set_environment_variable (worker, "XDG_SEAT", seat_id); - } - - if (strcmp (service, "gdm-launch-environment") == 0) { - gdm_session_worker_set_environment_variable (worker, "XDG_SESSION_CLASS", "greeter"); - } - - g_debug ("GdmSessionWorker: state SETUP_COMPLETE"); - gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE); - -- /* Temporarily set PAM_TTY with the currently active VT (login screen) -+ /* Temporarily set PAM_TTY with the login VT, - PAM_TTY will be reset with the users VT right before the user session is opened */ -- ensure_login_vt (worker); -- g_snprintf (tty_string, 256, "/dev/tty%d", worker->priv->login_vt); -+ g_snprintf (tty_string, 256, "/dev/tty%d", GDM_INITIAL_VT); - pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string); - if (!display_is_local) - worker->priv->password_is_required = TRUE; - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - return TRUE; - } - - static gboolean - gdm_session_worker_authenticate_user (GdmSessionWorker *worker, - gboolean password_is_required, - GError **error) - { - int error_code; - int authentication_flags; - - g_debug ("GdmSessionWorker: authenticating user %s", worker->priv->username); - - authentication_flags = 0; - - if (password_is_required) { - authentication_flags |= PAM_DISALLOW_NULL_AUTHTOK; - } - - /* blocking call, does the actual conversation */ --- -2.27.0 - diff --git a/SOURCES/0044-session-worker-ensure-initial-vt-is-never-picked-for.patch b/SOURCES/0044-session-worker-ensure-initial-vt-is-never-picked-for.patch deleted file mode 100644 index 0e55560..0000000 --- a/SOURCES/0044-session-worker-ensure-initial-vt-is-never-picked-for.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 75b65846ca77bd2d42e25365b4b7242a406330cf Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 7 Apr 2020 14:37:41 -0400 -Subject: [PATCH 44/51] session-worker: ensure initial vt is never picked for - !is_initial displays - -Normally, a !is_initial display would never "get" tty1, since the system -boots to tty1. But if, for some reason, the user booted to runlevel 3, -then switched to runlevel 5, the login screen could get started when -tty1 is free. - -That means, e.g., an autologin user can end up getting allocated tty1, -which is bad, since we assume tty1 is used for the login screen. - -This commit opens up /dev/tty1 when querying for available VTs, so that -it never gets returned by the kernel as available. ---- - daemon/gdm-session-worker.c | 39 +++++++++++++++++++++++++------------ - 1 file changed, 27 insertions(+), 12 deletions(-) - -diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c -index 0bd78cfaf..42c415837 100644 ---- a/daemon/gdm-session-worker.c -+++ b/daemon/gdm-session-worker.c -@@ -2167,105 +2167,120 @@ gdm_session_worker_start_session (GdmSessionWorker *worker, - - /* If we end up execing again, make sure we don't use the executable context set up - * by pam_selinux durin pam_open_session - */ - #ifdef HAVE_SELINUX - setexeccon (NULL); - #endif - - worker->priv->child_pid = session_pid; - - g_debug ("GdmSessionWorker: session opened creating reply..."); - g_assert (sizeof (GPid) <= sizeof (int)); - - g_debug ("GdmSessionWorker: state SESSION_STARTED"); - gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_SESSION_STARTED); - - gdm_session_worker_watch_child (worker); - - out: - if (error_code != PAM_SUCCESS) { - gdm_session_worker_uninitialize_pam (worker, error_code); - return FALSE; - } - - return TRUE; - } - - static gboolean - set_up_for_new_vt (GdmSessionWorker *worker) - { -- int fd; -+ int initial_vt_fd; - char vt_string[256], tty_string[256]; - int session_vt = 0; - -- fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); -- -- if (fd < 0) { -- g_debug ("GdmSessionWorker: couldn't open VT master: %m"); -+ /* open the initial vt. We need it for two scenarios: -+ * -+ * 1) display_is_initial is TRUE. We need it directly. -+ * 2) display_is_initial is FALSE. We need it to mark -+ * the initial VT as "in use" so it doesn't get returned -+ * by VT_OPENQRY -+ * */ -+ g_snprintf (tty_string, sizeof (tty_string), "/dev/tty%d", GDM_INITIAL_VT); -+ initial_vt_fd = open (tty_string, O_RDWR | O_NOCTTY); -+ -+ if (initial_vt_fd < 0) { -+ g_debug ("GdmSessionWorker: couldn't open console of initial fd: %m"); - return FALSE; - } - - if (worker->priv->display_is_initial) { - session_vt = GDM_INITIAL_VT; - } else { -- if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) { -+ -+ /* Typically VT_OPENQRY is called on /dev/tty0, but we already -+ * have /dev/tty1 open above, so might as well use it. -+ */ -+ if (ioctl (initial_vt_fd, VT_OPENQRY, &session_vt) < 0) { - g_debug ("GdmSessionWorker: couldn't open new VT: %m"); - goto fail; - } - } - - worker->priv->session_vt = session_vt; - -- close (fd); -- fd = -1; -- - g_assert (session_vt > 0); - - g_snprintf (vt_string, sizeof (vt_string), "%d", session_vt); - - /* Set the VTNR. This is used by logind to configure a session in - * the logind-managed case, but it doesn't hurt to set it always. - * When logind gains support for XDG_VTNR=auto, we can make the - * OPENQRY and this whole path only used by the new VT code. */ - gdm_session_worker_set_environment_variable (worker, - "XDG_VTNR", - vt_string); - -- g_snprintf (tty_string, 256, "/dev/tty%d", session_vt); -- worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY); -+ if (worker->priv->display_is_initial) { -+ worker->priv->session_tty_fd = initial_vt_fd; -+ } else { -+ g_snprintf (tty_string, sizeof (tty_string), "/dev/tty%d", session_vt); -+ worker->priv->session_tty_fd = open (tty_string, O_RDWR | O_NOCTTY); -+ close (initial_vt_fd); -+ } -+ - pam_set_item (worker->priv->pam_handle, PAM_TTY, tty_string); - - return TRUE; - - fail: -- close (fd); -+ close (initial_vt_fd); - return FALSE; - } - - static gboolean - set_xdg_vtnr_to_current_vt (GdmSessionWorker *worker) - { - int fd; - char vt_string[256]; - struct vt_stat vt_state = { 0 }; - - fd = open ("/dev/tty0", O_RDWR | O_NOCTTY); - - if (fd < 0) { - g_debug ("GdmSessionWorker: couldn't open VT master: %m"); - return FALSE; - } - - if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) { - g_debug ("GdmSessionWorker: couldn't get current VT: %m"); - goto fail; - } - - close (fd); - fd = -1; - - g_snprintf (vt_string, sizeof (vt_string), "%d", vt_state.v_active); - - gdm_session_worker_set_environment_variable (worker, - "XDG_VTNR", - vt_string); --- -2.27.0 - diff --git a/SOURCES/0045-local-display-factory-Always-force-login-screen-to-V.patch b/SOURCES/0045-local-display-factory-Always-force-login-screen-to-V.patch deleted file mode 100644 index d464a2a..0000000 --- a/SOURCES/0045-local-display-factory-Always-force-login-screen-to-V.patch +++ /dev/null @@ -1,114 +0,0 @@ -From fc3503f16e9de535d2a36b904720b360370f880f Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 15 May 2020 10:08:24 -0400 -Subject: [PATCH 45/51] local-display-factory: Always force login screen to VT - 1 - -These days we always want the login screen on VT 1, even -when it's created by user switching. - -Unfortunately, since commit f843233ad the login screen -won't naturally pick VT 1 when user switching. - -This commit forces it to make the right choice. - -Closes https://gitlab.gnome.org/GNOME/gdm/-/issues/602 ---- - daemon/gdm-local-display-factory.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 7a013c694..a288f8765 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -197,84 +197,87 @@ store_display (GdmLocalDisplayFactory *factory, - gdm_display_store_add (store, display); - } - - static gboolean - gdm_local_display_factory_use_wayland (void) - { - #ifdef ENABLE_WAYLAND_SUPPORT - gboolean wayland_enabled = FALSE; - if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { - if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) - return TRUE; - } - #endif - return FALSE; - } - - /* - Example: - dbus-send --system --dest=org.gnome.DisplayManager \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/gnome/DisplayManager/Manager \ - org.gnome.DisplayManager.Manager.GetDisplays - */ - gboolean - gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory, - char **id, - GError **error) - { - gboolean ret; - GdmDisplay *display = NULL; -+ gboolean is_initial = FALSE; - - g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); - - ret = FALSE; - - g_debug ("GdmLocalDisplayFactory: Creating transient display"); - - #ifdef ENABLE_USER_DISPLAY_SERVER - display = gdm_local_display_new (); - if (gdm_local_display_factory_use_wayland ()) - g_object_set (G_OBJECT (display), "session-type", "wayland", NULL); -+ is_initial = TRUE; - #else - if (display == NULL) { - guint32 num; - - num = take_next_display_number (factory); - - display = gdm_legacy_display_new (num); - } - #endif - - g_object_set (display, - "seat-id", "seat0", - "allow-timed-login", FALSE, -+ "is-initial", is_initial, - NULL); - - 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 gboolean - finish_display_on_seat_if_waiting (GdmDisplayStore *display_store, - GdmDisplay *display, - const char *seat_id) - { - if (gdm_display_get_status (display) != GDM_DISPLAY_WAITING_TO_FINISH) - return FALSE; - --- -2.27.0 - diff --git a/SOURCES/0046-gdm-x-session-tell-x-server-to-not-vt-switch.patch b/SOURCES/0046-gdm-x-session-tell-x-server-to-not-vt-switch.patch deleted file mode 100644 index e29138c..0000000 --- a/SOURCES/0046-gdm-x-session-tell-x-server-to-not-vt-switch.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 763e31a576a4cd665e5ad06ad0eb4610cecc0b42 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 10 Jul 2020 10:45:52 -0400 -Subject: [PATCH 46/51] gdm-x-session: tell x server to not vt switch - -gdm already handles the VT switching on X's behalf, -so it's redundant, and X does it at inopportune times, -so instruct it to not get involved. ---- - daemon/gdm-x-session.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c -index 3b2fcef47..d8e3c7d53 100644 ---- a/daemon/gdm-x-session.c -+++ b/daemon/gdm-x-session.c -@@ -247,60 +247,61 @@ spawn_x_server (State *state, - } - - g_ptr_array_add (arguments, "-displayfd"); - g_ptr_array_add (arguments, display_fd_string); - - g_ptr_array_add (arguments, "-auth"); - g_ptr_array_add (arguments, auth_file); - - /* If we were compiled with Xserver >= 1.17 we need to specify - * '-listen tcp' as the X server dosen't listen on tcp sockets - * by default anymore. In older versions we need to pass - * -nolisten tcp to disable listening on tcp sockets. - */ - #ifdef HAVE_XSERVER_THAT_DEFAULTS_TO_LOCAL_ONLY - if (allow_remote_connections) { - g_ptr_array_add (arguments, "-listen"); - g_ptr_array_add (arguments, "tcp"); - } - #else - if (!allow_remote_connections) { - g_ptr_array_add (arguments, "-nolisten"); - g_ptr_array_add (arguments, "tcp"); - } - #endif - - g_ptr_array_add (arguments, "-background"); - g_ptr_array_add (arguments, "none"); - - g_ptr_array_add (arguments, "-noreset"); - g_ptr_array_add (arguments, "-keeptty"); -+ g_ptr_array_add (arguments, "-novtswitch"); - - g_ptr_array_add (arguments, "-verbose"); - if (state->debug_enabled) { - g_ptr_array_add (arguments, "7"); - } else { - g_ptr_array_add (arguments, "3"); - } - - if (state->debug_enabled) { - g_ptr_array_add (arguments, "-core"); - } - g_ptr_array_add (arguments, NULL); - - subprocess = g_subprocess_launcher_spawnv (launcher, - (const char * const *) arguments->pdata, - &error); - g_free (display_fd_string); - g_clear_object (&launcher); - g_ptr_array_free (arguments, TRUE); - - if (subprocess == NULL) { - g_debug ("could not start X server: %s", error->message); - goto out; - } - - input_stream = g_unix_input_stream_new (pipe_fds[0], TRUE); - data_stream = g_data_input_stream_new (input_stream); - g_clear_object (&input_stream); - - display_number = g_data_input_stream_read_line (data_stream, --- -2.27.0 - diff --git a/SOURCES/0047-local-display-factory-kill-X-on-login-just-like-wayl.patch b/SOURCES/0047-local-display-factory-kill-X-on-login-just-like-wayl.patch deleted file mode 100644 index 306b7fb..0000000 --- a/SOURCES/0047-local-display-factory-kill-X-on-login-just-like-wayl.patch +++ /dev/null @@ -1,115 +0,0 @@ -From a1c74e2e42dea464ab0b439b767da5c12cbf3986 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 11 Oct 2018 07:15:56 -0400 -Subject: [PATCH 47/51] local-display-factory: kill X on login just like - wayland - -These days we kill the wayland login screen during login to -conserve system resources. - -We've been reluctant to do the same for X based login screens, -because X didn't handle being killed in the background so well. - -This is no longer a problem, since this commit: - -https://gitlab.freedesktop.org/xorg/xserver/-/commit/ff91c696ff8f5f56da40e107cb5c321539758a81 - -So let's go ahead and kill it now. ---- - daemon/gdm-local-display-factory.c | 9 --------- - 1 file changed, 9 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index a288f8765..aae226750 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -599,86 +599,77 @@ on_seat_removed (GDBusConnection *connection, - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); - } - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - static gboolean - lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - const char *looking_for = user_data; - const char *current; - - current = gdm_display_get_session_id (display); - return g_strcmp0 (current, looking_for) == 0; - } - - static gboolean - wait_to_finish_timeout (GdmLocalDisplayFactory *factory) - { - finish_waiting_displays_on_seat (factory, "seat0"); - factory->priv->wait_to_finish_timeout_id = 0; - return G_SOURCE_REMOVE; - } - - static void - maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { -- g_autofree char *display_session_type = NULL; - gboolean doing_initial_setup = FALSE; - - if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) { - g_debug ("GdmLocalDisplayFactory: login window not in managed state, so ignoring"); - return; - } - - g_object_get (G_OBJECT (display), -- "session-type", &display_session_type, - "doing-initial-setup", &doing_initial_setup, - NULL); - - /* we don't ever stop initial-setup implicitly */ - if (doing_initial_setup) { - g_debug ("GdmLocalDisplayFactory: login window is performing initial-setup, so ignoring"); - return; - } - -- /* we can only stop greeter for wayland sessions, since -- * X server would jump back on exit */ -- if (g_strcmp0 (display_session_type, "wayland") != 0) { -- g_debug ("GdmLocalDisplayFactory: login window is running on Xorg, so ignoring"); -- return; -- } -- - g_debug ("GdmLocalDisplayFactory: killing login window once its unused"); - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); - - /* We stop the greeter after a timeout to avoid flicker */ - if (factory->priv->wait_to_finish_timeout_id != 0) - g_source_remove (factory->priv->wait_to_finish_timeout_id); - - factory->priv->wait_to_finish_timeout_id = - g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT, - (GSourceFunc)wait_to_finish_timeout, - factory); - } - - static gboolean - on_vt_changed (GIOChannel *source, - GIOCondition condition, - GdmLocalDisplayFactory *factory) - { - GIOStatus status; - g_autofree char *tty_of_active_vt = NULL; - g_autofree char *login_session_id = NULL; - g_autofree char *active_session_id = NULL; - unsigned int previous_vt, new_vt; - const char *session_type = NULL; - int ret, n_returned; - - g_debug ("GdmLocalDisplayFactory: received VT change event"); - g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL); - - if (condition & G_IO_PRI) { --- -2.27.0 - diff --git a/SOURCES/0048-manager-don-t-kill-initial-setup-right-away-with-Xor.patch b/SOURCES/0048-manager-don-t-kill-initial-setup-right-away-with-Xor.patch deleted file mode 100644 index 041a8be..0000000 --- a/SOURCES/0048-manager-don-t-kill-initial-setup-right-away-with-Xor.patch +++ /dev/null @@ -1,149 +0,0 @@ -From f1b7d85b46dfc253176d6a043dcce26da3a26dfb Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Mon, 13 Jul 2020 09:23:06 -0400 -Subject: [PATCH 48/51] manager: don't kill initial-setup right away with Xorg - either - -The login screen for both Xorg and wayland sessions is now silently -killed in the background post login. - -We still kill initial-setup for Xorg sessions up front, though. - -This commit fixes that. ---- - daemon/gdm-manager.c | 20 ++------------------ - 1 file changed, 2 insertions(+), 18 deletions(-) - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index cf982870c..b147d73db 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -1757,123 +1757,107 @@ chown_initial_setup_home_dir (void) - - uid = (uid_t) atoi (gis_uid_contents); - pwe = getpwuid (uid); - if (uid == 0 || pwe == NULL) { - g_warning ("UID '%s' in %s is not valid", gis_uid_contents, gis_uid_path); - goto out; - } - - error = NULL; - dir = g_file_new_for_path (gis_dir_path); - if (!chown_recursively (dir, pwe->pw_uid, pwe->pw_gid, &error)) { - g_warning ("Failed to change ownership for %s: %s", gis_dir_path, error->message); - g_error_free (error); - } - g_object_unref (dir); - out: - g_free (gis_uid_contents); - g_free (gis_uid_path); - g_free (gis_dir_path); - } - - static gboolean - on_start_user_session (StartUserSessionOperation *operation) - { - GdmManager *self = operation->manager; - gboolean migrated; - gboolean fail_if_already_switched = TRUE; - gboolean doing_initial_setup = FALSE; - GdmDisplay *display; - const char *session_id; --#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -- g_autofree char *display_session_type = NULL; --#endif - - g_debug ("GdmManager: start or jump to session"); - - /* If there's already a session running, jump to it. - * If the only session running is the one we just opened, - * start a session on it. - */ - migrated = switch_to_compatible_user_session (operation->manager, operation->session, fail_if_already_switched); - - g_debug ("GdmManager: migrated: %d", migrated); - if (migrated) { - /* We don't stop the manager here because - when Xorg exits it switches to the VT it was - started from. That interferes with fast - user switching. */ - gdm_session_reset (operation->session); - destroy_start_user_session_operation (operation); - goto out; - } - - display = get_display_for_user_session (operation->session); - - g_object_get (G_OBJECT (display), - "doing-initial-setup", &doing_initial_setup, --#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -- "session-type", &display_session_type, --#endif - NULL); - - session_id = gdm_session_get_conversation_session_id (operation->session, - operation->service_name); - - if (gdm_session_get_display_mode (operation->session) == GDM_SESSION_DISPLAY_MODE_REUSE_VT) { - /* In this case, the greeter's display is morphing into - * the user session display. Kill the greeter on this session - * and let the user session follow the same display. */ - gdm_display_stop_greeter_session (display); - g_object_set (G_OBJECT (display), - "session-class", "user", - "session-id", session_id, - NULL); - } else { - uid_t allowed_uid; - - g_object_ref (display); - if (doing_initial_setup) { - g_autoptr(GError) error = NULL; - --#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -- if (g_strcmp0 (display_session_type, "wayland") == 0) { -- g_debug ("GdmManager: closing down initial setup display in background"); -- g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); -- } --#endif -- if (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) { -- g_debug ("GdmManager: closing down initial setup display"); -- gdm_display_stop_greeter_session (display); -- gdm_display_unmanage (display); -- gdm_display_finish (display); -- } -+ g_debug ("GdmManager: closing down initial setup display in background"); -+ g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); - - chown_initial_setup_home_dir (); - - if (!g_file_set_contents (ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT, - "1", - 1, - &error)) { - g_warning ("GdmDisplay: Could not write initial-setup-done marker to %s: %s", - ALREADY_RAN_INITIAL_SETUP_ON_THIS_BOOT, - error->message); - g_clear_error (&error); - } - } else { - g_debug ("GdmManager: session has its display server, reusing our server for another login screen"); - } - - /* The user session is going to follow the session worker - * into the new display. Untie it from this display and - * create a new session for a future user login. */ - allowed_uid = gdm_session_get_allowed_user (operation->session); - g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL); - g_object_set_data (G_OBJECT (operation->session), "gdm-display", NULL); - create_user_session_for_display (operation->manager, display, allowed_uid); - - /* Give the user session a new display object for bookkeeping purposes */ - create_display_for_user_session (operation->manager, - operation->session, - session_id); - - if ((g_strcmp0 (operation->service_name, "gdm-autologin") == 0) && --- -2.27.0 - diff --git a/SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch b/SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch deleted file mode 100644 index 79e7eda..0000000 --- a/SOURCES/0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch +++ /dev/null @@ -1,551 +0,0 @@ -From 2724b4fd6d4ac527acc481f056f535141b63fe24 Mon Sep 17 00:00:00 2001 -From: Iain Lane -Date: Tue, 7 May 2019 15:57:43 +0100 -Subject: [PATCH 49/51] GdmManager, GdmDisplay: Add RegisterSession method - -Window managers can use this to register with GDM when they've finished -starting up and started displaying. ---- - daemon/gdm-display.c | 24 ++++++++++++++++++++++++ - daemon/gdm-manager.c | 30 ++++++++++++++++++++++++++++++ - daemon/gdm-manager.xml | 3 +++ - 3 files changed, 57 insertions(+) - -diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 1cef8c7c1..56799741d 100644 ---- a/daemon/gdm-display.c -+++ b/daemon/gdm-display.c -@@ -64,82 +64,84 @@ struct GdmDisplayPrivate - char *remote_hostname; - int x11_display_number; - char *x11_display_name; - int status; - time_t creation_time; - GTimer *server_timer; - - char *x11_cookie; - gsize x11_cookie_size; - GdmDisplayAccessFile *access_file; - - guint finish_idle_id; - - xcb_connection_t *xcb_connection; - int xcb_screen_number; - - GDBusConnection *connection; - GdmDisplayAccessFile *user_access_file; - - GdmDBusDisplay *display_skeleton; - GDBusObjectSkeleton *object_skeleton; - - /* this spawns and controls the greeter session */ - GdmLaunchEnvironment *launch_environment; - - guint is_local : 1; - guint is_initial : 1; - guint allow_timed_login : 1; - guint have_existing_user_accounts : 1; - guint doing_initial_setup : 1; -+ guint session_registered : 1; - }; - - enum { - PROP_0, - PROP_ID, - PROP_STATUS, - PROP_SEAT_ID, - PROP_SESSION_ID, - PROP_SESSION_CLASS, - PROP_SESSION_TYPE, - PROP_REMOTE_HOSTNAME, - PROP_X11_DISPLAY_NUMBER, - PROP_X11_DISPLAY_NAME, - PROP_X11_COOKIE, - PROP_X11_AUTHORITY_FILE, - PROP_IS_CONNECTED, - PROP_IS_LOCAL, - PROP_LAUNCH_ENVIRONMENT, - PROP_IS_INITIAL, - PROP_ALLOW_TIMED_LOGIN, - PROP_HAVE_EXISTING_USER_ACCOUNTS, - PROP_DOING_INITIAL_SETUP, -+ PROP_SESSION_REGISTERED, - }; - - static void gdm_display_class_init (GdmDisplayClass *klass); - static void gdm_display_init (GdmDisplay *self); - static void gdm_display_finalize (GObject *object); - static void queue_finish (GdmDisplay *self); - static void _gdm_display_set_status (GdmDisplay *self, - int status); - static gboolean wants_initial_setup (GdmDisplay *self); - G_DEFINE_ABSTRACT_TYPE (GdmDisplay, gdm_display, G_TYPE_OBJECT) - - GQuark - gdm_display_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_display_error"); - } - - return ret; - } - - time_t - gdm_display_get_creation_time (GdmDisplay *self) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); - - return self->priv->creation_time; - } - -@@ -733,60 +735,68 @@ static void - _gdm_display_set_x11_display_number (GdmDisplay *self, - int num) - { - self->priv->x11_display_number = num; - } - - static void - _gdm_display_set_x11_display_name (GdmDisplay *self, - const char *x11_display) - { - g_free (self->priv->x11_display_name); - self->priv->x11_display_name = g_strdup (x11_display); - } - - static void - _gdm_display_set_x11_cookie (GdmDisplay *self, - const char *x11_cookie) - { - g_free (self->priv->x11_cookie); - self->priv->x11_cookie = g_strdup (x11_cookie); - } - - static void - _gdm_display_set_is_local (GdmDisplay *self, - gboolean is_local) - { - g_debug ("GdmDisplay: local: %s", is_local? "yes" : "no"); - self->priv->is_local = is_local; - } - -+static void -+_gdm_display_set_session_registered (GdmDisplay *self, -+ gboolean registered) -+{ -+ g_debug ("GdmDisplay: session registered: %s", registered? "yes" : "no"); -+ self->priv->session_registered = registered; -+} -+ - static void - _gdm_display_set_launch_environment (GdmDisplay *self, - GdmLaunchEnvironment *launch_environment) - { - g_clear_object (&self->priv->launch_environment); - - self->priv->launch_environment = g_object_ref (launch_environment); - } - - static void - _gdm_display_set_is_initial (GdmDisplay *self, - gboolean initial) - { - g_debug ("GdmDisplay: initial: %s", initial? "yes" : "no"); - self->priv->is_initial = initial; - } - - static void - _gdm_display_set_allow_timed_login (GdmDisplay *self, - gboolean allow_timed_login) - { - g_debug ("GdmDisplay: allow timed login: %s", allow_timed_login? "yes" : "no"); - self->priv->allow_timed_login = allow_timed_login; - } - - static void - gdm_display_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -@@ -811,60 +821,63 @@ gdm_display_set_property (GObject *object, - case PROP_SESSION_CLASS: - _gdm_display_set_session_class (self, g_value_get_string (value)); - break; - case PROP_SESSION_TYPE: - _gdm_display_set_session_type (self, g_value_get_string (value)); - break; - case PROP_REMOTE_HOSTNAME: - _gdm_display_set_remote_hostname (self, g_value_get_string (value)); - break; - case PROP_X11_DISPLAY_NUMBER: - _gdm_display_set_x11_display_number (self, g_value_get_int (value)); - break; - case PROP_X11_DISPLAY_NAME: - _gdm_display_set_x11_display_name (self, g_value_get_string (value)); - break; - case PROP_X11_COOKIE: - _gdm_display_set_x11_cookie (self, g_value_get_string (value)); - break; - case PROP_IS_LOCAL: - _gdm_display_set_is_local (self, g_value_get_boolean (value)); - break; - case PROP_ALLOW_TIMED_LOGIN: - _gdm_display_set_allow_timed_login (self, g_value_get_boolean (value)); - break; - case PROP_LAUNCH_ENVIRONMENT: - _gdm_display_set_launch_environment (self, g_value_get_object (value)); - break; - case PROP_IS_INITIAL: - _gdm_display_set_is_initial (self, g_value_get_boolean (value)); - break; -+ case PROP_SESSION_REGISTERED: -+ _gdm_display_set_session_registered (self, g_value_get_boolean (value)); -+ break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - gdm_display_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) - { - GdmDisplay *self; - - self = GDM_DISPLAY (object); - - switch (prop_id) { - case PROP_ID: - g_value_set_string (value, self->priv->id); - break; - case PROP_STATUS: - g_value_set_int (value, self->priv->status); - break; - case PROP_SEAT_ID: - g_value_set_string (value, self->priv->seat_id); - break; - case PROP_SESSION_ID: - g_value_set_string (value, self->priv->session_id); - break; - case PROP_SESSION_CLASS: -@@ -881,60 +894,63 @@ gdm_display_get_property (GObject *object, - break; - case PROP_X11_DISPLAY_NAME: - g_value_set_string (value, self->priv->x11_display_name); - break; - case PROP_X11_COOKIE: - g_value_set_string (value, self->priv->x11_cookie); - break; - case PROP_X11_AUTHORITY_FILE: - g_value_take_string (value, - self->priv->access_file? - gdm_display_access_file_get_path (self->priv->access_file) : NULL); - break; - case PROP_IS_LOCAL: - g_value_set_boolean (value, self->priv->is_local); - break; - case PROP_IS_CONNECTED: - g_value_set_boolean (value, self->priv->xcb_connection != NULL); - break; - case PROP_LAUNCH_ENVIRONMENT: - g_value_set_object (value, self->priv->launch_environment); - break; - case PROP_IS_INITIAL: - g_value_set_boolean (value, self->priv->is_initial); - break; - case PROP_HAVE_EXISTING_USER_ACCOUNTS: - g_value_set_boolean (value, self->priv->have_existing_user_accounts); - break; - case PROP_DOING_INITIAL_SETUP: - g_value_set_boolean (value, self->priv->doing_initial_setup); - break; -+ case PROP_SESSION_REGISTERED: -+ g_value_set_boolean (value, priv->session_registered); -+ break; - case PROP_ALLOW_TIMED_LOGIN: - g_value_set_boolean (value, self->priv->allow_timed_login); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static gboolean - handle_get_id (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - GdmDisplay *self) - { - char *id; - - gdm_display_get_id (self, &id, NULL); - - gdm_dbus_display_complete_get_id (skeleton, invocation, id); - - g_free (id); - return TRUE; - } - - static gboolean - handle_get_remote_hostname (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - GdmDisplay *self) - { - char *hostname; -@@ -1197,60 +1213,68 @@ gdm_display_class_init (GdmDisplayClass *klass) - G_PARAM_READABLE)); - - g_object_class_install_property (object_class, - PROP_IS_LOCAL, - g_param_spec_boolean ("is-local", - NULL, - NULL, - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_IS_CONNECTED, - g_param_spec_boolean ("is-connected", - NULL, - NULL, - TRUE, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, - PROP_HAVE_EXISTING_USER_ACCOUNTS, - g_param_spec_boolean ("have-existing-user-accounts", - NULL, - NULL, - FALSE, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, - PROP_DOING_INITIAL_SETUP, - g_param_spec_boolean ("doing-initial-setup", - NULL, - NULL, - FALSE, - G_PARAM_READABLE)); -+ g_object_class_install_property (object_class, -+ PROP_SESSION_REGISTERED, -+ g_param_spec_boolean ("session-registered", -+ NULL, -+ NULL, -+ FALSE, -+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -+ - g_object_class_install_property (object_class, - PROP_LAUNCH_ENVIRONMENT, - g_param_spec_object ("launch-environment", - NULL, - NULL, - GDM_TYPE_LAUNCH_ENVIRONMENT, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_STATUS, - g_param_spec_int ("status", - "status", - "status", - -1, - G_MAXINT, - GDM_DISPLAY_UNMANAGED, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_type_class_add_private (klass, sizeof (GdmDisplayPrivate)); - } - - static void - gdm_display_init (GdmDisplay *self) - { - - self->priv = GDM_DISPLAY_GET_PRIVATE (self); - - self->priv->creation_time = time (NULL); - self->priv->server_timer = g_timer_new (); - } - -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index b147d73db..bff602a07 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -789,60 +789,89 @@ gdm_manager_handle_register_display (GdmDBusManager *manager, - if (session != NULL) { - GPid pid; - - if (x11_display_name != NULL) { - g_object_set (G_OBJECT (session), "display-name", x11_display_name, NULL); - g_object_set (G_OBJECT (display), "x11-display-name", x11_display_name, NULL); - } - - /* FIXME: this should happen in gdm-session.c when the session is opened - */ - if (tty != NULL) - g_object_set (G_OBJECT (session), "display-device", tty, NULL); - - pid = gdm_session_get_pid (session); - - if (pid > 0) { - add_session_record (self, session, pid, SESSION_RECORD_LOGIN); - } - } - - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); - - gdm_dbus_manager_complete_register_display (GDM_DBUS_MANAGER (manager), - invocation); - - g_clear_pointer (&x11_display_name, g_free); - g_clear_pointer (&tty, g_free); - return TRUE; - } - -+static gboolean -+gdm_manager_handle_register_session (GdmDBusManager *manager, -+ GDBusMethodInvocation *invocation, -+ GVariant *details) -+{ -+ GdmManager *self = GDM_MANAGER (manager); -+ GdmDisplay *display; -+ const char *sender; -+ GDBusConnection *connection; -+ -+ sender = g_dbus_method_invocation_get_sender (invocation); -+ connection = g_dbus_method_invocation_get_connection (invocation); -+ -+ get_display_and_details_for_bus_sender (self, connection, sender, &display, -+ NULL, NULL, NULL, NULL, NULL, NULL, NULL); -+ -+ g_debug ("GdmManager: trying to register new session on display %p", display); -+ -+ if (display != NULL) -+ g_object_set (G_OBJECT (display), "session-registered", TRUE, NULL); -+ else -+ g_debug ("GdmManager: No display, not registering"); -+ -+ gdm_dbus_manager_complete_register_session (GDM_DBUS_MANAGER (manager), -+ invocation); -+ -+ return TRUE; -+} -+ - static gboolean - gdm_manager_handle_open_session (GdmDBusManager *manager, - GDBusMethodInvocation *invocation) - { - GdmManager *self = GDM_MANAGER (manager); - const char *sender; - GDBusConnection *connection; - GdmDisplay *display = NULL; - GdmSession *session = NULL; - const char *address; - GPid pid = 0; - uid_t uid = (uid_t) -1; - uid_t allowed_user; - - g_debug ("GdmManager: trying to open new session"); - - sender = g_dbus_method_invocation_get_sender (invocation); - connection = g_dbus_method_invocation_get_connection (invocation); - get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, NULL, &pid, &uid, NULL, NULL); - - if (display == NULL) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - _("No session available")); - - return TRUE; - } - - #ifdef HAVE_LIBXDMCP -@@ -1167,60 +1196,61 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager - g_hash_table_insert (self->priv->open_reauthentication_requests, - GINT_TO_POINTER (pid), - invocation); - } else if (is_login_screen) { - g_dbus_method_invocation_return_error_literal (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_ACCESS_DENIED, - "Login screen only allowed to open reauthentication channels for running sessions"); - return TRUE; - } else { - char *address; - address = open_temporary_reauthentication_channel (self, - seat_id, - session_id, - pid, - uid, - is_remote); - gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), - invocation, - address); - g_free (address); - } - - return TRUE; - } - - static void - manager_interface_init (GdmDBusManagerIface *interface) - { - interface->handle_register_display = gdm_manager_handle_register_display; -+ interface->handle_register_session = gdm_manager_handle_register_session; - interface->handle_open_session = gdm_manager_handle_open_session; - interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel; - } - - static gboolean - display_is_on_seat0 (GdmDisplay *display) - { - gboolean is_on_seat0 = TRUE; - char *seat_id = NULL; - - g_object_get (G_OBJECT (display), "seat-id", &seat_id, NULL); - - if (g_strcmp0 (seat_id, "seat0") != 0) { - is_on_seat0 = FALSE; - } - - g_free (seat_id); - - return is_on_seat0; - } - - static gboolean - get_timed_login_details (GdmManager *manager, - char **usernamep, - int *delayp) - { - gboolean res; - gboolean enabled; - - int delay; -diff --git a/daemon/gdm-manager.xml b/daemon/gdm-manager.xml -index f11f3fb73..92ef1d02d 100644 ---- a/daemon/gdm-manager.xml -+++ b/daemon/gdm-manager.xml -@@ -1,16 +1,19 @@ - - - - - - -+ -+ -+ - - - - - - - - - - --- -2.28.0 - diff --git a/SOURCES/0050-Allow-sessions-to-register-with-GDM.patch b/SOURCES/0050-Allow-sessions-to-register-with-GDM.patch deleted file mode 100644 index 5a53144..0000000 --- a/SOURCES/0050-Allow-sessions-to-register-with-GDM.patch +++ /dev/null @@ -1,1917 +0,0 @@ -From d6aca6da3ab9c16e907c7f46cf6d7bc2abbc2890 Mon Sep 17 00:00:00 2001 -From: Iain Lane -Date: Tue, 7 May 2019 16:00:14 +0100 -Subject: [PATCH 50/51] Allow sessions to register with GDM -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Recording when sessions start, for Wayland → Xorg fallback or -transitioning to the user session, is currently done with timeouts. - -This isn't ideal, because on some very slow machines the timeout can be -hit before the session has had a chance to fail: if gnome-session takes -more than 3 seconds to fail then the session will be considered to have -exited rather than failed, and so we don't do Xorg fallback. - -We can do this more reliably if we allow sessions to optionally register -themselves with GDM. Then we will know when they've started, so can shut -down the greeter or fall back to Xorg as appropriate. The mechanism is -that they specify X-GDM-SessionRegisters=true in their file, and then -call RegsterSession on the DisplayManager interface on the bus (added in -the previous commit) to say that they've started up. - -If X-GDM-SessionRegisters is missing or false, GDM will call the same -method for them after 10 seconds. - -Closes: #483 ---- - common/gdm-common.h | 2 + - daemon/gdm-display.c | 19 ++----- - daemon/gdm-local-display-factory.c | 49 +++++++++--------- - daemon/gdm-session.c | 47 +++++++++++++++-- - daemon/gdm-session.h | 1 + - daemon/gdm-wayland-session.c | 81 +++++++++++++++++++++++------- - daemon/gdm-x-session.c | 81 +++++++++++++++++++++++------- - 7 files changed, 201 insertions(+), 79 deletions(-) - -diff --git a/common/gdm-common.h b/common/gdm-common.h -index 3fbf07653..7fd6458d7 100644 ---- a/common/gdm-common.h -+++ b/common/gdm-common.h -@@ -1,59 +1,61 @@ - /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - - #ifndef _GDM_COMMON_H - #define _GDM_COMMON_H - - #include - #include - - #include - #include - -+#define REGISTER_SESSION_TIMEOUT 10 -+ - #define VE_IGNORE_EINTR(expr) \ - do { \ - errno = 0; \ - expr; \ - } while G_UNLIKELY (errno == EINTR); - - GQuark gdm_common_error_quark (void); - #define GDM_COMMON_ERROR gdm_common_error_quark() - - typedef char * (*GdmExpandVarFunc) (const char *var, - gpointer user_data); - - G_BEGIN_DECLS - - int gdm_wait_on_pid (int pid); - int gdm_wait_on_and_disown_pid (int pid, - int timeout); - int gdm_signal_pid (int pid, - int signal); - gboolean gdm_get_pwent_for_name (const char *name, - struct passwd **pwentp); - - gboolean gdm_clear_close_on_exec_flag (int fd); - - const char * gdm_make_temp_dir (char *template); - - char *gdm_generate_random_bytes (gsize size, - GError **error); - gboolean gdm_get_login_window_session_id (const char *seat_id, - char **session_id); -diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 09cc2e116..ae20491cd 100644 ---- a/daemon/gdm-display.c -+++ b/daemon/gdm-display.c -@@ -39,61 +39,60 @@ - - #include "gdm-common.h" - #include "gdm-display.h" - #include "gdm-display-glue.h" - #include "gdm-display-access-file.h" - #include "gdm-launch-environment.h" - - #include "gdm-settings-direct.h" - #include "gdm-settings-keys.h" - - #include "gdm-launch-environment.h" - #include "gdm-dbus-util.h" - - #define GNOME_SESSION_SESSIONS_PATH DATADIR "/gnome-session/sessions" - - #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate)) - - struct GdmDisplayPrivate - { - char *id; - char *seat_id; - char *session_id; - char *session_class; - char *session_type; - - char *remote_hostname; - int x11_display_number; - char *x11_display_name; - int status; - time_t creation_time; -- GTimer *server_timer; - - char *x11_cookie; - gsize x11_cookie_size; - GdmDisplayAccessFile *access_file; - - guint finish_idle_id; - - xcb_connection_t *xcb_connection; - int xcb_screen_number; - - GDBusConnection *connection; - GdmDisplayAccessFile *user_access_file; - - GdmDBusDisplay *display_skeleton; - GDBusObjectSkeleton *object_skeleton; - - /* this spawns and controls the greeter session */ - GdmLaunchEnvironment *launch_environment; - - guint is_local : 1; - guint is_initial : 1; - guint allow_timed_login : 1; - guint have_existing_user_accounts : 1; - guint doing_initial_setup : 1; - guint session_registered : 1; - }; - - enum { - PROP_0, - PROP_ID, -@@ -510,62 +509,60 @@ gdm_display_prepare (GdmDisplay *self) - * asynchronously - */ - look_for_existing_users_sync (self); - - self->priv->doing_initial_setup = wants_initial_setup (self); - - g_object_ref (self); - ret = GDM_DISPLAY_GET_CLASS (self)->prepare (self); - g_object_unref (self); - - return ret; - } - - gboolean - gdm_display_manage (GdmDisplay *self) - { - gboolean res; - - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - g_debug ("GdmDisplay: Managing display: %s", self->priv->id); - - /* If not explicitly prepared, do it now */ - if (self->priv->status == GDM_DISPLAY_UNMANAGED) { - res = gdm_display_prepare (self); - if (! res) { - return FALSE; - } - } - -- g_timer_start (self->priv->server_timer); -- - if (g_strcmp0 (self->priv->session_class, "greeter") == 0) { - if (GDM_DISPLAY_GET_CLASS (self)->manage != NULL) { - GDM_DISPLAY_GET_CLASS (self)->manage (self); - } - } - - return TRUE; - } - - gboolean - gdm_display_finish (GdmDisplay *self) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - if (self->priv->finish_idle_id != 0) { - g_source_remove (self->priv->finish_idle_id); - self->priv->finish_idle_id = 0; - } - - _gdm_display_set_status (self, GDM_DISPLAY_FINISHED); - - g_debug ("GdmDisplay: finish display"); - - return TRUE; - } - - static void - gdm_display_disconnect (GdmDisplay *self) - { - /* These 3 bits are reserved/unused by the X protocol */ -@@ -576,85 +573,80 @@ gdm_display_disconnect (GdmDisplay *self) - - if (self->priv->xcb_connection == NULL) { - return; - } - - setup = xcb_get_setup (self->priv->xcb_connection); - - /* resource_id_mask is the bits given to each client for - * addressing resources */ - highest_client = (XID) ~unused_bits & ~setup->resource_id_mask; - client_increment = setup->resource_id_mask + 1; - - /* Kill every client but ourselves, then close our own connection - */ - for (client = 0; - client <= highest_client; - client += client_increment) { - - if (client != setup->resource_id_base) - xcb_kill_client (self->priv->xcb_connection, client); - } - - xcb_flush (self->priv->xcb_connection); - - g_clear_pointer (&self->priv->xcb_connection, xcb_disconnect); - } - - gboolean - gdm_display_unmanage (GdmDisplay *self) - { -- gdouble elapsed; -- - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - g_debug ("GdmDisplay: unmanage display"); - - gdm_display_disconnect (self); - -- g_timer_stop (self->priv->server_timer); -- - if (self->priv->user_access_file != NULL) { - gdm_display_access_file_close (self->priv->user_access_file); - g_object_unref (self->priv->user_access_file); - self->priv->user_access_file = NULL; - } - - if (self->priv->access_file != NULL) { - gdm_display_access_file_close (self->priv->access_file); - g_object_unref (self->priv->access_file); - self->priv->access_file = NULL; - } - -- elapsed = g_timer_elapsed (self->priv->server_timer, NULL); -- if (elapsed < 3) { -- g_warning ("GdmDisplay: display lasted %lf seconds", elapsed); -+ if (!self->priv->session_registered) { -+ g_warning ("GdmDisplay: Session never registered, failing"); - _gdm_display_set_status (self, GDM_DISPLAY_FAILED); - } else { - _gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED); - } - - return TRUE; - } - - gboolean - gdm_display_get_id (GdmDisplay *self, - char **id, - GError **error) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - if (id != NULL) { - *id = g_strdup (self->priv->id); - } - - return TRUE; - } - - gboolean - gdm_display_get_x11_display_name (GdmDisplay *self, - char **x11_display, - GError **error) - { - g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE); - - if (x11_display != NULL) { -@@ -898,61 +890,61 @@ gdm_display_get_property (GObject *object, - case PROP_X11_DISPLAY_NAME: - g_value_set_string (value, self->priv->x11_display_name); - break; - case PROP_X11_COOKIE: - g_value_set_string (value, self->priv->x11_cookie); - break; - case PROP_X11_AUTHORITY_FILE: - g_value_take_string (value, - self->priv->access_file? - gdm_display_access_file_get_path (self->priv->access_file) : NULL); - break; - case PROP_IS_LOCAL: - g_value_set_boolean (value, self->priv->is_local); - break; - case PROP_IS_CONNECTED: - g_value_set_boolean (value, self->priv->xcb_connection != NULL); - break; - case PROP_LAUNCH_ENVIRONMENT: - g_value_set_object (value, self->priv->launch_environment); - break; - case PROP_IS_INITIAL: - g_value_set_boolean (value, self->priv->is_initial); - break; - case PROP_HAVE_EXISTING_USER_ACCOUNTS: - g_value_set_boolean (value, self->priv->have_existing_user_accounts); - break; - case PROP_DOING_INITIAL_SETUP: - g_value_set_boolean (value, self->priv->doing_initial_setup); - break; - case PROP_SESSION_REGISTERED: -- g_value_set_boolean (value, priv->session_registered); -+ g_value_set_boolean (value, self->priv->session_registered); - break; - case PROP_ALLOW_TIMED_LOGIN: - g_value_set_boolean (value, self->priv->allow_timed_login); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static gboolean - handle_get_id (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - GdmDisplay *self) - { - char *id; - - gdm_display_get_id (self, &id, NULL); - - gdm_dbus_display_complete_get_id (skeleton, invocation, id); - - g_free (id); - return TRUE; - } - - static gboolean - handle_get_remote_hostname (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - GdmDisplay *self) - { -@@ -1251,99 +1243,94 @@ gdm_display_class_init (GdmDisplayClass *klass) - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_LAUNCH_ENVIRONMENT, - g_param_spec_object ("launch-environment", - NULL, - NULL, - GDM_TYPE_LAUNCH_ENVIRONMENT, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_STATUS, - g_param_spec_int ("status", - "status", - "status", - -1, - G_MAXINT, - GDM_DISPLAY_UNMANAGED, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_type_class_add_private (klass, sizeof (GdmDisplayPrivate)); - } - - static void - gdm_display_init (GdmDisplay *self) - { - - self->priv = GDM_DISPLAY_GET_PRIVATE (self); - - self->priv->creation_time = time (NULL); -- self->priv->server_timer = g_timer_new (); - } - - static void - gdm_display_finalize (GObject *object) - { - GdmDisplay *self; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_DISPLAY (object)); - - self = GDM_DISPLAY (object); - - g_return_if_fail (self->priv != NULL); - - g_debug ("GdmDisplay: Finalizing display: %s", self->priv->id); - g_free (self->priv->id); - g_free (self->priv->seat_id); - g_free (self->priv->session_class); - g_free (self->priv->remote_hostname); - g_free (self->priv->x11_display_name); - g_free (self->priv->x11_cookie); - - g_clear_object (&self->priv->display_skeleton); - g_clear_object (&self->priv->object_skeleton); - g_clear_object (&self->priv->connection); - - if (self->priv->access_file != NULL) { - g_object_unref (self->priv->access_file); - } - - if (self->priv->user_access_file != NULL) { - g_object_unref (self->priv->user_access_file); - } - -- if (self->priv->server_timer != NULL) { -- g_timer_destroy (self->priv->server_timer); -- } -- - G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object); - } - - GDBusObjectSkeleton * - gdm_display_get_object_skeleton (GdmDisplay *self) - { - return self->priv->object_skeleton; - } - - static void - on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment, - GdmDisplay *self) - { - char *session_id; - - g_debug ("GdmDisplay: Greeter session opened"); - session_id = gdm_launch_environment_get_session_id (launch_environment); - _gdm_display_set_session_id (self, session_id); - g_free (session_id); - } - - static void - on_launch_environment_session_started (GdmLaunchEnvironment *launch_environment, - GdmDisplay *self) - { - g_debug ("GdmDisplay: Greeter started"); - } - - static void - self_destruct (GdmDisplay *self) -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index aae226750..35880563d 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -39,61 +39,60 @@ - #include "gdm-settings-keys.h" - #include "gdm-settings-direct.h" - #include "gdm-display-store.h" - #include "gdm-local-display.h" - #include "gdm-legacy-display.h" - - #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate)) - - #define GDM_DBUS_PATH "/org/gnome/DisplayManager" - #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory" - #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory" - - #define MAX_DISPLAY_FAILURES 5 - #define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */ - - struct GdmLocalDisplayFactoryPrivate - { - GdmDBusLocalDisplayFactory *skeleton; - GDBusConnection *connection; - GHashTable *used_display_numbers; - - /* FIXME: this needs to be per seat? */ - guint num_failures; - - guint seat_new_id; - guint seat_removed_id; - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - unsigned int active_vt; - guint active_vt_watch_id; -- guint wait_to_finish_timeout_id; - #endif - }; - - enum { - PROP_0, - }; - - static void gdm_local_display_factory_class_init (GdmLocalDisplayFactoryClass *klass); - static void gdm_local_display_factory_init (GdmLocalDisplayFactory *factory); - static void gdm_local_display_factory_finalize (GObject *object); - - static GdmDisplay *create_display (GdmLocalDisplayFactory *factory, - const char *seat_id, - const char *session_type, - gboolean initial_display); - - static void on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmLocalDisplayFactory *factory); - - static gboolean gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory); - static gpointer local_display_factory_object = NULL; - static gboolean lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data); - - G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY) - - GQuark - gdm_local_display_factory_error_quark (void) -@@ -276,60 +275,79 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact - static gboolean - finish_display_on_seat_if_waiting (GdmDisplayStore *display_store, - GdmDisplay *display, - const char *seat_id) - { - if (gdm_display_get_status (display) != GDM_DISPLAY_WAITING_TO_FINISH) - return FALSE; - - g_debug ("GdmLocalDisplayFactory: finish background display\n"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); - - return FALSE; - } - - static void - finish_waiting_displays_on_seat (GdmLocalDisplayFactory *factory, - const char *seat_id) - { - GdmDisplayStore *store; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - gdm_display_store_foreach (store, - (GdmDisplayStoreFunc) finish_display_on_seat_if_waiting, - (gpointer) - seat_id); - } - -+static void -+on_session_registered_cb (GObject *gobject, -+ GParamSpec *pspec, -+ gpointer user_data) -+{ -+ GdmDisplay *display = GDM_DISPLAY (gobject); -+ GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); -+ gboolean registered; -+ -+ g_object_get (display, "session-registered", ®istered, NULL); -+ -+ if (!registered) -+ return; -+ -+ g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill"); -+ -+ finish_waiting_displays_on_seat (factory, "seat0"); -+} -+ - static void - on_display_status_changed (GdmDisplay *display, - GParamSpec *arg1, - GdmLocalDisplayFactory *factory) - { - int status; - 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); - - 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 -@@ -359,60 +377,67 @@ on_display_status_changed (GdmDisplay *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; - - /* workaround logind race for now - * bug 1643874 - */ - g_usleep (2 * G_USEC_PER_SEC); - } - - #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: -+#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -+ g_signal_connect_object (display, -+ "notify::session-registered", -+ G_CALLBACK (on_session_registered_cb), -+ factory, -+ 0); -+#endif - break; - case GDM_DISPLAY_WAITING_TO_FINISH: - 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; - } -@@ -587,100 +612,83 @@ on_seat_new (GDBusConnection *connection, - } - - static void - on_seat_removed (GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) - { - const char *seat; - - g_variant_get (parameters, "(&s&o)", &seat, NULL); - delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat); - } - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - static gboolean - lookup_by_session_id (const char *id, - GdmDisplay *display, - gpointer user_data) - { - const char *looking_for = user_data; - const char *current; - - current = gdm_display_get_session_id (display); - return g_strcmp0 (current, looking_for) == 0; - } - --static gboolean --wait_to_finish_timeout (GdmLocalDisplayFactory *factory) --{ -- finish_waiting_displays_on_seat (factory, "seat0"); -- factory->priv->wait_to_finish_timeout_id = 0; -- return G_SOURCE_REMOVE; --} -- - static void - maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - gboolean doing_initial_setup = FALSE; - - if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) { - g_debug ("GdmLocalDisplayFactory: login window not in managed state, so ignoring"); - return; - } - - g_object_get (G_OBJECT (display), - "doing-initial-setup", &doing_initial_setup, - NULL); - - /* we don't ever stop initial-setup implicitly */ - if (doing_initial_setup) { - g_debug ("GdmLocalDisplayFactory: login window is performing initial-setup, so ignoring"); - return; - } - - g_debug ("GdmLocalDisplayFactory: killing login window once its unused"); - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); -- -- /* We stop the greeter after a timeout to avoid flicker */ -- if (factory->priv->wait_to_finish_timeout_id != 0) -- g_source_remove (factory->priv->wait_to_finish_timeout_id); -- -- factory->priv->wait_to_finish_timeout_id = -- g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT, -- (GSourceFunc)wait_to_finish_timeout, -- factory); - } - - static gboolean - on_vt_changed (GIOChannel *source, - GIOCondition condition, - GdmLocalDisplayFactory *factory) - { - GIOStatus status; - g_autofree char *tty_of_active_vt = NULL; - g_autofree char *login_session_id = NULL; - g_autofree char *active_session_id = NULL; - unsigned int previous_vt, new_vt; - const char *session_type = NULL; - int ret, n_returned; - - g_debug ("GdmLocalDisplayFactory: received VT change event"); - g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL); - - if (condition & G_IO_PRI) { - g_autoptr (GError) error = NULL; - status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error); - - if (error != NULL) { - g_warning ("could not read active VT from kernel: %s", error->message); - } - switch (status) { - case G_IO_STATUS_ERROR: - return G_SOURCE_REMOVE; - case G_IO_STATUS_EOF: - return G_SOURCE_REMOVE; -@@ -722,61 +730,60 @@ on_vt_changed (GIOChannel *source, - factory->priv->active_vt = new_vt; - - /* don't do anything at start up */ - if (previous_vt == 0) { - g_debug ("GdmLocalDisplayFactory: VT is %u at startup", - factory->priv->active_vt); - return G_SOURCE_CONTINUE; - } - - g_debug ("GdmLocalDisplayFactory: VT changed from %u to %u", - previous_vt, factory->priv->active_vt); - - /* if the old VT was running a wayland login screen kill it - */ - if (gdm_get_login_window_session_id ("seat0", &login_session_id)) { - unsigned int login_window_vt; - - ret = sd_session_get_vt (login_session_id, &login_window_vt); - if (ret == 0 && login_window_vt != 0) { - g_debug ("GdmLocalDisplayFactory: VT of login window is %u", login_window_vt); - if (login_window_vt == previous_vt) { - GdmDisplayStore *store; - GdmDisplay *display; - - g_debug ("GdmLocalDisplayFactory: VT switched from login window"); - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); -- - if (display != NULL) - maybe_stop_greeter_in_background (factory, display); - } else { - g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); - } - } - } - - /* if user jumped back to initial vt and it's empty put a login screen - * on it (unless a login screen is already running elsewhere, then - * jump to that login screen) - */ - if (factory->priv->active_vt != GDM_INITIAL_VT) { - g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring"); - return G_SOURCE_CONTINUE; - } - - if (gdm_local_display_factory_use_wayland ()) - session_type = "wayland"; - - g_debug ("GdmLocalDisplayFactory: creating new display on seat0 because of VT change"); - - create_display (factory, "seat0", session_type, TRUE); - - return G_SOURCE_CONTINUE; - } - #endif - - static void - gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) -@@ -805,64 +812,60 @@ gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory) - g_object_unref); - - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - io_channel = g_io_channel_new_file ("/sys/class/tty/tty0/active", "r", NULL); - - if (io_channel != NULL) { - factory->priv->active_vt_watch_id = - g_io_add_watch (io_channel, - G_IO_PRI, - (GIOFunc) - on_vt_changed, - factory); - } - #endif - } - - static void - gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory) - { - if (factory->priv->seat_new_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_new_id); - factory->priv->seat_new_id = 0; - } - if (factory->priv->seat_removed_id) { - g_dbus_connection_signal_unsubscribe (factory->priv->connection, - factory->priv->seat_removed_id); - factory->priv->seat_removed_id = 0; - } - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -- if (factory->priv->wait_to_finish_timeout_id != 0) { -- g_source_remove (factory->priv->wait_to_finish_timeout_id); -- factory->priv->wait_to_finish_timeout_id = 0; -- } - if (factory->priv->active_vt_watch_id) { - g_source_remove (factory->priv->active_vt_watch_id); - factory->priv->active_vt_watch_id = 0; - } - #endif - } - - static void - on_display_added (GdmDisplayStore *display_store, - const char *id, - GdmLocalDisplayFactory *factory) - { - GdmDisplay *display; - - display = gdm_display_store_lookup (display_store, id); - - if (display != NULL) { - g_signal_connect_object (display, "notify::status", - G_CALLBACK (on_display_status_changed), - factory, - 0); - - g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory); - } - } - - static void - on_display_removed (GdmDisplayStore *display_store, - GdmDisplay *display, - GdmLocalDisplayFactory *factory) -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 5b76ba129..540a2534d 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -2849,132 +2849,139 @@ on_start_program_cb (GdmDBusWorker *worker, - - self = conversation->session; - service_name = conversation->service_name; - - if (worked) { - self->priv->session_pid = pid; - self->priv->session_conversation = conversation; - - g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", pid); - g_signal_emit (self, signals[SESSION_STARTED], 0, service_name, pid); - } else { - gdm_session_stop_conversation (self, service_name); - - g_debug ("GdmSession: Emitting 'session-start-failed' signal"); - g_signal_emit (self, signals[SESSION_START_FAILED], 0, service_name, error->message); - } - } - - void - gdm_session_start_session (GdmSession *self, - const char *service_name) - { - GdmSessionConversation *conversation; - GdmSessionDisplayMode display_mode; - gboolean is_x11 = TRUE; - gboolean run_launcher = FALSE; - gboolean allow_remote_connections = FALSE; - gboolean run_separate_bus = FALSE; - char *command; - char *program; -+ gboolean register_session; - - g_return_if_fail (GDM_IS_SESSION (self)); - g_return_if_fail (self->priv->session_conversation == NULL); - - conversation = find_conversation_by_name (self, service_name); - - if (conversation == NULL) { - g_warning ("GdmSession: Tried to start session of " - "nonexistent conversation %s", service_name); - return; - } - - stop_all_other_conversations (self, conversation, FALSE); - - display_mode = gdm_session_get_display_mode (self); - - #ifdef ENABLE_WAYLAND_SUPPORT - is_x11 = g_strcmp0 (self->priv->session_type, "wayland") != 0; - #endif - - if (display_mode == GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED || - display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) { - run_launcher = TRUE; - } - - if (g_strcmp0 (self->priv->display_seat_id, "seat0") != 0 && !run_launcher) { - run_separate_bus = TRUE; - } - -+ register_session = !gdm_session_session_registers (self); -+ - if (self->priv->selected_program == NULL) { - gboolean run_xsession_script; - - command = get_session_command (self); - - run_xsession_script = !gdm_session_bypasses_xsession (self); - - if (self->priv->display_is_local) { - gboolean disallow_tcp = TRUE; - gdm_settings_direct_get_boolean (GDM_KEY_DISALLOW_TCP, &disallow_tcp); - allow_remote_connections = !disallow_tcp; - } else { - allow_remote_connections = TRUE; - } - - if (run_launcher) { - if (is_x11) { -- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s %s\"%s\"", -+ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s%s %s\"%s\"", -+ register_session ? "--register-session " : "", - run_xsession_script? "--run-script " : "", - allow_remote_connections? "--allow-remote-connections " : "", - command); - } else { -- program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"", -+ program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"", -+ register_session ? "--register-session " : "", - command); - } - } else if (run_xsession_script) { - if (run_separate_bus) { - program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command); - } else { - program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command); - } - } else { - program = g_strdup (command); - } - - g_free (command); - } else { - if (run_launcher) { - if (is_x11) { -- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"", -+ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"%s\"", -+ register_session ? "--register-session " : "", - self->priv->selected_program); - } else { -- program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"", -+ program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"", -+ register_session ? "--register-session " : "", - self->priv->selected_program); - } - } else { - if (run_separate_bus) { - program = g_strdup_printf ("dbus-run-session -- %s", - self->priv->selected_program); - } else { - program = g_strdup (self->priv->selected_program); - } - } - } - - set_up_session_environment (self); - send_environment (self, conversation); - - gdm_dbus_worker_call_start_program (conversation->worker_proxy, - program, - conversation->worker_cancellable, - (GAsyncReadyCallback) on_start_program_cb, - conversation); - g_free (program); - } - - static void - stop_all_conversations (GdmSession *self) - { - stop_all_other_conversations (self, NULL, TRUE); - } - - static void -@@ -3199,60 +3206,92 @@ gdm_session_is_wayland_session (GdmSession *self) - } - - if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { - is_wayland_session = TRUE; - } - } - - out: - g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); - - return is_wayland_session; - } - #endif - - static void - update_session_type (GdmSession *self) - { - #ifdef ENABLE_WAYLAND_SUPPORT - gboolean is_wayland_session = FALSE; - - is_wayland_session = gdm_session_is_wayland_session (self); - - if (is_wayland_session) { - set_session_type (self, "wayland"); - } else { - set_session_type (self, NULL); - } - #endif - } - -+gboolean -+gdm_session_session_registers (GdmSession *self) -+{ -+ g_autoptr(GError) error = NULL; -+ g_autoptr(GKeyFile) key_file = NULL; -+ gboolean session_registers = FALSE; -+ g_autofree char *filename = NULL; -+ -+ g_return_val_if_fail (self != NULL, FALSE); -+ g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); -+ -+ filename = get_session_filename (self); -+ -+ key_file = load_key_file_for_file (self, filename, NULL, NULL); -+ -+ session_registers = g_key_file_get_boolean (key_file, -+ G_KEY_FILE_DESKTOP_GROUP, -+ "X-GDM-SessionRegisters", -+ &error); -+ if (!session_registers && -+ error != NULL && -+ !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { -+ g_warning ("GdmSession: Couldn't read session file '%s'", filename); -+ return FALSE; -+ } -+ -+ g_debug ("GdmSession: '%s' %s self", filename, -+ session_registers ? "registers" : "does not register"); -+ -+ return session_registers; -+} -+ - gboolean - gdm_session_bypasses_xsession (GdmSession *self) - { - GError *error; - GKeyFile *key_file; - gboolean res; - gboolean bypasses_xsession = FALSE; - char *filename = NULL; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); - - #ifdef ENABLE_WAYLAND_SUPPORT - if (gdm_session_is_wayland_session (self)) { - bypasses_xsession = TRUE; - goto out; - } - #endif - - filename = get_session_filename (self); - - key_file = load_key_file_for_file (self, filename, "x11", NULL); - - error = NULL; - res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", NULL); - if (!res) { - goto out; - } else { - bypasses_xsession = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", &error); - if (error) { -diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h -index a22c09543..682d2c99f 100644 ---- a/daemon/gdm-session.h -+++ b/daemon/gdm-session.h -@@ -108,60 +108,61 @@ typedef struct - void (* conversation_started) (GdmSession *session, - const char *service_name); - void (* conversation_stopped) (GdmSession *session, - const char *service_name); - void (* setup_complete) (GdmSession *session, - const char *service_name); - } GdmSessionClass; - - GType gdm_session_get_type (void); - - GdmSession *gdm_session_new (GdmSessionVerificationMode verification_mode, - uid_t allowed_user, - const char *display_name, - const char *display_hostname, - const char *display_device, - const char *display_seat_id, - const char *display_x11_authority_file, - gboolean display_is_local, - const char * const *environment); - uid_t gdm_session_get_allowed_user (GdmSession *session); - void gdm_session_start_reauthentication (GdmSession *session, - GPid pid_of_caller, - uid_t uid_of_caller); - - const char *gdm_session_get_server_address (GdmSession *session); - const char *gdm_session_get_username (GdmSession *session); - const char *gdm_session_get_display_device (GdmSession *session); - const char *gdm_session_get_display_seat_id (GdmSession *session); - const char *gdm_session_get_session_id (GdmSession *session); - gboolean gdm_session_bypasses_xsession (GdmSession *session); -+gboolean gdm_session_session_registers (GdmSession *session); - GdmSessionDisplayMode gdm_session_get_display_mode (GdmSession *session); - - #ifdef ENABLE_WAYLAND_SUPPORT - void gdm_session_set_ignore_wayland (GdmSession *session, - gboolean ignore_wayland); - #endif - gboolean gdm_session_start_conversation (GdmSession *session, - const char *service_name); - void gdm_session_stop_conversation (GdmSession *session, - const char *service_name); - const char *gdm_session_get_conversation_session_id (GdmSession *session, - const char *service_name); - void gdm_session_setup (GdmSession *session, - const char *service_name); - void gdm_session_setup_for_user (GdmSession *session, - const char *service_name, - const char *username); - void gdm_session_setup_for_program (GdmSession *session, - const char *service_name, - const char *username, - const char *log_file); - void gdm_session_set_environment_variable (GdmSession *session, - const char *key, - const char *value); - void gdm_session_send_environment (GdmSession *self, - const char *service_name); - void gdm_session_reset (GdmSession *session); - void gdm_session_cancel (GdmSession *session); - void gdm_session_authenticate (GdmSession *session, - const char *service_name); -diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c -index 94f49e19c..35679b194 100644 ---- a/daemon/gdm-wayland-session.c -+++ b/daemon/gdm-wayland-session.c -@@ -18,68 +18,71 @@ - * 02110-1301, USA. - */ - #include "config.h" - - #include - #include - - #include "gdm-common.h" - #include "gdm-settings-direct.h" - #include "gdm-settings-keys.h" - #include "gdm-log.h" - - #include "gdm-manager-glue.h" - - #include - #include - #include - #include - - #include - - #define BUS_ADDRESS_FILENO (STDERR_FILENO + 1) - - typedef struct - { - GdmSettings *settings; - GCancellable *cancellable; - - GSubprocess *bus_subprocess; - GDBusConnection *bus_connection; -+ GdmDBusManager *display_manager_proxy; - char *bus_address; - - char **environment; - - GSubprocess *session_subprocess; - char *session_command; - int session_exit_status; - -+ guint register_session_id; -+ - GMainLoop *main_loop; - - guint32 debug_enabled : 1; - } State; - - static void - on_bus_finished (GSubprocess *subprocess, - GAsyncResult *result, - State *state) - { - gboolean cancelled; - - cancelled = !g_subprocess_wait_finish (subprocess, result, NULL); - - if (cancelled) { - goto out; - } - - if (g_subprocess_get_if_exited (subprocess)) { - int exit_status; - - exit_status = g_subprocess_get_exit_status (subprocess); - - g_debug ("message bus exited with status %d", exit_status); - } else { - int signal_number; - - signal_number = g_subprocess_get_term_sig (subprocess); - g_debug ("message bus was killed with status %d", signal_number); - } -@@ -358,140 +361,170 @@ out: - } - - static void - signal_subprocesses (State *state) - { - if (state->session_subprocess != NULL) { - g_subprocess_send_signal (state->session_subprocess, SIGTERM); - } - - if (state->bus_subprocess != NULL) { - g_subprocess_send_signal (state->bus_subprocess, SIGTERM); - } - } - - static void - wait_on_subprocesses (State *state) - { - if (state->bus_subprocess != NULL) { - g_subprocess_wait (state->bus_subprocess, NULL, NULL); - } - - if (state->session_subprocess != NULL) { - g_subprocess_wait (state->session_subprocess, NULL, NULL); - } - } - - static gboolean - register_display (State *state, - GCancellable *cancellable) - { -- GdmDBusManager *manager = NULL; - GError *error = NULL; - gboolean registered = FALSE; - GVariantBuilder details; - -- manager = gdm_dbus_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, -- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | -- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, -- "org.gnome.DisplayManager", -- "/org/gnome/DisplayManager/Manager", -- cancellable, -- &error); -- -- if (!manager) { -- g_debug ("could not contact display manager: %s", error->message); -- g_error_free (error); -- goto out; -- } -- - g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); - g_variant_builder_add (&details, "{ss}", "session-type", "wayland"); - -- registered = gdm_dbus_manager_call_register_display_sync (manager, -+ registered = gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy, - g_variant_builder_end (&details), - cancellable, - &error); - if (error != NULL) { - g_debug ("Could not register display: %s", error->message); - g_error_free (error); - } - --out: -- g_clear_object (&manager); - return registered; - } - - static void - init_state (State **state) - { - static State state_allocation; - - *state = &state_allocation; - } - - static void - clear_state (State **out_state) - { - State *state = *out_state; - - g_clear_object (&state->cancellable); - g_clear_object (&state->bus_connection); - g_clear_object (&state->session_subprocess); - g_clear_pointer (&state->environment, g_strfreev); - g_clear_pointer (&state->main_loop, g_main_loop_unref); -+ g_clear_handle_id (&state->register_session_id, g_source_remove); - *out_state = NULL; - } - - static gboolean - on_sigterm (State *state) - { - g_cancellable_cancel (state->cancellable); - - if (g_main_loop_is_running (state->main_loop)) { - g_main_loop_quit (state->main_loop); - } - - return G_SOURCE_CONTINUE; - } - -+static gboolean -+register_session_timeout_cb (gpointer user_data) -+{ -+ State *state; -+ GError *error = NULL; -+ -+ state = (State *) user_data; -+ -+ gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy, -+ g_variant_new ("a{sv}", NULL), -+ state->cancellable, -+ &error); -+ -+ if (error != NULL) { -+ g_warning ("Could not register session: %s", error->message); -+ g_error_free (error); -+ } -+ -+ return G_SOURCE_REMOVE; -+} -+ -+static gboolean -+connect_to_display_manager (State *state) -+{ -+ g_autoptr (GError) error = NULL; -+ -+ state->display_manager_proxy = gdm_dbus_manager_proxy_new_for_bus_sync ( -+ G_BUS_TYPE_SYSTEM, -+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, -+ "org.gnome.DisplayManager", -+ "/org/gnome/DisplayManager/Manager", -+ state->cancellable, -+ &error); -+ -+ if (state->display_manager_proxy == NULL) { -+ g_printerr ("gdm-wayland-session: could not contact display manager: %s\n", -+ error->message); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ - int - main (int argc, - char **argv) - { - State *state = NULL; - GOptionContext *context = NULL; - static char **args = NULL; - gboolean debug = FALSE; - gboolean ret; - int exit_status = EX_OK; -+ static gboolean register_session = FALSE; -+ - static GOptionEntry entries [] = { -+ { "register-session", 0, 0, G_OPTION_ARG_NONE, ®ister_session, "Register session after a delay", NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - gdm_log_init (); - - context = g_option_context_new (_("GNOME Display Manager Wayland Session Launcher")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - if (args == NULL || args[0] == NULL || args[1] != NULL) { - g_warning ("gdm-wayland-session takes one argument (the session)"); - exit_status = EX_USAGE; - goto out; - } - - init_state (&state); - - state->session_command = args[0]; - - state->settings = gdm_settings_new (); - ret = gdm_settings_direct_init (state->settings, DATADIR "/gdm/gdm.schemas", "/"); - - if (!ret) { -@@ -501,55 +534,67 @@ main (int argc, - } - - gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug); - state->debug_enabled = debug; - - gdm_log_set_debug (debug); - - state->main_loop = g_main_loop_new (NULL, FALSE); - state->cancellable = g_cancellable_new (); - - g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state); - - ret = spawn_bus (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session message bus\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - import_environment (state, state->cancellable); - - ret = spawn_session (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -+ if (!connect_to_display_manager (state)) -+ goto out; -+ - ret = register_display (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to register display with display manager\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -+ if (register_session) { -+ g_debug ("gdm-wayland-session: Will register session in %d seconds", REGISTER_SESSION_TIMEOUT); -+ state->register_session_id = g_timeout_add_seconds (REGISTER_SESSION_TIMEOUT, -+ register_session_timeout_cb, -+ state); -+ } else { -+ g_debug ("gdm-wayland-session: Session will register itself"); -+ } -+ - g_main_loop_run (state->main_loop); - - /* Only use exit status of session if we're here because it exit */ - - if (state->session_subprocess == NULL) { - exit_status = state->session_exit_status; - } - - out: - if (state != NULL) { - signal_subprocesses (state); - wait_on_subprocesses (state); - clear_state (&state); - } - - return exit_status; - } -diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c -index d8e3c7d53..f0082fdc6 100644 ---- a/daemon/gdm-x-session.c -+++ b/daemon/gdm-x-session.c -@@ -24,68 +24,71 @@ - - #include "gdm-common.h" - #include "gdm-settings-direct.h" - #include "gdm-settings-keys.h" - #include "gdm-log.h" - - #include "gdm-manager-glue.h" - - #include - #include - #include - #include - #include - #include - #include - - #define DISPLAY_FILENO (STDERR_FILENO + 1) - #define BUS_ADDRESS_FILENO (DISPLAY_FILENO + 1) - - typedef struct - { - GdmSettings *settings; - GCancellable *cancellable; - - GSubprocess *x_subprocess; - char *auth_file; - char *display_name; - - GSubprocess *bus_subprocess; - GDBusConnection *bus_connection; -+ GdmDBusManager *display_manager_proxy; - char *bus_address; - - char **environment; - - GSubprocess *session_subprocess; - char *session_command; - int session_exit_status; - -+ guint register_session_id; -+ - GMainLoop *main_loop; - - guint32 debug_enabled : 1; - } State; - - static FILE * - create_auth_file (char **filename) - { - char *auth_dir = NULL; - char *auth_file = NULL; - int fd; - FILE *fp = NULL; - - auth_dir = g_build_filename (g_get_user_runtime_dir (), - "gdm", - NULL); - - g_mkdir_with_parents (auth_dir, 0711); - auth_file = g_build_filename (auth_dir, "Xauthority", NULL); - g_clear_pointer (&auth_dir, g_free); - - fd = g_open (auth_file, O_RDWR | O_CREAT | O_TRUNC, 0700); - - if (fd < 0) { - g_debug ("could not open %s to store auth cookie: %m", - auth_file); - g_clear_pointer (&auth_file, g_free); - goto out; - } - -@@ -711,148 +714,178 @@ signal_subprocesses (State *state) - - if (state->bus_subprocess != NULL) { - g_subprocess_send_signal (state->bus_subprocess, SIGTERM); - } - - if (state->x_subprocess != NULL) { - g_subprocess_send_signal (state->x_subprocess, SIGTERM); - } - } - - static void - wait_on_subprocesses (State *state) - { - if (state->x_subprocess != NULL) { - g_subprocess_wait (state->x_subprocess, NULL, NULL); - } - - if (state->bus_subprocess != NULL) { - g_subprocess_wait (state->bus_subprocess, NULL, NULL); - } - - if (state->session_subprocess != NULL) { - g_subprocess_wait (state->session_subprocess, NULL, NULL); - } - } - - static gboolean - register_display (State *state, - GCancellable *cancellable) - { -- GdmDBusManager *manager = NULL; - GError *error = NULL; - gboolean registered = FALSE; - GVariantBuilder details; - -- manager = gdm_dbus_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, -- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | -- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, -- "org.gnome.DisplayManager", -- "/org/gnome/DisplayManager/Manager", -- cancellable, -- &error); -- -- if (!manager) { -- g_debug ("could not contact display manager: %s", error->message); -- g_error_free (error); -- goto out; -- } -- - g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); - g_variant_builder_add (&details, "{ss}", "session-type", "x11"); - g_variant_builder_add (&details, "{ss}", "x11-display-name", state->display_name); - -- registered = gdm_dbus_manager_call_register_display_sync (manager, -+ registered = gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy, - g_variant_builder_end (&details), - cancellable, - &error); - if (error != NULL) { - g_debug ("Could not register display: %s", error->message); - g_error_free (error); - } - --out: -- g_clear_object (&manager); - return registered; - } - - static void - init_state (State **state) - { - static State state_allocation; - - *state = &state_allocation; - } - - static void - clear_state (State **out_state) - { - State *state = *out_state; - - g_clear_object (&state->cancellable); - g_clear_object (&state->bus_connection); - g_clear_object (&state->session_subprocess); - g_clear_object (&state->x_subprocess); - g_clear_pointer (&state->environment, g_strfreev); - g_clear_pointer (&state->auth_file, g_free); - g_clear_pointer (&state->display_name, g_free); - g_clear_pointer (&state->main_loop, g_main_loop_unref); -+ g_clear_handle_id (&state->register_session_id, g_source_remove); - *out_state = NULL; - } - - static gboolean - on_sigterm (State *state) - { - g_cancellable_cancel (state->cancellable); - - if (g_main_loop_is_running (state->main_loop)) { - g_main_loop_quit (state->main_loop); - } - - return G_SOURCE_CONTINUE; - } - -+static gboolean -+register_session_timeout_cb (gpointer user_data) -+{ -+ State *state; -+ GError *error = NULL; -+ -+ state = (State *) user_data; -+ -+ gdm_dbus_manager_call_register_session_sync (state->display_manager_proxy, -+ g_variant_new ("a{sv}", NULL), -+ state->cancellable, -+ &error); -+ -+ if (error != NULL) { -+ g_warning ("Could not register session: %s", error->message); -+ g_error_free (error); -+ } -+ -+ return G_SOURCE_REMOVE; -+} -+ -+static gboolean -+connect_to_display_manager (State *state) -+{ -+ g_autoptr (GError) error = NULL; -+ -+ state->display_manager_proxy = gdm_dbus_manager_proxy_new_for_bus_sync ( -+ G_BUS_TYPE_SYSTEM, -+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, -+ "org.gnome.DisplayManager", -+ "/org/gnome/DisplayManager/Manager", -+ state->cancellable, -+ &error); -+ -+ if (state->display_manager_proxy == NULL) { -+ g_printerr ("gdm-x-session: could not contact display manager: %s\n", -+ error->message); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ - int - main (int argc, - char **argv) - { - State *state = NULL; - GOptionContext *context = NULL; - static char **args = NULL; - static gboolean run_script = FALSE; - static gboolean allow_remote_connections = FALSE; - gboolean debug = FALSE; - gboolean ret; - int exit_status = EX_OK; -+ static gboolean register_session = FALSE; -+ - static GOptionEntry entries [] = { - { "run-script", 'r', 0, G_OPTION_ARG_NONE, &run_script, N_("Run program through /etc/gdm/Xsession wrapper script"), NULL }, - { "allow-remote-connections", 'a', 0, G_OPTION_ARG_NONE, &allow_remote_connections, N_("Listen on TCP socket"), NULL }, -+ { "register-session", 0, 0, G_OPTION_ARG_NONE, ®ister_session, "Register session after a delay", NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" }, - { NULL } - }; - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - setlocale (LC_ALL, ""); - - gdm_log_init (); - - context = g_option_context_new (_("GNOME Display Manager X Session Launcher")); - g_option_context_add_main_entries (context, entries, NULL); - - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - if (args == NULL || args[0] == NULL || args[1] != NULL) { - g_warning ("gdm-x-session takes one argument (the session)"); - exit_status = EX_USAGE; - goto out; - } - - init_state (&state); - - state->session_command = args[0]; - - state->settings = gdm_settings_new (); - ret = gdm_settings_direct_init (state->settings, DATADIR "/gdm/gdm.schemas", "/"); - - if (!ret) { -@@ -870,63 +903,75 @@ main (int argc, - state->cancellable = g_cancellable_new (); - - g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state); - - ret = spawn_x_server (state, allow_remote_connections, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run X server\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - ret = spawn_bus (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session message bus\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - import_environment (state, state->cancellable); - - ret = update_bus_environment (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to update bus environment\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -+ if (!connect_to_display_manager (state)) -+ goto out; -+ - ret = register_display (state, state->cancellable); - - if (!ret) { - g_printerr ("Unable to register display with display manager\n"); - exit_status = EX_SOFTWARE; - goto out; - } - - ret = spawn_session (state, run_script, state->cancellable); - - if (!ret) { - g_printerr ("Unable to run session\n"); - exit_status = EX_SOFTWARE; - goto out; - } - -+ if (register_session) { -+ g_debug ("gdm-x-session: Will register session in %d seconds", REGISTER_SESSION_TIMEOUT); -+ state->register_session_id = g_timeout_add_seconds (REGISTER_SESSION_TIMEOUT, -+ register_session_timeout_cb, -+ state); -+ } else { -+ g_debug ("gdm-x-session: Session will register itself"); -+ } -+ - g_main_loop_run (state->main_loop); - - /* Only use exit status of session if we're here because it exit */ - - if (state->session_subprocess == NULL) { - exit_status = state->session_exit_status; - } - - out: - if (state != NULL) { - signal_subprocesses (state); - wait_on_subprocesses (state); - clear_state (&state); - } - - return exit_status; - } --- -2.27.0 - diff --git a/SPECS/gdm.spec b/SPECS/gdm.spec index 5679bd8..92deefd 100644 --- a/SPECS/gdm.spec +++ b/SPECS/gdm.spec @@ -7,135 +7,73 @@ %define desktop_file_utils_version 0.2.90 %define nss_version 3.11.1 +%global tarball_version %%(echo %{version} | tr '~' '.') + Name: gdm Epoch: 1 -Version: 3.28.3 -Release: 39%{?dist} +Version: 40.0 +Release: 15%{?dist} Summary: The GNOME Display Manager License: GPLv2+ URL: https://wiki.gnome.org/Projects/GDM -Source0: http://download.gnome.org/sources/gdm/3.28/gdm-%{version}.tar.xz +Source0: http://download.gnome.org/sources/gdm/40/gdm-%{version}.tar.xz Source1: org.gnome.login-screen.gschema.override -Patch00001: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch -Patch10001: 0001-utils-add-new-gdm-disable-wayland-binary.patch +# Lets customers using vendor nvidia driver pick wayland sessions from the login screen +Patch10001: 0001-local-display-factory-Provide-more-flexibility-for-c.patch +Patch10002: 0002-libgdm-Sort-session-list.patch +Patch10003: 0003-xdmcp-display-factory-Set-supported-session-types-fo.patch -Patch20001: 0001-display-access-file-drop-unused-function.patch +# Race fix +Patch40001: 0001-display-Handle-failure-before-display-registration.patch -Patch30001: 0001-data-disable-wayland-for-proprietary-nvidia-machines.patch -Patch30002: 0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch -Patch30003: 0001-data-enable-wayland-on-cirrus.patch -Patch30004: 0001-data-only-disable-wayland-on-passthrough-virt-setups.patch +# Don't bother building gdm-screenshot, nothing uses it +Patch50001: 0001-utils-Drop-gdm-screenshot.patch -Patch40001: 0001-local-display-factory-pause-for-a-few-seconds-before.patch +# Questionable feature to support logging in over multiple XDMCP consoles at the same time +Patch60001: 0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch +Patch60002: 0002-gdm-x-session-run-session-bus-on-non-seat0-seats.patch +Patch60003: 0003-session-ensure-login-screen-over-XDMCP-connects-to-i.patch -Patch60001: 0001-session-ensure-login-screen-over-XDMCP-connects-to-i.patch +# Upstream change that's moderately risky so revert it +Patch70001: 0001-Revert-gdm-wayland-x-session-don-t-overwrite-user-en.patch -Patch70001: 0001-worker-don-t-load-user-settings-for-program-sessions.patch -Patch70002: 0002-session-support-new-accountsservice-Session-and-Sess.patch -Patch70003: 0003-daemon-save-os-release-in-accountsservice.patch -Patch70004: 0004-daemon-handle-upgrades-from-RHEL-7.patch +# Crash fix +Patch80001: 0001-local-display-factory-Don-t-try-to-respawn-displays-.patch -Patch80001: 0001-session-worker-expose-worker-state-enum-to-type-syst.patch -Patch80002: 0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch -Patch80003: 0003-session-worker-uninitialize-pam-if-worker-is-killed.patch -Patch80004: 0004-data-reap-gdm-sessions-on-shutdown.patch +# Non-upstreamable workarounds +Patch66610001: 0001-local-display-factory-pause-for-a-few-seconds-before.patch +Patch66620001: 0001-data-reap-gdm-sessions-on-shutdown.patch -# CVE-2019-3825 -Patch90001: 0001-manager-don-t-kill-timed-login-session-immediately-a.patch -Patch90002: 0002-manager-session-Add-some-debugging-around-starting-r.patch -Patch90003: 0003-session-Don-t-allow-greeter-operations-on-an-running.patch -Patch90004: 0004-GdmManager-Don-t-perform-timed-login-if-session-gets.patch +# Non-upstreamable integration patches +Patch99910001: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch -Patch100001: 0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch -Patch100002: 0002-gdm-x-session-run-session-bus-on-non-seat0-seats.patch +Patch99920001: 0001-worker-don-t-load-user-settings-for-program-sessions.patch +Patch99920002: 0002-session-support-new-accountsservice-Session-and-Sess.patch +Patch99920003: 0003-daemon-save-os-release-in-accountsservice.patch +Patch99920004: 0004-daemon-handle-upgrades-from-RHEL-7.patch -Patch110001: 0001-display-ask-accountservice-if-there-are-users-rather.patch +Patch99920006: 0001-data-Disable-network-configuration-on-login-screen.patch -Patch120001: 0001-daemon-fix-wayland-detection-when-deciding-to-bypass.patch +Patch99930001: 0001-data-add-system-dconf-databases-to-gdm-profile.patch -# This truckload of patches reworks how VT allocation is done, and makes sure -# the login screen is killed after login -# https://bugzilla.redhat.com/show_bug.cgi?id=1618481 -Patch200001: 0001-display-factory-avoid-removing-a-display-from-store-.patch -Patch200002: 0002-local-display-factory-Add-gdm_local_display_factory_.patch -Patch200003: 0003-local-display-factory-Use-correct-session-type-for-n.patch -Patch200004: 0004-manager-make-get_login_window_session_id-fail-if-no-.patch -Patch200005: 0005-manager-avoid-leaking-session_id.patch -Patch200006: 0006-manager-gracefully-handle-the-case-of-no-session-for.patch -Patch200007: 0007-common-dedupe-gdm_get_login_window_session_id.patch -Patch200008: 0008-common-dedupe-activate_session_id.patch -Patch200009: 0009-manager-plug-leak-in-maybe_activate_other_session.patch -Patch200010: 0010-manager-start-login-screen-if-old-one-is-finished.patch -Patch200011: 0011-manager-don-t-bail-if-session-disappears-out-from-un.patch -Patch200012: 0012-daemon-try-harder-to-get-to-a-login-screen-at-logout.patch -Patch200013: 0013-local-display-factory-ensure-non-seat0-codepath-does.patch -Patch200014: 0014-daemon-kill-and-restart-greeter-on-demand-under-wayl.patch -Patch200015: 0015-local-display-factory-add-more-debug-messages-to-new.patch -Patch200016: 0016-local-display-factory-don-t-start-two-greeters-at-st.patch -Patch200017: 0017-session-worker-don-t-switch-VTs-if-we-re-already-on-.patch -Patch200018: 0018-session-worker-fix-current-vt-detection-short-circui.patch -Patch200019: 0019-local-display-factory-don-t-jump-to-failed-display.patch -Patch200020: 0020-local-display-factory-add-some-more-debug-statements.patch -Patch200021: 0021-local-display-factory-ignore-spurios-SeatNew-signal-.patch -Patch200022: 0022-common-remove-unnecessary-free.patch -Patch200023: 0023-common-don-t-bail-if-session-disappears-out-from-und.patch -Patch200024: 0024-manager-better-logind-handling.patch -Patch200025: 0025-session-worker-clear-VT-before-jumping-to-it.patch -Patch200026: 0026-manager-don-t-set-ran_once-after-running-initial-set.patch -Patch200027: 0027-manager-start-initial-setup-right-away.patch -Patch200028: 0028-gdm-wayland-session-gdm-x-session-register-after-del.patch -Patch200029: 0029-local-display-factory-defer-killing-greeter-until-ne.patch -Patch200030: 0030-daemon-Move-the-waiting-the-session-to-have-taken-ov.patch -Patch200031: 0031-local-display-factory-don-t-autoreap-initial-setup.patch -Patch200032: 0032-manager-rework-how-autologin-is-figured-out.patch -Patch200033: 0033-manager-correct-display-confusion.patch -Patch200034: 0034-manager-don-t-run-autologin-display-on-tty1.patch -Patch200035: 0035-local-display-factory-Remove-initial-VT-is-in-use-ch.patch -Patch200036: 0036-local-display-factory-Remove-same-VT-so-don-t-switch.patch -Patch200037: 0037-local-display-factory-handle-reviving-displays-that-.patch -Patch200038: 0038-manager-don-t-kill-initial-setup-before-starting-use.patch -Patch200039: 0039-manager-do-initial-setup-post-work-in-manager-code.patch -Patch200040: 0040-display-store-make-foreach-ignore-callback-return-va.patch -Patch200041: 0041-xdmcp-display-factory-don-t-return-value-from-foreac.patch -Patch200042: 0042-GdmLocalDisplayFactory-Store-VT-number-not-tty-ident.patch -Patch200043: 0043-gdm-session-worker-Drop-login_vt-assuming-it-is-GDM_.patch -Patch200044: 0044-session-worker-ensure-initial-vt-is-never-picked-for.patch -Patch200045: 0045-local-display-factory-Always-force-login-screen-to-V.patch -Patch200046: 0046-gdm-x-session-tell-x-server-to-not-vt-switch.patch -Patch200047: 0047-local-display-factory-kill-X-on-login-just-like-wayl.patch -Patch200048: 0048-manager-don-t-kill-initial-setup-right-away-with-Xor.patch -Patch200049: 0049-GdmManager-GdmDisplay-Add-RegisterSession-method.patch -Patch200050: 0050-Allow-sessions-to-register-with-GDM.patch -Patch200051: 0051-display-Handle-failure-before-display-registration.patch +Patch99940001: 0001-data-disable-wayland-on-certain-hardware.patch -# CVE-2020-16125 -Patch210001: 0001-display-Exit-with-failure-if-loading-existing-users-.patch - -# CVE-2020-27837 -Patch220001: 0001-session-worker-Don-t-switch-back-VTs-until-session-i.patch - -Patch300001: 0001-manager-Don-t-leak-session-objects.patch -Patch300002: 0002-session-Don-t-leak-remote-greeter-interface.patch -Patch300003: 0003-xdmcp-display-factory-Clear-launch-environment-when-.patch - -Patch900001: 0001-data-add-system-dconf-databases-to-gdm-profile.patch - -BuildRequires: pam-devel >= 0:%{pam_version} +BuildRequires: accountsservice-devel +BuildRequires: audit-libs-devel >= %{libauditver} +BuildRequires: dconf BuildRequires: desktop-file-utils >= %{desktop_file_utils_version} -BuildRequires: libtool automake autoconf -BuildRequires: libattr-devel -BuildRequires: gettext +BuildRequires: gettext-devel BuildRequires: git +BuildRequires: keyutils-libs-devel +BuildRequires: libXdmcp-devel +BuildRequires: libattr-devel BuildRequires: libdmx-devel BuildRequires: audit-libs-devel >= %{libauditver} -BuildRequires: autoconf automake libtool -BuildRequires: intltool -%ifnarch s390 s390x ppc ppc64 -BuildRequires: xorg-x11-server-Xorg -%endif +BuildRequires: meson BuildRequires: nss-devel >= %{nss_version} +BuildRequires: pam-devel >= 0:%{pam_version} BuildRequires: pkgconfig(accountsservice) >= 0.6.3 BuildRequires: pkgconfig(check) BuildRequires: pkgconfig(gobject-introspection-1.0) @@ -149,10 +87,15 @@ BuildRequires: pkgconfig(systemd) BuildRequires: pkgconfig(x11) BuildRequires: pkgconfig(xau) BuildRequires: pkgconfig(xorg-server) -BuildRequires: libXdmcp-devel +BuildRequires: plymouth-devel BuildRequires: systemd -BuildRequires: keyutils-libs-devel -BuildRequires: dconf +BuildRequires: systemd-devel +BuildRequires: which +%ifnarch s390 s390x ppc ppc64 +BuildRequires: xorg-x11-server-Xorg +%endif +BuildRequires: xorg-x11-server-devel +BuildRequires: yelp-tools Requires(pre): /usr/sbin/useradd %{?systemd_requires} @@ -181,6 +124,10 @@ Requires: xorg-x11-xinit Recommends: xorg-x11-server-Xorg Conflicts: xorg-x11-server-Xorg < 1.20.8-4 +# Until the greeter gets dynamic user support, it can't +# use a user bus +Requires: /usr/bin/dbus-run-session + Obsoletes: gdm-libs < 1:3.12.0-3 Provides: gdm-libs%{?_isa} = %{epoch}:%{version}-%{release} @@ -228,33 +175,22 @@ GDM specific authentication features. %prep %autosetup -S git -autoreconf -i -f -intltoolize -f - %build - -%configure --with-pam-prefix=%{_sysconfdir} \ - --with-run-dir=/run/gdm \ - --with-default-path=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin \ - --enable-split-authentication \ - --enable-profiling \ - --enable-console-helper \ - --with-plymouth \ - --with-selinux - -# drop unneeded direct library deps with --as-needed -# libtool doesn't make this easy, so we do it the hard way -sed -i -e 's/ -shared / -Wl,-O1,--as-needed\0 /g' -e 's/ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then/ func_append compile_command " -Wl,-O1,--as-needed"\n func_append finalize_command " -Wl,-O1,--as-needed"\n\0/' libtool - -%make_build - +%meson -Dpam-prefix=%{_sysconfdir} \ + -Drun-dir=/run/gdm \ + -Dudev-dir=%{_udevrulesdir} \ + -Ddefault-path=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin \ + -Dprofiling=true \ + -Dplymouth=enabled \ + -Dselinux=enabled +%meson_build %install mkdir -p %{buildroot}%{_sysconfdir}/gdm/Init mkdir -p %{buildroot}%{_sysconfdir}/gdm/PreSession mkdir -p %{buildroot}%{_sysconfdir}/gdm/PostSession -%make_install +%meson_install install -p -m644 -D %{SOURCE5} %{buildroot}%{_localstatedir}/lib/gdm/.config/pulse/default.pa @@ -266,6 +202,9 @@ cp -a %{SOURCE1} %{buildroot}%{_datadir}/glib-2.0/schemas # docs go elsewhere rm -rf %{buildroot}/%{_prefix}/doc +# we're not doing user sessions in rhel 8 +rm -rf %{buildroot}%{_prefix}/lib/systemd/user + # create log dir mkdir -p %{buildroot}/var/log/gdm @@ -277,10 +216,11 @@ mkdir -p %{buildroot}/run/gdm mkdir -p %{buildroot}%{_sysconfdir}/dconf/db/gdm.d/locks -rm -f %{buildroot}%{_bindir}/gdm-screenshot - -find %{buildroot} -name '*.a' -delete -find %{buildroot} -name '*.la' -delete +cat << EOF > %{buildroot}%{_libexecdir}/gdm-disable-wayland +#!/bin/sh +%{_libexecdir}/gdm-runtime-config set daemon WaylandEnable false +EOF +chmod a+x %{buildroot}%{_libexecdir}/gdm-disable-wayland %find_lang gdm --with-gnome @@ -351,7 +291,7 @@ fi %systemd_postun gdm.service %files -f gdm.lang -%doc AUTHORS NEWS README +%doc AUTHORS NEWS README.md %license COPYING %dir %{_sysconfdir}/gdm %config(noreplace) %{_sysconfdir}/gdm/custom.conf @@ -371,10 +311,10 @@ fi %dir %{_sysconfdir}/gdm/PostLogin %dir %{_sysconfdir}/dconf/db/gdm.d %dir %{_sysconfdir}/dconf/db/gdm.d/locks -%{_datadir}/pixmaps/*.png %{_datadir}/glib-2.0/schemas/org.gnome.login-screen.gschema.xml %{_datadir}/glib-2.0/schemas/org.gnome.login-screen.gschema.override %{_libexecdir}/gdm-disable-wayland +%{_libexecdir}/gdm-runtime-config %{_libexecdir}/gdm-host-chooser %{_libexecdir}/gdm-session-worker %{_libexecdir}/gdm-simple-chooser @@ -394,6 +334,7 @@ fi %{_datadir}/gdm/locale.alias %{_datadir}/gdm/gdb-cmd %{_datadir}/gnome-session/sessions/gnome-login.session +%{_datadir}/polkit-1/rules.d/org.gnome.gdm.rules %{_libdir}/girepository-1.0/Gdm-1.0.typelib %{_libdir}/security/pam_gdm.so %{_libdir}/libgdm*.so* @@ -403,8 +344,6 @@ fi %attr(0700, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.config/pulse %attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.config/pulse/default.pa %attr(0711, root, gdm) %dir /run/gdm -%attr(1755, root, gdm) %dir %{_localstatedir}/cache/gdm -%{_datadir}/icons/hicolor/*/*/*.png %config %{_sysconfdir}/pam.d/gdm-pin %config %{_sysconfdir}/pam.d/gdm-smartcard %config %{_sysconfdir}/pam.d/gdm-fingerprint @@ -425,6 +364,44 @@ fi %{_libdir}/pkgconfig/gdm-pam-extensions.pc %changelog +* Wed Sep 15 2021 Ray Strode - 40.0-14 +- Fix XDMCP + Resolves: #2004170 +- Fix crash at shutdown + Related: #2004170 + +* Wed Sep 01 2021 Ray Strode - 40.0-13 +- Disable Wayland on HyperV +- Fix Xorg fallback + Related: #1998989 + +* Thu Aug 19 2021 Ray Strode - 40.0-12 +- Redisable on server chips since rebase + Related: #1909300 + +* Wed Aug 04 2021 Ray Strode - 40.0-11 +- Read session settings from users even if they've never saved + before. Needed to support accountsservice templated user + defaults. + Related: #1812788 + +* Tue Jul 27 2021 Ray Strode - 40.0-10 +- Let customers using vendor nvidia driver choose wayland sessions + Resolves: #1962211 +- Drop unused patches + +* Tue Jun 08 2021 Florian Müllner - 40.0-3 +- Disable network items on login screen + Resolves: #1935261 + +* Wed May 19 2021 Ray Strode - 40.0-2 +- Fix workaround for systemd bug that's breaking X11 fallback + Resolves: #1962049 + +* Wed May 05 2021 Ray Strode - 40.0-1 +- Rebase to 40.0 + Resolves: #1909300 + * Wed Jan 27 2021 Ray Strode - 3.28.3-39 - Ensure login screen display server is is killed at log in - Pull in fixes for two security issues