import gdm-40.0-15.el8
This commit is contained in:
parent
9f0b1f2881
commit
7de8cc966a
@ -1 +1 @@
|
||||
3c619c91941b2df0362a67b905669f8852106bf5 SOURCES/gdm-3.28.3.tar.xz
|
||||
05c48de8765bde97768b6740417ad6c374c20763 SOURCES/gdm-40.0.tar.xz
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/gdm-3.28.3.tar.xz
|
||||
SOURCES/gdm-40.0.tar.xz
|
||||
|
@ -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 <tiagomatos@gmail.com>
|
||||
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;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
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
|
||||
+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;
|
||||
}
|
||||
|
||||
--
|
||||
2.9.3
|
||||
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.28.0
|
||||
|
||||
|
@ -0,0 +1,241 @@
|
||||
From 85951a0384cb7f37d99669575fad4aea155f25a8 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,135 +0,0 @@
|
||||
From b9f38b65417923624bf97a18daf1c2ede5e8651e Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -0,0 +1,103 @@
|
||||
From cebcf2a4d29f01061dedf8714db2842b9582900c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
|
||||
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
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
From f2ac0603854c7933ecea4a13876fa7e72fd66d1a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
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
|
||||
|
63
SOURCES/0001-data-disable-wayland-on-certain-hardware.patch
Normal file
63
SOURCES/0001-data-disable-wayland-on-certain-hardware.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From e01c0894669f5fe3d1a1c4148b7507e61b95d035 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 13a617e15cca421962be888b5607a9900bbfef51 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 7d9b41f1d82589999f8c89ed3bcc4eec6cee4978 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,55 +0,0 @@
|
||||
From ab9510df0b5f7bc29662804991729c6d6ee38b70 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
55
SOURCES/0001-data-reap-gdm-sessions-on-shutdown.patch
Normal file
55
SOURCES/0001-data-reap-gdm-sessions-on-shutdown.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From 7f910ee7554703a2e775e73ace10ced5d7a0fe66 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,140 +0,0 @@
|
||||
From e339ad74ca408c665a62bb4bd98dd1ef6caedd20 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
|
||||
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
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,206 +0,0 @@
|
||||
From fb55ec1c2e2957eb4c11a220874e5089fd357286 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,269 +0,0 @@
|
||||
From 781e865705b0c134271c9ec21655cd5d8ce37fec Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,433 +0,0 @@
|
||||
From a9422c7b5f4200ad36300bb06134d545bb9d48d2 Mon Sep 17 00:00:00 2001
|
||||
From: Lubomir Rintel <lkundrak@v3.sk>
|
||||
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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#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
|
||||
|
@ -0,0 +1,325 @@
|
||||
From d8fd8d4d6ff6a119f6bd27eb07316384c4776d12 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 <rstrode@redhat.com>
|
||||
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);
|
||||
if (g_strcmp0 (preferred_display_server, "none") == 0) {
|
||||
g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display");
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
ret = sd_seat_can_graphical (seat_id);
|
||||
|
||||
factory->priv->num_failures++;
|
||||
if (ret < 0) {
|
||||
g_critical ("Failed to query CanGraphical information for seat %s", seat_id);
|
||||
return;
|
||||
}
|
||||
|
||||
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");
|
||||
if (ret == 0) {
|
||||
g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics");
|
||||
seat_supports_graphics = FALSE;
|
||||
} else {
|
||||
#ifdef ENABLE_WAYLAND_SUPPORT
|
||||
if (g_strcmp0 (session_type, "wayland") == 0) {
|
||||
g_free (session_type);
|
||||
session_type = NULL;
|
||||
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);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lookup_by_seat_id (const char *id,
|
||||
GdmDisplay *display,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *looking_for = user_data;
|
||||
char *current;
|
||||
gboolean res;
|
||||
/* 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
|
||||
|
||||
|
@ -1,353 +0,0 @@
|
||||
From de229615d80fd7c8a38ab5d5d7b30aa98f43721d Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,28 +1,28 @@
|
||||
From bb58b5762272840a414f2bfe3ab59d733099a06c Mon Sep 17 00:00:00 2001
|
||||
From: rpm-build <rpm-build>
|
||||
From d80807171a457ff87bdc9bd861939161749a37a8 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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),
|
||||
@ -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 @@
|
||||
<schema>
|
||||
<key>xdmcp/DisplaysPerHost</key>
|
||||
<signature>i</signature>
|
||||
@ -338,6 +338,7 @@ index 8ad203101..003f92c63 100644
|
||||
+ </schema>
|
||||
</schemalist>
|
||||
</gdmschemafile>
|
||||
--
|
||||
2.21.1
|
||||
|
||||
--
|
||||
2.30.1
|
||||
|
||||
|
@ -1,87 +0,0 @@
|
||||
From ecd37ba6d56a49dd896613f68d1e1754633b9f0c Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,683 +0,0 @@
|
||||
From 3864af1ea06d2125c1b1f5afa6fc12caa833980a Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <login_cap.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <X11/Xauth.h>
|
||||
|
||||
#include <systemd/sd-daemon.h>
|
||||
|
||||
#ifdef ENABLE_SYSTEMD_JOURNAL
|
||||
#include <systemd/sd-journal.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
#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 @@
|
||||
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
+<node>
|
||||
+ <interface name="org.freedesktop.DBus.Peer">
|
||||
+ <method name="GetMachineId">
|
||||
+ <arg direction="out" type="s"/>
|
||||
+ </method>
|
||||
+ <method name="Ping">
|
||||
+ </method>
|
||||
+ </interface>
|
||||
+</node>
|
||||
+
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,470 +0,0 @@
|
||||
From 521ff70fe447558461dd38cdec62a7c0a5a74f7a Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <glib-object.h>
|
||||
+
|
||||
+/*** 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 <glib-object.h>
|
||||
+
|
||||
+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 <rstrode@redhat.com>
|
||||
*
|
||||
* 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 <glib-object.h>
|
||||
|
||||
#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
|
||||
|
362
SOURCES/0001-utils-Drop-gdm-screenshot.patch
Normal file
362
SOURCES/0001-utils-Drop-gdm-screenshot.patch
Normal file
@ -0,0 +1,362 @@
|
||||
From 7b5ee288d992f85eaefbfbc4dac663a29fcae446 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <jmccann@redhat.com>
|
||||
- *
|
||||
- * 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 <stdlib.h>
|
||||
-#include <stdio.h>
|
||||
-#include <unistd.h>
|
||||
-#include <string.h>
|
||||
-#include <locale.h>
|
||||
-
|
||||
-#include <glib/gi18n.h>
|
||||
-#include <gtk/gtk.h>
|
||||
-#include <canberra-gtk.h>
|
||||
-
|
||||
-#include <X11/Xatom.h>
|
||||
-#include <gdk/gdkx.h>
|
||||
-
|
||||
-#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 <jrb@alum.mit.edu> */
|
||||
-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 <jrb@alum.mit.edu> */
|
||||
-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 <jrb@alum.mit.edu> */
|
||||
-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
|
||||
|
@ -1,161 +0,0 @@
|
||||
From 14656db42a6b4d4d48cf74127f3187dfe85607ec Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <locale.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <sysexits.h>
|
||||
+
|
||||
+#include <glib.h>
|
||||
+
|
||||
+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
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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
|
||||
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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,12 +99,14 @@ 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) {
|
||||
@ -117,49 +122,30 @@ index a8263ba11..55637b378 100644
|
||||
|
||||
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
|
||||
|
||||
|
131
SOURCES/0002-libgdm-Sort-session-list.patch
Normal file
131
SOURCES/0002-libgdm-Sort-session-list.patch
Normal file
@ -0,0 +1,131 @@
|
||||
From 677d370e892788635c4086b139d78499510fa86c Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,164 +0,0 @@
|
||||
From 417f0aed42959719c40f0f8ec65050dcf2510bd1 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,87 +0,0 @@
|
||||
From aeb88313c2110389ec530c8c7d5d816bac24d254 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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
|
||||
</interface>
|
||||
</node>
|
||||
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,
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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;
|
||||
case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
|
||||
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
|
||||
- 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,23 +1254,26 @@ 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,
|
||||
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->priv->saved_session);
|
||||
self->priv->saved_session = g_strdup (session_name);
|
||||
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,
|
||||
if (self->greeter_interface != NULL) {
|
||||
gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface,
|
||||
session_name);
|
||||
}
|
||||
}
|
||||
|
||||
update_session_type (self);
|
||||
if (self->saved_session_type != NULL)
|
||||
set_session_type (self, self->saved_session_type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
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, "wayland", &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
|
||||
|
||||
|
@ -1,922 +0,0 @@
|
||||
From 4db5bf628396a7191f2392e7d09ab9bbd7c2b533 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaoguang Wang <xwang@suse.com>
|
||||
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 <glib-object.h>
|
||||
|
||||
#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
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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 @@
|
||||
+<node>
|
||||
+ <interface name="com.redhat.AccountsServiceUser.System">
|
||||
+
|
||||
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)
|
||||
|
||||
+ <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
|
||||
+
|
||||
+ <property name="id" type="s" access="readwrite"/>
|
||||
+ <property name="version-id" type="s" access="readwrite"/>
|
||||
+
|
||||
+ </interface>
|
||||
+</node>
|
||||
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 @@
|
||||
+<node>
|
||||
+ <interface name="com.redhat.AccountsServiceUser.System">
|
||||
+
|
||||
+ <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
|
||||
+
|
||||
+ <property name="id" type="s" access="readwrite"/>
|
||||
+ <property name="version-id" type="s" access="readwrite"/>
|
||||
+
|
||||
+ </interface>
|
||||
+</node>
|
||||
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
|
||||
|
||||
|
@ -1,83 +0,0 @@
|
||||
From db47f4de3aab9f4cd6b381ecd9341c94add59bf9 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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
|
||||
|
@ -1,227 +0,0 @@
|
||||
From 7b83c1dc9645cabadfeb253d7eca427f6a26d10f Mon Sep 17 00:00:00 2001
|
||||
From: Iain Lane <iainl@gnome.org>
|
||||
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
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,85 +0,0 @@
|
||||
From 1987a539495f38ade3efc561f65b56316080356e Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,87 +0,0 @@
|
||||
From 7c9e236f9015aae2ea5868b67ff8036766cb7099 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -0,0 +1,122 @@
|
||||
From e3a7ca44c0153ffa895786eabb020810b138eea2 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,105 +0,0 @@
|
||||
From 15a19ac7856c539aa9cfbf76997d18b0275aae35 Mon Sep 17 00:00:00 2001
|
||||
From: Iain Lane <iainl@gnome.org>
|
||||
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
|
||||
|
@ -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 <rstrode@redhat.com>
|
||||
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);
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
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.27.0
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
From f32adbe9bf26d502cb055b3a6cb98fc57e06bf13 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,137 +0,0 @@
|
||||
From e2e5d2a7d73baa7c24d1f14b276cb653c06dd82f Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,79 +0,0 @@
|
||||
From 34238a9e845455ae2b92159c71b75b7abedc2eb9 Mon Sep 17 00:00:00 2001
|
||||
From: Lubomir Rintel <lkundrak@v3.sk>
|
||||
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
|
||||
|
@ -1,89 +0,0 @@
|
||||
From 454a3daad5148a8ef30cb298af82aa0713e73af7 Mon Sep 17 00:00:00 2001
|
||||
From: Lubomir Rintel <lkundrak@v3.sk>
|
||||
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
|
||||
|
@ -1,432 +0,0 @@
|
||||
From 2fc9a5f9db7c9d2ab828bcff4ee5dec9c3cf3d3c Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <errno.h>
|
||||
|
||||
#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
|
||||
|
@ -1,401 +0,0 @@
|
||||
From 9d8e72ea9171566e9d74caaf28c8b5933ef34874 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <mccann@jhu.edu>
|
||||
*
|
||||
* 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 <glib-unix.h>
|
||||
+#include <gio/gio.h>
|
||||
+
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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
|
||||
|
@ -1,103 +0,0 @@
|
||||
From 5bc19a4eb6de02ba549252026911dcce86e0fc21 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,92 +0,0 @@
|
||||
From 2ec1b65c7bc2cefeabbd9a7a3a50436e1233804c Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,127 +0,0 @@
|
||||
From 67d29b19ff4e53d58879b14c2e79a3bda419576f Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,563 +0,0 @@
|
||||
From 9a3e9cb9a6bbf68ed6eb9f13d143a63af940f3ae Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <mccann@jhu.edu>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
+#include <systemd/sd-login.h>
|
||||
+
|
||||
#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
|
||||
|
@ -1,87 +0,0 @@
|
||||
From 299a0981f4e9fc02716d64abf5e5e692e2ad2951 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,369 +0,0 @@
|
||||
From 08f5f88ca6fb0edfc94af4c85912484b6048691b Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <hdegoede@redhat.com>
|
||||
|
||||
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
|
||||
|
@ -1,235 +0,0 @@
|
||||
From 59533722f1749d4e71360c5d717a18006c1f64c0 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,97 +0,0 @@
|
||||
From e5bf6d78ff8f54bbb74e572f05ccbf1c0df24017 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,128 +0,0 @@
|
||||
From de4b24f63e62a39b2cb10a8c58c54d86559f7f26 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,87 +0,0 @@
|
||||
From b9e5a2879a410b6a85be6c01c6f49cd7eb24c800 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,168 +0,0 @@
|
||||
From fe680d77cff9272843cb171c7e590c239f7afe5a Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,161 +0,0 @@
|
||||
From 94207dd5699f1cd2fe7d516c20e1de2b2e2778fb Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,162 +0,0 @@
|
||||
From abd8e1ef71d093a3ab5c110aea5fa2012d59d5e2 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,91 +0,0 @@
|
||||
From 9b8c21080286f943d0a19431bc8c0061f4833443 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,133 +0,0 @@
|
||||
From 4a948e4b203fdf5fcd9b5e53dd4a80ef2786c0cd Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,138 +0,0 @@
|
||||
From fac23cfa3e8e9fe21563733c0c1b739ddecead8a Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,90 +0,0 @@
|
||||
From cabcd21c17ca98e517a3eea7c9d5ce269445e3e0 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,133 +0,0 @@
|
||||
From b773eb570d8c5f9d2222ee39eecbc6a622d108d8 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,418 +0,0 @@
|
||||
From 3d4199f82136e7046b5b08fc7c583e3fce2d04a2 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,309 +0,0 @@
|
||||
From 3073c23c673ede5093c1f93fb0775c2cd3203d7f Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,399 +0,0 @@
|
||||
From d85448e2e523deb1487e7e405a480e1c4e6a5f6f Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
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
|
||||
|
@ -1,708 +0,0 @@
|
||||
From 0ff911467265831006aac6216060dbecff84c1cb Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
#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
|
||||
|
@ -1,100 +0,0 @@
|
||||
From 59b3b809400dfac25410cf99dbc15cb5f66f85a3 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,460 +0,0 @@
|
||||
From 566720ce07db8745c0ae6780ff289292dc0a9b60 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,85 +0,0 @@
|
||||
From 05e49542a9de81731fce68614babe22d437e8fff Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,99 +0,0 @@
|
||||
From e4c9a998f89d429d31b02997f146c8218c0742bc Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,110 +0,0 @@
|
||||
From 2843a951ef826afd01fa3c7340780b1929db38c7 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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
|
||||
|
@ -1,140 +0,0 @@
|
||||
From f5acee2766c05403235c06da6b1bb68af744da79 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,88 +0,0 @@
|
||||
From 59a4538e335362a92186217be03529f3694697e1 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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
|
||||
|
@ -1,151 +0,0 @@
|
||||
From c65a0dbd195be52f0db0c49ea0355fe1b5eb4c09 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,694 +0,0 @@
|
||||
From c08afca0807d8820030c19a40e7590f72878c788 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#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 <glib-object.h>
|
||||
|
||||
#include <act/act-user-manager.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
#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
|
||||
|
@ -1,117 +0,0 @@
|
||||
From 49383786d96414e7204ea50ca5ea0263be97b581 Mon Sep 17 00:00:00 2001
|
||||
From: xiaoguang wang <xwang@suse.com>
|
||||
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
|
||||
|
@ -1,180 +0,0 @@
|
||||
From 323358ef61d969588ea048d5b0eba6fd102d3dcf Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,538 +0,0 @@
|
||||
From 3cf5b4b12d3d39fa858ff593adeecfe711cdddaf Mon Sep 17 00:00:00 2001
|
||||
From: Iain Lane <iainl@gnome.org>
|
||||
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=<nr>],
|
||||
[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
|
||||
|
@ -1,344 +0,0 @@
|
||||
From 476230f7b721781c682d26983c9a2fd82afc45e1 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Berg <bberg@redhat.com>
|
||||
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 <iainl@gnome.org>,
|
||||
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
|
||||
|
@ -1,160 +0,0 @@
|
||||
From 75b65846ca77bd2d42e25365b4b7242a406330cf Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,114 +0,0 @@
|
||||
From fc3503f16e9de535d2a36b904720b360370f880f Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 763e31a576a4cd665e5ad06ad0eb4610cecc0b42 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,115 +0,0 @@
|
||||
From a1c74e2e42dea464ab0b439b767da5c12cbf3986 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,149 +0,0 @@
|
||||
From f1b7d85b46dfc253176d6a043dcce26da3a26dfb Mon Sep 17 00:00:00 2001
|
||||
From: Ray Strode <rstrode@redhat.com>
|
||||
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
|
||||
|
@ -1,551 +0,0 @@
|
||||
From 2724b4fd6d4ac527acc481f056f535141b63fe24 Mon Sep 17 00:00:00 2001
|
||||
From: Iain Lane <iainl@gnome.org>
|
||||
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 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node name="/org/gnome/DisplayManager/Manager">
|
||||
<interface name="org.gnome.DisplayManager.Manager">
|
||||
<method name="RegisterDisplay">
|
||||
<arg name="details" direction="in" type="a{ss}"/>
|
||||
</method>
|
||||
+ <method name="RegisterSession">
|
||||
+ <arg name="details" direction="in" type="a{sv}"/>
|
||||
+ </method>
|
||||
<method name="OpenSession">
|
||||
<arg name="address" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="OpenReauthenticationChannel">
|
||||
<arg name="username" direction="in" type="s"/>
|
||||
<arg name="address" direction="out" type="s"/>
|
||||
</method>
|
||||
<property name="Version" type="s" access="read"/>
|
||||
</interface>
|
||||
</node>
|
||||
--
|
||||
2.28.0
|
||||
|
File diff suppressed because it is too large
Load Diff
247
SPECS/gdm.spec
247
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 <rstrode@redhat.com> - 40.0-14
|
||||
- Fix XDMCP
|
||||
Resolves: #2004170
|
||||
- Fix crash at shutdown
|
||||
Related: #2004170
|
||||
|
||||
* Wed Sep 01 2021 Ray Strode <rstrode@redhat.com> - 40.0-13
|
||||
- Disable Wayland on HyperV
|
||||
- Fix Xorg fallback
|
||||
Related: #1998989
|
||||
|
||||
* Thu Aug 19 2021 Ray Strode <rstrode@redhat.com> - 40.0-12
|
||||
- Redisable on server chips since rebase
|
||||
Related: #1909300
|
||||
|
||||
* Wed Aug 04 2021 Ray Strode <rstrode@redhat.com> - 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 <rstrode@redhat.com> - 40.0-10
|
||||
- Let customers using vendor nvidia driver choose wayland sessions
|
||||
Resolves: #1962211
|
||||
- Drop unused patches
|
||||
|
||||
* Tue Jun 08 2021 Florian Müllner <fmuellner@redhat.com> - 40.0-3
|
||||
- Disable network items on login screen
|
||||
Resolves: #1935261
|
||||
|
||||
* Wed May 19 2021 Ray Strode <rstrode@redhat.com> - 40.0-2
|
||||
- Fix workaround for systemd bug that's breaking X11 fallback
|
||||
Resolves: #1962049
|
||||
|
||||
* Wed May 05 2021 Ray Strode <rstrode@redhat.com> - 40.0-1
|
||||
- Rebase to 40.0
|
||||
Resolves: #1909300
|
||||
|
||||
* Wed Jan 27 2021 Ray Strode <rstrode@redhat.com> - 3.28.3-39
|
||||
- Ensure login screen display server is is killed at log in
|
||||
- Pull in fixes for two security issues
|
||||
|
Loading…
Reference in New Issue
Block a user