From 73e397b24c06e86afc1d2c0c356511948bb76d77 Mon Sep 17 00:00:00 2001 From: Joan Torres Lopez Date: Fri, 14 Nov 2025 17:48:14 +0100 Subject: [PATCH] Fix recording wtmp/utmp/btmp Resolves: https://issues.redhat.com/browse/RHEL-129305 --- ...-record-Rework-wtmp-utmp-btmp-fields.patch | 350 ++++++++++++++++++ gdm.spec | 8 +- 2 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 0001-session-record-Rework-wtmp-utmp-btmp-fields.patch diff --git a/0001-session-record-Rework-wtmp-utmp-btmp-fields.patch b/0001-session-record-Rework-wtmp-utmp-btmp-fields.patch new file mode 100644 index 0000000..8889881 --- /dev/null +++ b/0001-session-record-Rework-wtmp-utmp-btmp-fields.patch @@ -0,0 +1,350 @@ +From 161ce350f8acd18ad49ca880667c1f90f2b55d93 Mon Sep 17 00:00:00 2001 +From: Adrian Vovk +Date: Wed, 12 Nov 2025 14:59:03 -0500 +Subject: [PATCH] session-record: Rework wtmp/utmp/btmp fields + +This reworks the logic we use when setting the various fields in the +wtmp/utmp/btmp records. + +Previously, we'd set the hostname to "[]:" in +the X11 case and to "login screen" on Wayland. We'd also set the "line" +(which is supposed to contain the TTY) to the TTY on X11 but the seat ID +on Wayland. And finally we simply wouldn't write these records for +remote Wayland sessions. + +Now: the hostname is always just a remote IP address for remote +sessions, and the string "local" for local sessions. The "line" is also +consistently set to the TTY, or the seat ID if no TTY is available, or +the string "headless" if no seat is set and the session is headless. +Also Wayland remote sessions are supported properly now. + +This also happens to get rid of this code's dependency on X11: we no +longer consider the X11 display name + +Co-authored-by: Joan Torres Lopez +--- + daemon/gdm-manager.c | 47 ++++---------- + daemon/gdm-session-record.c | 123 ++++++++++++++---------------------- + daemon/gdm-session-record.h | 13 ++-- + 3 files changed, 64 insertions(+), 119 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index 05bbb96..681c9f6 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -659,68 +659,46 @@ add_session_record (GdmManager *manager, + SessionRecord record) + { + const char *username; +- 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; ++ g_autofree char *hostname = NULL; ++ g_autofree char *display_device = NULL; ++ g_autofree char *display_seat_id = NULL; + + username = gdm_session_get_username (session); +- +- if (username == NULL) { +- goto out; +- } ++ if (username == NULL) ++ return FALSE; + + 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) { +- 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); ++ display_device, ++ display_seat_id); + break; + case SESSION_RECORD_LOGOUT: + gdm_session_record_logout (pid, + username, + hostname, +- display_name, +- display_device); ++ display_device, ++ display_seat_id); + break; + case SESSION_RECORD_FAILED: + gdm_session_record_failed (pid, + username, + hostname, +- display_name, +- display_device); ++ display_device, ++ display_seat_id); + break; + } + +- recorded = TRUE; +-out: +- g_free (display_name); +- g_free (hostname); +- g_free (display_device); +- g_free (display_seat_id); +- +- return recorded; ++ return FALSE; + } + + static GdmSession * +@@ -2035,7 +2013,6 @@ on_user_session_started (GdmSession *session, + GdmManager *manager) + { + g_debug ("GdmManager: session started %d", pid); +- add_session_record (manager, session, pid, SESSION_RECORD_LOGIN); + } + + static void +diff --git a/daemon/gdm-session-record.c b/daemon/gdm-session-record.c +index 310323b..3b549d8 100644 +--- a/daemon/gdm-session-record.c ++++ b/daemon/gdm-session-record.c +@@ -111,79 +111,52 @@ record_set_pid (UTMP *u, + + static void + record_set_host (UTMP *u, +- const char *x11_display_name, +- const char *host_name) ++ const char *remote_host) + { +- char *hostname; +- ++ const char *hostname; + #if defined(HAVE_UT_UT_HOST) +- hostname = NULL; +- +- /* +- * Set ut_host to hostname:$DISPLAY if remote, otherwise set +- * to $DISPLAY +- */ +- 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); ++ if (remote_host != NULL) ++ hostname = remote_host; ++ else ++ hostname = "local"; ++ 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)); ++ 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) ++ const char *tty, ++ const char *seat_id) + { +- /* +- * 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/")) { +- 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)); +- } +- ++ const char *line; ++ ++ if (tty != NULL) { ++ if (g_str_has_prefix (tty, "/dev/")) ++ line = tty + strlen("/dev/"); ++ else ++ line = tty; ++ } else if (seat_id != NULL) ++ line = seat_id; ++ else ++ line = "headless"; ++ ++ memccpy (u->ut_line, line, '\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) ++gdm_session_record_login (GPid session_pid, ++ const char *user_name, ++ const char *host_name, ++ const char *tty, ++ const char *seat_id) + { + 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"); +@@ -195,8 +168,8 @@ gdm_session_record_login (GPid session_pid, + + record_set_timestamp (&session_record); + record_set_pid (&session_record, session_pid); +- record_set_host (&session_record, x11_display_name, host_name); +- record_set_line (&session_record, display_device, x11_display_name); ++ record_set_host (&session_record, host_name); ++ record_set_line (&session_record, tty, seat_id); + + /* Handle wtmp */ + g_debug ("Writing wtmp session record to " GDM_NEW_SESSION_RECORDS_FILE); +@@ -224,16 +197,15 @@ gdm_session_record_login (GPid session_pid, + } + + void +-gdm_session_record_logout (GPid session_pid, +- const char *user_name, +- const char *host_name, +- const char *x11_display_name, +- const char *display_device) ++gdm_session_record_logout (GPid session_pid, ++ const char *user_name, ++ const char *host_name, ++ const char *tty, ++ const char *seat_id) + { + UTMP session_record = { 0 }; + +- if (x11_display_name == NULL) +- x11_display_name = display_device; ++ record_set_username (&session_record, user_name); + + g_debug ("Writing logout record"); + +@@ -244,8 +216,8 @@ gdm_session_record_logout (GPid session_pid, + + record_set_timestamp (&session_record); + record_set_pid (&session_record, session_pid); +- record_set_host (&session_record, x11_display_name, host_name); +- record_set_line (&session_record, display_device, x11_display_name); ++ record_set_host (&session_record, host_name); ++ record_set_line (&session_record, tty, seat_id); + + /* Handle wtmp */ + g_debug ("Writing wtmp logout record to " GDM_NEW_SESSION_RECORDS_FILE); +@@ -269,17 +241,14 @@ gdm_session_record_logout (GPid session_pid, + } + + void +-gdm_session_record_failed (GPid session_pid, +- const char *user_name, +- const char *host_name, +- const char *x11_display_name, +- const char *display_device) ++gdm_session_record_failed (GPid session_pid, ++ const char *user_name, ++ const char *host_name, ++ const char *tty, ++ const char *seat_id) + { + UTMP session_record = { 0 }; + +- if (x11_display_name == NULL) +- x11_display_name = display_device; +- + record_set_username (&session_record, user_name); + + g_debug ("Writing failed session attempt record"); +@@ -291,8 +260,8 @@ gdm_session_record_failed (GPid session_pid, + + record_set_timestamp (&session_record); + record_set_pid (&session_record, session_pid); +- record_set_host (&session_record, x11_display_name, host_name); +- record_set_line (&session_record, display_device, x11_display_name); ++ record_set_host (&session_record, host_name); ++ record_set_line (&session_record, tty, seat_id); + + #if defined(HAVE_UPDWTMPX) || defined(HAVE_UPDWTMP) + /* Handle btmp */ +diff --git a/daemon/gdm-session-record.h b/daemon/gdm-session-record.h +index 3c53268..bbe323a 100644 +--- a/daemon/gdm-session-record.h ++++ b/daemon/gdm-session-record.h +@@ -29,21 +29,20 @@ 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); ++ const char *tty, ++ const char *seat_id); + void + gdm_session_record_logout (GPid session_pid, + const char *user_name, + const char *host_name, +- const char *x11_display_name, +- const char *display_device); ++ const char *tty, ++ const char *seat_id); + void + gdm_session_record_failed (GPid session_pid, + const char *user_name, + const char *host_name, +- const char *x11_display_name, +- const char *display_device); +- ++ const char *tty, ++ const char *seat_id); + + G_END_DECLS + +-- +2.51.0 + diff --git a/gdm.spec b/gdm.spec index 3e2137e..9f6bd30 100644 --- a/gdm.spec +++ b/gdm.spec @@ -11,7 +11,7 @@ Name: gdm Epoch: 1 Version: 40.1 -Release: 40%{?dist} +Release: 41%{?dist} Summary: The GNOME Display Manager License: GPLv2+ @@ -72,6 +72,8 @@ Patch150001: 0001-libgdm-Don-t-collect-twice-sessions-on-usr-share.patch Patch160001: 0001-Revert-hack-that-quits-plymouth-late.patch +Patch170001: 0001-session-record-Rework-wtmp-utmp-btmp-fields.patch + # Non-upstreamable workarounds Patch66610001: 0001-data-reap-gdm-sessions-on-shutdown.patch @@ -375,6 +377,10 @@ dconf update || : %{_libdir}/pkgconfig/gdm-pam-extensions.pc %changelog +* Tue Nov 18 2025 Joan Torres Lopez - 40.1-41 +- Fix recording wtmp/utmp/btmp + Resolves: RHEL-129305 + * Tue Nov 18 2025 Joan Torres Lopez - 40.1-40 - Now Plymouth will quit even when no monitor is connected. Resolves: RHEL-129215