diff --git a/SOURCES/0001-meson-set-D_GNU_SOURCE-for-updwtmpx.patch b/SOURCES/0001-meson-set-D_GNU_SOURCE-for-updwtmpx.patch new file mode 100644 index 0000000..4c5be7a --- /dev/null +++ b/SOURCES/0001-meson-set-D_GNU_SOURCE-for-updwtmpx.patch @@ -0,0 +1,81 @@ +From 5a2d5dbdf8c6f6d3c896082a5a07b4292f5fb410 Mon Sep 17 00:00:00 2001 +From: Sam James +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 + diff --git a/SOURCES/0002-manager-Fix-btmp-record-accounting.patch b/SOURCES/0002-manager-Fix-btmp-record-accounting.patch new file mode 100644 index 0000000..2c69b53 --- /dev/null +++ b/SOURCES/0002-manager-Fix-btmp-record-accounting.patch @@ -0,0 +1,227 @@ +From 20725e4c65555178ed64a3cb77ee979ec98998f8 Mon Sep 17 00:00:00 2001 +From: Ray Strode +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 + diff --git a/SPECS/gdm.spec b/SPECS/gdm.spec index a984959..ee63271 100644 --- a/SPECS/gdm.spec +++ b/SPECS/gdm.spec @@ -12,7 +12,7 @@ Name: gdm Epoch: 1 Version: 40.0 -Release: 24%{?dist} +Release: 25%{?dist} Summary: The GNOME Display Manager License: GPLv2+ @@ -53,6 +53,10 @@ Patch100001: 0001-daemon-Infer-session-type-from-desktop-file-if-user-.patch Patch110001: 0001-meson-Fix-detection-of-Xorg-versions-that-need-liste.patch Patch110002: 0002-daemon-Support-X-servers-built-with-Dlisten_tcp-true.patch +# Fix btmp accounting +Patch120001: 0001-meson-set-D_GNU_SOURCE-for-updwtmpx.patch +Patch120002: 0002-manager-Fix-btmp-record-accounting.patch + # Non-upstreamable workarounds Patch66620001: 0001-data-reap-gdm-sessions-on-shutdown.patch @@ -375,6 +379,10 @@ fi %{_libdir}/pkgconfig/gdm-pam-extensions.pc %changelog +* Wed Oct 19 2022 Ray Strode - 40.0-25 +- Fix btmp accounting + Resolves: #2030043 + * Mon May 16 2022 Ray Strode - 40.0-24 - Fix typo that prevents the correct session type from being used when user switching.