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>
|
From: Rui Matos <tiagomatos@gmail.com>
|
||||||
Date: Mon, 23 Jan 2017 20:19:51 +0100
|
Date: Mon, 23 Jan 2017 20:19:51 +0100
|
||||||
Subject: [PATCH] Honor initial setup being disabled by distro installer
|
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
|
https://bugzilla.gnome.org/show_bug.cgi?id=777708
|
||||||
---
|
---
|
||||||
daemon/Makefile.am | 1 +
|
|
||||||
daemon/gdm-display.c | 29 +++++++++++++++++++++++++++++
|
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
|
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
|
--- a/daemon/gdm-display.c
|
||||||
+++ b/daemon/gdm-display.c
|
+++ b/daemon/gdm-display.c
|
||||||
@@ -1456,6 +1456,31 @@ can_create_environment (const char *session_id)
|
@@ -1591,103 +1591,132 @@ kernel_cmdline_initial_setup_force_state (gboolean *force_state)
|
||||||
|
GError *error = NULL;
|
||||||
|
gchar *contents = NULL;
|
||||||
|
gchar *setup_argument = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (force_state != NULL, FALSE);
|
||||||
|
|
||||||
|
if (!g_file_get_contents ("/proc/cmdline", &contents, NULL, &error)) {
|
||||||
|
g_debug ("GdmDisplay: Could not check kernel parameters, not forcing initial setup: %s",
|
||||||
|
error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("GdmDisplay: Checking kernel command buffer %s", contents);
|
||||||
|
|
||||||
|
if (!kernel_cmdline_initial_setup_argument (contents, &setup_argument, &error)) {
|
||||||
|
g_debug ("GdmDisplay: Failed to read kernel commandline: %s", error->message);
|
||||||
|
g_clear_pointer (&contents, g_free);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_pointer (&contents, g_free);
|
||||||
|
|
||||||
|
/* Poor-man's check for truthy or falsey values */
|
||||||
|
*force_state = setup_argument[0] == '1';
|
||||||
|
|
||||||
|
g_free (setup_argument);
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
+static gboolean
|
||||||
+initial_setup_disabled_by_anaconda (void)
|
+initial_setup_disabled_by_anaconda (void)
|
||||||
+{
|
+{
|
||||||
+ GKeyFile *key_file;
|
+ GKeyFile *key_file;
|
||||||
@ -62,11 +77,46 @@ index 0057e2c..2af8e13 100644
|
|||||||
+ return disabled;
|
+ return disabled;
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+static gboolean
|
static gboolean
|
||||||
wants_initial_setup (GdmDisplay *self)
|
wants_initial_setup (GdmDisplay *self)
|
||||||
{
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
gboolean enabled = FALSE;
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +127,33 @@ index 0057e2c..2af8e13 100644
|
|||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdm_display_start_greeter_session (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
GdmSession *session;
|
||||||
|
char *display_name;
|
||||||
|
char *seat_id;
|
||||||
|
char *hostname;
|
||||||
|
char *auth_file = NULL;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
g_return_if_fail (g_strcmp0 (priv->session_class, "greeter") == 0);
|
||||||
|
|
||||||
|
g_debug ("GdmDisplay: Running greeter");
|
||||||
|
|
||||||
|
display_name = NULL;
|
||||||
|
seat_id = NULL;
|
||||||
|
hostname = NULL;
|
||||||
|
|
||||||
|
g_object_get (self,
|
||||||
|
"x11-display-name", &display_name,
|
||||||
|
"seat-id", &seat_id,
|
||||||
|
"remote-hostname", &hostname,
|
||||||
|
NULL);
|
||||||
|
if (priv->access_file != NULL) {
|
||||||
|
auth_file = gdm_display_access_file_get_path (priv->access_file);
|
||||||
|
}
|
||||||
--
|
--
|
||||||
2.9.3
|
2.28.0
|
||||||
|
|
||||||
|
@ -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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Wed, 31 Jul 2013 17:32:55 -0400
|
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.
|
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(+)
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
diff --git a/data/dconf/gdm.in b/data/dconf/gdm.in
|
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
|
--- a/data/dconf/gdm.in
|
||||||
+++ b/data/dconf/gdm.in
|
+++ b/data/dconf/gdm.in
|
||||||
@@ -1,2 +1,6 @@
|
@@ -1,2 +1,6 @@
|
||||||
@ -20,5 +20,5 @@ index 4d8bf1748..606e0b863 100644
|
|||||||
+system-db:distro
|
+system-db:distro
|
||||||
file-db:@DATADIR@/@PACKAGE@/greeter-dconf-defaults
|
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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Tue, 1 Sep 2020 13:49:27 -0400
|
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
|
Normally, e.g., gdm-wayland-session would register its display
|
||||||
before starting the session. This display registration is how
|
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(-)
|
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
|
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
|
--- a/daemon/gdm-display.c
|
||||||
+++ b/daemon/gdm-display.c
|
+++ b/daemon/gdm-display.c
|
||||||
@@ -575,80 +575,79 @@ gdm_display_disconnect (GdmDisplay *self)
|
@@ -648,62 +648,60 @@ gdm_display_disconnect (GdmDisplay *self)
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup = xcb_get_setup (self->priv->xcb_connection);
|
|
||||||
|
|
||||||
/* resource_id_mask is the bits given to each client for
|
/* resource_id_mask is the bits given to each client for
|
||||||
* addressing resources */
|
* addressing resources */
|
||||||
@ -38,40 +34,43 @@ index ae20491cd..b8ccbbd72 100644
|
|||||||
client += client_increment) {
|
client += client_increment) {
|
||||||
|
|
||||||
if (client != setup->resource_id_base)
|
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
|
gboolean
|
||||||
gdm_display_unmanage (GdmDisplay *self)
|
gdm_display_unmanage (GdmDisplay *self)
|
||||||
{
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
|
||||||
- g_debug ("GdmDisplay: unmanage display");
|
- g_debug ("GdmDisplay: unmanage display");
|
||||||
-
|
-
|
||||||
gdm_display_disconnect (self);
|
gdm_display_disconnect (self);
|
||||||
|
|
||||||
if (self->priv->user_access_file != NULL) {
|
if (priv->user_access_file != NULL) {
|
||||||
gdm_display_access_file_close (self->priv->user_access_file);
|
gdm_display_access_file_close (priv->user_access_file);
|
||||||
g_object_unref (self->priv->user_access_file);
|
g_object_unref (priv->user_access_file);
|
||||||
self->priv->user_access_file = NULL;
|
priv->user_access_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->priv->access_file != NULL) {
|
if (priv->access_file != NULL) {
|
||||||
gdm_display_access_file_close (self->priv->access_file);
|
gdm_display_access_file_close (priv->access_file);
|
||||||
g_object_unref (self->priv->access_file);
|
g_object_unref (priv->access_file);
|
||||||
self->priv->access_file = NULL;
|
priv->access_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self->priv->session_registered) {
|
if (!priv->session_registered) {
|
||||||
g_warning ("GdmDisplay: Session never registered, failing");
|
g_warning ("GdmDisplay: Session never registered, failing");
|
||||||
_gdm_display_set_status (self, GDM_DISPLAY_FAILED);
|
_gdm_display_set_status (self, GDM_DISPLAY_FAILED);
|
||||||
} else {
|
} else {
|
||||||
+ g_debug ("GdmDisplay: Unmanage display");
|
|
||||||
_gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
|
_gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,31 +82,13 @@ index ae20491cd..b8ccbbd72 100644
|
|||||||
char **id,
|
char **id,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
GdmDisplayPrivate *priv;
|
||||||
|
@@ -1446,63 +1444,63 @@ gdm_display_get_object_skeleton (GdmDisplay *self)
|
||||||
if (id != NULL) {
|
|
||||||
*id = g_strdup (self->priv->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
gdm_display_get_x11_display_name (GdmDisplay *self,
|
|
||||||
char **x11_display,
|
|
||||||
GError **error)
|
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
if (x11_display != NULL) {
|
priv = gdm_display_get_instance_private (self);
|
||||||
*x11_display = g_strdup (self->priv->x11_display_name);
|
return priv->object_skeleton;
|
||||||
}
|
|
||||||
@@ -1309,63 +1308,62 @@ gdm_display_finalize (GObject *object)
|
|
||||||
|
|
||||||
GDBusObjectSkeleton *
|
|
||||||
gdm_display_get_object_skeleton (GdmDisplay *self)
|
|
||||||
{
|
|
||||||
return self->priv->object_skeleton;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -136,6 +117,7 @@ index ae20491cd..b8ccbbd72 100644
|
|||||||
- if (gdm_display_get_status (self) == GDM_DISPLAY_MANAGED) {
|
- if (gdm_display_get_status (self) == GDM_DISPLAY_MANAGED) {
|
||||||
- gdm_display_unmanage (self);
|
- gdm_display_unmanage (self);
|
||||||
- }
|
- }
|
||||||
|
+
|
||||||
+ g_debug ("GdmDisplay: initiating display self-destruct");
|
+ g_debug ("GdmDisplay: initiating display self-destruct");
|
||||||
+ gdm_display_unmanage (self);
|
+ gdm_display_unmanage (self);
|
||||||
|
|
||||||
@ -169,5 +151,5 @@ index ae20491cd..b8ccbbd72 100644
|
|||||||
{
|
{
|
||||||
g_debug ("GdmDisplay: Greeter died: %d", signal);
|
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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Mon, 29 Oct 2018 06:57:59 -0400
|
Date: Mon, 29 Oct 2018 06:57:59 -0400
|
||||||
Subject: [PATCH] local-display-factory: pause for a few seconds before falling
|
Subject: [PATCH] local-display-factory: pause for a few seconds before
|
||||||
back to X
|
falling back to X
|
||||||
|
|
||||||
logind currently gets confused if a session is started immediately as
|
logind currently gets confused if a session is started immediately as
|
||||||
one is shutting down.
|
one is shutting down.
|
||||||
@ -12,79 +12,81 @@ back to X.
|
|||||||
|
|
||||||
http://bugzilla.redhat.com/1643874
|
http://bugzilla.redhat.com/1643874
|
||||||
---
|
---
|
||||||
daemon/gdm-local-display-factory.c | 5 +++++
|
daemon/gdm-local-display-factory.c | 7 +++++++
|
||||||
1 file changed, 5 insertions(+)
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
|
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
|
--- a/daemon/gdm-local-display-factory.c
|
||||||
+++ b/daemon/gdm-local-display-factory.c
|
+++ b/daemon/gdm-local-display-factory.c
|
||||||
@@ -283,60 +283,65 @@ on_display_status_changed (GdmDisplay *display,
|
@@ -653,60 +653,67 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
|
||||||
/* if this is a local display, do a full resync. Only
|
preferred_display_server = get_preferred_display_server (factory);
|
||||||
* 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);
|
if (g_strcmp0 (preferred_display_server, "none") == 0) {
|
||||||
}
|
g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display");
|
||||||
break;
|
return;
|
||||||
case GDM_DISPLAY_FAILED:
|
|
||||||
/* leave the display number in factory->priv->used_display_numbers
|
|
||||||
so that it doesn't get reused */
|
|
||||||
gdm_display_store_remove (store, display);
|
|
||||||
|
|
||||||
/* Create a new equivalent display if it was static */
|
|
||||||
if (is_local) {
|
|
||||||
|
|
||||||
factory->priv->num_failures++;
|
|
||||||
|
|
||||||
if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) {
|
|
||||||
/* oh shit */
|
|
||||||
g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors");
|
|
||||||
} else {
|
|
||||||
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
||||||
if (g_strcmp0 (session_type, "wayland") == 0) {
|
|
||||||
g_free (session_type);
|
|
||||||
session_type = NULL;
|
|
||||||
+
|
|
||||||
+ /* workaround logind race for now
|
|
||||||
+ * bug 1643874
|
|
||||||
+ */
|
|
||||||
+ g_usleep (2 * G_USEC_PER_SEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
create_display (factory, seat_id, session_type, is_initial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GDM_DISPLAY_UNMANAGED:
|
|
||||||
break;
|
|
||||||
case GDM_DISPLAY_PREPARED:
|
|
||||||
break;
|
|
||||||
case GDM_DISPLAY_MANAGED:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (seat_id);
|
ret = sd_seat_can_graphical (seat_id);
|
||||||
g_free (session_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
if (ret < 0) {
|
||||||
lookup_by_seat_id (const char *id,
|
g_critical ("Failed to query CanGraphical information for seat %s", seat_id);
|
||||||
GdmDisplay *display,
|
return;
|
||||||
gpointer user_data)
|
}
|
||||||
{
|
|
||||||
const char *looking_for = user_data;
|
if (ret == 0) {
|
||||||
char *current;
|
g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics");
|
||||||
gboolean res;
|
seat_supports_graphics = FALSE;
|
||||||
|
} else {
|
||||||
|
g_debug ("GdmLocalDisplayFactory: System supports graphics");
|
||||||
|
seat_supports_graphics = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strcmp0 (seat_id, "seat0") == 0) {
|
||||||
|
is_seat0 = TRUE;
|
||||||
|
|
||||||
|
falling_back = factory->num_failures > 0;
|
||||||
|
session_types = gdm_local_display_factory_get_session_types (factory, falling_back);
|
||||||
|
|
||||||
|
g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
|
||||||
|
session_types[0], falling_back? " fallback" : "");
|
||||||
|
+
|
||||||
|
+ if (falling_back) {
|
||||||
|
+ /* workaround logind race for now
|
||||||
|
+ * bug 1643874
|
||||||
|
+ */
|
||||||
|
+ g_usleep (2 * G_USEC_PER_SEC);
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
is_seat0 = FALSE;
|
||||||
|
|
||||||
|
g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id);
|
||||||
|
/* Force legacy X11 for all auxiliary seats */
|
||||||
|
seat_supports_graphics = TRUE;
|
||||||
|
session_types = g_strdupv ((char **) legacy_session_types);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For seat0, we have a fallback logic to still try starting it after
|
||||||
|
* SEAT0_GRAPHICS_CHECK_TIMEOUT seconds. i.e. we simply continue even if
|
||||||
|
* CanGraphical is unset.
|
||||||
|
* This is ugly, but it means we'll come up eventually in some
|
||||||
|
* scenarios where no master device is present.
|
||||||
|
* Note that we'll force an X11 fallback even though there might be
|
||||||
|
* cases where an wayland capable device is present and simply not marked as
|
||||||
|
* master-of-seat. In these cases, this should likely be fixed in the
|
||||||
|
* udev rules.
|
||||||
|
*
|
||||||
|
* At the moment, systemd always sets CanGraphical for non-seat0 seats.
|
||||||
|
* This is because non-seat0 seats are defined by having master-of-seat
|
||||||
|
* set. This means we can avoid the fallback check for non-seat0 seats,
|
||||||
|
* which simplifies the code.
|
||||||
|
*/
|
||||||
|
if (is_seat0) {
|
||||||
|
if (!seat_supports_graphics) {
|
||||||
|
if (!factory->seat0_graphics_check_timed_out) {
|
||||||
|
if (factory->seat0_graphics_check_timeout_id == 0) {
|
||||||
|
g_debug ("GdmLocalDisplayFactory: seat0 doesn't yet support graphics. Waiting %d seconds to try again.", SEAT0_GRAPHICS_CHECK_TIMEOUT);
|
||||||
|
factory->seat0_graphics_check_timeout_id = g_timeout_add_seconds (SEAT0_GRAPHICS_CHECK_TIMEOUT,
|
||||||
--
|
--
|
||||||
2.19.1
|
2.27.0
|
||||||
|
|
||||||
|
@ -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 d80807171a457ff87bdc9bd861939161749a37a8 Mon Sep 17 00:00:00 2001
|
||||||
From: rpm-build <rpm-build>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Thu, 20 Dec 2018 14:51:38 -0500
|
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 +
|
common/gdm-settings-keys.h | 1 +
|
||||||
daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++----------
|
daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++----------
|
||||||
data/gdm.schemas.in.in | 5 +++
|
data/gdm.schemas.in | 5 +++
|
||||||
3 files changed, 59 insertions(+), 18 deletions(-)
|
3 files changed, 59 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
|
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
|
--- a/common/gdm-settings-keys.h
|
||||||
+++ b/common/gdm-settings-keys.h
|
+++ b/common/gdm-settings-keys.h
|
||||||
@@ -28,37 +28,38 @@ G_BEGIN_DECLS
|
@@ -30,37 +30,38 @@ G_BEGIN_DECLS
|
||||||
#define GDM_KEY_USER "daemon/User"
|
|
||||||
#define GDM_KEY_GROUP "daemon/Group"
|
|
||||||
#define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
|
#define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
|
||||||
#define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
|
#define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
|
||||||
#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
|
#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
|
||||||
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
|
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
|
||||||
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
|
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
|
||||||
#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable"
|
#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_WAYLAND_ENABLE "daemon/WaylandEnable"
|
||||||
|
#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable"
|
||||||
|
|
||||||
#define GDM_KEY_DEBUG "debug/Enable"
|
#define GDM_KEY_DEBUG "debug/Enable"
|
||||||
|
|
||||||
@ -53,11 +53,10 @@ index f0059b5cf..33676a851 100644
|
|||||||
|
|
||||||
#endif /* _GDM_SETTINGS_KEYS_H */
|
#endif /* _GDM_SETTINGS_KEYS_H */
|
||||||
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
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
|
--- a/daemon/gdm-manager.c
|
||||||
+++ b/daemon/gdm-manager.c
|
+++ b/daemon/gdm-manager.c
|
||||||
@@ -594,93 +594,106 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
@@ -566,93 +566,106 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
||||||
if (out_tty != NULL) {
|
|
||||||
*out_tty = get_tty_for_session_id (session_id, &error);
|
*out_tty = get_tty_for_session_id (session_id, &error);
|
||||||
|
|
||||||
if (error != NULL) {
|
if (error != NULL) {
|
||||||
@ -71,10 +70,11 @@ index 056560b20..de7357ad5 100644
|
|||||||
lookup_by_session_id,
|
lookup_by_session_id,
|
||||||
(gpointer) session_id);
|
(gpointer) session_id);
|
||||||
|
|
||||||
|
out:
|
||||||
if (out_display != NULL) {
|
if (out_display != NULL) {
|
||||||
*out_display = display;
|
*out_display = display;
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
g_free (session_id);
|
g_free (session_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ index 056560b20..de7357ad5 100644
|
|||||||
- if (existing_session != NULL) {
|
- if (existing_session != NULL) {
|
||||||
- ssid_to_activate = gdm_session_get_session_id (existing_session);
|
- ssid_to_activate = gdm_session_get_session_id (existing_session);
|
||||||
- if (seat_id != NULL) {
|
- 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) {
|
- if (! res) {
|
||||||
- g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
|
- g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
|
||||||
- goto out;
|
- goto out;
|
||||||
@ -138,7 +138,7 @@ index 056560b20..de7357ad5 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
+ if (seat_id != NULL) {
|
+ 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) {
|
+ if (! res) {
|
||||||
+ g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
|
+ g_debug ("GdmManager: unable to activate session: %s", ssid_to_activate);
|
||||||
+ goto out;
|
+ goto out;
|
||||||
@ -181,7 +181,7 @@ index 056560b20..de7357ad5 100644
|
|||||||
{
|
{
|
||||||
const char *username;
|
const char *username;
|
||||||
char *display_name, *hostname, *display_device;
|
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,
|
g_signal_connect (session,
|
||||||
"client-disconnected",
|
"client-disconnected",
|
||||||
G_CALLBACK (on_reauthentication_client_disconnected),
|
G_CALLBACK (on_reauthentication_client_disconnected),
|
||||||
@ -263,7 +263,7 @@ index 056560b20..de7357ad5 100644
|
|||||||
+ G_DBUS_ERROR,
|
+ G_DBUS_ERROR,
|
||||||
+ G_DBUS_ERROR_ACCESS_DENIED,
|
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||||
+ "Login screen creates new sessions for remote connections");
|
+ "Login screen creates new sessions for remote connections");
|
||||||
+ return TRUE;
|
+ return TRUE;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
if (is_login_screen) {
|
if (is_login_screen) {
|
||||||
@ -296,11 +296,11 @@ index 056560b20..de7357ad5 100644
|
|||||||
pid,
|
pid,
|
||||||
uid,
|
uid,
|
||||||
is_remote);
|
is_remote);
|
||||||
diff --git a/data/gdm.schemas.in.in b/data/gdm.schemas.in.in
|
diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in
|
||||||
index 8ad203101..003f92c63 100644
|
index a1035f95e..929d13d90 100644
|
||||||
--- a/data/gdm.schemas.in.in
|
--- a/data/gdm.schemas.in
|
||||||
+++ b/data/gdm.schemas.in.in
|
+++ b/data/gdm.schemas.in
|
||||||
@@ -102,32 +102,37 @@
|
@@ -112,33 +112,38 @@
|
||||||
<schema>
|
<schema>
|
||||||
<key>xdmcp/DisplaysPerHost</key>
|
<key>xdmcp/DisplaysPerHost</key>
|
||||||
<signature>i</signature>
|
<signature>i</signature>
|
||||||
@ -338,6 +338,7 @@ index 8ad203101..003f92c63 100644
|
|||||||
+ </schema>
|
+ </schema>
|
||||||
</schemalist>
|
</schemalist>
|
||||||
</gdmschemafile>
|
</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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Wed, 15 Aug 2018 10:48:16 -0400
|
Date: Wed, 15 Aug 2018 10:48:16 -0400
|
||||||
Subject: [PATCH 1/4] worker: don't load user settings for program sessions
|
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
|
We don't need or want the login greeter to access accountsservice
|
||||||
for its session name
|
for its session name
|
||||||
---
|
---
|
||||||
daemon/gdm-session-worker.c | 38 +++++++++++++++++++++++++------------
|
daemon/gdm-session-worker.c | 37 ++++++++++++++++++++++++++-----------
|
||||||
1 file changed, 26 insertions(+), 12 deletions(-)
|
1 file changed, 26 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
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
|
--- a/daemon/gdm-session-worker.c
|
||||||
+++ b/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
|
static gboolean
|
||||||
gdm_session_worker_get_username (GdmSessionWorker *worker,
|
gdm_session_worker_get_username (GdmSessionWorker *worker,
|
||||||
@ -124,12 +124,12 @@ index c1d89cab2..e79073996 100644
|
|||||||
worker->priv->service,
|
worker->priv->service,
|
||||||
question,
|
question,
|
||||||
answerp,
|
answerp,
|
||||||
@@ -2475,87 +2480,89 @@ gdm_session_worker_get_property (GObject *object,
|
@@ -2600,87 +2605,89 @@ gdm_session_worker_get_property (GObject *object,
|
||||||
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);
|
g_value_set_boolean (value, self->priv->is_reauth_session);
|
||||||
break;
|
break;
|
||||||
|
case PROP_STATE:
|
||||||
|
g_value_set_enum (value, self->priv->state);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -218,7 +218,8 @@ index c1d89cab2..e79073996 100644
|
|||||||
g_free (session_name);
|
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;
|
worker->priv->pending_invocation = NULL;
|
||||||
}
|
}
|
||||||
@ -248,7 +249,8 @@ index c1d89cab2..e79073996 100644
|
|||||||
g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED);
|
g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED);
|
||||||
|
|
||||||
g_debug ("GdmSessionWorker: saving account details for user %s", worker->priv->username);
|
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,
|
- if (!gdm_session_settings_save (worker->priv->user_settings,
|
||||||
- worker->priv->username)) {
|
- worker->priv->username)) {
|
||||||
- g_warning ("could not save session and language settings");
|
- 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);
|
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) {
|
if (g_strcmp0 (key, "service") == 0) {
|
||||||
worker->priv->service = g_variant_dup_string (value, NULL);
|
worker->priv->service = g_variant_dup_string (value, NULL);
|
||||||
} else if (g_strcmp0 (key, "extensions") == 0) {
|
} else if (g_strcmp0 (key, "extensions") == 0) {
|
||||||
@ -496,7 +498,7 @@ index c1d89cab2..e79073996 100644
|
|||||||
GDBusMethodInvocation *invocation,
|
GDBusMethodInvocation *invocation,
|
||||||
const char *service,
|
const char *service,
|
||||||
const char *username,
|
const char *username,
|
||||||
@@ -3459,98 +3474,97 @@ static void
|
@@ -3591,61 +3607,60 @@ static void
|
||||||
reauthentication_request_free (ReauthenticationRequest *request)
|
reauthentication_request_free (ReauthenticationRequest *request)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -558,44 +560,6 @@ index c1d89cab2..e79073996 100644
|
|||||||
|
|
||||||
g_return_if_fail (worker->priv != NULL);
|
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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Wed, 5 Feb 2020 15:20:48 -0500
|
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
|
GNOME doesn't deal very well with multiple sessions
|
||||||
running on a multiple seats at the moment.
|
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
|
Until that's fixed, ensure sessions run on auxillary
|
||||||
seats get their own session bus.
|
seats get their own session bus.
|
||||||
---
|
---
|
||||||
daemon/gdm-session.c | 17 +++++++++++++----
|
daemon/gdm-session.c | 11 ++++++++++-
|
||||||
1 file changed, 13 insertions(+), 4 deletions(-)
|
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
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
|
--- a/daemon/gdm-session.c
|
||||||
+++ b/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) ||
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) ||
|
||||||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
return;
|
return;
|
||||||
@ -25,8 +25,8 @@ index a8263ba11..55637b378 100644
|
|||||||
service_name = conversation->service_name;
|
service_name = conversation->service_name;
|
||||||
|
|
||||||
if (worked) {
|
if (worked) {
|
||||||
self->priv->session_pid = pid;
|
self->session_pid = pid;
|
||||||
self->priv->session_conversation = conversation;
|
self->session_conversation = conversation;
|
||||||
|
|
||||||
g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", pid);
|
g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", pid);
|
||||||
g_signal_emit (self, signals[SESSION_STARTED], 0, service_name, 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;
|
+ gboolean run_separate_bus = FALSE;
|
||||||
char *command;
|
char *command;
|
||||||
char *program;
|
char *program;
|
||||||
|
gboolean register_session;
|
||||||
|
|
||||||
g_return_if_fail (GDM_IS_SESSION (self));
|
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);
|
conversation = find_conversation_by_name (self, service_name);
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ index a8263ba11..55637b378 100644
|
|||||||
display_mode = gdm_session_get_display_mode (self);
|
display_mode = gdm_session_get_display_mode (self);
|
||||||
|
|
||||||
#ifdef ENABLE_WAYLAND_SUPPORT
|
#ifdef ENABLE_WAYLAND_SUPPORT
|
||||||
is_x11 = g_strcmp0 (self->priv->session_type, "wayland") != 0;
|
is_x11 = g_strcmp0 (self->session_type, "wayland") != 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (display_mode == GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED ||
|
if (display_mode == GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED ||
|
||||||
@ -75,18 +76,20 @@ index a8263ba11..55637b378 100644
|
|||||||
run_launcher = TRUE;
|
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;
|
+ run_separate_bus = TRUE;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
if (self->priv->selected_program == NULL) {
|
if (self->selected_program == NULL) {
|
||||||
gboolean run_xsession_script;
|
gboolean run_xsession_script;
|
||||||
|
|
||||||
command = get_session_command (self);
|
command = get_session_command (self);
|
||||||
|
|
||||||
run_xsession_script = !gdm_session_bypasses_xsession (self);
|
run_xsession_script = !gdm_session_bypasses_xsession (self);
|
||||||
|
|
||||||
if (self->priv->display_is_local) {
|
if (self->display_is_local) {
|
||||||
gboolean disallow_tcp = TRUE;
|
gboolean disallow_tcp = TRUE;
|
||||||
gdm_settings_direct_get_boolean (GDM_KEY_DISALLOW_TCP, &disallow_tcp);
|
gdm_settings_direct_get_boolean (GDM_KEY_DISALLOW_TCP, &disallow_tcp);
|
||||||
allow_remote_connections = !disallow_tcp;
|
allow_remote_connections = !disallow_tcp;
|
||||||
@ -96,70 +99,53 @@ index a8263ba11..55637b378 100644
|
|||||||
|
|
||||||
if (run_launcher) {
|
if (run_launcher) {
|
||||||
if (is_x11) {
|
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 " : "",
|
run_xsession_script? "--run-script " : "",
|
||||||
allow_remote_connections? "--allow-remote-connections " : "",
|
allow_remote_connections? "--allow-remote-connections " : "",
|
||||||
command);
|
command);
|
||||||
} else {
|
} 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);
|
command);
|
||||||
}
|
}
|
||||||
} else if (run_xsession_script) {
|
} else if (run_xsession_script) {
|
||||||
- program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
|
- program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
|
||||||
+ if (run_separate_bus) {
|
+ if (run_separate_bus) {
|
||||||
+ program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command);
|
+ program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
|
+ program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
|
||||||
+ }
|
+ }
|
||||||
} else {
|
} else {
|
||||||
program = g_strdup (command);
|
program = g_strdup (command);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (command);
|
g_free (command);
|
||||||
} else {
|
} 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 (run_launcher) {
|
||||||
if (is_x11) {
|
if (is_x11) {
|
||||||
- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"",
|
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"dbus-run-session -- %s\"",
|
||||||
- self->priv->selected_program);
|
register_session ? "--register-session " : "",
|
||||||
+ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session \"%s\"",
|
self->selected_program);
|
||||||
+ self->priv->selected_program);
|
|
||||||
} else {
|
} else {
|
||||||
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session \"%s\"",
|
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"dbus-run-session -- %s\"",
|
||||||
self->priv->selected_program);
|
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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Tue, 14 Aug 2018 14:52:41 -0400
|
Date: Tue, 14 Aug 2018 14:52:41 -0400
|
||||||
Subject: [PATCH 2/4] session: support new accountsservice Session and
|
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.
|
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-settings.h | 3 ++
|
||||||
daemon/gdm-session-worker.c | 28 +++++++++++++
|
daemon/gdm-session-worker.c | 28 +++++++++++
|
||||||
daemon/gdm-session-worker.xml | 3 ++
|
daemon/gdm-session-worker.xml | 3 ++
|
||||||
daemon/gdm-session.c | 78 ++++++++++++++++++++++++++---------
|
daemon/gdm-session.c | 87 +++++++++++++++++++++++++----------
|
||||||
5 files changed, 148 insertions(+), 25 deletions(-)
|
5 files changed, 153 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
|
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
|
--- a/daemon/gdm-session-settings.c
|
||||||
+++ b/daemon/gdm-session-settings.c
|
+++ b/daemon/gdm-session-settings.c
|
||||||
@@ -12,114 +12,121 @@
|
@@ -12,114 +12,121 @@
|
||||||
@ -79,7 +79,9 @@ index 933f095bc..8463fad32 100644
|
|||||||
PROP_IS_LOADED
|
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
|
static void
|
||||||
gdm_session_settings_class_init (GdmSessionSettingsClass *settings_class)
|
gdm_session_settings_class_init (GdmSessionSettingsClass *settings_class)
|
||||||
@ -91,8 +93,6 @@ index 933f095bc..8463fad32 100644
|
|||||||
object_class->finalize = gdm_session_settings_finalize;
|
object_class->finalize = gdm_session_settings_finalize;
|
||||||
|
|
||||||
gdm_session_settings_class_install_properties (settings_class);
|
gdm_session_settings_class_install_properties (settings_class);
|
||||||
|
|
||||||
g_type_class_add_private (settings_class, sizeof (GdmSessionSettingsPrivate));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -107,7 +107,7 @@ index 933f095bc..8463fad32 100644
|
|||||||
|
|
||||||
param_spec = g_param_spec_string ("session-name", "Session Name",
|
param_spec = g_param_spec_string ("session-name", "Session Name",
|
||||||
"The name of the session",
|
"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);
|
g_object_class_install_property (object_class, PROP_SESSION_NAME, param_spec);
|
||||||
|
|
||||||
+ param_spec = g_param_spec_string ("session-type", "Session Type",
|
+ 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",
|
param_spec = g_param_spec_string ("language-name", "Language Name",
|
||||||
"The name of the language",
|
"The name of the language",
|
||||||
NULL,
|
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);
|
g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec);
|
||||||
|
|
||||||
param_spec = g_param_spec_boolean ("is-loaded", NULL, NULL,
|
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);
|
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);
|
- session_name = act_user_get_x_session (settings->priv->user);
|
||||||
- g_debug ("GdmSessionSettings: saved session is %s", session_name);
|
- 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))
|
- if (session_name != NULL) {
|
||||||
+ goto out;
|
+
|
||||||
|
+
|
||||||
+
|
+
|
||||||
+ session_type = act_user_get_session_type (settings->priv->user);
|
+ session_type = act_user_get_session_type (settings->priv->user);
|
||||||
+ session_name = act_user_get_session (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);
|
+ g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type);
|
||||||
+
|
+
|
||||||
+ if (session_type != NULL && session_type[0] != '\0') {
|
+ if (session_type != NULL && session_type[0] != '\0') {
|
||||||
@ -409,7 +409,7 @@ index 933f095bc..8463fad32 100644
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
diff --git a/daemon/gdm-session-settings.h b/daemon/gdm-session-settings.h
|
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
|
--- a/daemon/gdm-session-settings.h
|
||||||
+++ b/daemon/gdm-session-settings.h
|
+++ b/daemon/gdm-session-settings.h
|
||||||
@@ -33,37 +33,40 @@ G_BEGIN_DECLS
|
@@ -33,37 +33,40 @@ G_BEGIN_DECLS
|
||||||
@ -454,10 +454,10 @@ index 20946bff1..db38ffc72 100644
|
|||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* GDM_SESSION_SETTINGS_H */
|
#endif /* GDM_SESSION_SETTINGS_H */
|
||||||
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
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
|
--- a/daemon/gdm-session-worker.c
|
||||||
+++ b/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);
|
gdm_dbus_worker_complete_set_language_name (object, invocation);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -532,7 +532,7 @@ index e79073996..ae86d28ac 100644
|
|||||||
static void
|
static void
|
||||||
do_authenticate (GdmSessionWorker *worker)
|
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) {
|
} else if (g_strcmp0 (key, "x11-authority-file") == 0) {
|
||||||
worker->priv->x11_authority_file = g_variant_dup_string (value, NULL);
|
worker->priv->x11_authority_file = g_variant_dup_string (value, NULL);
|
||||||
} else if (g_strcmp0 (key, "console") == 0) {
|
} else if (g_strcmp0 (key, "console") == 0) {
|
||||||
@ -706,7 +706,7 @@ index e79073996..ae86d28ac 100644
|
|||||||
const char *log_file)
|
const char *log_file)
|
||||||
{
|
{
|
||||||
diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml
|
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
|
--- a/daemon/gdm-session-worker.xml
|
||||||
+++ b/daemon/gdm-session-worker.xml
|
+++ b/daemon/gdm-session-worker.xml
|
||||||
@@ -51,40 +51,43 @@
|
@@ -51,40 +51,43 @@
|
||||||
@ -754,12 +754,10 @@ index 4280fe095..a215779c8 100644
|
|||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
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
|
--- a/daemon/gdm-session.c
|
||||||
+++ b/daemon/gdm-session.c
|
+++ b/daemon/gdm-session.c
|
||||||
@@ -59,60 +59,61 @@
|
@@ -61,60 +61,61 @@
|
||||||
|
|
||||||
#define GDM_SESSION_DBUS_ERROR_CANCEL "org.gnome.DisplayManager.Session.Error.Cancel"
|
|
||||||
#define GDM_SESSION_DBUS_OBJECT_PATH "/org/gnome/DisplayManager/Session"
|
#define GDM_SESSION_DBUS_OBJECT_PATH "/org/gnome/DisplayManager/Session"
|
||||||
|
|
||||||
#define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker"
|
#define GDM_WORKER_DBUS_PATH "/org/gnome/DisplayManager/Worker"
|
||||||
@ -782,8 +780,10 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
GPid reauth_pid_of_caller;
|
GPid reauth_pid_of_caller;
|
||||||
} GdmSessionConversation;
|
} GdmSessionConversation;
|
||||||
|
|
||||||
struct _GdmSessionPrivate
|
struct _GdmSession
|
||||||
{
|
{
|
||||||
|
GObject parent;
|
||||||
|
|
||||||
/* per open scope */
|
/* per open scope */
|
||||||
char *selected_program;
|
char *selected_program;
|
||||||
char *selected_session;
|
char *selected_session;
|
||||||
@ -819,25 +819,14 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
char *display_name;
|
char *display_name;
|
||||||
char *display_hostname;
|
char *display_hostname;
|
||||||
char *display_device;
|
char *display_device;
|
||||||
@@ -312,295 +313,310 @@ on_establish_credentials_cb (GdmDBusWorker *proxy,
|
@@ -328,309 +329,325 @@ on_establish_credentials_cb (GdmDBusWorker *proxy,
|
||||||
return;
|
|
||||||
|
|
||||||
self = g_object_ref (conversation->session);
|
|
||||||
service_name = g_strdup (conversation->service_name);
|
|
||||||
|
|
||||||
if (worked) {
|
|
||||||
if (self->priv->user_verifier_interface != NULL) {
|
|
||||||
gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface,
|
|
||||||
service_name);
|
|
||||||
g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (self->priv->verification_mode) {
|
|
||||||
case GDM_SESSION_VERIFICATION_MODE_LOGIN:
|
|
||||||
case GDM_SESSION_VERIFICATION_MODE_CHOOSER:
|
|
||||||
gdm_session_open_session (self, service_name);
|
|
||||||
break;
|
|
||||||
case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
|
case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
|
||||||
|
if (self->user_verifier_interface != NULL) {
|
||||||
|
gdm_dbus_user_verifier_emit_verification_complete (self->user_verifier_interface,
|
||||||
|
service_name);
|
||||||
|
g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -849,6 +838,17 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
g_object_unref (self);
|
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 **
|
static char **
|
||||||
-get_system_session_dirs (GdmSession *self)
|
-get_system_session_dirs (GdmSession *self)
|
||||||
+get_system_session_dirs (GdmSession *self,
|
+get_system_session_dirs (GdmSession *self,
|
||||||
@ -856,6 +856,8 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
{
|
{
|
||||||
GArray *search_array = NULL;
|
GArray *search_array = NULL;
|
||||||
char **search_dirs;
|
char **search_dirs;
|
||||||
|
int i, j;
|
||||||
|
const gchar * const *system_data_dirs = g_get_system_data_dirs ();
|
||||||
|
|
||||||
static const char *x_search_dirs[] = {
|
static const char *x_search_dirs[] = {
|
||||||
"/etc/X11/sessions/",
|
"/etc/X11/sessions/",
|
||||||
@ -868,20 +870,33 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
|
|
||||||
search_array = g_array_new (TRUE, TRUE, sizeof (char *));
|
search_array = g_array_new (TRUE, TRUE, sizeof (char *));
|
||||||
|
|
||||||
- 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++) {
|
||||||
+ if (type == NULL || strcmp (type, "x11") == 0)
|
const char *supported_type = self->supported_session_types[j];
|
||||||
+ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
|
|
||||||
|
- if (g_str_equal (supported_type, "x11")) {
|
||||||
|
+ 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
|
#ifdef ENABLE_WAYLAND_SUPPORT
|
||||||
- if (!self->priv->ignore_wayland) {
|
- if (g_str_equal (supported_type, "wayland")) {
|
||||||
+ if ((!self->priv->ignore_wayland && type == NULL) || g_strcmp0 (type, "wayland") == 0) {
|
+ if (g_str_equal (supported_type, "wayland") ||
|
||||||
#ifdef ENABLE_USER_DISPLAY_SERVER
|
+ (type == NULL || g_str_equal (type, supported_type))) {
|
||||||
g_array_prepend_val (search_array, wayland_search_dir);
|
for (i = 0; system_data_dirs[i]; i++) {
|
||||||
#else
|
gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
|
||||||
g_array_append_val (search_array, wayland_search_dir);
|
g_array_append_val (search_array, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_append_val (search_array, wayland_search_dir);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
search_dirs = g_strdupv ((char **) search_array->data);
|
search_dirs = g_strdupv ((char **) search_array->data);
|
||||||
|
|
||||||
@ -961,9 +976,9 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
*command = NULL;
|
*command = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ if (self->priv->ignore_wayland && g_strcmp0 (type, "wayland") == 0) {
|
+ if (!supports_session_type (self, type)) {
|
||||||
+ g_debug ("GdmSession: ignoring wayland session command request for file '%s'",
|
+ g_debug ("GdmSession: ignoring %s session command request for file '%s'",
|
||||||
+ file);
|
+ type, file);
|
||||||
+ goto out;
|
+ goto out;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@ -1046,11 +1061,11 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
{
|
{
|
||||||
const char *default_language;
|
const char *default_language;
|
||||||
|
|
||||||
if (self->priv->saved_language != NULL) {
|
if (self->saved_language != NULL) {
|
||||||
return self->priv->saved_language;
|
return self->saved_language;
|
||||||
}
|
}
|
||||||
|
|
||||||
default_language = g_hash_table_lookup (self->priv->environment,
|
default_language = g_hash_table_lookup (self->environment,
|
||||||
"LANG");
|
"LANG");
|
||||||
|
|
||||||
if (default_language != NULL) {
|
if (default_language != NULL) {
|
||||||
@ -1069,10 +1084,10 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
GSequence *sessions;
|
GSequence *sessions;
|
||||||
GSequenceIter *session;
|
GSequenceIter *session;
|
||||||
|
|
||||||
if (self->priv->fallback_session_name != NULL) {
|
if (self->fallback_session_name != NULL) {
|
||||||
/* verify that the cached version still exists */
|
/* 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->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, NULL)) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1080,8 +1095,8 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
name = g_strdup ("gnome");
|
name = g_strdup ("gnome");
|
||||||
- if (get_session_command_for_name (self, name, NULL)) {
|
- if (get_session_command_for_name (self, name, NULL)) {
|
||||||
+ if (get_session_command_for_name (self, name, NULL, NULL)) {
|
+ if (get_session_command_for_name (self, name, NULL, NULL)) {
|
||||||
g_free (self->priv->fallback_session_name);
|
g_free (self->fallback_session_name);
|
||||||
self->priv->fallback_session_name = name;
|
self->fallback_session_name = name;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
g_free (name);
|
g_free (name);
|
||||||
@ -1136,27 +1151,24 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
session = g_sequence_iter_next (session);
|
session = g_sequence_iter_next (session);
|
||||||
} while (!g_sequence_iter_is_end (session));
|
} while (!g_sequence_iter_is_end (session));
|
||||||
|
|
||||||
g_free (self->priv->fallback_session_name);
|
g_free (self->fallback_session_name);
|
||||||
self->priv->fallback_session_name = g_strdup (name);
|
self->fallback_session_name = g_strdup (name);
|
||||||
|
|
||||||
g_sequence_free (sessions);
|
g_sequence_free (sessions);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return self->priv->fallback_session_name;
|
return self->fallback_session_name;
|
||||||
@@ -616,60 +632,63 @@ get_default_session_name (GdmSession *self)
|
@@ -649,60 +666,63 @@ get_default_session_name (GdmSession *self)
|
||||||
return get_fallback_session_name (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdm_session_defaults_changed (GdmSession *self)
|
gdm_session_defaults_changed (GdmSession *self)
|
||||||
{
|
{
|
||||||
|
|
||||||
update_session_type (self);
|
update_session_type (self);
|
||||||
|
|
||||||
if (self->priv->greeter_interface != NULL) {
|
if (self->greeter_interface != NULL) {
|
||||||
gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface,
|
gdm_dbus_greeter_emit_default_language_name_changed (self->greeter_interface,
|
||||||
get_default_language_name (self));
|
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));
|
get_default_session_name (self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1166,19 +1178,22 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
const char *text)
|
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);
|
g_free (self->selected_user);
|
||||||
self->priv->selected_user = g_strdup (text);
|
self->selected_user = g_strdup (text);
|
||||||
|
|
||||||
g_free (self->priv->saved_session);
|
g_free (self->saved_session);
|
||||||
self->priv->saved_session = NULL;
|
self->saved_session = NULL;
|
||||||
|
|
||||||
+ g_free (self->priv->saved_session_type);
|
+ g_free (self->saved_session_type);
|
||||||
+ self->priv->saved_session_type = NULL;
|
+ self->saved_session_type = NULL;
|
||||||
+
|
+
|
||||||
g_free (self->priv->saved_language);
|
g_free (self->saved_language);
|
||||||
self->priv->saved_language = NULL;
|
self->saved_language = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1207,7 +1222,7 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
set_pending_query (GdmSessionConversation *conversation,
|
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;
|
GdmSession *self = conversation->session;
|
||||||
g_debug ("GdmSession: Emitting 'reauthenticated' signal ");
|
g_debug ("GdmSession: Emitting 'reauthenticated' signal ");
|
||||||
g_signal_emit (self, signals[REAUTHENTICATED], 0, service_name);
|
g_signal_emit (self, signals[REAUTHENTICATED], 0, service_name);
|
||||||
@ -1221,11 +1236,11 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
GdmSession *self = conversation->session;
|
GdmSession *self = conversation->session;
|
||||||
|
|
||||||
if (strlen (language_name) > 0) {
|
if (strlen (language_name) > 0) {
|
||||||
g_free (self->priv->saved_language);
|
g_free (self->saved_language);
|
||||||
self->priv->saved_language = g_strdup (language_name);
|
self->saved_language = g_strdup (language_name);
|
||||||
|
|
||||||
if (self->priv->greeter_interface != NULL) {
|
if (self->greeter_interface != NULL) {
|
||||||
gdm_dbus_greeter_emit_default_language_name_changed (self->priv->greeter_interface,
|
gdm_dbus_greeter_emit_default_language_name_changed (self->greeter_interface,
|
||||||
language_name);
|
language_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1239,24 +1254,27 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
GdmSession *self = conversation->session;
|
GdmSession *self = conversation->session;
|
||||||
|
|
||||||
- if (! get_session_command_for_name (self, session_name, NULL)) {
|
- 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 */
|
/* ignore sessions that don't exist */
|
||||||
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
|
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
|
||||||
g_free (self->priv->saved_session);
|
g_free (self->saved_session);
|
||||||
self->priv->saved_session = NULL;
|
self->saved_session = NULL;
|
||||||
} else if (strcmp (session_name,
|
update_session_type (self);
|
||||||
get_default_session_name (self)) != 0) {
|
} else {
|
||||||
g_free (self->priv->saved_session);
|
if (strcmp (session_name,
|
||||||
self->priv->saved_session = g_strdup (session_name);
|
get_default_session_name (self)) != 0) {
|
||||||
|
g_free (self->saved_session);
|
||||||
|
self->saved_session = g_strdup (session_name);
|
||||||
|
|
||||||
if (self->priv->greeter_interface != NULL) {
|
if (self->greeter_interface != NULL) {
|
||||||
gdm_dbus_greeter_emit_default_session_name_changed (self->priv->greeter_interface,
|
gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface,
|
||||||
session_name);
|
session_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (self->saved_session_type != NULL)
|
||||||
|
set_session_type (self, self->saved_session_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_session_type (self);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+static void
|
+static void
|
||||||
@ -1266,8 +1284,8 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
+{
|
+{
|
||||||
+ GdmSession *self = conversation->session;
|
+ GdmSession *self = conversation->session;
|
||||||
+
|
+
|
||||||
+ g_free (self->priv->saved_session_type);
|
+ g_free (self->saved_session_type);
|
||||||
+ self->priv->saved_session_type = g_strdup (session_type);
|
+ self->saved_session_type = g_strdup (session_type);
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
static GdmSessionConversation *
|
static GdmSessionConversation *
|
||||||
@ -1277,7 +1295,7 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
gpointer key, value;
|
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)) {
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
GdmSessionConversation *conversation;
|
GdmSessionConversation *conversation;
|
||||||
|
|
||||||
@ -1300,7 +1318,7 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
uid_t connecting_user;
|
uid_t connecting_user;
|
||||||
|
|
||||||
connecting_user = g_credentials_get_unix_user (credentials, NULL);
|
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);
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||||
|
|
||||||
conversation->worker_proxy = gdm_dbus_worker_proxy_new_sync (connection,
|
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_debug ("GdmSession: Emitting conversation-started signal");
|
||||||
g_signal_emit (self, signals[CONVERSATION_STARTED], 0, conversation->service_name);
|
g_signal_emit (self, signals[CONVERSATION_STARTED], 0, conversation->service_name);
|
||||||
|
|
||||||
if (self->priv->user_verifier_interface != NULL) {
|
if (self->user_verifier_interface != NULL) {
|
||||||
gdm_dbus_user_verifier_emit_conversation_started (self->priv->user_verifier_interface,
|
gdm_dbus_user_verifier_emit_conversation_started (self->user_verifier_interface,
|
||||||
conversation->service_name);
|
conversation->service_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1364,9 +1382,9 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
g_debug ("GdmSession: Conversation started");
|
g_debug ("GdmSession: Conversation started");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -1804,60 +1837,63 @@ static void
|
@@ -1921,60 +1955,63 @@ free_conversation (GdmSessionConversation *conversation)
|
||||||
free_conversation (GdmSessionConversation *conversation)
|
close_conversation (conversation);
|
||||||
{
|
|
||||||
if (conversation->job != NULL) {
|
if (conversation->job != NULL) {
|
||||||
g_warning ("Freeing conversation '%s' with active job", conversation->service_name);
|
g_warning ("Freeing conversation '%s' with active job", conversation->service_name);
|
||||||
}
|
}
|
||||||
@ -1428,7 +1446,7 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
error = NULL;
|
error = NULL;
|
||||||
if (!g_file_get_contents (config_file, &contents, &length, &error)) {
|
if (!g_file_get_contents (config_file, &contents, &length, &error)) {
|
||||||
g_debug ("Failed to parse '%s': %s",
|
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));
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||||||
|
|
||||||
conversation = find_conversation_by_name (self, service_name);
|
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? */
|
/* FIXME: test the session names before we use them? */
|
||||||
|
|
||||||
if (self->priv->selected_session != NULL) {
|
if (self->selected_session != NULL) {
|
||||||
return self->priv->selected_session;
|
return self->selected_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_default_session_name (self);
|
return get_default_session_name (self);
|
||||||
@ -1476,7 +1494,7 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
GKeyFile *keyfile;
|
GKeyFile *keyfile;
|
||||||
gchar *desktop_names = NULL;
|
gchar *desktop_names = NULL;
|
||||||
|
|
||||||
if (self->priv->selected_program != NULL) {
|
if (self->selected_program != NULL) {
|
||||||
return g_strdup ("GNOME-Greeter:GNOME");
|
return g_strdup ("GNOME-Greeter:GNOME");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1509,13 +1527,12 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
g_return_if_fail (key != NULL);
|
g_return_if_fail (key != NULL);
|
||||||
g_return_if_fail (value != 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 (key),
|
||||||
g_strdup (value));
|
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);
|
conversation = find_conversation_by_name (self, service_name);
|
||||||
|
|
||||||
if (conversation == NULL) {
|
if (conversation == NULL) {
|
||||||
@ -1545,11 +1562,16 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
|
|
||||||
filename = get_session_filename (self);
|
filename = get_session_filename (self);
|
||||||
|
|
||||||
- key_file = load_key_file_for_file (self, filename, &full_path);
|
if (supports_session_type (self, "wayland")) {
|
||||||
+ key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
|
- key_file = load_key_file_for_file (self, filename, &full_path);
|
||||||
|
+ key_file = load_key_file_for_file (self, filename, NULL, &full_path);
|
||||||
|
|
||||||
if (key_file == NULL) {
|
- if (key_file == NULL) {
|
||||||
goto out;
|
- goto out;
|
||||||
|
- }
|
||||||
|
+ if (key_file == NULL) {
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
|
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");
|
g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free);
|
g_clear_pointer (&key_file, g_key_file_free);
|
||||||
g_free (filename);
|
g_free (filename);
|
||||||
return is_wayland_session;
|
return is_wayland_session;
|
||||||
}
|
}
|
||||||
@ -1571,7 +1593,7 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
- gboolean is_wayland_session;
|
- gboolean is_wayland_session;
|
||||||
+ gboolean is_wayland_session = FALSE;
|
+ 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);
|
||||||
|
|
||||||
- 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
|
#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
|
gboolean
|
||||||
gdm_session_bypasses_xsession (GdmSession *self)
|
gdm_session_bypasses_xsession (GdmSession *self)
|
||||||
{
|
{
|
||||||
@ -1632,10 +1687,10 @@ index 19d26c92e..e6640aac7 100644
|
|||||||
gdm_session_get_display_mode (GdmSession *self)
|
gdm_session_get_display_mode (GdmSession *self)
|
||||||
{
|
{
|
||||||
g_debug ("GdmSession: type %s, program? %s, seat %s",
|
g_debug ("GdmSession: type %s, program? %s, seat %s",
|
||||||
self->priv->session_type,
|
self->session_type,
|
||||||
self->priv->is_program_session? "yes" : "no",
|
self->is_program_session? "yes" : "no",
|
||||||
self->priv->display_seat_id);
|
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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Mon, 20 Aug 2018 14:30:59 -0400
|
Date: Mon, 20 Aug 2018 14:30:59 -0400
|
||||||
Subject: [PATCH 3/4] daemon: save os-release in accountsservice
|
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.
|
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 ++
|
.../com.redhat.AccountsServiceUser.System.xml | 10 ++
|
||||||
4 files changed, 120 insertions(+)
|
daemon/gdm-session-settings.c | 98 +++++++++++++++++++
|
||||||
create mode 100644 data/com.redhat.AccountsServiceUser.System.xml
|
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
|
diff --git a/daemon/com.redhat.AccountsServiceUser.System.xml b/daemon/com.redhat.AccountsServiceUser.System.xml
|
||||||
index 3b1b15122..b77c9276e 100644
|
new file mode 100644
|
||||||
--- a/daemon/Makefile.am
|
index 00000000..67f5f302
|
||||||
+++ b/daemon/Makefile.am
|
--- /dev/null
|
||||||
@@ -14,137 +14,147 @@ AM_CPPFLAGS = \
|
+++ b/daemon/com.redhat.AccountsServiceUser.System.xml
|
||||||
-DLIBEXECDIR=\"$(libexecdir)\" \
|
@@ -0,0 +1,10 @@
|
||||||
-DLOCALSTATEDIR=\"$(localstatedir)\" \
|
+<node>
|
||||||
-DLOGDIR=\"$(logdir)\" \
|
+ <interface name="com.redhat.AccountsServiceUser.System">
|
||||||
-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
|
|
||||||
+
|
+
|
||||||
noinst_PROGRAMS = \
|
+ <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
|
||||||
test-session-client \
|
+
|
||||||
$(NULL)
|
+ <property name="id" type="s" access="readwrite"/>
|
||||||
|
+ <property name="version-id" type="s" access="readwrite"/>
|
||||||
test_session_client_SOURCES = \
|
+
|
||||||
test-session-client.c \
|
+ </interface>
|
||||||
$(NULL)
|
+</node>
|
||||||
|
|
||||||
nodist_test_session_client_SOURCES = \
|
|
||||||
gdm-session-glue.h \
|
|
||||||
gdm-session-glue.c \
|
|
||||||
gdm-manager-glue.h \
|
|
||||||
gdm-manager-glue.c \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
test_session_client_LDADD = \
|
|
||||||
$(DAEMON_LIBS) \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
libexec_PROGRAMS = \
|
|
||||||
gdm-session-worker \
|
|
||||||
gdm-wayland-session \
|
|
||||||
gdm-x-session \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
gdm_session_worker_SOURCES = \
|
|
||||||
session-worker-main.c \
|
|
||||||
+ com.redhat.AccountsServiceUser.System.h \
|
|
||||||
+ com.redhat.AccountsServiceUser.System.c \
|
|
||||||
gdm-session.c \
|
|
||||||
gdm-session.h \
|
|
||||||
gdm-session-settings.h \
|
|
||||||
gdm-session-settings.c \
|
|
||||||
gdm-session-auditor.h \
|
|
||||||
gdm-session-auditor.c \
|
|
||||||
gdm-session-record.c \
|
|
||||||
gdm-session-record.h \
|
|
||||||
gdm-session-worker.h \
|
|
||||||
gdm-session-worker.c \
|
|
||||||
gdm-session-worker-job.c \
|
|
||||||
gdm-session-worker-common.c \
|
|
||||||
gdm-session-worker-common.h \
|
|
||||||
gdm-dbus-util.c \
|
|
||||||
gdm-dbus-util.h \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
if SUPPORTS_PAM_EXTENSIONS
|
|
||||||
gdm_session_worker_SOURCES += $(top_srcdir)/pam-extensions/gdm-pam-extensions.h
|
|
||||||
endif
|
|
||||||
|
|
||||||
nodist_gdm_session_worker_SOURCES = \
|
|
||||||
gdm-session-glue.h \
|
|
||||||
gdm-session-glue.c \
|
|
||||||
gdm-session-worker-glue.c \
|
|
||||||
gdm-session-worker-glue.h \
|
|
||||||
gdm-session-enum-types.c \
|
|
||||||
gdm-session-enum-types.h \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
|
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
|
--- a/daemon/gdm-session-settings.c
|
||||||
+++ b/daemon/gdm-session-settings.c
|
+++ b/daemon/gdm-session-settings.c
|
||||||
@@ -1,70 +1,77 @@
|
@@ -1,70 +1,77 @@
|
||||||
@ -245,15 +109,15 @@ index 8463fad32..921e4d501 100644
|
|||||||
PROP_IS_LOADED
|
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
|
@@ -107,60 +114,62 @@ gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings
|
||||||
g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec);
|
g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec);
|
||||||
|
|
||||||
param_spec = g_param_spec_boolean ("is-loaded", NULL, NULL,
|
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);
|
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_type = act_user_get_session_type (settings->priv->user);
|
||||||
session_name = act_user_get_session (settings->priv->user);
|
session_name = act_user_get_session (settings->priv->user);
|
||||||
@ -536,89 +400,212 @@ index 8463fad32..921e4d501 100644
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
diff --git a/data/Makefile.am b/data/Makefile.am
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||||||
index 192dfa052..d69021985 100644
|
index 43da024f..c8e04c1b 100644
|
||||||
--- a/data/Makefile.am
|
--- a/daemon/gdm-session.c
|
||||||
+++ b/data/Makefile.am
|
+++ b/daemon/gdm-session.c
|
||||||
@@ -8,60 +8,62 @@ SUBDIRS = \
|
@@ -351,72 +351,72 @@ supports_session_type (GdmSession *self,
|
||||||
$(NULL)
|
if (session_type == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
initdir = $(gdmconfdir)/Init
|
return g_strv_contains ((const char * const *) self->supported_session_types,
|
||||||
postdir = $(gdmconfdir)/PostSession
|
session_type);
|
||||||
predir = $(gdmconfdir)/PreSession
|
}
|
||||||
postlogindir = $(gdmconfdir)/PostLogin
|
|
||||||
workingdir = $(GDM_WORKING_DIR)
|
|
||||||
xauthdir = $(GDM_XAUTH_DIR)
|
|
||||||
screenshotdir = $(GDM_SCREENSHOT_DIR)
|
|
||||||
cachedir = $(localstatedir)/cache/gdm
|
|
||||||
|
|
||||||
Init: $(srcdir)/Init.in
|
static char **
|
||||||
sed -e 's,[@]X_PATH[@],$(X_PATH),g' \
|
get_system_session_dirs (GdmSession *self,
|
||||||
<$(srcdir)/Init.in >Init
|
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
|
static const char *x_search_dirs[] = {
|
||||||
sed -e 's,[@]X_PATH[@],$(X_PATH),g' \
|
"/etc/X11/sessions/",
|
||||||
<$(srcdir)/PreSession.in >PreSession
|
DMCONFDIR "/Sessions/",
|
||||||
PostSession: $(srcdir)/PostSession.in
|
DATADIR "/gdm/BuiltInSessions/",
|
||||||
sed -e 's,[@]X_PATH[@],$(X_PATH),g' \
|
DATADIR "/xsessions/",
|
||||||
<$(srcdir)/PostSession.in >PostSession
|
};
|
||||||
|
|
||||||
gdm.conf-custom: $(srcdir)/gdm.conf-custom.in
|
static const char *wayland_search_dir = DATADIR "/wayland-sessions/";
|
||||||
sed -e 's,[@]GDM_DEFAULTS_CONF[@],$(GDM_DEFAULTS_CONF),g' \
|
|
||||||
<$(srcdir)/gdm.conf-custom.in >gdm.conf-custom
|
|
||||||
|
|
||||||
dbusconfdir = $(DBUS_SYS_DIR)
|
search_array = g_array_new (TRUE, TRUE, sizeof (char *));
|
||||||
dbusconf_in_files = gdm.conf.in
|
|
||||||
dbusconf_DATA = $(dbusconf_in_files:.conf.in=.conf)
|
|
||||||
|
|
||||||
+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@
|
gdm_session_enums = gnome.mkenums('gdm-session-enum-types',
|
||||||
@INTLTOOL_XML_NOMERGE_RULE@
|
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
|
# Daemons deps
|
||||||
dconf_db_files = \
|
gdm_daemon_deps = [
|
||||||
dconf/defaults/00-upstream-settings \
|
libgdmcommon_dep,
|
||||||
dconf/defaults/locks/00-upstream-settings-locks
|
accountsservice_dep,
|
||||||
|
gobject_dep,
|
||||||
|
gio_dep,
|
||||||
|
gio_unix_dep,
|
||||||
|
libpam_dep,
|
||||||
|
x_deps,
|
||||||
|
xcb_dep,
|
||||||
|
]
|
||||||
|
|
||||||
dconfdbdir = $(pkgdatadir)
|
if xdmcp_dep.found() and get_option('tcp-wrappers')
|
||||||
dconfdb_DATA = greeter-dconf-defaults
|
gdm_daemon_deps += libwrap_dep
|
||||||
greeter-dconf-defaults: $(dconf_db_files)
|
endif
|
||||||
$(AM_V_GEN) dconf compile $@ $(srcdir)/dconf/defaults
|
|
||||||
|
|
||||||
dconfprofiledir = $(DATADIR)/dconf/profile
|
# test-session-client
|
||||||
dconfprofile_DATA = dconf/gdm
|
test_session_client_src = [
|
||||||
|
'test-session-client.c',
|
||||||
|
session_dbus_gen,
|
||||||
|
manager_dbus_gen,
|
||||||
|
]
|
||||||
|
|
||||||
gsettings_SCHEMAS = org.gnome.login-screen.gschema.xml
|
test_session_client = executable('test-session-client',
|
||||||
@GSETTINGS_RULES@
|
test_session_client_src,
|
||||||
|
dependencies: gdm_daemon_deps,
|
||||||
|
include_directories: config_h_dir,
|
||||||
|
)
|
||||||
|
|
||||||
schemasdir = $(pkgdatadir)
|
# Session worker
|
||||||
schemas_in_files = gdm.schemas.in
|
gdm_session_worker_src = [
|
||||||
schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
|
'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
|
gdm_session_worker_deps = [
|
||||||
sed -e 's,[@]GDMPREFETCHCMD[@],$(GDMPREFETCHCMD),g' \
|
gdm_daemon_deps,
|
||||||
-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' \
|
gdm_session_worker_includes = [
|
||||||
-e 's,[@]GDM_GROUPNAME[@],$(GDM_GROUPNAME),g' \
|
config_h_dir,
|
||||||
-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
|
if pam_extensions_supported
|
||||||
index 000000000..67f5f302c
|
gdm_session_worker_src += '../pam-extensions/gdm-pam-extensions.h'
|
||||||
--- /dev/null
|
gdm_session_worker_includes += pam_extensions_inc
|
||||||
+++ b/data/com.redhat.AccountsServiceUser.System.xml
|
endif
|
||||||
@@ -0,0 +1,10 @@
|
|
||||||
+<node>
|
if libaudit_dep.found()
|
||||||
+ <interface name="com.redhat.AccountsServiceUser.System">
|
gdm_session_worker_deps += libaudit_dep
|
||||||
+
|
|
||||||
+ <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
|
gdm_session_worker_src += [
|
||||||
+
|
'gdm-session-linux-auditor.c',
|
||||||
+ <property name="id" type="s" access="readwrite"/>
|
]
|
||||||
+ <property name="version-id" type="s" access="readwrite"/>
|
endif
|
||||||
+
|
|
||||||
+ </interface>
|
if have_adt
|
||||||
+</node>
|
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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Mon, 11 Feb 2019 10:32:55 -0500
|
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
|
session
|
||||||
|
|
||||||
Right now GTK preferentially picks the wayland display over an
|
Right now GTK preferentially picks the wayland display over an
|
||||||
@ -17,10 +17,10 @@ the session is X11.
|
|||||||
1 file changed, 19 insertions(+)
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
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
|
--- a/daemon/gdm-session.c
|
||||||
+++ b/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
|
static void
|
||||||
@ -42,8 +42,8 @@ index e6640aac7..0f821e390 100644
|
|||||||
{
|
{
|
||||||
const char *session_type = "x11";
|
const char *session_type = "x11";
|
||||||
|
|
||||||
if (self->priv->session_type != NULL) {
|
if (self->session_type != NULL) {
|
||||||
session_type = self->priv->session_type;
|
session_type = self->session_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy,
|
gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy,
|
||||||
@ -101,5 +101,5 @@ index e6640aac7..0f821e390 100644
|
|||||||
gpointer key, value;
|
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>
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
Date: Mon, 20 Aug 2018 14:30:59 -0400
|
Date: Mon, 20 Aug 2018 14:30:59 -0400
|
||||||
Subject: [PATCH 4/4] daemon: handle upgrades from RHEL 7
|
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.
|
try to get the right settings.
|
||||||
---
|
---
|
||||||
daemon/gdm-session-settings.c | 19 +++++++++++++++++++
|
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
|
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
|
--- a/daemon/gdm-session-settings.c
|
||||||
+++ b/daemon/gdm-session-settings.c
|
+++ b/daemon/gdm-session-settings.c
|
||||||
@@ -270,95 +270,114 @@ gdm_session_settings_get_property (GObject *object,
|
@@ -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_type = act_user_get_session_type (settings->priv->user);
|
||||||
session_name = act_user_get_session (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),
|
G_CALLBACK (on_user_is_loaded_changed),
|
||||||
settings);
|
settings);
|
||||||
}
|
}
|
||||||
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||||||
|
index c8e04c1b..3103e9df 100644
|
||||||
|
--- a/daemon/gdm-session.c
|
||||||
|
+++ b/daemon/gdm-session.c
|
||||||
|
@@ -3205,98 +3205,95 @@ gdm_session_get_session_id (GdmSession *self)
|
||||||
|
return conversation->session_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gdm_session_get_conversation_session_id (GdmSession *self,
|
||||||
|
const char *service_name)
|
||||||
|
{
|
||||||
|
GdmSessionConversation *conversation;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDM_IS_SESSION (self), NULL);
|
||||||
|
|
||||||
|
conversation = find_conversation_by_name (self, service_name);
|
||||||
|
|
||||||
|
if (conversation == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return conversation->session_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_session_filename (GdmSession *self)
|
||||||
|
{
|
||||||
|
return g_strdup_printf ("%s.desktop", get_session_name (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_WAYLAND_SUPPORT
|
||||||
|
static gboolean
|
||||||
|
gdm_session_is_wayland_session (GdmSession *self)
|
||||||
|
{
|
||||||
|
- GKeyFile *key_file;
|
||||||
|
+ g_autoptr (GKeyFile) key_file = NULL;
|
||||||
|
gboolean is_wayland_session = FALSE;
|
||||||
|
- char *filename;
|
||||||
|
- char *full_path = NULL;
|
||||||
|
+ g_autofree char *filename = NULL;
|
||||||
|
+ g_autofree char *full_path = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
|
||||||
|
|
||||||
|
filename = get_session_filename (self);
|
||||||
|
|
||||||
|
if (supports_session_type (self, "wayland")) {
|
||||||
|
key_file = load_key_file_for_file (self, filename, NULL, &full_path);
|
||||||
|
|
||||||
|
if (key_file == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
|
||||||
|
- is_wayland_session = TRUE;
|
||||||
|
+ if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
|
||||||
|
+ is_wayland_session = TRUE;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
|
||||||
|
|
||||||
|
out:
|
||||||
|
- g_clear_pointer (&key_file, g_key_file_free);
|
||||||
|
- g_free (filename);
|
||||||
|
+ g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
|
||||||
|
return is_wayland_session;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_session_type (GdmSession *self)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_WAYLAND_SUPPORT
|
||||||
|
gboolean is_wayland_session = FALSE;
|
||||||
|
|
||||||
|
- if (supports_session_type (self, "wayland"))
|
||||||
|
- is_wayland_session = gdm_session_is_wayland_session (self);
|
||||||
|
+ is_wayland_session = gdm_session_is_wayland_session (self);
|
||||||
|
|
||||||
|
if (is_wayland_session) {
|
||||||
|
set_session_type (self, "wayland");
|
||||||
|
} else {
|
||||||
|
set_session_type (self, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_session_session_registers (GdmSession *self)
|
||||||
|
{
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(GKeyFile) key_file = NULL;
|
||||||
|
gboolean session_registers = FALSE;
|
||||||
|
g_autofree char *filename = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (self != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
|
||||||
|
|
||||||
|
filename = get_session_filename (self);
|
||||||
|
|
||||||
|
key_file = load_key_file_for_file (self, filename, NULL, NULL);
|
||||||
|
|
||||||
|
session_registers = g_key_file_get_boolean (key_file,
|
||||||
|
G_KEY_FILE_DESKTOP_GROUP,
|
||||||
|
"X-GDM-SessionRegisters",
|
||||||
|
&error);
|
||||||
|
if (!session_registers &&
|
||||||
|
error != NULL &&
|
||||||
--
|
--
|
||||||
2.17.1
|
2.27.0
|
||||||
|
|
||||||
|
@ -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 desktop_file_utils_version 0.2.90
|
||||||
%define nss_version 3.11.1
|
%define nss_version 3.11.1
|
||||||
|
|
||||||
|
%global tarball_version %%(echo %{version} | tr '~' '.')
|
||||||
|
|
||||||
Name: gdm
|
Name: gdm
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
Version: 3.28.3
|
Version: 40.0
|
||||||
Release: 39%{?dist}
|
Release: 15%{?dist}
|
||||||
Summary: The GNOME Display Manager
|
Summary: The GNOME Display Manager
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: https://wiki.gnome.org/Projects/GDM
|
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
|
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
|
# Don't bother building gdm-screenshot, nothing uses it
|
||||||
Patch30002: 0001-data-disable-wayland-on-server-chips-and-dual-gpu-se.patch
|
Patch50001: 0001-utils-Drop-gdm-screenshot.patch
|
||||||
Patch30003: 0001-data-enable-wayland-on-cirrus.patch
|
|
||||||
Patch30004: 0001-data-only-disable-wayland-on-passthrough-virt-setups.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
|
# Crash fix
|
||||||
Patch70002: 0002-session-support-new-accountsservice-Session-and-Sess.patch
|
Patch80001: 0001-local-display-factory-Don-t-try-to-respawn-displays-.patch
|
||||||
Patch70003: 0003-daemon-save-os-release-in-accountsservice.patch
|
|
||||||
Patch70004: 0004-daemon-handle-upgrades-from-RHEL-7.patch
|
|
||||||
|
|
||||||
Patch80001: 0001-session-worker-expose-worker-state-enum-to-type-syst.patch
|
# Non-upstreamable workarounds
|
||||||
Patch80002: 0002-session-worker-kill-user-sessions-when-stop-gdm-serv.patch
|
Patch66610001: 0001-local-display-factory-pause-for-a-few-seconds-before.patch
|
||||||
Patch80003: 0003-session-worker-uninitialize-pam-if-worker-is-killed.patch
|
Patch66620001: 0001-data-reap-gdm-sessions-on-shutdown.patch
|
||||||
Patch80004: 0004-data-reap-gdm-sessions-on-shutdown.patch
|
|
||||||
|
|
||||||
# CVE-2019-3825
|
# Non-upstreamable integration patches
|
||||||
Patch90001: 0001-manager-don-t-kill-timed-login-session-immediately-a.patch
|
Patch99910001: 0001-Honor-initial-setup-being-disabled-by-distro-install.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
|
|
||||||
|
|
||||||
Patch100001: 0001-manager-allow-multiple-xdmcp-logins-for-the-same-use.patch
|
Patch99920001: 0001-worker-don-t-load-user-settings-for-program-sessions.patch
|
||||||
Patch100002: 0002-gdm-x-session-run-session-bus-on-non-seat0-seats.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
|
Patch99940001: 0001-data-disable-wayland-on-certain-hardware.patch
|
||||||
# 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
|
|
||||||
|
|
||||||
# CVE-2020-16125
|
BuildRequires: accountsservice-devel
|
||||||
Patch210001: 0001-display-Exit-with-failure-if-loading-existing-users-.patch
|
BuildRequires: audit-libs-devel >= %{libauditver}
|
||||||
|
BuildRequires: dconf
|
||||||
# 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: desktop-file-utils >= %{desktop_file_utils_version}
|
BuildRequires: desktop-file-utils >= %{desktop_file_utils_version}
|
||||||
BuildRequires: libtool automake autoconf
|
BuildRequires: gettext-devel
|
||||||
BuildRequires: libattr-devel
|
|
||||||
BuildRequires: gettext
|
|
||||||
BuildRequires: git
|
BuildRequires: git
|
||||||
|
BuildRequires: keyutils-libs-devel
|
||||||
|
BuildRequires: libXdmcp-devel
|
||||||
|
BuildRequires: libattr-devel
|
||||||
BuildRequires: libdmx-devel
|
BuildRequires: libdmx-devel
|
||||||
BuildRequires: audit-libs-devel >= %{libauditver}
|
BuildRequires: audit-libs-devel >= %{libauditver}
|
||||||
BuildRequires: autoconf automake libtool
|
BuildRequires: meson
|
||||||
BuildRequires: intltool
|
|
||||||
%ifnarch s390 s390x ppc ppc64
|
|
||||||
BuildRequires: xorg-x11-server-Xorg
|
|
||||||
%endif
|
|
||||||
BuildRequires: nss-devel >= %{nss_version}
|
BuildRequires: nss-devel >= %{nss_version}
|
||||||
|
BuildRequires: pam-devel >= 0:%{pam_version}
|
||||||
BuildRequires: pkgconfig(accountsservice) >= 0.6.3
|
BuildRequires: pkgconfig(accountsservice) >= 0.6.3
|
||||||
BuildRequires: pkgconfig(check)
|
BuildRequires: pkgconfig(check)
|
||||||
BuildRequires: pkgconfig(gobject-introspection-1.0)
|
BuildRequires: pkgconfig(gobject-introspection-1.0)
|
||||||
@ -149,10 +87,15 @@ BuildRequires: pkgconfig(systemd)
|
|||||||
BuildRequires: pkgconfig(x11)
|
BuildRequires: pkgconfig(x11)
|
||||||
BuildRequires: pkgconfig(xau)
|
BuildRequires: pkgconfig(xau)
|
||||||
BuildRequires: pkgconfig(xorg-server)
|
BuildRequires: pkgconfig(xorg-server)
|
||||||
BuildRequires: libXdmcp-devel
|
BuildRequires: plymouth-devel
|
||||||
BuildRequires: systemd
|
BuildRequires: systemd
|
||||||
BuildRequires: keyutils-libs-devel
|
BuildRequires: systemd-devel
|
||||||
BuildRequires: dconf
|
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
|
Requires(pre): /usr/sbin/useradd
|
||||||
%{?systemd_requires}
|
%{?systemd_requires}
|
||||||
@ -181,6 +124,10 @@ Requires: xorg-x11-xinit
|
|||||||
Recommends: xorg-x11-server-Xorg
|
Recommends: xorg-x11-server-Xorg
|
||||||
Conflicts: xorg-x11-server-Xorg < 1.20.8-4
|
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
|
Obsoletes: gdm-libs < 1:3.12.0-3
|
||||||
Provides: gdm-libs%{?_isa} = %{epoch}:%{version}-%{release}
|
Provides: gdm-libs%{?_isa} = %{epoch}:%{version}-%{release}
|
||||||
|
|
||||||
@ -228,33 +175,22 @@ GDM specific authentication features.
|
|||||||
%prep
|
%prep
|
||||||
%autosetup -S git
|
%autosetup -S git
|
||||||
|
|
||||||
autoreconf -i -f
|
|
||||||
intltoolize -f
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
|
%meson -Dpam-prefix=%{_sysconfdir} \
|
||||||
%configure --with-pam-prefix=%{_sysconfdir} \
|
-Drun-dir=/run/gdm \
|
||||||
--with-run-dir=/run/gdm \
|
-Dudev-dir=%{_udevrulesdir} \
|
||||||
--with-default-path=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin \
|
-Ddefault-path=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin \
|
||||||
--enable-split-authentication \
|
-Dprofiling=true \
|
||||||
--enable-profiling \
|
-Dplymouth=enabled \
|
||||||
--enable-console-helper \
|
-Dselinux=enabled
|
||||||
--with-plymouth \
|
%meson_build
|
||||||
--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
|
|
||||||
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
mkdir -p %{buildroot}%{_sysconfdir}/gdm/Init
|
mkdir -p %{buildroot}%{_sysconfdir}/gdm/Init
|
||||||
mkdir -p %{buildroot}%{_sysconfdir}/gdm/PreSession
|
mkdir -p %{buildroot}%{_sysconfdir}/gdm/PreSession
|
||||||
mkdir -p %{buildroot}%{_sysconfdir}/gdm/PostSession
|
mkdir -p %{buildroot}%{_sysconfdir}/gdm/PostSession
|
||||||
|
|
||||||
%make_install
|
%meson_install
|
||||||
|
|
||||||
install -p -m644 -D %{SOURCE5} %{buildroot}%{_localstatedir}/lib/gdm/.config/pulse/default.pa
|
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
|
# docs go elsewhere
|
||||||
rm -rf %{buildroot}/%{_prefix}/doc
|
rm -rf %{buildroot}/%{_prefix}/doc
|
||||||
|
|
||||||
|
# we're not doing user sessions in rhel 8
|
||||||
|
rm -rf %{buildroot}%{_prefix}/lib/systemd/user
|
||||||
|
|
||||||
# create log dir
|
# create log dir
|
||||||
mkdir -p %{buildroot}/var/log/gdm
|
mkdir -p %{buildroot}/var/log/gdm
|
||||||
|
|
||||||
@ -277,10 +216,11 @@ mkdir -p %{buildroot}/run/gdm
|
|||||||
|
|
||||||
mkdir -p %{buildroot}%{_sysconfdir}/dconf/db/gdm.d/locks
|
mkdir -p %{buildroot}%{_sysconfdir}/dconf/db/gdm.d/locks
|
||||||
|
|
||||||
rm -f %{buildroot}%{_bindir}/gdm-screenshot
|
cat << EOF > %{buildroot}%{_libexecdir}/gdm-disable-wayland
|
||||||
|
#!/bin/sh
|
||||||
find %{buildroot} -name '*.a' -delete
|
%{_libexecdir}/gdm-runtime-config set daemon WaylandEnable false
|
||||||
find %{buildroot} -name '*.la' -delete
|
EOF
|
||||||
|
chmod a+x %{buildroot}%{_libexecdir}/gdm-disable-wayland
|
||||||
|
|
||||||
%find_lang gdm --with-gnome
|
%find_lang gdm --with-gnome
|
||||||
|
|
||||||
@ -351,7 +291,7 @@ fi
|
|||||||
%systemd_postun gdm.service
|
%systemd_postun gdm.service
|
||||||
|
|
||||||
%files -f gdm.lang
|
%files -f gdm.lang
|
||||||
%doc AUTHORS NEWS README
|
%doc AUTHORS NEWS README.md
|
||||||
%license COPYING
|
%license COPYING
|
||||||
%dir %{_sysconfdir}/gdm
|
%dir %{_sysconfdir}/gdm
|
||||||
%config(noreplace) %{_sysconfdir}/gdm/custom.conf
|
%config(noreplace) %{_sysconfdir}/gdm/custom.conf
|
||||||
@ -371,10 +311,10 @@ fi
|
|||||||
%dir %{_sysconfdir}/gdm/PostLogin
|
%dir %{_sysconfdir}/gdm/PostLogin
|
||||||
%dir %{_sysconfdir}/dconf/db/gdm.d
|
%dir %{_sysconfdir}/dconf/db/gdm.d
|
||||||
%dir %{_sysconfdir}/dconf/db/gdm.d/locks
|
%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.xml
|
||||||
%{_datadir}/glib-2.0/schemas/org.gnome.login-screen.gschema.override
|
%{_datadir}/glib-2.0/schemas/org.gnome.login-screen.gschema.override
|
||||||
%{_libexecdir}/gdm-disable-wayland
|
%{_libexecdir}/gdm-disable-wayland
|
||||||
|
%{_libexecdir}/gdm-runtime-config
|
||||||
%{_libexecdir}/gdm-host-chooser
|
%{_libexecdir}/gdm-host-chooser
|
||||||
%{_libexecdir}/gdm-session-worker
|
%{_libexecdir}/gdm-session-worker
|
||||||
%{_libexecdir}/gdm-simple-chooser
|
%{_libexecdir}/gdm-simple-chooser
|
||||||
@ -394,6 +334,7 @@ fi
|
|||||||
%{_datadir}/gdm/locale.alias
|
%{_datadir}/gdm/locale.alias
|
||||||
%{_datadir}/gdm/gdb-cmd
|
%{_datadir}/gdm/gdb-cmd
|
||||||
%{_datadir}/gnome-session/sessions/gnome-login.session
|
%{_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}/girepository-1.0/Gdm-1.0.typelib
|
||||||
%{_libdir}/security/pam_gdm.so
|
%{_libdir}/security/pam_gdm.so
|
||||||
%{_libdir}/libgdm*.so*
|
%{_libdir}/libgdm*.so*
|
||||||
@ -403,8 +344,6 @@ fi
|
|||||||
%attr(0700, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.config/pulse
|
%attr(0700, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.config/pulse
|
||||||
%attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.config/pulse/default.pa
|
%attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.config/pulse/default.pa
|
||||||
%attr(0711, root, gdm) %dir /run/gdm
|
%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-pin
|
||||||
%config %{_sysconfdir}/pam.d/gdm-smartcard
|
%config %{_sysconfdir}/pam.d/gdm-smartcard
|
||||||
%config %{_sysconfdir}/pam.d/gdm-fingerprint
|
%config %{_sysconfdir}/pam.d/gdm-fingerprint
|
||||||
@ -425,6 +364,44 @@ fi
|
|||||||
%{_libdir}/pkgconfig/gdm-pam-extensions.pc
|
%{_libdir}/pkgconfig/gdm-pam-extensions.pc
|
||||||
|
|
||||||
%changelog
|
%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
|
* Wed Jan 27 2021 Ray Strode <rstrode@redhat.com> - 3.28.3-39
|
||||||
- Ensure login screen display server is is killed at log in
|
- Ensure login screen display server is is killed at log in
|
||||||
- Pull in fixes for two security issues
|
- Pull in fixes for two security issues
|
||||||
|
Loading…
Reference in New Issue
Block a user