Compare commits
No commits in common. "c10-beta" and "c8" have entirely different histories.
1
.gdm.metadata
Normal file
1
.gdm.metadata
Normal file
@ -0,0 +1 @@
|
|||||||
|
05c48de8765bde97768b6740417ad6c374c20763 SOURCES/gdm-40.0.tar.xz
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
gdm-47.alpha.tar.xz
|
SOURCES/gdm-40.0.tar.xz
|
||||||
|
@ -1,219 +0,0 @@
|
|||||||
From a8a0d952293337544da4681f0c896052eafd9d0f Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
|
||||||
Date: Fri, 5 Apr 2024 16:44:07 +0200
|
|
||||||
Subject: [PATCH] Add headless session files
|
|
||||||
|
|
||||||
It consists of a python script for running the session, and a systemd
|
|
||||||
system service template.
|
|
||||||
---
|
|
||||||
data/gnome-headless-session@.service | 6 +
|
|
||||||
data/meson.build | 4 +
|
|
||||||
utils/gdm-headless-login-session | 157 +++++++++++++++++++++++++++
|
|
||||||
utils/meson.build | 5 +
|
|
||||||
4 files changed, 172 insertions(+)
|
|
||||||
create mode 100644 data/gnome-headless-session@.service
|
|
||||||
create mode 100644 utils/gdm-headless-login-session
|
|
||||||
|
|
||||||
diff --git a/data/gnome-headless-session@.service b/data/gnome-headless-session@.service
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..269d16288
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/data/gnome-headless-session@.service
|
|
||||||
@@ -0,0 +1,6 @@
|
|
||||||
+[Unit]
|
|
||||||
+Description=Headless desktop session
|
|
||||||
+
|
|
||||||
+[Service]
|
|
||||||
+ExecStart=/usr/libexec/gdm-headless-login-session --user=%i
|
|
||||||
+Restart=on-failure
|
|
||||||
diff --git a/data/meson.build b/data/meson.build
|
|
||||||
index 2211e98b5..2df07cd32 100644
|
|
||||||
--- a/data/meson.build
|
|
||||||
+++ b/data/meson.build
|
|
||||||
@@ -221,3 +221,7 @@ if get_option('gdm-xsession')
|
|
||||||
install_dir: gdmconfdir,
|
|
||||||
)
|
|
||||||
endif
|
|
||||||
+
|
|
||||||
+headless_session_service = install_data('gnome-headless-session@.service',
|
|
||||||
+ install_dir: systemd_systemunitdir,
|
|
||||||
+ )
|
|
||||||
diff --git a/utils/gdm-headless-login-session b/utils/gdm-headless-login-session
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..e108be523
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/utils/gdm-headless-login-session
|
|
||||||
@@ -0,0 +1,157 @@
|
|
||||||
+#!/usr/bin/env python3
|
|
||||||
+
|
|
||||||
+import argparse
|
|
||||||
+import pam
|
|
||||||
+import pwd
|
|
||||||
+import os
|
|
||||||
+import signal
|
|
||||||
+import sys
|
|
||||||
+
|
|
||||||
+import gi
|
|
||||||
+gi.require_version('AccountsService', '1.0')
|
|
||||||
+from gi.repository import AccountsService, GLib
|
|
||||||
+
|
|
||||||
+def run_desktop_in_new_session(pam_environment, user, session_desktop, tty_input, tty_output):
|
|
||||||
+ keyfile = GLib.KeyFile()
|
|
||||||
+ keyfile.load_from_data_dirs(f'wayland-sessions/{session_desktop}.desktop',
|
|
||||||
+ GLib.KeyFileFlags.NONE)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ can_run_headless = keyfile.get_boolean(GLib.KEY_FILE_DESKTOP_GROUP,
|
|
||||||
+ 'X-GDM-CanRunHeadless')
|
|
||||||
+ except GLib.GError:
|
|
||||||
+ raise Exception(f"Session {session_desktop} can't run headlessly")
|
|
||||||
+
|
|
||||||
+ if not can_run_headless:
|
|
||||||
+ raise Exception(f"Session {session_desktop} can't run headlessly")
|
|
||||||
+
|
|
||||||
+ executable = keyfile.get_string(GLib.KEY_FILE_DESKTOP_GROUP,
|
|
||||||
+ GLib.KEY_FILE_DESKTOP_KEY_TRY_EXEC)
|
|
||||||
+ if GLib.find_program_in_path(executable) is None:
|
|
||||||
+ raise Exception(f"Invalid session {session_desktop}")
|
|
||||||
+
|
|
||||||
+ command = keyfile.get_string(GLib.KEY_FILE_DESKTOP_GROUP,
|
|
||||||
+ GLib.KEY_FILE_DESKTOP_KEY_EXEC)
|
|
||||||
+ [success, args] = GLib.shell_parse_argv(command)
|
|
||||||
+
|
|
||||||
+ pam_handle = pam.pam()
|
|
||||||
+
|
|
||||||
+ for key, value in pam_environment.items():
|
|
||||||
+ pam_handle.putenv(f'{key}={value}')
|
|
||||||
+
|
|
||||||
+ if not pam_handle.authenticate(user, '', service='gdm-autologin', call_end=False):
|
|
||||||
+ raise Exception("Authentication failed")
|
|
||||||
+
|
|
||||||
+ for key, value in pam_environment.items():
|
|
||||||
+ pam_handle.putenv(f'{key}={value}')
|
|
||||||
+
|
|
||||||
+ if pam_handle.open_session() != pam.PAM_SUCCESS:
|
|
||||||
+ raise Exception("Failed to open PAM session")
|
|
||||||
+
|
|
||||||
+ session_environment = os.environ.copy()
|
|
||||||
+ session_environment.update(pam_handle.getenvlist())
|
|
||||||
+
|
|
||||||
+ user_info = pwd.getpwnam(user)
|
|
||||||
+ uid = user_info.pw_uid
|
|
||||||
+ gid = user_info.pw_gid
|
|
||||||
+
|
|
||||||
+ old_tty_output = os.fdopen(os.dup(2), 'w')
|
|
||||||
+
|
|
||||||
+ pid = os.fork()
|
|
||||||
+ if pid == 0:
|
|
||||||
+ try:
|
|
||||||
+ os.setsid()
|
|
||||||
+ except OSError as e:
|
|
||||||
+ print(f"Could not create new pid session: {e}", file=old_tty_output)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ os.dup2(tty_input.fileno(), 0)
|
|
||||||
+ os.dup2(tty_output.fileno(), 1)
|
|
||||||
+ os.dup2(tty_output.fileno(), 2)
|
|
||||||
+ except OSError as e:
|
|
||||||
+ print(f"Could not set up standard i/o: {e}", file=old_tty_output)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ os.initgroups(user, gid)
|
|
||||||
+ os.setgid(gid)
|
|
||||||
+ os.setuid(uid);
|
|
||||||
+ except OSError as e:
|
|
||||||
+ print(f"Could not become user {user} (uid={uid}): {e}", file=old_tty_output)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ os.execvpe(args[0], args, session_environment)
|
|
||||||
+ except OSError as e:
|
|
||||||
+ print(f"Could not run program \"{' '.join(arguments)}\": {e}", file=old_tty_output)
|
|
||||||
+ os._exit(1)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ def signal_handler(sig, frame):
|
|
||||||
+ os.kill(pid, sig)
|
|
||||||
+
|
|
||||||
+ signal.signal(signal.SIGTERM, signal_handler)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ (_, exit_code) = os.waitpid(pid, 0);
|
|
||||||
+ except KeyboardInterrupt:
|
|
||||||
+ os.kill(pid, signal.SIGTERM)
|
|
||||||
+ except OSError as e:
|
|
||||||
+ print(f"Could not wait for program to finish: {e}", file=old_tty_output)
|
|
||||||
+
|
|
||||||
+ if os.WIFEXITED(exit_code):
|
|
||||||
+ exit_code = os.WEXITSTATUS(exit_code)
|
|
||||||
+ else:
|
|
||||||
+ os.kill(os.getpid(), os.WTERMSIG(exit_code))
|
|
||||||
+ old_tty_output.close()
|
|
||||||
+
|
|
||||||
+ if pam_handle.close_session() != pam.PAM_SUCCESS:
|
|
||||||
+ raise Exception("Failed to close PAM session")
|
|
||||||
+
|
|
||||||
+ pam_handle.end()
|
|
||||||
+
|
|
||||||
+ return exit_code
|
|
||||||
+
|
|
||||||
+def wait_for_user_data(user):
|
|
||||||
+ main_context = GLib.MainContext.default()
|
|
||||||
+ while not user.is_loaded():
|
|
||||||
+ main_context.iteration(True)
|
|
||||||
+
|
|
||||||
+def main():
|
|
||||||
+ parser = argparse.ArgumentParser(description='Run a desktop session in a PAM session as a specified user.')
|
|
||||||
+ parser.add_argument('--user', help='Username for which to run the session')
|
|
||||||
+
|
|
||||||
+ args = parser.parse_args()
|
|
||||||
+
|
|
||||||
+ if args.user is None:
|
|
||||||
+ parser.print_usage()
|
|
||||||
+ sys.exit(1)
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ tty_path = '/dev/null'
|
|
||||||
+
|
|
||||||
+ tty_input = open(tty_path, 'r')
|
|
||||||
+ tty_output = open(tty_path, 'w')
|
|
||||||
+ except OSError as e:
|
|
||||||
+ raise Exception(f"Error opening /dev/null as tty associated with VT {vt}: {e}")
|
|
||||||
+
|
|
||||||
+ user_manager = AccountsService.UserManager().get_default()
|
|
||||||
+ user = user_manager.get_user(args.user)
|
|
||||||
+ wait_for_user_data(user)
|
|
||||||
+ session_desktop = user.get_session()
|
|
||||||
+ if not session_desktop:
|
|
||||||
+ session_desktop = 'gnome'
|
|
||||||
+
|
|
||||||
+ pam_environment = {}
|
|
||||||
+ pam_environment['XDG_SESSION_TYPE'] = 'wayland'
|
|
||||||
+ pam_environment['XDG_SESSION_CLASS'] = 'user'
|
|
||||||
+ pam_environment['XDG_SESSION_DESKTOP'] = session_desktop
|
|
||||||
+
|
|
||||||
+ try:
|
|
||||||
+ result = run_desktop_in_new_session(pam_environment, args.user, session_desktop, tty_input, tty_output)
|
|
||||||
+ except Exception as e:
|
|
||||||
+ raise Exception(f"Error running desktop session \"{session_desktop}\": {e}")
|
|
||||||
+ tty_input.close()
|
|
||||||
+ tty_output.close()
|
|
||||||
+ sys.exit(result)
|
|
||||||
+
|
|
||||||
+if __name__ == '__main__':
|
|
||||||
+ main()
|
|
||||||
diff --git a/utils/meson.build b/utils/meson.build
|
|
||||||
index e4141fb13..57dd6519f 100644
|
|
||||||
--- a/utils/meson.build
|
|
||||||
+++ b/utils/meson.build
|
|
||||||
@@ -65,3 +65,8 @@ if distro != 'none'
|
|
||||||
install_dir: get_option('libexecdir'),
|
|
||||||
)
|
|
||||||
endif
|
|
||||||
+
|
|
||||||
+gdm_headless_login_session = install_data('gdm-headless-login-session',
|
|
||||||
+ install_mode: 'rwxr-xr-x',
|
|
||||||
+ install_dir: get_option('libexecdir'),
|
|
||||||
+ )
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
|||||||
From 42b18e4c84d470f33cdec5fc1f481cb25c25cf0d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Rui Matos <tiagomatos@gmail.com>
|
|
||||||
Date: Mon, 23 Jan 2017 20:19:51 +0100
|
|
||||||
Subject: [PATCH] Honor initial setup being disabled by distro installer
|
|
||||||
|
|
||||||
Sysadmins might want to disable any kind of initial setup for their
|
|
||||||
users, perhaps because they pre-configure their environments. We
|
|
||||||
already provide a configuration file option for this but distro
|
|
||||||
installers might have their own way of requesting this.
|
|
||||||
|
|
||||||
At least the anaconda installer provides an option to skip any kind
|
|
||||||
post-install setup tools so, for now we're only adding support for
|
|
||||||
that but more might be added in the future.
|
|
||||||
|
|
||||||
https://bugzilla.gnome.org/show_bug.cgi?id=777708
|
|
||||||
---
|
|
||||||
daemon/Makefile.am | 1 +
|
|
||||||
daemon/gdm-display.c | 29 +++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 30 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
|
|
||||||
index 5e193f2..878be88 100644
|
|
||||||
--- a/daemon/gdm-display.c
|
|
||||||
+++ b/daemon/gdm-display.c
|
|
||||||
@@ -1547,6 +1547,31 @@ kernel_cmdline_initial_setup_force_state (gboolean *force_state)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static gboolean
|
|
||||||
+initial_setup_disabled_by_anaconda (void)
|
|
||||||
+{
|
|
||||||
+ GKeyFile *key_file;
|
|
||||||
+ const gchar *file_name = SYSCONFDIR "/sysconfig/anaconda";
|
|
||||||
+ gboolean disabled = FALSE;
|
|
||||||
+ GError *error = NULL;
|
|
||||||
+
|
|
||||||
+ key_file = g_key_file_new ();
|
|
||||||
+ if (!g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error)) {
|
|
||||||
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
|
|
||||||
+ !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) {
|
|
||||||
+ g_warning ("Could not read %s: %s", file_name, error->message);
|
|
||||||
+ }
|
|
||||||
+ g_error_free (error);
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ disabled = g_key_file_get_boolean (key_file, "General",
|
|
||||||
+ "post_install_tools_disabled", NULL);
|
|
||||||
+ out:
|
|
||||||
+ g_key_file_unref (key_file);
|
|
||||||
+ return disabled;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static gboolean
|
|
||||||
wants_initial_setup (GdmDisplay *self)
|
|
||||||
{
|
|
||||||
@@ -1587,6 +1612,10 @@ wants_initial_setup (GdmDisplay *self)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (initial_setup_disabled_by_anaconda ()) {
|
|
||||||
+ return FALSE;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.19.0
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
Avoid the Xorg build-time dependency, as we already know the answers
|
|
||||||
to the questions that are trying to be determined.
|
|
||||||
|
|
||||||
diff --git a/meson.build b/meson.build
|
|
||||||
index bf0e58506..7d8f964c3 100644
|
|
||||||
--- a/meson.build
|
|
||||||
+++ b/meson.build
|
|
||||||
@@ -92,8 +92,9 @@ if find_x_server_out != ''
|
|
||||||
else
|
|
||||||
# what to do, what to do, this is wrong, but this just sets the
|
|
||||||
# defaults, perhaps this user is cross compiling or some such
|
|
||||||
- x_path = '/usr/bin/X11:/usr/X11R6/bin:/opt/X11R6/bin'
|
|
||||||
- x_bin = '/usr/bin/X'
|
|
||||||
+ x_path = '/usr/bin'
|
|
||||||
+ x_bin = '/usr/bin/Xorg'
|
|
||||||
+ xserver_has_listen = true
|
|
||||||
endif
|
|
||||||
xdmcp_dep = cc.find_library('Xdmcp', required: get_option('xdmcp'))
|
|
||||||
if xdmcp_dep.found() and get_option('tcp-wrappers')
|
|
@ -0,0 +1,159 @@
|
|||||||
|
From a447cd87b99868348ecf69479eb7958f20a318a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rui Matos <tiagomatos@gmail.com>
|
||||||
|
Date: Mon, 23 Jan 2017 20:19:51 +0100
|
||||||
|
Subject: [PATCH] Honor initial setup being disabled by distro installer
|
||||||
|
|
||||||
|
Sysadmins might want to disable any kind of initial setup for their
|
||||||
|
users, perhaps because they pre-configure their environments. We
|
||||||
|
already provide a configuration file option for this but distro
|
||||||
|
installers might have their own way of requesting this.
|
||||||
|
|
||||||
|
At least the anaconda installer provides an option to skip any kind
|
||||||
|
post-install setup tools so, for now we're only adding support for
|
||||||
|
that but more might be added in the future.
|
||||||
|
|
||||||
|
https://bugzilla.gnome.org/show_bug.cgi?id=777708
|
||||||
|
---
|
||||||
|
daemon/gdm-display.c | 29 +++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 29 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
|
||||||
|
index 687e7da4b..b3bdf066d 100644
|
||||||
|
--- a/daemon/gdm-display.c
|
||||||
|
+++ b/daemon/gdm-display.c
|
||||||
|
@@ -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
|
||||||
|
+initial_setup_disabled_by_anaconda (void)
|
||||||
|
+{
|
||||||
|
+ GKeyFile *key_file;
|
||||||
|
+ const gchar *file_name = SYSCONFDIR "/sysconfig/anaconda";
|
||||||
|
+ gboolean disabled = FALSE;
|
||||||
|
+ GError *error = NULL;
|
||||||
|
+
|
||||||
|
+ key_file = g_key_file_new ();
|
||||||
|
+ if (!g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error)) {
|
||||||
|
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
|
||||||
|
+ !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND)) {
|
||||||
|
+ g_warning ("Could not read %s: %s", file_name, error->message);
|
||||||
|
+ }
|
||||||
|
+ g_error_free (error);
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ disabled = g_key_file_get_boolean (key_file, "General",
|
||||||
|
+ "post_install_tools_disabled", NULL);
|
||||||
|
+ out:
|
||||||
|
+ g_key_file_unref (key_file);
|
||||||
|
+ return disabled;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gboolean
|
||||||
|
wants_initial_setup (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
gboolean enabled = FALSE;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (initial_setup_disabled_by_anaconda ()) {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
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.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
|
||||||
|
|
86
SOURCES/0001-build-Support-keyutils-1.5.11-and-older.patch
Normal file
86
SOURCES/0001-build-Support-keyutils-1.5.11-and-older.patch
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
From 2fc7d94280a82e079129468d9b0db312725e5926 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Mon, 12 Dec 2022 15:37:38 -0500
|
||||||
|
Subject: [PATCH 1/2] build: Support keyutils 1.5.11 and older
|
||||||
|
|
||||||
|
keyutils didn't get a pkgconfig file until 1.6.
|
||||||
|
|
||||||
|
This commit looks for the library directly if it can't find
|
||||||
|
the pkgconfig file.
|
||||||
|
---
|
||||||
|
meson.build | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 4a286f97..1a557e9a 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -26,60 +26,65 @@ lang_config_file = (get_option('lang-file') != '')? get_option('lang-file') : gd
|
||||||
|
pam_mod_dir = (get_option('pam-mod-dir') != '')? get_option('pam-mod-dir') : gdm_prefix / get_option('libdir') / 'security'
|
||||||
|
dbus_sys_dir = (get_option('dbus-sys') != '')? get_option('dbus-sys') : get_option('sysconfdir') / 'dbus-1' / 'system.d'
|
||||||
|
gdm_defaults_conf = (get_option('defaults-conf') != '')? get_option('defaults-conf') : gdm_prefix / get_option('datadir') / 'gdm' / 'defaults.conf'
|
||||||
|
gdm_custom_conf = (get_option('custom-conf') != '')? get_option('custom-conf') : gdmconfdir / 'custom.conf'
|
||||||
|
gnome_settings_daemon_dir = (get_option('gnome-settings-daemon-dir') != '')? get_option('gnome-settings-daemon-dir') : gdm_prefix / get_option('libexecdir')
|
||||||
|
gdm_run_dir = (get_option('run-dir') != '')? get_option('run-dir') : gdm_prefix / get_option('localstatedir') / 'run' / 'gdm'
|
||||||
|
gdm_runtime_conf = (get_option('runtime-conf') != '')? get_option('runtime-conf') : gdm_run_dir / 'custom.conf'
|
||||||
|
gdm_pid_file = (get_option('pid-file') != '')? get_option('pid-file') : gdm_run_dir / 'gdm.pid'
|
||||||
|
ran_once_marker_dir = (get_option('ran-once-marker-dir') != '')? get_option('ran-once-marker-dir') : gdm_run_dir
|
||||||
|
working_dir = (get_option('working-dir') != '')? get_option('working-dir') : gdm_prefix / get_option('localstatedir') / 'lib' / 'gdm'
|
||||||
|
gdm_xauth_dir = (get_option('xauth-dir') != '')? get_option('xauth-dir') : gdm_run_dir
|
||||||
|
gdm_screenshot_dir = (get_option('screenshot-dir') != '')? get_option('screenshot-dir') : gdm_run_dir / 'greeter'
|
||||||
|
|
||||||
|
# Common variables
|
||||||
|
config_h_dir = include_directories('.')
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
udev_dep = dependency('udev')
|
||||||
|
|
||||||
|
glib_min_version = '2.56.0'
|
||||||
|
|
||||||
|
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
||||||
|
gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version)
|
||||||
|
gio_dep = dependency('gio-2.0', version: '>=' + glib_min_version)
|
||||||
|
gio_unix_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
|
||||||
|
gtk_dep = dependency('gtk+-3.0', version: '>= 2.91.1')
|
||||||
|
libcanberra_gtk_dep = dependency('libcanberra-gtk3', version: '>= 0.4')
|
||||||
|
accountsservice_dep = dependency('accountsservice', version: '>= 0.6.35')
|
||||||
|
xcb_dep = dependency('xcb')
|
||||||
|
keyutils_dep = dependency('libkeyutils', required: false)
|
||||||
|
+
|
||||||
|
+if not keyutils_dep.found()
|
||||||
|
+ keyutils_dep = cc.find_library('libkeyutils')
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
libselinux_dep = dependency('libselinux', required: get_option('selinux'))
|
||||||
|
|
||||||
|
# udev
|
||||||
|
if udev_dir == ''
|
||||||
|
if udev_dep.found()
|
||||||
|
udev_prefix = udev_dep.get_pkgconfig_variable('udevdir')
|
||||||
|
else
|
||||||
|
udev_prefix = gdm_prefix / 'lib' / 'udev'
|
||||||
|
endif
|
||||||
|
udev_dir = udev_prefix / 'rules.d'
|
||||||
|
endif
|
||||||
|
|
||||||
|
# X11
|
||||||
|
x_deps = declare_dependency(
|
||||||
|
dependencies: [
|
||||||
|
dependency('x11'),
|
||||||
|
dependency('xau'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
# Xserver 1.17 & later default to -nolisten and require -listen for remote access
|
||||||
|
xserver_deps = dependency('xorg-server', version : '>=1.17', required : false)
|
||||||
|
xserver_has_listen = xserver_deps.found()
|
||||||
|
find_x_server_script = find_program('build-aux/find-x-server.sh', native: true)
|
||||||
|
find_x_server_out = run_command(find_x_server_script).stdout().strip()
|
||||||
|
if find_x_server_out != ''
|
||||||
|
x_bin = find_x_server_out
|
||||||
|
x_bin_path_split = x_bin.split('/')
|
||||||
|
i = 0
|
||||||
|
x_path = '/'
|
||||||
|
foreach dir : x_bin_path_split
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
570
SOURCES/0001-daemon-Don-t-error-on-shutdown.patch
Normal file
570
SOURCES/0001-daemon-Don-t-error-on-shutdown.patch
Normal file
@ -0,0 +1,570 @@
|
|||||||
|
From fbdb5fdfc5f4c5569643239cae1d6fe5fac13717 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Mon, 12 Dec 2022 10:52:58 -0500
|
||||||
|
Subject: [PATCH] daemon: Don't error on shutdown
|
||||||
|
|
||||||
|
Right now we complain if shutdown happens while the display is
|
||||||
|
comming up.
|
||||||
|
|
||||||
|
This commit detects that case and avoids the error in that case.
|
||||||
|
---
|
||||||
|
daemon/gdm-display.c | 28 +++++++++++++++++++++++++++-
|
||||||
|
daemon/gdm-manager.c | 11 +++++++----
|
||||||
|
2 files changed, 34 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
|
||||||
|
index 9438fe72..a93857e9 100644
|
||||||
|
--- a/daemon/gdm-display.c
|
||||||
|
+++ b/daemon/gdm-display.c
|
||||||
|
@@ -66,86 +66,88 @@ typedef struct _GdmDisplayPrivate
|
||||||
|
char *x11_display_name;
|
||||||
|
int status;
|
||||||
|
time_t creation_time;
|
||||||
|
|
||||||
|
char *x11_cookie;
|
||||||
|
gsize x11_cookie_size;
|
||||||
|
GdmDisplayAccessFile *access_file;
|
||||||
|
|
||||||
|
guint finish_idle_id;
|
||||||
|
|
||||||
|
xcb_connection_t *xcb_connection;
|
||||||
|
int xcb_screen_number;
|
||||||
|
|
||||||
|
GDBusConnection *connection;
|
||||||
|
GdmDisplayAccessFile *user_access_file;
|
||||||
|
|
||||||
|
GdmDBusDisplay *display_skeleton;
|
||||||
|
GDBusObjectSkeleton *object_skeleton;
|
||||||
|
|
||||||
|
GDBusProxy *accountsservice_proxy;
|
||||||
|
|
||||||
|
/* this spawns and controls the greeter session */
|
||||||
|
GdmLaunchEnvironment *launch_environment;
|
||||||
|
|
||||||
|
guint is_local : 1;
|
||||||
|
guint is_initial : 1;
|
||||||
|
guint allow_timed_login : 1;
|
||||||
|
guint have_existing_user_accounts : 1;
|
||||||
|
guint doing_initial_setup : 1;
|
||||||
|
guint session_registered : 1;
|
||||||
|
+ guint shutting_down : 1;
|
||||||
|
|
||||||
|
GStrv supported_session_types;
|
||||||
|
} GdmDisplayPrivate;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0,
|
||||||
|
PROP_ID,
|
||||||
|
PROP_STATUS,
|
||||||
|
PROP_SEAT_ID,
|
||||||
|
PROP_SESSION_ID,
|
||||||
|
PROP_SESSION_CLASS,
|
||||||
|
PROP_SESSION_TYPE,
|
||||||
|
PROP_REMOTE_HOSTNAME,
|
||||||
|
PROP_X11_DISPLAY_NUMBER,
|
||||||
|
PROP_X11_DISPLAY_NAME,
|
||||||
|
PROP_X11_COOKIE,
|
||||||
|
PROP_X11_AUTHORITY_FILE,
|
||||||
|
PROP_IS_CONNECTED,
|
||||||
|
PROP_IS_LOCAL,
|
||||||
|
PROP_LAUNCH_ENVIRONMENT,
|
||||||
|
PROP_IS_INITIAL,
|
||||||
|
PROP_ALLOW_TIMED_LOGIN,
|
||||||
|
PROP_HAVE_EXISTING_USER_ACCOUNTS,
|
||||||
|
PROP_DOING_INITIAL_SETUP,
|
||||||
|
PROP_SESSION_REGISTERED,
|
||||||
|
PROP_SUPPORTED_SESSION_TYPES,
|
||||||
|
+ PROP_SHUTTING_DOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gdm_display_class_init (GdmDisplayClass *klass);
|
||||||
|
static void gdm_display_init (GdmDisplay *self);
|
||||||
|
static void gdm_display_finalize (GObject *object);
|
||||||
|
static void queue_finish (GdmDisplay *self);
|
||||||
|
static void _gdm_display_set_status (GdmDisplay *self,
|
||||||
|
int status);
|
||||||
|
static gboolean wants_initial_setup (GdmDisplay *self);
|
||||||
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdmDisplay, gdm_display, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
GQuark
|
||||||
|
gdm_display_error_quark (void)
|
||||||
|
{
|
||||||
|
static GQuark ret = 0;
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = g_quark_from_static_string ("gdm_display_error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t
|
||||||
|
gdm_display_get_creation_time (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), 0);
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
@@ -665,61 +667,61 @@ gdm_display_disconnect (GdmDisplay *self)
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_flush (priv->xcb_connection);
|
||||||
|
|
||||||
|
g_clear_pointer (&priv->xcb_connection, xcb_disconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_display_unmanage (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
|
||||||
|
gdm_display_disconnect (self);
|
||||||
|
|
||||||
|
if (priv->user_access_file != NULL) {
|
||||||
|
gdm_display_access_file_close (priv->user_access_file);
|
||||||
|
g_object_unref (priv->user_access_file);
|
||||||
|
priv->user_access_file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->access_file != NULL) {
|
||||||
|
gdm_display_access_file_close (priv->access_file);
|
||||||
|
g_object_unref (priv->access_file);
|
||||||
|
priv->access_file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!priv->session_registered) {
|
||||||
|
+ if (!priv->session_registered && !priv->shutting_down) {
|
||||||
|
g_warning ("GdmDisplay: Session never registered, failing");
|
||||||
|
_gdm_display_set_status (self, GDM_DISPLAY_FAILED);
|
||||||
|
} else {
|
||||||
|
_gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_display_get_id (GdmDisplay *self,
|
||||||
|
char **id,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
if (id != NULL) {
|
||||||
|
*id = g_strdup (priv->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_display_get_x11_display_name (GdmDisplay *self,
|
||||||
|
char **x11_display,
|
||||||
|
GError **error)
|
||||||
|
@@ -851,60 +853,70 @@ _gdm_display_set_x11_cookie (GdmDisplay *self,
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
g_free (priv->x11_cookie);
|
||||||
|
priv->x11_cookie = g_strdup (x11_cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gdm_display_set_is_local (GdmDisplay *self,
|
||||||
|
gboolean is_local)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
g_debug ("GdmDisplay: local: %s", is_local? "yes" : "no");
|
||||||
|
priv->is_local = is_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gdm_display_set_session_registered (GdmDisplay *self,
|
||||||
|
gboolean registered)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
g_debug ("GdmDisplay: session registered: %s", registered? "yes" : "no");
|
||||||
|
priv->session_registered = registered;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+_gdm_display_set_shutting_down (GdmDisplay *self,
|
||||||
|
+ gboolean shutting_down)
|
||||||
|
+{
|
||||||
|
+ GdmDisplayPrivate *priv;
|
||||||
|
+
|
||||||
|
+ priv = gdm_display_get_instance_private (self);
|
||||||
|
+ priv->shutting_down = shutting_down;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
_gdm_display_set_launch_environment (GdmDisplay *self,
|
||||||
|
GdmLaunchEnvironment *launch_environment)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
|
||||||
|
g_clear_object (&priv->launch_environment);
|
||||||
|
|
||||||
|
priv->launch_environment = g_object_ref (launch_environment);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gdm_display_set_is_initial (GdmDisplay *self,
|
||||||
|
gboolean initial)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
g_debug ("GdmDisplay: initial: %s", initial? "yes" : "no");
|
||||||
|
priv->is_initial = initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gdm_display_set_allow_timed_login (GdmDisplay *self,
|
||||||
|
gboolean allow_timed_login)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
@@ -962,60 +974,63 @@ gdm_display_set_property (GObject *object,
|
||||||
|
case PROP_REMOTE_HOSTNAME:
|
||||||
|
_gdm_display_set_remote_hostname (self, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
case PROP_X11_DISPLAY_NUMBER:
|
||||||
|
_gdm_display_set_x11_display_number (self, g_value_get_int (value));
|
||||||
|
break;
|
||||||
|
case PROP_X11_DISPLAY_NAME:
|
||||||
|
_gdm_display_set_x11_display_name (self, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
case PROP_X11_COOKIE:
|
||||||
|
_gdm_display_set_x11_cookie (self, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
case PROP_IS_LOCAL:
|
||||||
|
_gdm_display_set_is_local (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_ALLOW_TIMED_LOGIN:
|
||||||
|
_gdm_display_set_allow_timed_login (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_LAUNCH_ENVIRONMENT:
|
||||||
|
_gdm_display_set_launch_environment (self, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
case PROP_IS_INITIAL:
|
||||||
|
_gdm_display_set_is_initial (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_SESSION_REGISTERED:
|
||||||
|
_gdm_display_set_session_registered (self, g_value_get_boolean (value));
|
||||||
|
break;
|
||||||
|
case PROP_SUPPORTED_SESSION_TYPES:
|
||||||
|
_gdm_display_set_supported_session_types (self, g_value_get_boxed (value));
|
||||||
|
break;
|
||||||
|
+ case PROP_SHUTTING_DOWN:
|
||||||
|
+ _gdm_display_set_shutting_down (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;
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
self = GDM_DISPLAY (object);
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_ID:
|
||||||
|
g_value_set_string (value, priv->id);
|
||||||
|
break;
|
||||||
|
case PROP_STATUS:
|
||||||
|
g_value_set_int (value, priv->status);
|
||||||
|
break;
|
||||||
|
case PROP_SEAT_ID:
|
||||||
|
g_value_set_string (value, priv->seat_id);
|
||||||
|
break;
|
||||||
|
case PROP_SESSION_ID:
|
||||||
|
g_value_set_string (value, priv->session_id);
|
||||||
|
@@ -1043,60 +1058,63 @@ gdm_display_get_property (GObject *object,
|
||||||
|
priv->access_file?
|
||||||
|
gdm_display_access_file_get_path (priv->access_file) : NULL);
|
||||||
|
break;
|
||||||
|
case PROP_IS_LOCAL:
|
||||||
|
g_value_set_boolean (value, priv->is_local);
|
||||||
|
break;
|
||||||
|
case PROP_IS_CONNECTED:
|
||||||
|
g_value_set_boolean (value, priv->xcb_connection != NULL);
|
||||||
|
break;
|
||||||
|
case PROP_LAUNCH_ENVIRONMENT:
|
||||||
|
g_value_set_object (value, priv->launch_environment);
|
||||||
|
break;
|
||||||
|
case PROP_IS_INITIAL:
|
||||||
|
g_value_set_boolean (value, priv->is_initial);
|
||||||
|
break;
|
||||||
|
case PROP_HAVE_EXISTING_USER_ACCOUNTS:
|
||||||
|
g_value_set_boolean (value, priv->have_existing_user_accounts);
|
||||||
|
break;
|
||||||
|
case PROP_DOING_INITIAL_SETUP:
|
||||||
|
g_value_set_boolean (value, priv->doing_initial_setup);
|
||||||
|
break;
|
||||||
|
case PROP_SESSION_REGISTERED:
|
||||||
|
g_value_set_boolean (value, priv->session_registered);
|
||||||
|
break;
|
||||||
|
case PROP_ALLOW_TIMED_LOGIN:
|
||||||
|
g_value_set_boolean (value, priv->allow_timed_login);
|
||||||
|
break;
|
||||||
|
case PROP_SUPPORTED_SESSION_TYPES:
|
||||||
|
g_value_set_boxed (value, priv->supported_session_types);
|
||||||
|
break;
|
||||||
|
+ case PROP_SHUTTING_DOWN:
|
||||||
|
+ g_value_set_boolean (value, priv->shutting_down);
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_get_id (GdmDBusDisplay *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
GdmDisplay *self)
|
||||||
|
{
|
||||||
|
char *id;
|
||||||
|
|
||||||
|
gdm_display_get_id (self, &id, NULL);
|
||||||
|
|
||||||
|
gdm_dbus_display_complete_get_id (skeleton, invocation, id);
|
||||||
|
|
||||||
|
g_free (id);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_get_remote_hostname (GdmDBusDisplay *skeleton,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
GdmDisplay *self)
|
||||||
|
{
|
||||||
|
char *hostname;
|
||||||
|
|
||||||
|
gdm_display_get_remote_hostname (self, &hostname, NULL);
|
||||||
|
|
||||||
|
@@ -1397,60 +1415,68 @@ gdm_display_class_init (GdmDisplayClass *klass)
|
||||||
|
g_param_spec_boolean ("session-registered",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_LAUNCH_ENVIRONMENT,
|
||||||
|
g_param_spec_object ("launch-environment",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
GDM_TYPE_LAUNCH_ENVIRONMENT,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_STATUS,
|
||||||
|
g_param_spec_int ("status",
|
||||||
|
"status",
|
||||||
|
"status",
|
||||||
|
-1,
|
||||||
|
G_MAXINT,
|
||||||
|
GDM_DISPLAY_UNMANAGED,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_SUPPORTED_SESSION_TYPES,
|
||||||
|
g_param_spec_boxed ("supported-session-types",
|
||||||
|
"supported session types",
|
||||||
|
"supported session types",
|
||||||
|
G_TYPE_STRV,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
|
||||||
|
+
|
||||||
|
+ g_object_class_install_property (object_class,
|
||||||
|
+ PROP_SHUTTING_DOWN,
|
||||||
|
+ g_param_spec_boolean ("shutting-down",
|
||||||
|
+ NULL,
|
||||||
|
+ NULL,
|
||||||
|
+ FALSE,
|
||||||
|
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdm_display_init (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
|
||||||
|
priv->creation_time = time (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdm_display_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GdmDisplay *self;
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (object != NULL);
|
||||||
|
g_return_if_fail (GDM_IS_DISPLAY (object));
|
||||||
|
|
||||||
|
self = GDM_DISPLAY (object);
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
|
||||||
|
g_return_if_fail (priv != NULL);
|
||||||
|
|
||||||
|
g_debug ("GdmDisplay: Finalizing display: %s", priv->id);
|
||||||
|
g_free (priv->id);
|
||||||
|
g_free (priv->seat_id);
|
||||||
|
g_free (priv->session_class);
|
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
||||||
|
index c70248f3..05851001 100644
|
||||||
|
--- a/daemon/gdm-manager.c
|
||||||
|
+++ b/daemon/gdm-manager.c
|
||||||
|
@@ -2759,117 +2759,120 @@ gdm_manager_init (GdmManager *manager)
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify)
|
||||||
|
g_object_unref);
|
||||||
|
manager->priv->transient_sessions = g_hash_table_new_full (NULL,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify)
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify)
|
||||||
|
g_object_unref);
|
||||||
|
g_signal_connect (G_OBJECT (manager->priv->display_store),
|
||||||
|
"display-added",
|
||||||
|
G_CALLBACK (on_display_added),
|
||||||
|
manager);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (manager->priv->display_store),
|
||||||
|
"display-removed",
|
||||||
|
G_CALLBACK (on_display_removed),
|
||||||
|
manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
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)
|
||||||
|
+shut_down_display (const char *id,
|
||||||
|
+ GdmDisplay *display,
|
||||||
|
+ GdmManager *manager)
|
||||||
|
{
|
||||||
|
gdm_display_stop_greeter_session (display);
|
||||||
|
+
|
||||||
|
+ g_object_set (G_OBJECT (display), "shutting-down", TRUE, NULL);
|
||||||
|
+
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
gdm_display_store_foreach (manager->priv->display_store,
|
||||||
|
- (GdmDisplayStoreFunc) finish_display,
|
||||||
|
+ (GdmDisplayStoreFunc) shut_down_display,
|
||||||
|
manager);
|
||||||
|
|
||||||
|
gdm_display_store_clear (manager->priv->display_store);
|
||||||
|
|
||||||
|
g_dbus_object_manager_server_set_connection (manager->priv->object_manager, NULL);
|
||||||
|
|
||||||
|
g_clear_object (&manager->priv->connection);
|
||||||
|
g_clear_object (&manager->priv->object_manager);
|
||||||
|
g_clear_object (&manager->priv->display_store);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gdm_manager_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
GdmManager *
|
||||||
|
gdm_manager_new (void)
|
||||||
|
{
|
||||||
|
if (manager_object != NULL) {
|
||||||
|
g_object_ref (manager_object);
|
||||||
|
} else {
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
manager_object = g_object_new (GDM_TYPE_MANAGER, NULL);
|
||||||
|
g_object_add_weak_pointer (manager_object,
|
||||||
|
(gpointer *) &manager_object);
|
||||||
|
res = register_manager (manager_object);
|
||||||
|
if (! res) {
|
||||||
|
g_object_unref (manager_object);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.37.0.rc1
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
From ff689b18fd0a5fd03e5941723cb2adff3b7e4b24 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Wed, 29 Sep 2021 11:03:41 -0400
|
||||||
|
Subject: [PATCH] daemon: Infer session type from desktop file if user has no
|
||||||
|
saved session type
|
||||||
|
|
||||||
|
The accountsservice user cache file can specify a session type
|
||||||
|
associated with the saved session. This is optional though. If one
|
||||||
|
isn't specified GDM needs to figure out the session type based on the
|
||||||
|
list of preferred session types for the system and the session file
|
||||||
|
itself.
|
||||||
|
|
||||||
|
It was failing to do the latter, though. This commit fixes that.
|
||||||
|
---
|
||||||
|
daemon/gdm-session.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||||||
|
index 29459346..72afe7b2 100644
|
||||||
|
--- a/daemon/gdm-session.c
|
||||||
|
+++ b/daemon/gdm-session.c
|
||||||
|
@@ -988,60 +988,62 @@ worker_on_saved_language_name_read (GdmDBusWorker *worker,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
worker_on_saved_session_name_read (GdmDBusWorker *worker,
|
||||||
|
const char *session_name,
|
||||||
|
GdmSessionConversation *conversation)
|
||||||
|
{
|
||||||
|
GdmSession *self = conversation->session;
|
||||||
|
|
||||||
|
if (! get_session_command_for_name (self, session_name, NULL)) {
|
||||||
|
/* ignore sessions that don't exist */
|
||||||
|
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
|
||||||
|
g_free (self->saved_session);
|
||||||
|
self->saved_session = NULL;
|
||||||
|
update_session_type (self);
|
||||||
|
} else {
|
||||||
|
if (strcmp (session_name,
|
||||||
|
get_default_session_name (self)) != 0) {
|
||||||
|
g_free (self->saved_session);
|
||||||
|
self->saved_session = g_strdup (session_name);
|
||||||
|
|
||||||
|
if (self->greeter_interface != NULL) {
|
||||||
|
gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface,
|
||||||
|
session_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self->saved_session_type != NULL)
|
||||||
|
set_session_type (self, self->saved_session_type);
|
||||||
|
+ else
|
||||||
|
+ update_session_type (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdmSessionConversation *
|
||||||
|
find_conversation_by_pid (GdmSession *self,
|
||||||
|
GPid pid)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, self->conversations);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||||
|
GdmSessionConversation *conversation;
|
||||||
|
|
||||||
|
conversation = (GdmSessionConversation *) value;
|
||||||
|
|
||||||
|
if (conversation->worker_pid == pid) {
|
||||||
|
return conversation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
allow_worker_function (GDBusAuthObserver *observer,
|
||||||
|
GIOStream *stream,
|
||||||
|
GCredentials *credentials,
|
||||||
|
GdmSession *self)
|
||||||
|
--
|
||||||
|
2.33.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 b1557adf711577c62609f8a784f11fad66eb54ef 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.
|
||||||
---
|
---
|
||||||
@ -20,5 +20,5 @@ index 4d8bf1748..9694078fb 100644
|
|||||||
+system-db:distro
|
+system-db:distro
|
||||||
file-db:@DATADIR@/@PACKAGE@/greeter-dconf-defaults
|
file-db:@DATADIR@/@PACKAGE@/greeter-dconf-defaults
|
||||||
--
|
--
|
||||||
2.28.0
|
2.30.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
|
||||||
|
|
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
|
||||||
|
|
@ -0,0 +1,155 @@
|
|||||||
|
From cbfb3ef99ecc9cbb4e6850e5dd0cc9fb65dd398a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Tue, 1 Sep 2020 13:49:27 -0400
|
||||||
|
Subject: [PATCH 1/3] display: Handle failure before display registration
|
||||||
|
|
||||||
|
Normally, e.g., gdm-wayland-session would register its display
|
||||||
|
before starting the session. This display registration is how
|
||||||
|
the display moves to the "managed" state. We currently detect
|
||||||
|
session failure in gdm_display_unmanage. If gdm-wayland-session
|
||||||
|
is killed before it registers the display, gdm_display_unmanage
|
||||||
|
won't run, and failure won't be detected.
|
||||||
|
|
||||||
|
This commit make gdm_display_unmanage get called, even if the
|
||||||
|
display isn't yet fully managed.
|
||||||
|
---
|
||||||
|
daemon/gdm-display.c | 8 +++-----
|
||||||
|
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
|
||||||
|
index 7c954ad24..3a260923a 100644
|
||||||
|
--- a/daemon/gdm-display.c
|
||||||
|
+++ b/daemon/gdm-display.c
|
||||||
|
@@ -648,62 +648,60 @@ gdm_display_disconnect (GdmDisplay *self)
|
||||||
|
|
||||||
|
/* resource_id_mask is the bits given to each client for
|
||||||
|
* addressing resources */
|
||||||
|
highest_client = (XID) ~unused_bits & ~setup->resource_id_mask;
|
||||||
|
client_increment = setup->resource_id_mask + 1;
|
||||||
|
|
||||||
|
/* Kill every client but ourselves, then close our own connection
|
||||||
|
*/
|
||||||
|
for (client = 0;
|
||||||
|
client <= highest_client;
|
||||||
|
client += client_increment) {
|
||||||
|
|
||||||
|
if (client != setup->resource_id_base)
|
||||||
|
xcb_kill_client (priv->xcb_connection, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_flush (priv->xcb_connection);
|
||||||
|
|
||||||
|
g_clear_pointer (&priv->xcb_connection, xcb_disconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_display_unmanage (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
|
||||||
|
- g_debug ("GdmDisplay: unmanage display");
|
||||||
|
-
|
||||||
|
gdm_display_disconnect (self);
|
||||||
|
|
||||||
|
if (priv->user_access_file != NULL) {
|
||||||
|
gdm_display_access_file_close (priv->user_access_file);
|
||||||
|
g_object_unref (priv->user_access_file);
|
||||||
|
priv->user_access_file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->access_file != NULL) {
|
||||||
|
gdm_display_access_file_close (priv->access_file);
|
||||||
|
g_object_unref (priv->access_file);
|
||||||
|
priv->access_file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!priv->session_registered) {
|
||||||
|
g_warning ("GdmDisplay: Session never registered, failing");
|
||||||
|
_gdm_display_set_status (self, GDM_DISPLAY_FAILED);
|
||||||
|
} else {
|
||||||
|
_gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_display_get_id (GdmDisplay *self,
|
||||||
|
char **id,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
@@ -1446,63 +1444,63 @@ gdm_display_get_object_skeleton (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
GdmDisplayPrivate *priv;
|
||||||
|
|
||||||
|
priv = gdm_display_get_instance_private (self);
|
||||||
|
return priv->object_skeleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment,
|
||||||
|
GdmDisplay *self)
|
||||||
|
{
|
||||||
|
char *session_id;
|
||||||
|
|
||||||
|
g_debug ("GdmDisplay: Greeter session opened");
|
||||||
|
session_id = gdm_launch_environment_get_session_id (launch_environment);
|
||||||
|
_gdm_display_set_session_id (self, session_id);
|
||||||
|
g_free (session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_launch_environment_session_started (GdmLaunchEnvironment *launch_environment,
|
||||||
|
GdmDisplay *self)
|
||||||
|
{
|
||||||
|
g_debug ("GdmDisplay: Greeter started");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
self_destruct (GdmDisplay *self)
|
||||||
|
{
|
||||||
|
g_object_ref (self);
|
||||||
|
- if (gdm_display_get_status (self) == GDM_DISPLAY_MANAGED) {
|
||||||
|
- gdm_display_unmanage (self);
|
||||||
|
- }
|
||||||
|
+
|
||||||
|
+ g_debug ("GdmDisplay: initiating display self-destruct");
|
||||||
|
+ gdm_display_unmanage (self);
|
||||||
|
|
||||||
|
if (gdm_display_get_status (self) != GDM_DISPLAY_FINISHED) {
|
||||||
|
queue_finish (self);
|
||||||
|
}
|
||||||
|
g_object_unref (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_launch_environment_session_stopped (GdmLaunchEnvironment *launch_environment,
|
||||||
|
GdmDisplay *self)
|
||||||
|
{
|
||||||
|
g_debug ("GdmDisplay: Greeter stopped");
|
||||||
|
self_destruct (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_launch_environment_session_exited (GdmLaunchEnvironment *launch_environment,
|
||||||
|
int code,
|
||||||
|
GdmDisplay *self)
|
||||||
|
{
|
||||||
|
g_debug ("GdmDisplay: Greeter exited: %d", code);
|
||||||
|
self_destruct (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_launch_environment_session_died (GdmLaunchEnvironment *launch_environment,
|
||||||
|
int signal,
|
||||||
|
GdmDisplay *self)
|
||||||
|
{
|
||||||
|
g_debug ("GdmDisplay: Greeter died: %d", signal);
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -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
@ -0,0 +1,344 @@
|
|||||||
|
From d80807171a457ff87bdc9bd861939161749a37a8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Thu, 20 Dec 2018 14:51:38 -0500
|
||||||
|
Subject: [PATCH 1/3] manager: allow multiple xdmcp logins for the same user
|
||||||
|
|
||||||
|
---
|
||||||
|
common/gdm-settings-keys.h | 1 +
|
||||||
|
daemon/gdm-manager.c | 71 ++++++++++++++++++++++++++++----------
|
||||||
|
data/gdm.schemas.in | 5 +++
|
||||||
|
3 files changed, 59 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
|
||||||
|
index 87685d3cd..4b3a1ffeb 100644
|
||||||
|
--- a/common/gdm-settings-keys.h
|
||||||
|
+++ b/common/gdm-settings-keys.h
|
||||||
|
@@ -30,37 +30,38 @@ G_BEGIN_DECLS
|
||||||
|
#define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
|
||||||
|
#define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
|
||||||
|
#define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
|
||||||
|
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
|
||||||
|
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
|
||||||
|
#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable"
|
||||||
|
#define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer"
|
||||||
|
#define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable"
|
||||||
|
#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable"
|
||||||
|
|
||||||
|
#define GDM_KEY_DEBUG "debug/Enable"
|
||||||
|
|
||||||
|
#define GDM_KEY_INCLUDE "greeter/Include"
|
||||||
|
#define GDM_KEY_EXCLUDE "greeter/Exclude"
|
||||||
|
#define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
|
||||||
|
|
||||||
|
#define GDM_KEY_DISALLOW_TCP "security/DisallowTCP"
|
||||||
|
#define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin"
|
||||||
|
|
||||||
|
#define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable"
|
||||||
|
#define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter"
|
||||||
|
#define GDM_KEY_MAX_PENDING "xdmcp/MaxPending"
|
||||||
|
#define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions"
|
||||||
|
#define GDM_KEY_MAX_WAIT "xdmcp/MaxWait"
|
||||||
|
#define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost"
|
||||||
|
#define GDM_KEY_UDP_PORT "xdmcp/Port"
|
||||||
|
#define GDM_KEY_INDIRECT "xdmcp/HonorIndirect"
|
||||||
|
#define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect"
|
||||||
|
#define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds"
|
||||||
|
#define GDM_KEY_WILLING "xdmcp/Willing"
|
||||||
|
+#define GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER "xdmcp/AllowMultipleSessionsPerUser"
|
||||||
|
|
||||||
|
#define GDM_KEY_MULTICAST "chooser/Multicast"
|
||||||
|
#define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr"
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* _GDM_SETTINGS_KEYS_H */
|
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
||||||
|
index e433acf3b..ce8565bf9 100644
|
||||||
|
--- a/daemon/gdm-manager.c
|
||||||
|
+++ b/daemon/gdm-manager.c
|
||||||
|
@@ -566,93 +566,106 @@ get_display_and_details_for_bus_sender (GdmManager *self,
|
||||||
|
*out_tty = get_tty_for_session_id (session_id, &error);
|
||||||
|
|
||||||
|
if (error != NULL) {
|
||||||
|
g_debug ("GdmManager: Error while retrieving tty for session: %s",
|
||||||
|
error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display = gdm_display_store_find (self->priv->display_store,
|
||||||
|
lookup_by_session_id,
|
||||||
|
(gpointer) session_id);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (out_display != NULL) {
|
||||||
|
*out_display = display;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (session_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
switch_to_compatible_user_session (GdmManager *manager,
|
||||||
|
GdmSession *session,
|
||||||
|
gboolean fail_if_already_switched)
|
||||||
|
{
|
||||||
|
gboolean res;
|
||||||
|
gboolean ret;
|
||||||
|
const char *username;
|
||||||
|
const char *seat_id;
|
||||||
|
- const char *ssid_to_activate;
|
||||||
|
+ const char *ssid_to_activate = NULL;
|
||||||
|
GdmSession *existing_session;
|
||||||
|
|
||||||
|
ret = FALSE;
|
||||||
|
|
||||||
|
username = gdm_session_get_username (session);
|
||||||
|
seat_id = gdm_session_get_display_seat_id (session);
|
||||||
|
|
||||||
|
- if (!fail_if_already_switched) {
|
||||||
|
- session = NULL;
|
||||||
|
- }
|
||||||
|
+ if (!fail_if_already_switched)
|
||||||
|
+ ssid_to_activate = gdm_session_get_session_id (session);
|
||||||
|
|
||||||
|
- existing_session = find_session_for_user_on_seat (manager, username, seat_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 (existing_session != NULL) {
|
||||||
|
- ssid_to_activate = gdm_session_get_session_id (existing_session);
|
||||||
|
- if (seat_id != NULL) {
|
||||||
|
- 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;
|
||||||
|
- }
|
||||||
|
+ if (!fail_if_already_switched) {
|
||||||
|
+ session = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- res = session_unlock (manager, ssid_to_activate);
|
||||||
|
- if (!res) {
|
||||||
|
- /* this isn't fatal */
|
||||||
|
- g_debug ("GdmManager: unable to unlock session: %s", ssid_to_activate);
|
||||||
|
+ 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);
|
||||||
|
}
|
||||||
|
- } else {
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ssid_to_activate == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (seat_id != NULL) {
|
||||||
|
+ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_object_get_data (G_OBJECT (display), "gdm-user-session");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
add_session_record (GdmManager *manager,
|
||||||
|
GdmSession *session,
|
||||||
|
GPid pid,
|
||||||
|
SessionRecord record)
|
||||||
|
{
|
||||||
|
const char *username;
|
||||||
|
char *display_name, *hostname, *display_device;
|
||||||
|
@@ -1089,92 +1102,114 @@ open_temporary_reauthentication_channel (GdmManager *self,
|
||||||
|
g_signal_connect (session,
|
||||||
|
"client-disconnected",
|
||||||
|
G_CALLBACK (on_reauthentication_client_disconnected),
|
||||||
|
self);
|
||||||
|
g_signal_connect (session,
|
||||||
|
"client-rejected",
|
||||||
|
G_CALLBACK (on_reauthentication_client_rejected),
|
||||||
|
self);
|
||||||
|
g_signal_connect (session,
|
||||||
|
"cancelled",
|
||||||
|
G_CALLBACK (on_reauthentication_cancelled),
|
||||||
|
self);
|
||||||
|
g_signal_connect (session,
|
||||||
|
"conversation-started",
|
||||||
|
G_CALLBACK (on_reauthentication_conversation_started),
|
||||||
|
self);
|
||||||
|
g_signal_connect (session,
|
||||||
|
"conversation-stopped",
|
||||||
|
G_CALLBACK (on_reauthentication_conversation_stopped),
|
||||||
|
self);
|
||||||
|
g_signal_connect (session,
|
||||||
|
"verification-complete",
|
||||||
|
G_CALLBACK (on_reauthentication_verification_complete),
|
||||||
|
self);
|
||||||
|
|
||||||
|
address = gdm_session_get_server_address (session);
|
||||||
|
|
||||||
|
return g_strdup (address);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static gboolean
|
||||||
|
+remote_users_can_log_in_more_than_once (GdmManager *manager)
|
||||||
|
+{
|
||||||
|
+ gboolean enabled;
|
||||||
|
+
|
||||||
|
+ enabled = FALSE;
|
||||||
|
+
|
||||||
|
+ gdm_settings_direct_get_boolean (GDM_KEY_ALLOW_MULTIPLE_SESSIONS_PER_USER, &enabled);
|
||||||
|
+
|
||||||
|
+ g_debug ("GdmDisplay: Remote users allowed to log in more than once: %s", enabled? "yes" : "no");
|
||||||
|
+
|
||||||
|
+ return enabled;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static gboolean
|
||||||
|
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
const char *username)
|
||||||
|
{
|
||||||
|
GdmManager *self = GDM_MANAGER (manager);
|
||||||
|
const char *sender;
|
||||||
|
GdmDisplay *display = NULL;
|
||||||
|
GdmSession *session;
|
||||||
|
GDBusConnection *connection;
|
||||||
|
char *seat_id = NULL;
|
||||||
|
char *session_id = NULL;
|
||||||
|
GPid pid = 0;
|
||||||
|
uid_t uid = (uid_t) -1;
|
||||||
|
gboolean is_login_screen = FALSE;
|
||||||
|
gboolean is_remote = FALSE;
|
||||||
|
|
||||||
|
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
|
||||||
|
|
||||||
|
sender = g_dbus_method_invocation_get_sender (invocation);
|
||||||
|
connection = g_dbus_method_invocation_get_connection (invocation);
|
||||||
|
get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id, NULL, &pid, &uid, &is_login_screen, &is_remote);
|
||||||
|
|
||||||
|
if (session_id == NULL || pid == 0 || uid == (uid_t) -1) {
|
||||||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||||||
|
G_DBUS_ERROR,
|
||||||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||||||
|
_("No session available"));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (is_login_screen && is_remote && remote_users_can_log_in_more_than_once (self)) {
|
||||||
|
+ g_dbus_method_invocation_return_error_literal (invocation,
|
||||||
|
+ G_DBUS_ERROR,
|
||||||
|
+ G_DBUS_ERROR_ACCESS_DENIED,
|
||||||
|
+ "Login screen creates new sessions for remote connections");
|
||||||
|
+ return TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (is_login_screen) {
|
||||||
|
g_debug ("GdmManager: looking for login screen session for user %s on seat %s", username, seat_id);
|
||||||
|
session = find_session_for_user_on_seat (self,
|
||||||
|
username,
|
||||||
|
seat_id,
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
|
g_debug ("GdmManager: looking for user session on display");
|
||||||
|
session = get_user_session_for_display (display);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session != NULL && gdm_session_is_running (session)) {
|
||||||
|
gdm_session_start_reauthentication (session, pid, uid);
|
||||||
|
g_hash_table_insert (self->priv->open_reauthentication_requests,
|
||||||
|
GINT_TO_POINTER (pid),
|
||||||
|
invocation);
|
||||||
|
} else if (is_login_screen) {
|
||||||
|
g_dbus_method_invocation_return_error_literal (invocation,
|
||||||
|
G_DBUS_ERROR,
|
||||||
|
G_DBUS_ERROR_ACCESS_DENIED,
|
||||||
|
"Login screen only allowed to open reauthentication channels for running sessions");
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
char *address;
|
||||||
|
address = open_temporary_reauthentication_channel (self,
|
||||||
|
seat_id,
|
||||||
|
session_id,
|
||||||
|
pid,
|
||||||
|
uid,
|
||||||
|
is_remote);
|
||||||
|
diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in
|
||||||
|
index a1035f95e..929d13d90 100644
|
||||||
|
--- a/data/gdm.schemas.in
|
||||||
|
+++ b/data/gdm.schemas.in
|
||||||
|
@@ -112,33 +112,38 @@
|
||||||
|
<schema>
|
||||||
|
<key>xdmcp/DisplaysPerHost</key>
|
||||||
|
<signature>i</signature>
|
||||||
|
<default>1</default>
|
||||||
|
</schema>
|
||||||
|
<schema>
|
||||||
|
<key>xdmcp/Port</key>
|
||||||
|
<signature>i</signature>
|
||||||
|
<default>177</default>
|
||||||
|
</schema>
|
||||||
|
<schema>
|
||||||
|
<key>xdmcp/HonorIndirect</key>
|
||||||
|
<signature>b</signature>
|
||||||
|
<default>true</default>
|
||||||
|
</schema>
|
||||||
|
<schema>
|
||||||
|
<key>xdmcp/MaxWaitIndirect</key>
|
||||||
|
<signature>i</signature>
|
||||||
|
<default>30</default>
|
||||||
|
</schema>
|
||||||
|
<schema>
|
||||||
|
<key>xdmcp/PingIntervalSeconds</key>
|
||||||
|
<signature>i</signature>
|
||||||
|
<default>0</default>
|
||||||
|
</schema>
|
||||||
|
<schema>
|
||||||
|
<key>xdmcp/Willing</key>
|
||||||
|
<signature>s</signature>
|
||||||
|
<default>@gdmconfdir@/Xwilling</default>
|
||||||
|
</schema>
|
||||||
|
+ <schema>
|
||||||
|
+ <key>xdmcp/AllowMultipleSessionsPerUser</key>
|
||||||
|
+ <signature>b</signature>
|
||||||
|
+ <default>false</default>
|
||||||
|
+ </schema>
|
||||||
|
</schemalist>
|
||||||
|
</gdmschemafile>
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
@ -0,0 +1,144 @@
|
|||||||
|
From f101371f418bb0013af1e5e1ef522277011fd48d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Coopersmith <alan.coopersmith@oracle.com>
|
||||||
|
Date: Thu, 7 Oct 2021 18:22:11 -0700
|
||||||
|
Subject: [PATCH 1/2] meson: Fix detection of Xorg versions that need -listen
|
||||||
|
tcp
|
||||||
|
|
||||||
|
Closes #704
|
||||||
|
---
|
||||||
|
meson.build | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index e6fcf4b8..06d09659 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -42,60 +42,63 @@ udev_dep = dependency('udev')
|
||||||
|
glib_min_version = '2.56.0'
|
||||||
|
|
||||||
|
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
||||||
|
gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version)
|
||||||
|
gio_dep = dependency('gio-2.0', version: '>=' + glib_min_version)
|
||||||
|
gio_unix_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
|
||||||
|
gtk_dep = dependency('gtk+-3.0', version: '>= 2.91.1')
|
||||||
|
libcanberra_gtk_dep = dependency('libcanberra-gtk3', version: '>= 0.4')
|
||||||
|
accountsservice_dep = dependency('accountsservice', version: '>= 0.6.35')
|
||||||
|
xcb_dep = dependency('xcb')
|
||||||
|
keyutils_dep = dependency('libkeyutils', required: false)
|
||||||
|
libselinux_dep = dependency('libselinux', required: get_option('selinux'))
|
||||||
|
|
||||||
|
# udev
|
||||||
|
if udev_dir == ''
|
||||||
|
if udev_dep.found()
|
||||||
|
udev_prefix = udev_dep.get_pkgconfig_variable('udevdir')
|
||||||
|
else
|
||||||
|
udev_prefix = gdm_prefix / 'lib' / 'udev'
|
||||||
|
endif
|
||||||
|
udev_dir = udev_prefix / 'rules.d'
|
||||||
|
endif
|
||||||
|
|
||||||
|
# X11
|
||||||
|
x_deps = declare_dependency(
|
||||||
|
dependencies: [
|
||||||
|
dependency('x11'),
|
||||||
|
dependency('xau'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
+# Xserver 1.17 & later default to -nolisten and require -listen for remote access
|
||||||
|
+xserver_deps = dependency('xorg-server', version : '>=1.17', required : false)
|
||||||
|
+xserver_nolisten_default = xserver_deps.found()
|
||||||
|
find_x_server_script = find_program('build-aux/find-x-server.sh', native: true)
|
||||||
|
find_x_server_out = run_command(find_x_server_script).stdout().strip()
|
||||||
|
if find_x_server_out != ''
|
||||||
|
x_bin = find_x_server_out
|
||||||
|
x_bin_path_split = x_bin.split('/')
|
||||||
|
i = 0
|
||||||
|
x_path = '/'
|
||||||
|
foreach dir : x_bin_path_split
|
||||||
|
if i < x_bin_path_split.length() - 1
|
||||||
|
x_path = x_path / dir
|
||||||
|
endif
|
||||||
|
i = i + 1
|
||||||
|
endforeach
|
||||||
|
else
|
||||||
|
# what to do, what to do, this is wrong, but this just sets the
|
||||||
|
# defaults, perhaps this user is cross compiling or some such
|
||||||
|
x_path = '/usr/bin/X11:/usr/X11R6/bin:/opt/X11R6/bin'
|
||||||
|
x_bin = '/usr/bin/X'
|
||||||
|
endif
|
||||||
|
xdmcp_dep = cc.find_library('Xdmcp', required: get_option('xdmcp'))
|
||||||
|
if xdmcp_dep.found() and get_option('tcp-wrappers')
|
||||||
|
libwrap_dep = cc.find_library('libwrap')
|
||||||
|
endif
|
||||||
|
# systemd
|
||||||
|
systemd_dep = dependency('systemd')
|
||||||
|
libsystemd_dep = dependency('libsystemd')
|
||||||
|
if meson.version().version_compare('>= 0.53')
|
||||||
|
systemd_multiseat_x = find_program('systemd-multi-seat-x',
|
||||||
|
required: false,
|
||||||
|
dirs: [
|
||||||
|
@@ -197,60 +200,61 @@ conf.set_quoted('SYSCONFDIR', gdm_prefix / get_option('sysconfdir'))
|
||||||
|
conf.set_quoted('BINDIR', gdm_prefix / get_option('bindir'))
|
||||||
|
conf.set_quoted('LIBDIR', gdm_prefix / get_option('libdir'))
|
||||||
|
conf.set_quoted('LIBEXECDIR', gdm_prefix / get_option('libexecdir'))
|
||||||
|
conf.set_quoted('LOGDIR', get_option('log-dir'))
|
||||||
|
conf.set_quoted('DMCONFDIR', dmconfdir)
|
||||||
|
conf.set_quoted('GDMCONFDIR', gdmconfdir)
|
||||||
|
conf.set_quoted('GDM_SCREENSHOT_DIR', gdm_screenshot_dir)
|
||||||
|
conf.set_quoted('GDM_XAUTH_DIR', gdm_xauth_dir)
|
||||||
|
conf.set_quoted('GDM_RAN_ONCE_MARKER_DIR', ran_once_marker_dir)
|
||||||
|
conf.set_quoted('GDM_RUN_DIR', gdm_run_dir)
|
||||||
|
conf.set_quoted('GNOMELOCALEDIR', gdm_prefix / get_option('localedir'))
|
||||||
|
conf.set_quoted('AT_SPI_REGISTRYD_DIR', at_spi_registryd_dir)
|
||||||
|
conf.set_quoted('GDM_PID_FILE', gdm_pid_file)
|
||||||
|
conf.set_quoted('GNOME_SETTINGS_DAEMON_DIR', gnome_settings_daemon_dir)
|
||||||
|
conf.set_quoted('LANG_CONFIG_FILE', lang_config_file)
|
||||||
|
conf.set('HAVE_ADT', have_adt)
|
||||||
|
conf.set('HAVE_UTMP_H', have_utmp_header)
|
||||||
|
conf.set('HAVE_UTMPX_H', have_utmpx_header)
|
||||||
|
conf.set('HAVE_POSIX_GETPWNAM_R', have_posix_getpwnam_r)
|
||||||
|
conf.set('UTMP', utmp_struct)
|
||||||
|
conf.set('HAVE_GETUTXENT', cc.has_function('getutxent'))
|
||||||
|
conf.set('HAVE_UPDWTMP', cc.has_function('updwtmp'))
|
||||||
|
conf.set('HAVE_UPDWTMPX', cc.has_function('updwtmpx'))
|
||||||
|
conf.set('HAVE_LOGIN', cc.has_function('login', args: '-lutil'))
|
||||||
|
conf.set('HAVE_LOGOUT', cc.has_function('logout', args: '-lutil'))
|
||||||
|
conf.set('HAVE_LOGWTMP', cc.has_function('logwtmp', args: '-lutil'))
|
||||||
|
conf.set('HAVE_PAM_SYSLOG', have_pam_syslog)
|
||||||
|
conf.set('HAVE_KEYUTILS', keyutils_dep.found())
|
||||||
|
conf.set('SUPPORTS_PAM_EXTENSIONS', pam_extensions_supported)
|
||||||
|
conf.set('HAVE_SELINUX', libselinux_dep.found())
|
||||||
|
+conf.set('HAVE_XSERVER_THAT_DEFAULTS_TO_LOCAL_ONLY', xserver_nolisten_default)
|
||||||
|
conf.set('ENABLE_USER_DISPLAY_SERVER', get_option('user-display-server'))
|
||||||
|
conf.set('ENABLE_SYSTEMD_JOURNAL', get_option('systemd-journal'))
|
||||||
|
conf.set('ENABLE_WAYLAND_SUPPORT', get_option('wayland-support'))
|
||||||
|
conf.set('ENABLE_PROFILING', get_option('profiling'))
|
||||||
|
conf.set('GDM_INITIAL_VT', get_option('initial-vt'))
|
||||||
|
conf.set_quoted('GDM_DEFAULTS_CONF', gdm_defaults_conf)
|
||||||
|
conf.set_quoted('GDM_CUSTOM_CONF', gdm_custom_conf)
|
||||||
|
conf.set_quoted('GDM_RUNTIME_CONF', gdm_runtime_conf)
|
||||||
|
conf.set_quoted('GDM_SESSION_DEFAULT_PATH', get_option('default-path'))
|
||||||
|
conf.set_quoted('GDM_USERNAME', get_option('user'))
|
||||||
|
conf.set_quoted('GDM_GROUPNAME', get_option('group'))
|
||||||
|
conf.set('HAVE_LIBXDMCP', xdmcp_dep.found())
|
||||||
|
conf.set_quoted('SYSTEMD_X_SERVER', systemd_x_server)
|
||||||
|
conf.set('WITH_PLYMOUTH', plymouth_dep.found())
|
||||||
|
conf.set_quoted('X_SERVER', x_bin)
|
||||||
|
conf.set_quoted('X_PATH', x_path)
|
||||||
|
conf.set('HAVE_UT_UT_HOST', utmp_has_host_field)
|
||||||
|
conf.set('HAVE_UT_UT_PID', utmp_has_pid_field)
|
||||||
|
conf.set('HAVE_UT_UT_ID', utmp_has_id_field)
|
||||||
|
conf.set('HAVE_UT_UT_NAME', utmp_has_name_field)
|
||||||
|
conf.set('HAVE_UT_UT_TYPE', utmp_has_type_field)
|
||||||
|
conf.set('HAVE_UT_UT_EXIT_E_TERMINATION', utmp_has_exit_e_termination_field)
|
||||||
|
conf.set('HAVE_UT_UT_USER', utmp_has_user_field)
|
||||||
|
conf.set('HAVE_UT_UT_TIME', utmp_has_time_field)
|
||||||
|
conf.set('HAVE_UT_UT_TV', utmp_has_tv_field)
|
||||||
|
conf.set('HAVE_UT_UT_SYSLEN', utmp_has_syslen_field)
|
||||||
|
conf.set('ENABLE_IPV6', get_option('ipv6'))
|
||||||
|
configure_file(output: 'config.h', configuration: conf)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
81
SOURCES/0001-meson-set-D_GNU_SOURCE-for-updwtmpx.patch
Normal file
81
SOURCES/0001-meson-set-D_GNU_SOURCE-for-updwtmpx.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
From 5a2d5dbdf8c6f6d3c896082a5a07b4292f5fb410 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sam James <sam@gentoo.org>
|
||||||
|
Date: Tue, 5 Jul 2022 01:47:35 +0100
|
||||||
|
Subject: [PATCH 1/2] meson: set -D_GNU_SOURCE for updwtmpx
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Without setting GNU_SOURCE, we end up getting:
|
||||||
|
```
|
||||||
|
../gdm-42.0/daemon/gdm-session-record.c:200:9: error: implicit declaration of function ‘updwtmpx’; did you mean ‘updwtmp’? [-Werror=implicit-function-declaration]
|
||||||
|
updwtmpx (GDM_NEW_SESSION_RECORDS_FILE, &session_record);
|
||||||
|
```
|
||||||
|
|
||||||
|
This ended up exposing a bug in updwtmp(3) (which is now fixed
|
||||||
|
thanks to the man-pages maintainers!) as it didn't mention that updwtmpx
|
||||||
|
is a GNU extension (and hence needs GNU_SOURCE in order to be available).
|
||||||
|
|
||||||
|
Alternatively, we could just #define _GNU_SOURCE in gdm-session-record.c
|
||||||
|
for updwtmpx.
|
||||||
|
|
||||||
|
Bug: https://bugzilla.kernel.org/show_bug.cgi?id=216168
|
||||||
|
---
|
||||||
|
meson.build | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 8328dd97..4a286f97 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -1,44 +1,47 @@
|
||||||
|
project('gdm', 'c',
|
||||||
|
version: '40.0',
|
||||||
|
license: 'GPL2+',
|
||||||
|
meson_version: '>= 0.50',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Modules
|
||||||
|
gnome = import('gnome')
|
||||||
|
pkgconfig = import('pkgconfig')
|
||||||
|
i18n = import('i18n')
|
||||||
|
|
||||||
|
# Compiler
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
|
||||||
|
+# Use GNU extensions if available
|
||||||
|
+add_project_arguments('-D_GNU_SOURCE', language: 'c')
|
||||||
|
+
|
||||||
|
# Options
|
||||||
|
gdm_prefix = get_option('prefix')
|
||||||
|
|
||||||
|
gdmconfdir = (get_option('sysconfsubdir') == '')? gdm_prefix / get_option('sysconfdir') : gdm_prefix / get_option('sysconfdir') / get_option('sysconfsubdir')
|
||||||
|
dmconfdir = (get_option('dmconfdir') != '')? get_option('dmconfdir') : gdm_prefix / get_option('sysconfdir') / 'dm'
|
||||||
|
udev_dir = get_option('udev-dir')
|
||||||
|
at_spi_registryd_dir = (get_option('at-spi-registryd-dir') != '')? get_option('at-spi-registryd-dir') : gdm_prefix / get_option('libexecdir')
|
||||||
|
lang_config_file = (get_option('lang-file') != '')? get_option('lang-file') : gdm_prefix / get_option('sysconfdir') / 'locale.conf'
|
||||||
|
pam_mod_dir = (get_option('pam-mod-dir') != '')? get_option('pam-mod-dir') : gdm_prefix / get_option('libdir') / 'security'
|
||||||
|
dbus_sys_dir = (get_option('dbus-sys') != '')? get_option('dbus-sys') : get_option('sysconfdir') / 'dbus-1' / 'system.d'
|
||||||
|
gdm_defaults_conf = (get_option('defaults-conf') != '')? get_option('defaults-conf') : gdm_prefix / get_option('datadir') / 'gdm' / 'defaults.conf'
|
||||||
|
gdm_custom_conf = (get_option('custom-conf') != '')? get_option('custom-conf') : gdmconfdir / 'custom.conf'
|
||||||
|
gnome_settings_daemon_dir = (get_option('gnome-settings-daemon-dir') != '')? get_option('gnome-settings-daemon-dir') : gdm_prefix / get_option('libexecdir')
|
||||||
|
gdm_run_dir = (get_option('run-dir') != '')? get_option('run-dir') : gdm_prefix / get_option('localstatedir') / 'run' / 'gdm'
|
||||||
|
gdm_runtime_conf = (get_option('runtime-conf') != '')? get_option('runtime-conf') : gdm_run_dir / 'custom.conf'
|
||||||
|
gdm_pid_file = (get_option('pid-file') != '')? get_option('pid-file') : gdm_run_dir / 'gdm.pid'
|
||||||
|
ran_once_marker_dir = (get_option('ran-once-marker-dir') != '')? get_option('ran-once-marker-dir') : gdm_run_dir
|
||||||
|
working_dir = (get_option('working-dir') != '')? get_option('working-dir') : gdm_prefix / get_option('localstatedir') / 'lib' / 'gdm'
|
||||||
|
gdm_xauth_dir = (get_option('xauth-dir') != '')? get_option('xauth-dir') : gdm_run_dir
|
||||||
|
gdm_screenshot_dir = (get_option('screenshot-dir') != '')? get_option('screenshot-dir') : gdm_run_dir / 'greeter'
|
||||||
|
|
||||||
|
# Common variables
|
||||||
|
config_h_dir = include_directories('.')
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
udev_dep = dependency('udev')
|
||||||
|
|
||||||
|
glib_min_version = '2.56.0'
|
||||||
|
|
||||||
|
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,84 @@
|
|||||||
|
From 56d12ad9697d5695c780a5be0065d23fec6bd1a5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chingkai Chu <3013329+chuchingkai@users.noreply.github.com>
|
||||||
|
Date: Thu, 12 Aug 2021 10:34:01 +0800
|
||||||
|
Subject: [PATCH] session-worker: Set session_vt=0 out of pam uninitialization
|
||||||
|
|
||||||
|
MR GNOME/gdm!123 moved jump_to_vt and session_vt reseting to a
|
||||||
|
separate function, so we don't need to reset session_vt in pam
|
||||||
|
uninitialization.
|
||||||
|
|
||||||
|
https://gitlab.gnome.org/GNOME/gdm/-/issues/719
|
||||||
|
---
|
||||||
|
daemon/gdm-session-worker.c | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
||||||
|
index c1201b70..9cff53a5 100644
|
||||||
|
--- a/daemon/gdm-session-worker.c
|
||||||
|
+++ b/daemon/gdm-session-worker.c
|
||||||
|
@@ -1076,62 +1076,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);
|
||||||
|
|
||||||
|
- 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) {
|
||||||
|
--
|
||||||
|
2.31.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
|
||||||
|
|
@ -0,0 +1,565 @@
|
|||||||
|
From f0dce28fa02210caa445e96d9cbec1d150b79e80 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Wed, 15 Aug 2018 10:48:16 -0400
|
||||||
|
Subject: [PATCH 1/4] worker: don't load user settings for program sessions
|
||||||
|
|
||||||
|
We don't need or want the login greeter to access accountsservice
|
||||||
|
for its session name
|
||||||
|
---
|
||||||
|
daemon/gdm-session-worker.c | 37 ++++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 26 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
||||||
|
index 9b8e0d87..438348df 100644
|
||||||
|
--- a/daemon/gdm-session-worker.c
|
||||||
|
+++ b/daemon/gdm-session-worker.c
|
||||||
|
@@ -400,103 +400,108 @@ gdm_session_execute (const char *file,
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_get_username (GdmSessionWorker *worker,
|
||||||
|
char **username)
|
||||||
|
{
|
||||||
|
gconstpointer item;
|
||||||
|
|
||||||
|
g_assert (worker->priv->pam_handle != NULL);
|
||||||
|
|
||||||
|
if (pam_get_item (worker->priv->pam_handle, PAM_USER, &item) == PAM_SUCCESS) {
|
||||||
|
if (username != NULL) {
|
||||||
|
*username = g_strdup ((char *) item);
|
||||||
|
g_debug ("GdmSessionWorker: username is '%s'",
|
||||||
|
*username != NULL ? *username : "<unset>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (worker->priv->auditor != NULL) {
|
||||||
|
gdm_session_auditor_set_username (worker->priv->auditor, (char *)item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
attempt_to_load_user_settings (GdmSessionWorker *worker,
|
||||||
|
const char *username)
|
||||||
|
{
|
||||||
|
+ if (worker->priv->user_settings == NULL)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (gdm_session_settings_is_loaded (worker->priv->user_settings))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
g_debug ("GdmSessionWorker: attempting to load user settings");
|
||||||
|
gdm_session_settings_load (worker->priv->user_settings,
|
||||||
|
username);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdm_session_worker_update_username (GdmSessionWorker *worker)
|
||||||
|
{
|
||||||
|
char *username;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
username = NULL;
|
||||||
|
res = gdm_session_worker_get_username (worker, &username);
|
||||||
|
if (res) {
|
||||||
|
g_debug ("GdmSessionWorker: old-username='%s' new-username='%s'",
|
||||||
|
worker->priv->username != NULL ? worker->priv->username : "<unset>",
|
||||||
|
username != NULL ? username : "<unset>");
|
||||||
|
|
||||||
|
|
||||||
|
gdm_session_auditor_set_username (worker->priv->auditor, worker->priv->username);
|
||||||
|
|
||||||
|
if ((worker->priv->username == username) ||
|
||||||
|
((worker->priv->username != NULL) && (username != NULL) &&
|
||||||
|
(strcmp (worker->priv->username, username) == 0)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
g_debug ("GdmSessionWorker: setting username to '%s'", username);
|
||||||
|
|
||||||
|
g_free (worker->priv->username);
|
||||||
|
worker->priv->username = username;
|
||||||
|
username = NULL;
|
||||||
|
|
||||||
|
gdm_dbus_worker_emit_username_changed (GDM_DBUS_WORKER (worker),
|
||||||
|
worker->priv->username);
|
||||||
|
|
||||||
|
/* We have a new username to try. If we haven't been able to
|
||||||
|
* read user settings up until now, then give it a go now
|
||||||
|
* (see the comment in do_setup for rationale on why it's useful
|
||||||
|
* to keep trying to read settings)
|
||||||
|
*/
|
||||||
|
if (worker->priv->username != NULL &&
|
||||||
|
- worker->priv->username[0] != '\0' &&
|
||||||
|
- !gdm_session_settings_is_loaded (worker->priv->user_settings)) {
|
||||||
|
+ worker->priv->username[0] != '\0') {
|
||||||
|
attempt_to_load_user_settings (worker, worker->priv->username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free (username);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_ask_question (GdmSessionWorker *worker,
|
||||||
|
const char *question,
|
||||||
|
char **answerp)
|
||||||
|
{
|
||||||
|
return gdm_dbus_worker_manager_call_info_query_sync (worker->priv->manager,
|
||||||
|
worker->priv->service,
|
||||||
|
question,
|
||||||
|
answerp,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_ask_for_secret (GdmSessionWorker *worker,
|
||||||
|
const char *question,
|
||||||
|
char **answerp)
|
||||||
|
{
|
||||||
|
return gdm_dbus_worker_manager_call_secret_info_query_sync (worker->priv->manager,
|
||||||
|
worker->priv->service,
|
||||||
|
question,
|
||||||
|
answerp,
|
||||||
|
@@ -2598,87 +2603,89 @@ gdm_session_worker_get_property (GObject *object,
|
||||||
|
g_value_set_boolean (value, self->priv->is_reauth_session);
|
||||||
|
break;
|
||||||
|
case PROP_STATE:
|
||||||
|
g_value_set_enum (value, self->priv->state);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
- gdm_session_settings_set_session_name (worker->priv->user_settings,
|
||||||
|
- 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_handle_set_session_display_mode (GdmDBusWorker *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
const char *str)
|
||||||
|
{
|
||||||
|
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
|
||||||
|
g_debug ("GdmSessionWorker: session display mode set to %s", str);
|
||||||
|
worker->priv->display_mode = gdm_session_display_mode_from_string (str);
|
||||||
|
gdm_dbus_worker_complete_set_session_display_mode (object, invocation);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_handle_set_language_name (GdmDBusWorker *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
const char *language_name)
|
||||||
|
{
|
||||||
|
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
|
||||||
|
g_debug ("GdmSessionWorker: language name set to %s", language_name);
|
||||||
|
- gdm_session_settings_set_language_name (worker->priv->user_settings,
|
||||||
|
- language_name);
|
||||||
|
+ if (worker->priv->user_settings != NULL)
|
||||||
|
+ gdm_session_settings_set_language_name (worker->priv->user_settings,
|
||||||
|
+ language_name);
|
||||||
|
gdm_dbus_worker_complete_set_language_name (object, invocation);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_saved_language_name_read (GdmSessionWorker *worker)
|
||||||
|
{
|
||||||
|
char *language_name;
|
||||||
|
|
||||||
|
language_name = gdm_session_settings_get_language_name (worker->priv->user_settings);
|
||||||
|
|
||||||
|
g_debug ("GdmSessionWorker: Saved language is %s", language_name);
|
||||||
|
gdm_dbus_worker_emit_saved_language_name_read (GDM_DBUS_WORKER (worker),
|
||||||
|
language_name);
|
||||||
|
g_free (language_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_saved_session_name_read (GdmSessionWorker *worker)
|
||||||
|
{
|
||||||
|
char *session_name;
|
||||||
|
|
||||||
|
session_name = gdm_session_settings_get_session_name (worker->priv->user_settings);
|
||||||
|
|
||||||
|
g_debug ("GdmSessionWorker: Saved session is %s", session_name);
|
||||||
|
gdm_dbus_worker_emit_saved_session_name_read (GDM_DBUS_WORKER (worker),
|
||||||
|
session_name);
|
||||||
|
g_free (session_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2756,110 +2763,113 @@ 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);
|
||||||
|
+
|
||||||
|
gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED);
|
||||||
|
- if (!gdm_session_settings_save (worker->priv->user_settings,
|
||||||
|
- worker->priv->username)) {
|
||||||
|
- g_warning ("could not save session and language settings");
|
||||||
|
+ 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);
|
||||||
|
|
||||||
|
if (worker->priv->state == GDM_SESSION_WORKER_STATE_NONE) {
|
||||||
|
g_debug ("GdmSessionWorker: queuing setup for user: %s %s",
|
||||||
|
worker->priv->username, worker->priv->display_device);
|
||||||
|
queue_state_change (worker);
|
||||||
|
} else if (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED) {
|
||||||
|
save_account_details_now (worker);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (worker->priv->user_settings),
|
||||||
|
G_CALLBACK (on_settings_is_loaded_changed),
|
||||||
|
worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_save_account_details_when_ready (GdmSessionWorker *worker)
|
||||||
|
{
|
||||||
|
g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCREDITED);
|
||||||
|
|
||||||
|
- if (!gdm_session_settings_is_loaded (worker->priv->user_settings)) {
|
||||||
|
+ if (worker->priv->user_settings != NULL && !gdm_session_settings_is_loaded (worker->priv->user_settings)) {
|
||||||
|
g_signal_connect (G_OBJECT (worker->priv->user_settings),
|
||||||
|
"notify::is-loaded",
|
||||||
|
G_CALLBACK (on_settings_is_loaded_changed),
|
||||||
|
worker);
|
||||||
|
g_debug ("GdmSessionWorker: user %s, not fully loaded yet, will save account details later",
|
||||||
|
worker->priv->username);
|
||||||
|
gdm_session_settings_load (worker->priv->user_settings,
|
||||||
|
worker->priv->username);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
save_account_details_now (worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_open_session (GdmSessionWorker *worker)
|
||||||
|
{
|
||||||
|
GError *error;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
res = gdm_session_worker_open_session (worker, &error);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
char *session_id = worker->priv->session_id;
|
||||||
|
if (session_id == NULL) {
|
||||||
|
session_id = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
gdm_dbus_worker_complete_open (GDM_DBUS_WORKER (worker), worker->priv->pending_invocation, session_id);
|
||||||
|
@@ -3103,155 +3113,161 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object,
|
||||||
|
if (g_strcmp0 (key, "service") == 0) {
|
||||||
|
worker->priv->service = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "extensions") == 0) {
|
||||||
|
worker->priv->extensions = filter_extensions (g_variant_get_strv (value, NULL));
|
||||||
|
} else if (g_strcmp0 (key, "username") == 0) {
|
||||||
|
worker->priv->username = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "is-program-session") == 0) {
|
||||||
|
worker->priv->is_program_session = g_variant_get_boolean (value);
|
||||||
|
} else if (g_strcmp0 (key, "log-file") == 0) {
|
||||||
|
worker->priv->log_file = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "x11-display-name") == 0) {
|
||||||
|
worker->priv->x11_display_name = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "x11-authority-file") == 0) {
|
||||||
|
worker->priv->x11_authority_file = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "console") == 0) {
|
||||||
|
worker->priv->display_device = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "seat-id") == 0) {
|
||||||
|
worker->priv->display_seat_id = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "hostname") == 0) {
|
||||||
|
worker->priv->hostname = g_variant_dup_string (value, NULL);
|
||||||
|
} else if (g_strcmp0 (key, "display-is-local") == 0) {
|
||||||
|
worker->priv->display_is_local = g_variant_get_boolean (value);
|
||||||
|
} else if (g_strcmp0 (key, "display-is-initial") == 0) {
|
||||||
|
worker->priv->display_is_initial = g_variant_get_boolean (value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
worker->priv->pending_invocation = invocation;
|
||||||
|
|
||||||
|
if (!worker->priv->is_program_session) {
|
||||||
|
+ worker->priv->user_settings = gdm_session_settings_new ();
|
||||||
|
+
|
||||||
|
g_signal_connect_swapped (worker->priv->user_settings,
|
||||||
|
"notify::language-name",
|
||||||
|
G_CALLBACK (on_saved_language_name_read),
|
||||||
|
worker);
|
||||||
|
|
||||||
|
g_signal_connect_swapped (worker->priv->user_settings,
|
||||||
|
"notify::session-name",
|
||||||
|
G_CALLBACK (on_saved_session_name_read),
|
||||||
|
worker);
|
||||||
|
|
||||||
|
if (worker->priv->username) {
|
||||||
|
wait_for_settings = !gdm_session_settings_load (worker->priv->user_settings,
|
||||||
|
worker->priv->username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_for_settings) {
|
||||||
|
/* Load settings from accounts daemon before continuing
|
||||||
|
*/
|
||||||
|
g_signal_connect (G_OBJECT (worker->priv->user_settings),
|
||||||
|
"notify::is-loaded",
|
||||||
|
G_CALLBACK (on_settings_is_loaded_changed),
|
||||||
|
worker);
|
||||||
|
} else {
|
||||||
|
queue_state_change (worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_handle_setup (GdmDBusWorker *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
const char *service,
|
||||||
|
const char *x11_display_name,
|
||||||
|
const char *x11_authority_file,
|
||||||
|
const char *console,
|
||||||
|
const char *seat_id,
|
||||||
|
const char *hostname,
|
||||||
|
gboolean display_is_local,
|
||||||
|
gboolean display_is_initial)
|
||||||
|
{
|
||||||
|
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
|
||||||
|
validate_and_queue_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE);
|
||||||
|
|
||||||
|
worker->priv->service = g_strdup (service);
|
||||||
|
worker->priv->x11_display_name = g_strdup (x11_display_name);
|
||||||
|
worker->priv->x11_authority_file = g_strdup (x11_authority_file);
|
||||||
|
worker->priv->display_device = g_strdup (console);
|
||||||
|
worker->priv->display_seat_id = g_strdup (seat_id);
|
||||||
|
worker->priv->hostname = g_strdup (hostname);
|
||||||
|
worker->priv->display_is_local = display_is_local;
|
||||||
|
worker->priv->display_is_initial = display_is_initial;
|
||||||
|
worker->priv->username = NULL;
|
||||||
|
|
||||||
|
+ worker->priv->user_settings = gdm_session_settings_new ();
|
||||||
|
+
|
||||||
|
g_signal_connect_swapped (worker->priv->user_settings,
|
||||||
|
"notify::language-name",
|
||||||
|
G_CALLBACK (on_saved_language_name_read),
|
||||||
|
worker);
|
||||||
|
|
||||||
|
g_signal_connect_swapped (worker->priv->user_settings,
|
||||||
|
"notify::session-name",
|
||||||
|
G_CALLBACK (on_saved_session_name_read),
|
||||||
|
worker);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_handle_setup_for_user (GdmDBusWorker *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
const char *service,
|
||||||
|
const char *username,
|
||||||
|
const char *x11_display_name,
|
||||||
|
const char *x11_authority_file,
|
||||||
|
const char *console,
|
||||||
|
const char *seat_id,
|
||||||
|
const char *hostname,
|
||||||
|
gboolean display_is_local,
|
||||||
|
gboolean display_is_initial)
|
||||||
|
{
|
||||||
|
GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
|
||||||
|
|
||||||
|
if (!validate_state_change (worker, invocation, GDM_SESSION_WORKER_STATE_SETUP_COMPLETE))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
worker->priv->service = g_strdup (service);
|
||||||
|
worker->priv->x11_display_name = g_strdup (x11_display_name);
|
||||||
|
worker->priv->x11_authority_file = g_strdup (x11_authority_file);
|
||||||
|
worker->priv->display_device = g_strdup (console);
|
||||||
|
worker->priv->display_seat_id = g_strdup (seat_id);
|
||||||
|
worker->priv->hostname = g_strdup (hostname);
|
||||||
|
worker->priv->display_is_local = display_is_local;
|
||||||
|
worker->priv->display_is_initial = display_is_initial;
|
||||||
|
worker->priv->username = g_strdup (username);
|
||||||
|
|
||||||
|
+ worker->priv->user_settings = gdm_session_settings_new ();
|
||||||
|
+
|
||||||
|
g_signal_connect_swapped (worker->priv->user_settings,
|
||||||
|
"notify::language-name",
|
||||||
|
G_CALLBACK (on_saved_language_name_read),
|
||||||
|
worker);
|
||||||
|
|
||||||
|
g_signal_connect_swapped (worker->priv->user_settings,
|
||||||
|
"notify::session-name",
|
||||||
|
G_CALLBACK (on_saved_session_name_read),
|
||||||
|
worker);
|
||||||
|
|
||||||
|
/* Load settings from accounts daemon before continuing
|
||||||
|
*/
|
||||||
|
worker->priv->pending_invocation = invocation;
|
||||||
|
if (gdm_session_settings_load (worker->priv->user_settings, username)) {
|
||||||
|
queue_state_change (worker);
|
||||||
|
} else {
|
||||||
|
g_signal_connect (G_OBJECT (worker->priv->user_settings),
|
||||||
|
"notify::is-loaded",
|
||||||
|
G_CALLBACK (on_settings_is_loaded_changed),
|
||||||
|
worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_session_worker_handle_setup_for_program (GdmDBusWorker *object,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
const char *service,
|
||||||
|
const char *username,
|
||||||
|
@@ -3589,61 +3605,60 @@ 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)
|
||||||
|
{
|
||||||
|
worker->priv = GDM_SESSION_WORKER_GET_PRIVATE (worker);
|
||||||
|
|
||||||
|
- worker->priv->user_settings = gdm_session_settings_new ();
|
||||||
|
worker->priv->reauthentication_requests = g_hash_table_new_full (NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify)
|
||||||
|
reauthentication_request_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,327 @@
|
|||||||
|
From d3823a5084e12d8f342fd4cbec29e23bdb646de7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alan Coopersmith <alan.coopersmith@oracle.com>
|
||||||
|
Date: Thu, 7 Oct 2021 18:22:11 -0700
|
||||||
|
Subject: [PATCH 2/2] daemon: Support X servers built with -Dlisten_tcp=true
|
||||||
|
|
||||||
|
Xorg since version 1.17 doesn't listen to tcp sockets by default
|
||||||
|
unless it's explicitly built with -Dlisten_tcp=true.
|
||||||
|
|
||||||
|
GDM currently assumes X servers 1.17 and later are always built
|
||||||
|
without specifying -Dlisten_tcp=true and doesn't work properly
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
This commit enhances GDM to better handle these non-standard builds by
|
||||||
|
always passing '-nolisten tcp' on the command line when tcp should
|
||||||
|
be disabled, and likewise always passing '-listen tcp' on the command
|
||||||
|
line, assuming the X server is new enough to support it, when tcp
|
||||||
|
should be enabled.
|
||||||
|
|
||||||
|
Related #704
|
||||||
|
---
|
||||||
|
daemon/gdm-server.c | 21 +++++++++++----------
|
||||||
|
daemon/gdm-x-session.c | 12 ++++++------
|
||||||
|
meson.build | 4 ++--
|
||||||
|
3 files changed, 19 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
|
||||||
|
index 1ba00d45..e5d23521 100644
|
||||||
|
--- a/daemon/gdm-server.c
|
||||||
|
+++ b/daemon/gdm-server.c
|
||||||
|
@@ -290,72 +290,73 @@ gdm_server_resolve_command_line (GdmServer *server,
|
||||||
|
if (strcmp (arg, "-query") == 0 ||
|
||||||
|
strcmp (arg, "-indirect") == 0)
|
||||||
|
query_in_arglist = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
argv = g_renew (char *, argv, len + 12);
|
||||||
|
/* shift args down one */
|
||||||
|
for (i = len - 1; i >= 1; i--) {
|
||||||
|
argv[i+1] = argv[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* server number is the FIRST argument, before any others */
|
||||||
|
argv[1] = g_strdup (server->display_name);
|
||||||
|
len++;
|
||||||
|
|
||||||
|
if (server->auth_file != NULL) {
|
||||||
|
argv[len++] = g_strdup ("-auth");
|
||||||
|
argv[len++] = g_strdup (server->auth_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server->display_seat_id != NULL) {
|
||||||
|
argv[len++] = g_strdup ("-seat");
|
||||||
|
argv[len++] = g_strdup (server->display_seat_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (!server->disable_tcp && ! query_in_arglist) {
|
||||||
|
- argv[len++] = g_strdup ("-listen");
|
||||||
|
- argv[len++] = g_strdup ("tcp");
|
||||||
|
- }
|
||||||
|
-#else
|
||||||
|
- if (server->disable_tcp && ! query_in_arglist) {
|
||||||
|
- argv[len++] = g_strdup ("-nolisten");
|
||||||
|
- argv[len++] = g_strdup ("tcp");
|
||||||
|
- }
|
||||||
|
+ if (!query_in_arglist) {
|
||||||
|
+ if (server->disable_tcp) {
|
||||||
|
+ argv[len++] = g_strdup ("-nolisten");
|
||||||
|
+ argv[len++] = g_strdup ("tcp");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+#ifdef HAVE_XSERVER_WITH_LISTEN
|
||||||
|
+ if (!server->disable_tcp) {
|
||||||
|
+ argv[len++] = g_strdup ("-listen");
|
||||||
|
+ argv[len++] = g_strdup ("tcp");
|
||||||
|
+ }
|
||||||
|
#endif
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (vtarg != NULL && ! gotvtarg) {
|
||||||
|
argv[len++] = g_strdup (vtarg);
|
||||||
|
}
|
||||||
|
|
||||||
|
argv[len++] = NULL;
|
||||||
|
|
||||||
|
*argvp = argv;
|
||||||
|
*argcp = len;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rotate_logs (const char *path,
|
||||||
|
guint n_copies)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = n_copies - 1; i > 0; i--) {
|
||||||
|
char *name_n;
|
||||||
|
char *name_n1;
|
||||||
|
|
||||||
|
name_n = g_strdup_printf ("%s.%d", path, i);
|
||||||
|
if (i > 1) {
|
||||||
|
name_n1 = g_strdup_printf ("%s.%d", path, i - 1);
|
||||||
|
} else {
|
||||||
|
name_n1 = g_strdup (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
|
||||||
|
index b1548361..d2a8aeb3 100644
|
||||||
|
--- a/daemon/gdm-x-session.c
|
||||||
|
+++ b/daemon/gdm-x-session.c
|
||||||
|
@@ -233,70 +233,70 @@ spawn_x_server (State *state,
|
||||||
|
|
||||||
|
if (g_getenv ("XDG_VTNR") != NULL) {
|
||||||
|
int vt;
|
||||||
|
|
||||||
|
vt = atoi (g_getenv ("XDG_VTNR"));
|
||||||
|
|
||||||
|
if (vt > 0 && vt < 64) {
|
||||||
|
vt_string = g_strdup_printf ("vt%d", vt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
display_fd_string = g_strdup_printf ("%d", DISPLAY_FILENO);
|
||||||
|
|
||||||
|
g_ptr_array_add (arguments, X_SERVER);
|
||||||
|
|
||||||
|
if (vt_string != NULL) {
|
||||||
|
g_ptr_array_add (arguments, vt_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 doesn'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");
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_XSERVER_WITH_LISTEN
|
||||||
|
+ if (allow_remote_connections) {
|
||||||
|
+ g_ptr_array_add (arguments, "-listen");
|
||||||
|
+ 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);
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 06d09659..8328dd97 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -44,61 +44,61 @@ glib_min_version = '2.56.0'
|
||||||
|
glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version)
|
||||||
|
gobject_dep = dependency('gobject-2.0', version: '>=' + glib_min_version)
|
||||||
|
gio_dep = dependency('gio-2.0', version: '>=' + glib_min_version)
|
||||||
|
gio_unix_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version)
|
||||||
|
gtk_dep = dependency('gtk+-3.0', version: '>= 2.91.1')
|
||||||
|
libcanberra_gtk_dep = dependency('libcanberra-gtk3', version: '>= 0.4')
|
||||||
|
accountsservice_dep = dependency('accountsservice', version: '>= 0.6.35')
|
||||||
|
xcb_dep = dependency('xcb')
|
||||||
|
keyutils_dep = dependency('libkeyutils', required: false)
|
||||||
|
libselinux_dep = dependency('libselinux', required: get_option('selinux'))
|
||||||
|
|
||||||
|
# udev
|
||||||
|
if udev_dir == ''
|
||||||
|
if udev_dep.found()
|
||||||
|
udev_prefix = udev_dep.get_pkgconfig_variable('udevdir')
|
||||||
|
else
|
||||||
|
udev_prefix = gdm_prefix / 'lib' / 'udev'
|
||||||
|
endif
|
||||||
|
udev_dir = udev_prefix / 'rules.d'
|
||||||
|
endif
|
||||||
|
|
||||||
|
# X11
|
||||||
|
x_deps = declare_dependency(
|
||||||
|
dependencies: [
|
||||||
|
dependency('x11'),
|
||||||
|
dependency('xau'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
# Xserver 1.17 & later default to -nolisten and require -listen for remote access
|
||||||
|
xserver_deps = dependency('xorg-server', version : '>=1.17', required : false)
|
||||||
|
-xserver_nolisten_default = xserver_deps.found()
|
||||||
|
+xserver_has_listen = xserver_deps.found()
|
||||||
|
find_x_server_script = find_program('build-aux/find-x-server.sh', native: true)
|
||||||
|
find_x_server_out = run_command(find_x_server_script).stdout().strip()
|
||||||
|
if find_x_server_out != ''
|
||||||
|
x_bin = find_x_server_out
|
||||||
|
x_bin_path_split = x_bin.split('/')
|
||||||
|
i = 0
|
||||||
|
x_path = '/'
|
||||||
|
foreach dir : x_bin_path_split
|
||||||
|
if i < x_bin_path_split.length() - 1
|
||||||
|
x_path = x_path / dir
|
||||||
|
endif
|
||||||
|
i = i + 1
|
||||||
|
endforeach
|
||||||
|
else
|
||||||
|
# what to do, what to do, this is wrong, but this just sets the
|
||||||
|
# defaults, perhaps this user is cross compiling or some such
|
||||||
|
x_path = '/usr/bin/X11:/usr/X11R6/bin:/opt/X11R6/bin'
|
||||||
|
x_bin = '/usr/bin/X'
|
||||||
|
endif
|
||||||
|
xdmcp_dep = cc.find_library('Xdmcp', required: get_option('xdmcp'))
|
||||||
|
if xdmcp_dep.found() and get_option('tcp-wrappers')
|
||||||
|
libwrap_dep = cc.find_library('libwrap')
|
||||||
|
endif
|
||||||
|
# systemd
|
||||||
|
systemd_dep = dependency('systemd')
|
||||||
|
libsystemd_dep = dependency('libsystemd')
|
||||||
|
if meson.version().version_compare('>= 0.53')
|
||||||
|
systemd_multiseat_x = find_program('systemd-multi-seat-x',
|
||||||
|
required: false,
|
||||||
|
dirs: [
|
||||||
|
@@ -200,61 +200,61 @@ conf.set_quoted('SYSCONFDIR', gdm_prefix / get_option('sysconfdir'))
|
||||||
|
conf.set_quoted('BINDIR', gdm_prefix / get_option('bindir'))
|
||||||
|
conf.set_quoted('LIBDIR', gdm_prefix / get_option('libdir'))
|
||||||
|
conf.set_quoted('LIBEXECDIR', gdm_prefix / get_option('libexecdir'))
|
||||||
|
conf.set_quoted('LOGDIR', get_option('log-dir'))
|
||||||
|
conf.set_quoted('DMCONFDIR', dmconfdir)
|
||||||
|
conf.set_quoted('GDMCONFDIR', gdmconfdir)
|
||||||
|
conf.set_quoted('GDM_SCREENSHOT_DIR', gdm_screenshot_dir)
|
||||||
|
conf.set_quoted('GDM_XAUTH_DIR', gdm_xauth_dir)
|
||||||
|
conf.set_quoted('GDM_RAN_ONCE_MARKER_DIR', ran_once_marker_dir)
|
||||||
|
conf.set_quoted('GDM_RUN_DIR', gdm_run_dir)
|
||||||
|
conf.set_quoted('GNOMELOCALEDIR', gdm_prefix / get_option('localedir'))
|
||||||
|
conf.set_quoted('AT_SPI_REGISTRYD_DIR', at_spi_registryd_dir)
|
||||||
|
conf.set_quoted('GDM_PID_FILE', gdm_pid_file)
|
||||||
|
conf.set_quoted('GNOME_SETTINGS_DAEMON_DIR', gnome_settings_daemon_dir)
|
||||||
|
conf.set_quoted('LANG_CONFIG_FILE', lang_config_file)
|
||||||
|
conf.set('HAVE_ADT', have_adt)
|
||||||
|
conf.set('HAVE_UTMP_H', have_utmp_header)
|
||||||
|
conf.set('HAVE_UTMPX_H', have_utmpx_header)
|
||||||
|
conf.set('HAVE_POSIX_GETPWNAM_R', have_posix_getpwnam_r)
|
||||||
|
conf.set('UTMP', utmp_struct)
|
||||||
|
conf.set('HAVE_GETUTXENT', cc.has_function('getutxent'))
|
||||||
|
conf.set('HAVE_UPDWTMP', cc.has_function('updwtmp'))
|
||||||
|
conf.set('HAVE_UPDWTMPX', cc.has_function('updwtmpx'))
|
||||||
|
conf.set('HAVE_LOGIN', cc.has_function('login', args: '-lutil'))
|
||||||
|
conf.set('HAVE_LOGOUT', cc.has_function('logout', args: '-lutil'))
|
||||||
|
conf.set('HAVE_LOGWTMP', cc.has_function('logwtmp', args: '-lutil'))
|
||||||
|
conf.set('HAVE_PAM_SYSLOG', have_pam_syslog)
|
||||||
|
conf.set('HAVE_KEYUTILS', keyutils_dep.found())
|
||||||
|
conf.set('SUPPORTS_PAM_EXTENSIONS', pam_extensions_supported)
|
||||||
|
conf.set('HAVE_SELINUX', libselinux_dep.found())
|
||||||
|
-conf.set('HAVE_XSERVER_THAT_DEFAULTS_TO_LOCAL_ONLY', xserver_nolisten_default)
|
||||||
|
+conf.set('HAVE_XSERVER_WITH_LISTEN', xserver_has_listen)
|
||||||
|
conf.set('ENABLE_USER_DISPLAY_SERVER', get_option('user-display-server'))
|
||||||
|
conf.set('ENABLE_SYSTEMD_JOURNAL', get_option('systemd-journal'))
|
||||||
|
conf.set('ENABLE_WAYLAND_SUPPORT', get_option('wayland-support'))
|
||||||
|
conf.set('ENABLE_PROFILING', get_option('profiling'))
|
||||||
|
conf.set('GDM_INITIAL_VT', get_option('initial-vt'))
|
||||||
|
conf.set_quoted('GDM_DEFAULTS_CONF', gdm_defaults_conf)
|
||||||
|
conf.set_quoted('GDM_CUSTOM_CONF', gdm_custom_conf)
|
||||||
|
conf.set_quoted('GDM_RUNTIME_CONF', gdm_runtime_conf)
|
||||||
|
conf.set_quoted('GDM_SESSION_DEFAULT_PATH', get_option('default-path'))
|
||||||
|
conf.set_quoted('GDM_USERNAME', get_option('user'))
|
||||||
|
conf.set_quoted('GDM_GROUPNAME', get_option('group'))
|
||||||
|
conf.set('HAVE_LIBXDMCP', xdmcp_dep.found())
|
||||||
|
conf.set_quoted('SYSTEMD_X_SERVER', systemd_x_server)
|
||||||
|
conf.set('WITH_PLYMOUTH', plymouth_dep.found())
|
||||||
|
conf.set_quoted('X_SERVER', x_bin)
|
||||||
|
conf.set_quoted('X_PATH', x_path)
|
||||||
|
conf.set('HAVE_UT_UT_HOST', utmp_has_host_field)
|
||||||
|
conf.set('HAVE_UT_UT_PID', utmp_has_pid_field)
|
||||||
|
conf.set('HAVE_UT_UT_ID', utmp_has_id_field)
|
||||||
|
conf.set('HAVE_UT_UT_NAME', utmp_has_name_field)
|
||||||
|
conf.set('HAVE_UT_UT_TYPE', utmp_has_type_field)
|
||||||
|
conf.set('HAVE_UT_UT_EXIT_E_TERMINATION', utmp_has_exit_e_termination_field)
|
||||||
|
conf.set('HAVE_UT_UT_USER', utmp_has_user_field)
|
||||||
|
conf.set('HAVE_UT_UT_TIME', utmp_has_time_field)
|
||||||
|
conf.set('HAVE_UT_UT_TV', utmp_has_tv_field)
|
||||||
|
conf.set('HAVE_UT_UT_SYSLEN', utmp_has_syslen_field)
|
||||||
|
conf.set('ENABLE_IPV6', get_option('ipv6'))
|
||||||
|
configure_file(output: 'config.h', configuration: conf)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,151 @@
|
|||||||
|
From 874b26e3674d540df37d7f145df853bcf81e5a26 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Wed, 5 Feb 2020 15:20:48 -0500
|
||||||
|
Subject: [PATCH 2/3] gdm-x-session: run session bus on non-seat0 seats
|
||||||
|
|
||||||
|
GNOME doesn't deal very well with multiple sessions
|
||||||
|
running on a multiple seats at the moment.
|
||||||
|
|
||||||
|
Until that's fixed, ensure sessions run on auxillary
|
||||||
|
seats get their own session bus.
|
||||||
|
---
|
||||||
|
daemon/gdm-session.c | 11 ++++++++++-
|
||||||
|
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||||||
|
index 418240dc0..77d6b8ff0 100644
|
||||||
|
--- a/daemon/gdm-session.c
|
||||||
|
+++ b/daemon/gdm-session.c
|
||||||
|
@@ -2822,119 +2822,128 @@ on_start_program_cb (GdmDBusWorker *worker,
|
||||||
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED) ||
|
||||||
|
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
self = conversation->session;
|
||||||
|
service_name = conversation->service_name;
|
||||||
|
|
||||||
|
if (worked) {
|
||||||
|
self->session_pid = pid;
|
||||||
|
self->session_conversation = conversation;
|
||||||
|
|
||||||
|
g_debug ("GdmSession: Emitting 'session-started' signal with pid '%d'", pid);
|
||||||
|
g_signal_emit (self, signals[SESSION_STARTED], 0, service_name, pid);
|
||||||
|
} else {
|
||||||
|
gdm_session_stop_conversation (self, service_name);
|
||||||
|
|
||||||
|
g_debug ("GdmSession: Emitting 'session-start-failed' signal");
|
||||||
|
g_signal_emit (self, signals[SESSION_START_FAILED], 0, service_name, error->message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdm_session_start_session (GdmSession *self,
|
||||||
|
const char *service_name)
|
||||||
|
{
|
||||||
|
GdmSessionConversation *conversation;
|
||||||
|
GdmSessionDisplayMode display_mode;
|
||||||
|
gboolean is_x11 = TRUE;
|
||||||
|
gboolean run_launcher = FALSE;
|
||||||
|
gboolean allow_remote_connections = FALSE;
|
||||||
|
+ gboolean run_separate_bus = FALSE;
|
||||||
|
char *command;
|
||||||
|
char *program;
|
||||||
|
gboolean register_session;
|
||||||
|
|
||||||
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||||||
|
g_return_if_fail (self->session_conversation == NULL);
|
||||||
|
|
||||||
|
conversation = find_conversation_by_name (self, service_name);
|
||||||
|
|
||||||
|
if (conversation == NULL) {
|
||||||
|
g_warning ("GdmSession: Tried to start session of "
|
||||||
|
"nonexistent conversation %s", service_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_all_other_conversations (self, conversation, FALSE);
|
||||||
|
|
||||||
|
display_mode = gdm_session_get_display_mode (self);
|
||||||
|
|
||||||
|
#ifdef ENABLE_WAYLAND_SUPPORT
|
||||||
|
is_x11 = g_strcmp0 (self->session_type, "wayland") != 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (display_mode == GDM_SESSION_DISPLAY_MODE_LOGIND_MANAGED ||
|
||||||
|
display_mode == GDM_SESSION_DISPLAY_MODE_NEW_VT) {
|
||||||
|
run_launcher = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_session = !gdm_session_session_registers (self);
|
||||||
|
|
||||||
|
+ if (g_strcmp0 (self->display_seat_id, "seat0") != 0 && !run_launcher) {
|
||||||
|
+ run_separate_bus = TRUE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (self->selected_program == NULL) {
|
||||||
|
gboolean run_xsession_script;
|
||||||
|
|
||||||
|
command = get_session_command (self);
|
||||||
|
|
||||||
|
run_xsession_script = !gdm_session_bypasses_xsession (self);
|
||||||
|
|
||||||
|
if (self->display_is_local) {
|
||||||
|
gboolean disallow_tcp = TRUE;
|
||||||
|
gdm_settings_direct_get_boolean (GDM_KEY_DISALLOW_TCP, &disallow_tcp);
|
||||||
|
allow_remote_connections = !disallow_tcp;
|
||||||
|
} else {
|
||||||
|
allow_remote_connections = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (run_launcher) {
|
||||||
|
if (is_x11) {
|
||||||
|
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s%s %s\"%s\"",
|
||||||
|
register_session ? "--register-session " : "",
|
||||||
|
run_xsession_script? "--run-script " : "",
|
||||||
|
allow_remote_connections? "--allow-remote-connections " : "",
|
||||||
|
command);
|
||||||
|
} else {
|
||||||
|
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"",
|
||||||
|
register_session ? "--register-session " : "",
|
||||||
|
command);
|
||||||
|
}
|
||||||
|
} else if (run_xsession_script) {
|
||||||
|
- program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
|
||||||
|
+ if (run_separate_bus) {
|
||||||
|
+ program = g_strdup_printf ("dbus-run-session -- " GDMCONFDIR "/Xsession \"%s\"", command);
|
||||||
|
+ } else {
|
||||||
|
+ program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
program = g_strdup (command);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (command);
|
||||||
|
} else {
|
||||||
|
/* FIXME:
|
||||||
|
* Always use a separate DBus bus for each greeter session.
|
||||||
|
* Firstly, this means that if we run multiple greeter session
|
||||||
|
* (which we really should not do, but have to currently), then
|
||||||
|
* each one will get its own DBus session bus.
|
||||||
|
* But, we also explicitly do this for seat0, because that way
|
||||||
|
* it cannot make use of systemd to run the GNOME session. This
|
||||||
|
* prevents the session lookup logic from getting confused.
|
||||||
|
* This has a similar effect as passing --builtin to gnome-session.
|
||||||
|
*
|
||||||
|
* We really should not be doing this. But the fix is to use
|
||||||
|
* separate dynamically created users and that requires some
|
||||||
|
* major refactorings.
|
||||||
|
*/
|
||||||
|
if (run_launcher) {
|
||||||
|
if (is_x11) {
|
||||||
|
program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"dbus-run-session -- %s\"",
|
||||||
|
register_session ? "--register-session " : "",
|
||||||
|
self->selected_program);
|
||||||
|
} else {
|
||||||
|
program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"dbus-run-session -- %s\"",
|
||||||
|
register_session ? "--register-session " : "",
|
||||||
|
self->selected_program);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
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 c00daca1579c47f3f62894ff2378c37e6cbebfd3 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/4] 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.34.1
|
||||||
|
|
227
SOURCES/0002-manager-Fix-btmp-record-accounting.patch
Normal file
227
SOURCES/0002-manager-Fix-btmp-record-accounting.patch
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
From 20725e4c65555178ed64a3cb77ee979ec98998f8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Wed, 19 Oct 2022 14:50:33 -0400
|
||||||
|
Subject: [PATCH 2/2] manager: Fix btmp record accounting
|
||||||
|
|
||||||
|
Before a user logs in they don't have a display.
|
||||||
|
|
||||||
|
btmp records currently need a display though, and they
|
||||||
|
get written when the user can't log in.
|
||||||
|
|
||||||
|
Furthermore, the display from X11 point of view is
|
||||||
|
somewhat archaic. We use wayland by default now.
|
||||||
|
|
||||||
|
In lieu of a display, this commit gives the btmp record
|
||||||
|
the seat id instead.
|
||||||
|
---
|
||||||
|
daemon/gdm-manager.c | 11 +++++++++--
|
||||||
|
daemon/gdm-session-record.c | 8 ++++++--
|
||||||
|
2 files changed, 15 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
|
||||||
|
index 4b62b8b1..c70248f3 100644
|
||||||
|
--- a/daemon/gdm-manager.c
|
||||||
|
+++ b/daemon/gdm-manager.c
|
||||||
|
@@ -641,113 +641,120 @@ switch_to_compatible_user_session (GdmManager *manager,
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_object_get_data (G_OBJECT (display), "gdm-user-session");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
add_session_record (GdmManager *manager,
|
||||||
|
GdmSession *session,
|
||||||
|
GPid pid,
|
||||||
|
SessionRecord record)
|
||||||
|
{
|
||||||
|
const char *username;
|
||||||
|
- char *display_name, *hostname, *display_device;
|
||||||
|
+ char *display_name, *hostname, *display_device, *display_seat_id;
|
||||||
|
gboolean recorded = FALSE;
|
||||||
|
|
||||||
|
display_name = NULL;
|
||||||
|
username = NULL;
|
||||||
|
hostname = NULL;
|
||||||
|
display_device = NULL;
|
||||||
|
+ display_seat_id = NULL;
|
||||||
|
|
||||||
|
username = gdm_session_get_username (session);
|
||||||
|
|
||||||
|
if (username == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_get (G_OBJECT (session),
|
||||||
|
"display-name", &display_name,
|
||||||
|
"display-hostname", &hostname,
|
||||||
|
"display-device", &display_device,
|
||||||
|
+ "display-seat-id", &display_seat_id,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (display_name == NULL && display_device == NULL) {
|
||||||
|
- goto out;
|
||||||
|
+ if (display_seat_id == NULL)
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ display_name = g_strdup ("login screen");
|
||||||
|
+ display_device = g_strdup (display_seat_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (record) {
|
||||||
|
case SESSION_RECORD_LOGIN:
|
||||||
|
gdm_session_record_login (pid,
|
||||||
|
username,
|
||||||
|
hostname,
|
||||||
|
display_name,
|
||||||
|
display_device);
|
||||||
|
break;
|
||||||
|
case SESSION_RECORD_LOGOUT:
|
||||||
|
gdm_session_record_logout (pid,
|
||||||
|
username,
|
||||||
|
hostname,
|
||||||
|
display_name,
|
||||||
|
display_device);
|
||||||
|
break;
|
||||||
|
case SESSION_RECORD_FAILED:
|
||||||
|
gdm_session_record_failed (pid,
|
||||||
|
username,
|
||||||
|
hostname,
|
||||||
|
display_name,
|
||||||
|
display_device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
recorded = TRUE;
|
||||||
|
out:
|
||||||
|
g_free (display_name);
|
||||||
|
g_free (hostname);
|
||||||
|
g_free (display_device);
|
||||||
|
+ g_free (display_seat_id);
|
||||||
|
|
||||||
|
return recorded;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdmSession *
|
||||||
|
find_user_session_for_display (GdmManager *self,
|
||||||
|
GdmDisplay *display)
|
||||||
|
{
|
||||||
|
|
||||||
|
GList *node = self->priv->user_sessions;
|
||||||
|
|
||||||
|
while (node != NULL) {
|
||||||
|
GdmSession *session = node->data;
|
||||||
|
GdmDisplay *candidate_display;
|
||||||
|
GList *next_node = node->next;
|
||||||
|
|
||||||
|
candidate_display = get_display_for_user_session (session);
|
||||||
|
|
||||||
|
if (candidate_display == display)
|
||||||
|
return session;
|
||||||
|
|
||||||
|
node = next_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gdm_manager_handle_register_display (GdmDBusManager *manager,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c
|
||||||
|
index 7719d0a8..310323b6 100644
|
||||||
|
--- a/daemon/gdm-session-record.c
|
||||||
|
+++ b/daemon/gdm-session-record.c
|
||||||
|
@@ -125,66 +125,70 @@ record_set_host (UTMP *u,
|
||||||
|
*/
|
||||||
|
if (host_name != NULL
|
||||||
|
&& x11_display_name != NULL
|
||||||
|
&& g_str_has_prefix (x11_display_name, ":")) {
|
||||||
|
hostname = g_strdup_printf ("%s%s", host_name, x11_display_name);
|
||||||
|
} else {
|
||||||
|
hostname = g_strdup (x11_display_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hostname != NULL) {
|
||||||
|
memccpy (u->ut_host, hostname, '\0', sizeof (u->ut_host));
|
||||||
|
g_debug ("using ut_host %.*s", (int) sizeof (u->ut_host), u->ut_host);
|
||||||
|
#ifdef HAVE_UT_UT_SYSLEN
|
||||||
|
u->ut_syslen = MIN (strlen (hostname), sizeof (u->ut_host));
|
||||||
|
#endif
|
||||||
|
g_free (hostname);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
record_set_line (UTMP *u,
|
||||||
|
const char *display_device,
|
||||||
|
const char *x11_display_name)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set ut_line to the device name associated with this display
|
||||||
|
* but remove the "/dev/" prefix. If no device, then use the
|
||||||
|
* $DISPLAY value.
|
||||||
|
*/
|
||||||
|
- if (display_device != NULL
|
||||||
|
- && g_str_has_prefix (display_device, "/dev/")) {
|
||||||
|
+ if (display_device != NULL && g_str_has_prefix (display_device, "/dev/")) {
|
||||||
|
memccpy (u->ut_line,
|
||||||
|
display_device + strlen ("/dev/"),
|
||||||
|
'\0',
|
||||||
|
sizeof (u->ut_line));
|
||||||
|
+ } else if (display_device != NULL && g_str_has_prefix (display_device, "seat")) {
|
||||||
|
+ memccpy (u->ut_line,
|
||||||
|
+ display_device,
|
||||||
|
+ '\0',
|
||||||
|
+ sizeof (u->ut_line));
|
||||||
|
} else if (x11_display_name != NULL) {
|
||||||
|
memccpy (u->ut_line,
|
||||||
|
x11_display_name,
|
||||||
|
'\0',
|
||||||
|
sizeof (u->ut_line));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_debug ("using ut_line %.*s", (int) sizeof (u->ut_line), u->ut_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdm_session_record_login (GPid session_pid,
|
||||||
|
const char *user_name,
|
||||||
|
const char *host_name,
|
||||||
|
const char *x11_display_name,
|
||||||
|
const char *display_device)
|
||||||
|
{
|
||||||
|
UTMP session_record = { 0 };
|
||||||
|
|
||||||
|
if (x11_display_name == NULL)
|
||||||
|
x11_display_name = display_device;
|
||||||
|
|
||||||
|
record_set_username (&session_record, user_name);
|
||||||
|
|
||||||
|
g_debug ("Writing login record");
|
||||||
|
|
||||||
|
#if defined(HAVE_UT_UT_TYPE)
|
||||||
|
session_record.ut_type = USER_PROCESS;
|
||||||
|
g_debug ("using ut_type USER_PROCESS");
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,119 @@
|
|||||||
|
From 9f4b4ef1b5e1458ca67cff235b655060b27e357b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Graham Rogers <graham@rogers.me.uk>
|
||||||
|
Date: Sun, 18 Apr 2021 12:22:14 +0100
|
||||||
|
Subject: [PATCH 2/2] pam_gdm: Use the last cryptsetup password instead of the
|
||||||
|
first
|
||||||
|
|
||||||
|
---
|
||||||
|
pam_gdm/pam_gdm.c | 32 ++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 26 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/pam_gdm/pam_gdm.c b/pam_gdm/pam_gdm.c
|
||||||
|
index 767a6c8c..ef77f161 100644
|
||||||
|
--- a/pam_gdm/pam_gdm.c
|
||||||
|
+++ b/pam_gdm/pam_gdm.c
|
||||||
|
@@ -11,75 +11,95 @@
|
||||||
|
* 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 <unistd.h>
|
||||||
|
|
||||||
|
#include <security/_pam_macros.h>
|
||||||
|
#include <security/pam_ext.h>
|
||||||
|
#include <security/pam_misc.h>
|
||||||
|
#include <security/pam_modules.h>
|
||||||
|
#include <security/pam_modutil.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_KEYUTILS
|
||||||
|
#include <keyutils.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
pam_sm_authenticate (pam_handle_t *pamh,
|
||||||
|
int flags,
|
||||||
|
int argc,
|
||||||
|
const char **argv)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_KEYUTILS
|
||||||
|
- int r;
|
||||||
|
- void *cached_password = NULL;
|
||||||
|
+ long r;
|
||||||
|
+ size_t cached_passwords_length;
|
||||||
|
+ char *cached_passwords = NULL;
|
||||||
|
+ char *last_cached_password = NULL;
|
||||||
|
key_serial_t serial;
|
||||||
|
+ size_t i;
|
||||||
|
|
||||||
|
serial = find_key_by_type_and_desc ("user", "cryptsetup", 0);
|
||||||
|
if (serial == 0)
|
||||||
|
return PAM_AUTHINFO_UNAVAIL;
|
||||||
|
|
||||||
|
- r = keyctl_read_alloc (serial, &cached_password);
|
||||||
|
- if (r < 0 || r != strlen (cached_password))
|
||||||
|
+ r = keyctl_read_alloc (serial, &cached_passwords);
|
||||||
|
+ if (r < 0)
|
||||||
|
return PAM_AUTHINFO_UNAVAIL;
|
||||||
|
+
|
||||||
|
+ cached_passwords_length = r;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ Find the last password in the NUL-separated list of passwords.
|
||||||
|
+ Multiple passwords are returned either when the user enters an
|
||||||
|
+ incorrect password or there are multiple encrypted drives.
|
||||||
|
+ In the case of an incorrect password the last one is correct.
|
||||||
|
+ In the case of multiple drives, choosing the last drive is as
|
||||||
|
+ arbitrary a choice as any other, but choosing the last password at
|
||||||
|
+ least supports multiple attempts on the last drive.
|
||||||
|
+ */
|
||||||
|
+ last_cached_password = cached_passwords;
|
||||||
|
+ for (i = 0; i < cached_passwords_length; i++) {
|
||||||
|
+ last_cached_password = cached_passwords + i;
|
||||||
|
+ i += strlen (last_cached_password);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- r = pam_set_item (pamh, PAM_AUTHTOK, cached_password);
|
||||||
|
+ r = pam_set_item (pamh, PAM_AUTHTOK, last_cached_password);
|
||||||
|
|
||||||
|
- free (cached_password);
|
||||||
|
+ free (cached_passwords);
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
return PAM_AUTH_ERR;
|
||||||
|
else
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return PAM_AUTHINFO_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pam_sm_setcred (pam_handle_t *pamh,
|
||||||
|
int flags,
|
||||||
|
int argc,
|
||||||
|
const char **argv)
|
||||||
|
{
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pam_sm_acct_mgmt (pam_handle_t *pamh,
|
||||||
|
int flags,
|
||||||
|
int argc,
|
||||||
|
const char **argv)
|
||||||
|
{
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pam_sm_chauthtok (pam_handle_t *pamh,
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
611
SOURCES/0003-daemon-save-os-release-in-accountsservice.patch
Normal file
611
SOURCES/0003-daemon-save-os-release-in-accountsservice.patch
Normal file
@ -0,0 +1,611 @@
|
|||||||
|
From de95917e0e9d142703a86f94961ef9fd4151739d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Mon, 20 Aug 2018 14:30:59 -0400
|
||||||
|
Subject: [PATCH 3/4] daemon: save os-release in accountsservice
|
||||||
|
|
||||||
|
It can be useful to know what OS a user was running
|
||||||
|
when they logged in (to detect upgrades).
|
||||||
|
|
||||||
|
This commit saves that information in accountsservice.
|
||||||
|
---
|
||||||
|
.../com.redhat.AccountsServiceUser.System.xml | 10 ++
|
||||||
|
daemon/gdm-session-settings.c | 98 +++++++++++++++++++
|
||||||
|
daemon/gdm-session.c | 4 +-
|
||||||
|
daemon/meson.build | 8 ++
|
||||||
|
4 files changed, 118 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 daemon/com.redhat.AccountsServiceUser.System.xml
|
||||||
|
|
||||||
|
diff --git a/daemon/com.redhat.AccountsServiceUser.System.xml b/daemon/com.redhat.AccountsServiceUser.System.xml
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..67f5f302
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/daemon/com.redhat.AccountsServiceUser.System.xml
|
||||||
|
@@ -0,0 +1,10 @@
|
||||||
|
+<node>
|
||||||
|
+ <interface name="com.redhat.AccountsServiceUser.System">
|
||||||
|
+
|
||||||
|
+ <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/>
|
||||||
|
+
|
||||||
|
+ <property name="id" type="s" access="readwrite"/>
|
||||||
|
+ <property name="version-id" type="s" access="readwrite"/>
|
||||||
|
+
|
||||||
|
+ </interface>
|
||||||
|
+</node>
|
||||||
|
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
|
||||||
|
index f2b1addd..a4b7f1a6 100644
|
||||||
|
--- a/daemon/gdm-session-settings.c
|
||||||
|
+++ b/daemon/gdm-session-settings.c
|
||||||
|
@@ -1,70 +1,77 @@
|
||||||
|
/* gdm-session-settings.c - Loads session and language from ~/.dmrc
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 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, 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.
|
||||||
|
*
|
||||||
|
* Written by: Ray Strode <rstrode@redhat.com>
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "gdm-session-settings.h"
|
||||||
|
+#include "gdm-common.h"
|
||||||
|
+
|
||||||
|
+#include "com.redhat.AccountsServiceUser.System.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include <act/act-user-manager.h>
|
||||||
|
|
||||||
|
struct _GdmSessionSettingsPrivate
|
||||||
|
{
|
||||||
|
ActUserManager *user_manager;
|
||||||
|
ActUser *user;
|
||||||
|
+
|
||||||
|
+ /* used for retrieving the last OS user logged in with */
|
||||||
|
+ GdmAccountsServiceUserSystem *user_system_proxy;
|
||||||
|
+
|
||||||
|
char *session_name;
|
||||||
|
char *session_type;
|
||||||
|
char *language_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gdm_session_settings_finalize (GObject *object);
|
||||||
|
static void gdm_session_settings_class_install_properties (GdmSessionSettingsClass *
|
||||||
|
settings_class);
|
||||||
|
|
||||||
|
static void gdm_session_settings_set_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
static void gdm_session_settings_get_property (GObject *object,
|
||||||
|
guint prop_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_0 = 0,
|
||||||
|
PROP_SESSION_NAME,
|
||||||
|
PROP_SESSION_TYPE,
|
||||||
|
PROP_LANGUAGE_NAME,
|
||||||
|
PROP_IS_LOADED
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (GdmSessionSettings,
|
||||||
|
gdm_session_settings,
|
||||||
|
G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
@@ -107,60 +114,62 @@ gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings
|
||||||
|
g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec);
|
||||||
|
|
||||||
|
param_spec = g_param_spec_boolean ("is-loaded", NULL, NULL,
|
||||||
|
FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||||
|
g_object_class_install_property (object_class, PROP_IS_LOADED, param_spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdm_session_settings_init (GdmSessionSettings *settings)
|
||||||
|
{
|
||||||
|
settings->priv = G_TYPE_INSTANCE_GET_PRIVATE (settings,
|
||||||
|
GDM_TYPE_SESSION_SETTINGS,
|
||||||
|
GdmSessionSettingsPrivate);
|
||||||
|
|
||||||
|
settings->priv->user_manager = act_user_manager_get_default ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gdm_session_settings_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
GdmSessionSettings *settings;
|
||||||
|
GObjectClass *parent_class;
|
||||||
|
|
||||||
|
settings = GDM_SESSION_SETTINGS (object);
|
||||||
|
|
||||||
|
if (settings->priv->user != NULL) {
|
||||||
|
g_object_unref (settings->priv->user);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ g_clear_object (&settings->priv->user_system_proxy);
|
||||||
|
+
|
||||||
|
g_free (settings->priv->session_name);
|
||||||
|
g_free (settings->priv->language_name);
|
||||||
|
|
||||||
|
parent_class = G_OBJECT_CLASS (gdm_session_settings_parent_class);
|
||||||
|
|
||||||
|
if (parent_class->finalize != NULL) {
|
||||||
|
parent_class->finalize (object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdm_session_settings_set_language_name (GdmSessionSettings *settings,
|
||||||
|
const char *language_name)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings));
|
||||||
|
|
||||||
|
if (settings->priv->language_name == NULL ||
|
||||||
|
strcmp (settings->priv->language_name, language_name) != 0) {
|
||||||
|
settings->priv->language_name = g_strdup (language_name);
|
||||||
|
g_object_notify (G_OBJECT (settings), "language-name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdm_session_settings_set_session_name (GdmSessionSettings *settings,
|
||||||
|
const char *session_name)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings));
|
||||||
|
|
||||||
|
if (settings->priv->session_name == NULL ||
|
||||||
|
@@ -261,69 +270,86 @@ gdm_session_settings_get_property (GObject *object,
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GdmSessionSettings *
|
||||||
|
gdm_session_settings_new (void)
|
||||||
|
{
|
||||||
|
GdmSessionSettings *settings;
|
||||||
|
|
||||||
|
settings = g_object_new (GDM_TYPE_SESSION_SETTINGS,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_session_settings_is_loaded (GdmSessionSettings *settings)
|
||||||
|
{
|
||||||
|
if (settings->priv->user == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return act_user_is_loaded (settings->priv->user);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_settings_from_user (GdmSessionSettings *settings)
|
||||||
|
{
|
||||||
|
+ const char *object_path;
|
||||||
|
const char *session_name;
|
||||||
|
const char *session_type;
|
||||||
|
const char *language_name;
|
||||||
|
|
||||||
|
if (!act_user_is_loaded (settings->priv->user)) {
|
||||||
|
g_warning ("GdmSessionSettings: trying to load user settings from unloaded user");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ object_path = act_user_get_object_path (settings->priv->user);
|
||||||
|
+
|
||||||
|
+ if (object_path != NULL) {
|
||||||
|
+ g_autoptr (GError) error = NULL;
|
||||||
|
+ settings->priv->user_system_proxy = gdm_accounts_service_user_system_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||||
|
+ G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
+ "org.freedesktop.Accounts",
|
||||||
|
+ object_path,
|
||||||
|
+ NULL,
|
||||||
|
+ &error);
|
||||||
|
+ if (error != NULL) {
|
||||||
|
+ g_debug ("GdmSessionSettings: couldn't retrieve user system proxy from accountsservice: %s",
|
||||||
|
+ error->message);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
session_type = act_user_get_session_type (settings->priv->user);
|
||||||
|
session_name = act_user_get_session (settings->priv->user);
|
||||||
|
|
||||||
|
g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type);
|
||||||
|
|
||||||
|
if (session_type != NULL && session_type[0] != '\0') {
|
||||||
|
gdm_session_settings_set_session_type (settings, session_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session_name != NULL && session_name[0] != '\0') {
|
||||||
|
gdm_session_settings_set_session_name (settings, session_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
language_name = act_user_get_language (settings->priv->user);
|
||||||
|
|
||||||
|
g_debug ("GdmSessionSettings: saved language is %s", language_name);
|
||||||
|
if (language_name != NULL && language_name[0] != '\0') {
|
||||||
|
gdm_session_settings_set_language_name (settings, language_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_object_notify (G_OBJECT (settings), "is-loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_user_is_loaded_changed (ActUser *user,
|
||||||
|
@@ -349,64 +375,136 @@ gdm_session_settings_load (GdmSessionSettings *settings,
|
||||||
|
g_return_val_if_fail (!gdm_session_settings_is_loaded (settings), FALSE);
|
||||||
|
|
||||||
|
if (settings->priv->user != NULL) {
|
||||||
|
old_user = settings->priv->user;
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (settings->priv->user),
|
||||||
|
G_CALLBACK (on_user_is_loaded_changed),
|
||||||
|
settings);
|
||||||
|
} else {
|
||||||
|
old_user = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings->priv->user = act_user_manager_get_user (settings->priv->user_manager,
|
||||||
|
username);
|
||||||
|
|
||||||
|
g_clear_object (&old_user);
|
||||||
|
|
||||||
|
if (!act_user_is_loaded (settings->priv->user)) {
|
||||||
|
g_signal_connect (settings->priv->user,
|
||||||
|
"notify::is-loaded",
|
||||||
|
G_CALLBACK (on_user_is_loaded_changed),
|
||||||
|
settings);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
load_settings_from_user (settings);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+save_os_release (GdmSessionSettings *settings,
|
||||||
|
+ ActUser *user)
|
||||||
|
+{
|
||||||
|
+ g_autoptr(GFile) file = NULL;
|
||||||
|
+ g_autoptr(GError) error = NULL;
|
||||||
|
+ g_autofree char *contents = NULL;
|
||||||
|
+ g_auto(GStrv) lines = NULL;
|
||||||
|
+ size_t i;
|
||||||
|
+
|
||||||
|
+ if (settings->priv->user_system_proxy == NULL) {
|
||||||
|
+ g_debug ("GdmSessionSettings: not saving OS version to user account because accountsservice doesn't support it");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ file = g_file_new_for_path ("/etc/os-release");
|
||||||
|
+
|
||||||
|
+ if (!g_file_load_contents (file, NULL, &contents, NULL, NULL, &error)) {
|
||||||
|
+ g_debug ("GdmSessionSettings: couldn't load /etc/os-release: %s", error->message);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ lines = g_strsplit (contents, "\n", -1);
|
||||||
|
+ for (i = 0; lines[i] != NULL; i++) {
|
||||||
|
+ char *p, *name, *name_end, *value, *value_end;
|
||||||
|
+
|
||||||
|
+ p = lines[i];
|
||||||
|
+
|
||||||
|
+ while (g_ascii_isspace (*p))
|
||||||
|
+ p++;
|
||||||
|
+
|
||||||
|
+ if (*p == '#' || *p == '\0')
|
||||||
|
+ continue;
|
||||||
|
+ name = p;
|
||||||
|
+ while (gdm_shell_var_is_valid_char (*p, p == name))
|
||||||
|
+ p++;
|
||||||
|
+ name_end = p;
|
||||||
|
+ while (g_ascii_isspace (*p))
|
||||||
|
+ p++;
|
||||||
|
+ if (name == name_end || *p != '=') {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ *name_end = '\0';
|
||||||
|
+
|
||||||
|
+ p++;
|
||||||
|
+
|
||||||
|
+ while (g_ascii_isspace (*p))
|
||||||
|
+ p++;
|
||||||
|
+
|
||||||
|
+ value = p;
|
||||||
|
+ value_end = value + strlen(value) - 1;
|
||||||
|
+
|
||||||
|
+ if (value != value_end && *value == '"' && *value_end == '"') {
|
||||||
|
+ value++;
|
||||||
|
+ *value_end = '\0';
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strcmp (name, "ID") == 0) {
|
||||||
|
+ gdm_accounts_service_user_system_set_id (settings->priv->user_system_proxy,
|
||||||
|
+ value);
|
||||||
|
+ g_debug ("GdmSessionSettings: setting system OS for user to '%s'", value);
|
||||||
|
+ } else if (strcmp (name, "VERSION_ID") == 0) {
|
||||||
|
+ gdm_accounts_service_user_system_set_version_id (settings->priv->user_system_proxy,
|
||||||
|
+ value);
|
||||||
|
+ g_debug ("GdmSessionSettings: setting system OS version for user to '%s'", value);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
gboolean
|
||||||
|
gdm_session_settings_save (GdmSessionSettings *settings,
|
||||||
|
const char *username)
|
||||||
|
{
|
||||||
|
ActUser *user;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), FALSE);
|
||||||
|
g_return_val_if_fail (username != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (gdm_session_settings_is_loaded (settings), FALSE);
|
||||||
|
|
||||||
|
user = act_user_manager_get_user (settings->priv->user_manager,
|
||||||
|
username);
|
||||||
|
|
||||||
|
|
||||||
|
if (!act_user_is_loaded (user)) {
|
||||||
|
g_object_unref (user);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->priv->session_name != NULL) {
|
||||||
|
act_user_set_session (user, settings->priv->session_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->priv->session_type != NULL) {
|
||||||
|
act_user_set_session_type (user, settings->priv->session_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings->priv->language_name != NULL) {
|
||||||
|
act_user_set_language (user, settings->priv->language_name);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ save_os_release (settings, user);
|
||||||
|
+
|
||||||
|
g_object_unref (user);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||||||
|
index f4d0bef9..d1e2c301 100644
|
||||||
|
--- a/daemon/gdm-session.c
|
||||||
|
+++ b/daemon/gdm-session.c
|
||||||
|
@@ -351,72 +351,72 @@ supports_session_type (GdmSession *self,
|
||||||
|
if (session_type == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return g_strv_contains ((const char * const *) self->supported_session_types,
|
||||||
|
session_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char **
|
||||||
|
get_system_session_dirs (GdmSession *self,
|
||||||
|
const char *type)
|
||||||
|
{
|
||||||
|
GArray *search_array = NULL;
|
||||||
|
char **search_dirs;
|
||||||
|
int i, j;
|
||||||
|
const gchar * const *system_data_dirs = g_get_system_data_dirs ();
|
||||||
|
|
||||||
|
static const char *x_search_dirs[] = {
|
||||||
|
"/etc/X11/sessions/",
|
||||||
|
DMCONFDIR "/Sessions/",
|
||||||
|
DATADIR "/gdm/BuiltInSessions/",
|
||||||
|
DATADIR "/xsessions/",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *wayland_search_dir = DATADIR "/wayland-sessions/";
|
||||||
|
|
||||||
|
search_array = g_array_new (TRUE, TRUE, sizeof (char *));
|
||||||
|
|
||||||
|
for (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',
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
gdm_session_enums = gnome.mkenums('gdm-session-enum-types',
|
||||||
|
h_template: 'gdm-session-enum-types.h.in',
|
||||||
|
c_template: 'gdm-session-enum-types.c.in',
|
||||||
|
sources: 'gdm-session.h',
|
||||||
|
)
|
||||||
|
gdm_session_worker_enums = gnome.mkenums('gdm-session-worker-enum-types',
|
||||||
|
h_template: 'gdm-session-worker-enum-types.h.in',
|
||||||
|
c_template: 'gdm-session-worker-enum-types.c.in',
|
||||||
|
sources: 'gdm-session-worker.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Daemons deps
|
||||||
|
gdm_daemon_deps = [
|
||||||
|
libgdmcommon_dep,
|
||||||
|
accountsservice_dep,
|
||||||
|
gobject_dep,
|
||||||
|
gio_dep,
|
||||||
|
gio_unix_dep,
|
||||||
|
libpam_dep,
|
||||||
|
x_deps,
|
||||||
|
xcb_dep,
|
||||||
|
]
|
||||||
|
|
||||||
|
if xdmcp_dep.found() and get_option('tcp-wrappers')
|
||||||
|
gdm_daemon_deps += libwrap_dep
|
||||||
|
endif
|
||||||
|
|
||||||
|
# test-session-client
|
||||||
|
test_session_client_src = [
|
||||||
|
'test-session-client.c',
|
||||||
|
session_dbus_gen,
|
||||||
|
manager_dbus_gen,
|
||||||
|
]
|
||||||
|
|
||||||
|
test_session_client = executable('test-session-client',
|
||||||
|
test_session_client_src,
|
||||||
|
dependencies: gdm_daemon_deps,
|
||||||
|
include_directories: config_h_dir,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Session worker
|
||||||
|
gdm_session_worker_src = [
|
||||||
|
'session-worker-main.c',
|
||||||
|
'gdm-session.c',
|
||||||
|
'gdm-session-settings.c',
|
||||||
|
'gdm-session-auditor.c',
|
||||||
|
'gdm-session-record.c',
|
||||||
|
'gdm-session-worker.c',
|
||||||
|
'gdm-session-worker-job.c',
|
||||||
|
'gdm-session-worker-common.c',
|
||||||
|
'gdm-dbus-util.c',
|
||||||
|
dbus_gen,
|
||||||
|
session_dbus_gen,
|
||||||
|
session_worker_dbus_gen,
|
||||||
|
+ accountsservice_system_user_dbus_gen,
|
||||||
|
gdm_session_enums,
|
||||||
|
gdm_session_worker_enums,
|
||||||
|
]
|
||||||
|
|
||||||
|
gdm_session_worker_deps = [
|
||||||
|
gdm_daemon_deps,
|
||||||
|
]
|
||||||
|
|
||||||
|
gdm_session_worker_includes = [
|
||||||
|
config_h_dir,
|
||||||
|
]
|
||||||
|
|
||||||
|
if pam_extensions_supported
|
||||||
|
gdm_session_worker_src += '../pam-extensions/gdm-pam-extensions.h'
|
||||||
|
gdm_session_worker_includes += pam_extensions_inc
|
||||||
|
endif
|
||||||
|
|
||||||
|
if libaudit_dep.found()
|
||||||
|
gdm_session_worker_deps += libaudit_dep
|
||||||
|
|
||||||
|
gdm_session_worker_src += [
|
||||||
|
'gdm-session-linux-auditor.c',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if have_adt
|
||||||
|
gdm_session_worker_src += 'gdm-session-solaris-auditor.c'
|
||||||
|
endif
|
||||||
|
|
||||||
|
gdm_session_worker = executable('gdm-session-worker',
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,105 @@
|
|||||||
|
From 64e8db8432158e5115df18a03bb87ecc1d58ae63 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Mon, 11 Feb 2019 10:32:55 -0500
|
||||||
|
Subject: [PATCH 3/3] session: ensure login screen over XDMCP connects to its
|
||||||
|
session
|
||||||
|
|
||||||
|
Right now GTK preferentially picks the wayland display over an
|
||||||
|
X11 display if it finds one.
|
||||||
|
|
||||||
|
That causes a problem for XDMCP sessions, since there may be a
|
||||||
|
wayland display running on the local console for the GDM user.
|
||||||
|
|
||||||
|
This commit addresses the issue by forcing the X11 backend if
|
||||||
|
the session is X11.
|
||||||
|
---
|
||||||
|
daemon/gdm-session.c | 19 +++++++++++++++++++
|
||||||
|
1 file changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||||||
|
index 77d6b8ff0..357e4a297 100644
|
||||||
|
--- a/daemon/gdm-session.c
|
||||||
|
+++ b/daemon/gdm-session.c
|
||||||
|
@@ -2697,60 +2697,79 @@ set_up_session_environment (GdmSession *self)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_display_mode (GdmSession *self,
|
||||||
|
GdmSessionConversation *conversation)
|
||||||
|
{
|
||||||
|
GdmSessionDisplayMode mode;
|
||||||
|
|
||||||
|
mode = gdm_session_get_display_mode (self);
|
||||||
|
gdm_dbus_worker_call_set_session_display_mode (conversation->worker_proxy,
|
||||||
|
gdm_session_display_mode_to_string (mode),
|
||||||
|
conversation->worker_cancellable,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
send_session_type (GdmSession *self,
|
||||||
|
GdmSessionConversation *conversation)
|
||||||
|
{
|
||||||
|
const char *session_type = "x11";
|
||||||
|
|
||||||
|
if (self->session_type != NULL) {
|
||||||
|
session_type = self->session_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy,
|
||||||
|
"XDG_SESSION_TYPE",
|
||||||
|
session_type,
|
||||||
|
conversation->worker_cancellable,
|
||||||
|
NULL, NULL);
|
||||||
|
+
|
||||||
|
+ /* If the session type is x11, then set GDK_BACKEND to x11 as well.
|
||||||
|
+ * This is so gnome-session-check-accelerated from an XDMCP connection doesn't
|
||||||
|
+ * try to use the wayland display running on the local console for the gdm
|
||||||
|
+ * user login screen session.
|
||||||
|
+ *
|
||||||
|
+ * That's the only case where we let a user log in more than once, so it's
|
||||||
|
+ * the only situation that matters.
|
||||||
|
+ *
|
||||||
|
+ * We can drop this code if we ever switch the login screen to use systemd's
|
||||||
|
+ * DynamicUser feature.
|
||||||
|
+ */
|
||||||
|
+ if (g_strcmp0 (session_type, "x11") == 0) {
|
||||||
|
+ gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy,
|
||||||
|
+ "GDK_BACKEND",
|
||||||
|
+ "x11",
|
||||||
|
+ conversation->worker_cancellable,
|
||||||
|
+ NULL, NULL);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdm_session_open_session (GdmSession *self,
|
||||||
|
const char *service_name)
|
||||||
|
{
|
||||||
|
GdmSessionConversation *conversation;
|
||||||
|
|
||||||
|
g_return_if_fail (GDM_IS_SESSION (self));
|
||||||
|
|
||||||
|
conversation = find_conversation_by_name (self, service_name);
|
||||||
|
|
||||||
|
if (conversation != NULL) {
|
||||||
|
send_display_mode (self, conversation);
|
||||||
|
send_session_type (self, conversation);
|
||||||
|
|
||||||
|
gdm_dbus_worker_call_open (conversation->worker_proxy,
|
||||||
|
conversation->worker_cancellable,
|
||||||
|
(GAsyncReadyCallback) on_opened, conversation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
stop_all_other_conversations (GdmSession *self,
|
||||||
|
GdmSessionConversation *conversation_to_keep,
|
||||||
|
gboolean now)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.30.1
|
||||||
|
|
@ -0,0 +1,122 @@
|
|||||||
|
From b5472a30b1a71aec537ac309e2985cbac61b3136 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/4] 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 ce8f026e..abb58fae 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.34.1
|
||||||
|
|
250
SOURCES/0004-daemon-handle-upgrades-from-RHEL-7.patch
Normal file
250
SOURCES/0004-daemon-handle-upgrades-from-RHEL-7.patch
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
From 738a10ca78e154ad4c3df9a1298eaad01516457e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Mon, 20 Aug 2018 14:30:59 -0400
|
||||||
|
Subject: [PATCH 4/4] daemon: handle upgrades from RHEL 7
|
||||||
|
|
||||||
|
RHEL 7 users need to stay on X if they were using X,
|
||||||
|
and they need to stay on gnome-classic if they were using
|
||||||
|
gnome-classic.
|
||||||
|
|
||||||
|
This commit examines the user's config to deduce whether
|
||||||
|
or not they were using RHEL 7 and in the event they were
|
||||||
|
try to get the right settings.
|
||||||
|
---
|
||||||
|
daemon/gdm-session-settings.c | 19 +++++++++++++++++++
|
||||||
|
daemon/gdm-session.c | 19 ++++++++-----------
|
||||||
|
2 files changed, 27 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
|
||||||
|
index a4b7f1a6..a84b2ffa 100644
|
||||||
|
--- a/daemon/gdm-session-settings.c
|
||||||
|
+++ b/daemon/gdm-session-settings.c
|
||||||
|
@@ -270,95 +270,114 @@ gdm_session_settings_get_property (GObject *object,
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GdmSessionSettings *
|
||||||
|
gdm_session_settings_new (void)
|
||||||
|
{
|
||||||
|
GdmSessionSettings *settings;
|
||||||
|
|
||||||
|
settings = g_object_new (GDM_TYPE_SESSION_SETTINGS,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdm_session_settings_is_loaded (GdmSessionSettings *settings)
|
||||||
|
{
|
||||||
|
if (settings->priv->user == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return act_user_is_loaded (settings->priv->user);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_settings_from_user (GdmSessionSettings *settings)
|
||||||
|
{
|
||||||
|
+ const char *system_id = NULL, *system_version_id = NULL;
|
||||||
|
const char *object_path;
|
||||||
|
const char *session_name;
|
||||||
|
const char *session_type;
|
||||||
|
const char *language_name;
|
||||||
|
|
||||||
|
if (!act_user_is_loaded (settings->priv->user)) {
|
||||||
|
g_warning ("GdmSessionSettings: trying to load user settings from unloaded user");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_path = act_user_get_object_path (settings->priv->user);
|
||||||
|
|
||||||
|
if (object_path != NULL) {
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
settings->priv->user_system_proxy = gdm_accounts_service_user_system_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||||
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
|
"org.freedesktop.Accounts",
|
||||||
|
object_path,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (error != NULL) {
|
||||||
|
g_debug ("GdmSessionSettings: couldn't retrieve user system proxy from accountsservice: %s",
|
||||||
|
error->message);
|
||||||
|
+ } else {
|
||||||
|
+ system_id = gdm_accounts_service_user_system_get_id (settings->priv->user_system_proxy);
|
||||||
|
+ system_version_id = gdm_accounts_service_user_system_get_version_id (settings->priv->user_system_proxy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
session_type = act_user_get_session_type (settings->priv->user);
|
||||||
|
session_name = act_user_get_session (settings->priv->user);
|
||||||
|
|
||||||
|
g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type);
|
||||||
|
|
||||||
|
+ if (system_id == NULL || (g_strcmp0 (system_id, "rhel") == 0 && g_str_has_prefix (system_version_id, "7."))) {
|
||||||
|
+ /* if there's also no session name in the file and we're coming from RHEL 7,
|
||||||
|
+ * then we should assume classic session
|
||||||
|
+ */
|
||||||
|
+ if (session_name == NULL || session_name[0] == '\0')
|
||||||
|
+ session_name = "gnome-classic";
|
||||||
|
+
|
||||||
|
+ /* only presume wayland if the user specifically picked it in RHEL 7
|
||||||
|
+ */
|
||||||
|
+ if (g_strcmp0 (session_name, "gnome-wayland") == 0)
|
||||||
|
+ session_type = "wayland";
|
||||||
|
+ else
|
||||||
|
+ session_type = "x11";
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (session_type != NULL && session_type[0] != '\0') {
|
||||||
|
gdm_session_settings_set_session_type (settings, session_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session_name != NULL && session_name[0] != '\0') {
|
||||||
|
gdm_session_settings_set_session_name (settings, session_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
language_name = act_user_get_language (settings->priv->user);
|
||||||
|
|
||||||
|
g_debug ("GdmSessionSettings: saved language is %s", language_name);
|
||||||
|
if (language_name != NULL && language_name[0] != '\0') {
|
||||||
|
gdm_session_settings_set_language_name (settings, language_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_object_notify (G_OBJECT (settings), "is-loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_user_is_loaded_changed (ActUser *user,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
GdmSessionSettings *settings)
|
||||||
|
{
|
||||||
|
if (act_user_is_loaded (settings->priv->user)) {
|
||||||
|
load_settings_from_user (settings);
|
||||||
|
g_signal_handlers_disconnect_by_func (G_OBJECT (settings->priv->user),
|
||||||
|
G_CALLBACK (on_user_is_loaded_changed),
|
||||||
|
settings);
|
||||||
|
}
|
||||||
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
||||||
|
index d1e2c301..d4a46d87 100644
|
||||||
|
--- a/daemon/gdm-session.c
|
||||||
|
+++ b/daemon/gdm-session.c
|
||||||
|
@@ -3207,98 +3207,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.33.1
|
||||||
|
|
@ -0,0 +1,96 @@
|
|||||||
|
From dfca67899ea33da08d3aa9e84c1b4487991adad0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ray Strode <rstrode@redhat.com>
|
||||||
|
Date: Thu, 7 Oct 2021 15:34:27 -0400
|
||||||
|
Subject: [PATCH 4/4] local-display-factory: Don't crash if Xorg and Wayland
|
||||||
|
are both unavailable
|
||||||
|
|
||||||
|
At the moment if Wayland doesn't work, the login screen will fall back
|
||||||
|
to Xorg, and if Xorg doesn't work the login screen will fall back to
|
||||||
|
Wayland.
|
||||||
|
|
||||||
|
But if the fall back choice is disabled explicitly, GDM will just crash.
|
||||||
|
|
||||||
|
This commit fixes the crash.
|
||||||
|
|
||||||
|
Closes: https://gitlab.gnome.org/GNOME/gdm/-/issues/739
|
||||||
|
---
|
||||||
|
daemon/gdm-local-display-factory.c | 9 +++++++--
|
||||||
|
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
|
||||||
|
index eba38671..120847f9 100644
|
||||||
|
--- a/daemon/gdm-local-display-factory.c
|
||||||
|
+++ b/daemon/gdm-local-display-factory.c
|
||||||
|
@@ -651,62 +651,67 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
|
||||||
|
gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
|
||||||
|
|
||||||
|
preferred_display_server = get_preferred_display_server (factory);
|
||||||
|
|
||||||
|
if (g_strcmp0 (preferred_display_server, "none") == 0) {
|
||||||
|
g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sd_seat_can_graphical (seat_id);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
g_critical ("Failed to query CanGraphical information for seat %s", seat_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics");
|
||||||
|
seat_supports_graphics = FALSE;
|
||||||
|
} else {
|
||||||
|
g_debug ("GdmLocalDisplayFactory: System supports graphics");
|
||||||
|
seat_supports_graphics = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_strcmp0 (seat_id, "seat0") == 0) {
|
||||||
|
is_seat0 = TRUE;
|
||||||
|
|
||||||
|
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 (session_types == NULL) {
|
||||||
|
+ g_debug ("GdmLocalDisplayFactory: Both Wayland and Xorg are unavailable");
|
||||||
|
+ seat_supports_graphics = FALSE;
|
||||||
|
+ } else {
|
||||||
|
+ g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
|
||||||
|
+ session_types[0], falling_back? " fallback" : "");
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
is_seat0 = FALSE;
|
||||||
|
|
||||||
|
g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id);
|
||||||
|
/* Force legacy X11 for all auxiliary seats */
|
||||||
|
seat_supports_graphics = TRUE;
|
||||||
|
session_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.34.1
|
||||||
|
|
3352
SPECS/gdm.spec
Normal file
3352
SPECS/gdm.spec
Normal file
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
u gdm 42 "GNOME Display Manager" /var/lib/gdm
|
|
1
sources
1
sources
@ -1 +0,0 @@
|
|||||||
SHA512 (gdm-47.alpha.tar.xz) = 768931fc80b09754135ea0f8014bd3ba24ab2f74428efcfafb09720915264644186fbbcfd59004ca76df8ff29c8f41a224afb1d3ccaead47fae1e77ab4e7ae2e
|
|
@ -1,311 +0,0 @@
|
|||||||
From a5dcb9699cbb18c70da0a6ee57faa20124130787 Mon Sep 17 00:00:00 2001
|
|
||||||
From: rpm-build <rpm-build>
|
|
||||||
Date: Fri, 26 Jul 2024 16:21:35 -0400
|
|
||||||
Subject: [PATCH] wayland-only.patch
|
|
||||||
|
|
||||||
---
|
|
||||||
daemon/gdm-local-display-factory.c | 12 +++++++++++-
|
|
||||||
libgdm/gdm-sessions.c | 20 ++++++++++++--------
|
|
||||||
2 files changed, 23 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
|
|
||||||
index f2d8e15..cfbd598 100644
|
|
||||||
--- a/daemon/gdm-local-display-factory.c
|
|
||||||
+++ b/daemon/gdm-local-display-factory.c
|
|
||||||
@@ -192,75 +192,81 @@ take_next_display_number (GdmLocalDisplayFactory *factory)
|
|
||||||
|
|
||||||
/* now reserve this number */
|
|
||||||
g_debug ("GdmLocalDisplayFactory: Reserving X display: %u", ret);
|
|
||||||
g_hash_table_insert (factory->used_display_numbers, GUINT_TO_POINTER (ret), NULL);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
get_preferred_display_server (GdmLocalDisplayFactory *factory)
|
|
||||||
{
|
|
||||||
g_autofree gchar *preferred_display_server = NULL;
|
|
||||||
gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
|
|
||||||
|
|
||||||
gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
|
|
||||||
gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
|
|
||||||
|
|
||||||
if (wayland_enabled && !xorg_enabled) {
|
|
||||||
return g_strdup ("wayland");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wayland_enabled && !xorg_enabled) {
|
|
||||||
return g_strdup ("none");
|
|
||||||
}
|
|
||||||
|
|
||||||
gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server);
|
|
||||||
|
|
||||||
if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
|
|
||||||
if (wayland_enabled)
|
|
||||||
return g_strdup (preferred_display_server);
|
|
||||||
+#ifdef ENABLE_XORG_SUPPORT
|
|
||||||
else
|
|
||||||
return g_strdup ("xorg");
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_strcmp0 (preferred_display_server, "xorg") == 0) {
|
|
||||||
+#ifdef ENABLE_XORG_SUPPORT
|
|
||||||
if (xorg_enabled)
|
|
||||||
return g_strdup (preferred_display_server);
|
|
||||||
else
|
|
||||||
+#endif
|
|
||||||
return g_strdup ("wayland");
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef ENABLE_XORG_SUPPORT
|
|
||||||
if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
|
|
||||||
if (xorg_enabled)
|
|
||||||
return g_strdup (preferred_display_server);
|
|
||||||
}
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
return g_strdup ("none");
|
|
||||||
}
|
|
||||||
|
|
||||||
struct GdmDisplayServerConfiguration {
|
|
||||||
const char *display_server;
|
|
||||||
const char *key;
|
|
||||||
const char *binary;
|
|
||||||
const char *session_type;
|
|
||||||
} display_server_configuration[] = {
|
|
||||||
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
||||||
{ "wayland", GDM_KEY_WAYLAND_ENABLE, "/usr/bin/Xwayland", "wayland" },
|
|
||||||
#endif
|
|
||||||
{ "xorg", GDM_KEY_XORG_ENABLE, "/usr/bin/Xorg", "x11" },
|
|
||||||
{ NULL, NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
display_server_enabled (GdmLocalDisplayFactory *factory,
|
|
||||||
const char *display_server)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; display_server_configuration[i].display_server != NULL; i++) {
|
|
||||||
const char *key = display_server_configuration[i].key;
|
|
||||||
const char *binary = display_server_configuration[i].binary;
|
|
||||||
gboolean enabled = FALSE;
|
|
||||||
|
|
||||||
if (!g_str_equal (display_server_configuration[i].display_server,
|
|
||||||
display_server))
|
|
||||||
@@ -289,74 +295,78 @@ get_session_type_for_display_server (GdmLocalDisplayFactory *factory,
|
|
||||||
display_server))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return display_server_configuration[i].session_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char **
|
|
||||||
gdm_local_display_factory_get_session_types (GdmLocalDisplayFactory *factory,
|
|
||||||
gboolean should_fall_back)
|
|
||||||
{
|
|
||||||
g_autofree gchar *preferred_display_server = NULL;
|
|
||||||
const char *fallback_display_server = NULL;
|
|
||||||
gboolean wayland_preferred = FALSE;
|
|
||||||
gboolean xorg_preferred = FALSE;
|
|
||||||
g_autoptr (GPtrArray) session_types_array = NULL;
|
|
||||||
char **session_types;
|
|
||||||
|
|
||||||
session_types_array = g_ptr_array_new ();
|
|
||||||
|
|
||||||
preferred_display_server = get_preferred_display_server (factory);
|
|
||||||
|
|
||||||
g_debug ("GdmLocalDisplayFactory: Getting session type (prefers %s, falling back: %s)",
|
|
||||||
preferred_display_server, should_fall_back? "yes" : "no");
|
|
||||||
|
|
||||||
wayland_preferred = g_str_equal (preferred_display_server, "wayland");
|
|
||||||
xorg_preferred = g_str_equal (preferred_display_server, "xorg");
|
|
||||||
|
|
||||||
+#ifdef ENABLE_XORG_SUPPORT
|
|
||||||
if (wayland_preferred)
|
|
||||||
fallback_display_server = "xorg";
|
|
||||||
else if (xorg_preferred)
|
|
||||||
fallback_display_server = "wayland";
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
- if (!should_fall_back) {
|
|
||||||
+ if (!should_fall_back || fallback_display_server == NULL) {
|
|
||||||
if (display_server_enabled (factory, preferred_display_server))
|
|
||||||
g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, preferred_display_server));
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef ENABLE_XORG_SUPPORT
|
|
||||||
if (display_server_enabled (factory, fallback_display_server))
|
|
||||||
g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, fallback_display_server));
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
if (session_types_array->len == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
g_ptr_array_add (session_types_array, NULL);
|
|
||||||
|
|
||||||
session_types = g_strdupv ((char **) session_types_array->pdata);
|
|
||||||
|
|
||||||
return session_types;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_display_disposed (GdmLocalDisplayFactory *factory,
|
|
||||||
GdmDisplay *display)
|
|
||||||
{
|
|
||||||
g_debug ("GdmLocalDisplayFactory: Display %p disposed", display);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
store_display (GdmLocalDisplayFactory *factory,
|
|
||||||
GdmDisplay *display)
|
|
||||||
{
|
|
||||||
GdmDisplayStore *store;
|
|
||||||
|
|
||||||
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
|
|
||||||
gdm_display_store_add (store, display);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Example:
|
|
||||||
diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c
|
|
||||||
index 0aedcf9..211b6f6 100644
|
|
||||||
--- a/libgdm/gdm-sessions.c
|
|
||||||
+++ b/libgdm/gdm-sessions.c
|
|
||||||
@@ -304,115 +304,119 @@ collect_sessions_from_directory (const char *dirname)
|
|
||||||
g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
|
|
||||||
|
|
||||||
if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
|
|
||||||
g_debug ("Running under X11, ignoring %s", filename);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
id = g_strndup (filename, strlen (filename) - strlen (".desktop"));
|
|
||||||
|
|
||||||
full_path = g_build_filename (dirname, filename, NULL);
|
|
||||||
|
|
||||||
load_session_file (id, full_path);
|
|
||||||
|
|
||||||
g_free (id);
|
|
||||||
g_free (full_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_dir_close (dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
collect_sessions (void)
|
|
||||||
{
|
|
||||||
g_autoptr(GHashTable) names_seen_before = NULL;
|
|
||||||
g_autoptr(GPtrArray) xorg_search_array = NULL;
|
|
||||||
g_autoptr(GPtrArray) wayland_search_array = NULL;
|
|
||||||
gchar *session_dir = NULL;
|
|
||||||
int i;
|
|
||||||
- const char *xorg_search_dirs[] = {
|
|
||||||
- "/etc/X11/sessions/",
|
|
||||||
- DMCONFDIR "/Sessions/",
|
|
||||||
- DATADIR "/gdm/BuiltInSessions/",
|
|
||||||
- DATADIR "/xsessions/",
|
|
||||||
- };
|
|
||||||
const gchar *supported_session_types_env = NULL;
|
|
||||||
g_auto (GStrv) supported_session_types = NULL;
|
|
||||||
+ const gchar * const *system_data_dirs = g_get_system_data_dirs ();
|
|
||||||
|
|
||||||
supported_session_types_env = g_getenv ("GDM_SUPPORTED_SESSION_TYPES");
|
|
||||||
if (supported_session_types_env != NULL) {
|
|
||||||
supported_session_types = g_strsplit (supported_session_types_env, ":", -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
names_seen_before = g_hash_table_new (g_str_hash, g_str_equal);
|
|
||||||
- xorg_search_array = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
|
|
||||||
- const gchar * const *system_data_dirs = g_get_system_data_dirs ();
|
|
||||||
+#ifdef ENABLE_XORG_SUPPORT
|
|
||||||
+ const char *xorg_search_dirs[] = {
|
|
||||||
+ "/etc/X11/sessions/",
|
|
||||||
+ DMCONFDIR "/Sessions/",
|
|
||||||
+ DATADIR "/gdm/BuiltInSessions/",
|
|
||||||
+ DATADIR "/xsessions/",
|
|
||||||
+ };
|
|
||||||
+ xorg_search_array = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
|
|
||||||
for (i = 0; system_data_dirs[i]; i++) {
|
|
||||||
session_dir = g_build_filename (system_data_dirs[i], "xsessions", NULL);
|
|
||||||
g_ptr_array_add (xorg_search_array, session_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (xorg_search_dirs); i++) {
|
|
||||||
g_ptr_array_add (xorg_search_array, g_strdup (xorg_search_dirs[i]));
|
|
||||||
}
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_WAYLAND_SUPPORT
|
|
||||||
const char *wayland_search_dirs[] = {
|
|
||||||
DATADIR "/wayland-sessions/",
|
|
||||||
};
|
|
||||||
|
|
||||||
wayland_search_array = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
|
|
||||||
for (i = 0; system_data_dirs[i]; i++) {
|
|
||||||
session_dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
|
|
||||||
g_ptr_array_add (wayland_search_array, session_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (wayland_search_dirs); i++) {
|
|
||||||
g_ptr_array_add (wayland_search_array, g_strdup (wayland_search_dirs[i]));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (gdm_available_sessions_map == NULL) {
|
|
||||||
gdm_available_sessions_map = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
||||||
g_free, (GDestroyNotify)gdm_session_file_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef ENABLE_XORG_SUPPORT
|
|
||||||
if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "x11")) {
|
|
||||||
for (i = xorg_search_array->len - 1; i >= 0; i--) {
|
|
||||||
collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
#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 = wayland_search_array->len - 1; i >= 0; 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;
|
|
||||||
|
|
||||||
--
|
|
||||||
2.44.0
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user