From d9dd381a574a02b239438db4fcc9d6ac2fd82ee0 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 19 Oct 2022 14:50:33 -0400 Subject: [PATCH] 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 cc61efc9..e1bc62d7 100644 --- a/daemon/gdm-manager.c +++ b/daemon/gdm-manager.c @@ -628,113 +628,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.37.3