From aaa3e334e594d88e1a2cceae136494c08a62a147 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 19 Feb 2025 23:46:37 +0100 Subject: [PATCH] readutmp: Let callers distinguish LOGINs from USERs. Reported by Paul Eggert in . * lib/readutmp.h (LOGIN_PROCESS, UT_TYPE_LOGIN_PROCESS): New macros. * lib/readutmp.c (read_utmp_from_systemd): Possibly use LOGIN_PROCESS instead of USER_PROCESS, depending on the session's class. --- lib/readutmp.c | 19 ++++++++++++++----- lib/readutmp.h | 24 ++++++++++++++++-------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/readutmp.c b/lib/readutmp.c index 0938a094cb..efe0528cc3 100644 --- a/lib/readutmp.c +++ b/lib/readutmp.c @@ -1,6 +1,6 @@ /* GNU's read utmp module. - Copyright (C) 1992-2001, 2003-2006, 2009-2024 Free Software Foundation, Inc. + Copyright (C) 1992-2001, 2003-2006, 2009-2025 Free Software Foundation, 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 @@ -877,8 +877,8 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) } } - /* Create up to two USER_PROCESS entries: one for the seat, - one for the tty. */ + /* Create up to two USER_PROCESS or LOGIN_PROCESS entries: + one for the seat, one for the tty. */ if (seat != NULL || tty != NULL) { char *user; @@ -889,6 +889,13 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) if (sd_session_get_leader (session, &leader_pid) < 0) leader_pid = 0; + char *clasz; + if (sd_session_get_class (session, &clasz) < 0) + clasz = missing; + short ctype = + (strncmp (clasz, "manager", 7) == 0 ? LOGIN_PROCESS : + USER_PROCESS); + char *host; char *remote_host; if (sd_session_get_remote_host (session, &remote_host) < 0) @@ -932,7 +939,7 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) seat, strlen (seat), host, strlen (host), leader_pid /* the best we have */, - USER_PROCESS, start_ts, leader_pid, 0, 0); + ctype, start_ts, leader_pid, 0, 0); if (tty != NULL) a = add_utmp (a, options, user, strlen (user), @@ -940,10 +947,12 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) tty, strlen (tty), host, strlen (host), leader_pid /* the best we have */, - USER_PROCESS, start_ts, leader_pid, 0, 0); + ctype, start_ts, leader_pid, 0, 0); if (host != missing) free (host); + if (clasz != missing) + free (clasz); if (user != missing) free (user); } diff --git a/lib/readutmp.h b/lib/readutmp.h index dcfd44dbbc..60d63df959 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -1,6 +1,6 @@ /* Declarations for GNU's read utmp module. - Copyright (C) 1992-2007, 2009-2024 Free Software Foundation, Inc. + Copyright (C) 1992-2007, 2009-2025 Free Software Foundation, 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 @@ -45,7 +45,7 @@ # include #endif -/* Needed for BOOT_TIME and USER_PROCESS. */ +/* Needed for BOOT_TIME, USER_PROCESS, LOGIN_PROCESS. */ #if HAVE_UTMPX_H # if defined _THREAD_SAFE && defined UTMP_DATA_INIT /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE @@ -74,7 +74,8 @@ struct gl_utmp struct timespec ut_ts; /* time */ pid_t ut_pid; /* process ID of ? */ pid_t ut_session; /* process ID of session leader */ - short ut_type; /* BOOT_TIME, USER_PROCESS, or other */ + short ut_type; /* BOOT_TIME, USER_PROCESS, LOGIN_PROCESS, + or other */ struct { int e_termination; int e_exit; } ut_exit; }; @@ -257,19 +258,21 @@ struct utmpx32 # define WTMP_FILE "/etc/wtmp" #endif -/* In early versions of Android, did not define BOOT_TIME, only - USER_PROCESS. We need to use the value that is defined in newer versions - of Android. */ +/* In early versions of Android, did not define BOOT_TIME or + LOGIN_PROCESS, only USER_PROCESS. We need to use the value that is defined + in newer versions of Android. */ #if defined __ANDROID__ && !defined BOOT_TIME # define BOOT_TIME 2 +# define LOGIN_PROCESS 6 #endif /* Some platforms, such as OpenBSD, don't have an ut_type field and don't have - the BOOT_TIME and USER_PROCESS macros. But we want to support them in - 'struct gl_utmp'. */ + the BOOT_TIME, USER_PROCESS, and LOGIN_PROCESS macros. But we want to + support them in 'struct gl_utmp'. */ #if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) # define BOOT_TIME 2 # define USER_PROCESS 0 +# define LOGIN_PROCESS 6 #endif /* Macros that test (UT)->ut_type. */ @@ -283,6 +286,11 @@ struct utmpx32 #else # define UT_TYPE_USER_PROCESS(UT) 0 #endif +#ifdef LOGIN_PROCESS +# define UT_TYPE_LOGIN_PROCESS(UT) ((UT)->ut_type == LOGIN_PROCESS) +#else +# define UT_TYPE_LOGIN_PROCESS(UT) 0 +#endif /* Determines whether an entry *UT corresponds to a user process. */ #define IS_USER_PROCESS(UT) \ -- 2.39.5