From: Thorsten Kukuk Date: Fri, 24 Feb 2023 08:47:52 +0000 (+0100) Subject: sd-login: add sd_uid_get_login_time interface #26574 X-Git-Tag: v254-rc1~1154^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d622fefc008ce1cd3bf62ced4a606d3b5277b9fa;p=thirdparty%2Fsystemd.git sd-login: add sd_uid_get_login_time interface #26574 --- diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml index 087a2d539d0..e6cf77ff699 100644 --- a/man/sd_uid_get_state.xml +++ b/man/sd_uid_get_state.xml @@ -22,6 +22,7 @@ sd_uid_get_sessions sd_uid_get_seats sd_uid_get_display + sd_uid_get_login_time Determine login state of a specific Unix user ID @@ -62,6 +63,12 @@ char **session + + + int sd_uid_get_login_time + uid_t uid + uint64_t *usec + @@ -126,16 +133,27 @@ of the "primary" session of a user. If the user has graphical sessions, it will be the oldest graphical session. Otherwise, it will be the oldest open session. + + sd_uid_get_login_time() may be used to + determine the time the user's service manager has been invoked, + which is the time when the user's first active session, since which + they stayed logged in continuously, began. The usec + is in microseconds since the epoch (CLOCK_REALTIME). + This call will fail with -ENXIO if the user is not + currently logged in. Return Value - On success, sd_uid_get_state() returns 0 or a positive integer. If the test - succeeds, sd_uid_is_on_seat() returns a positive integer; if it fails, 0. - sd_uid_get_sessions() and sd_uid_get_seats() return the number - of entries in the returned arrays. sd_uid_get_display() returns a non-negative code - on success. On failure, these calls return a negative errno-style error code. + On success, sd_uid_get_state() and + sd_uid_get_login_time() returns 0 or a positive + integer. If the test succeeds, sd_uid_is_on_seat() + returns a positive integer; if it fails, 0. sd_uid_get_sessions() + and sd_uid_get_seats() return the number of entries + in the returned arrays. sd_uid_get_display() + returns a non-negative code on success. On failure, these calls return + a negative errno-style error code. Errors diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 8b5edabb75e..b54417f3d11 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -817,4 +817,5 @@ LIBSYSTEMD_254 { global: sd_session_get_username; sd_session_get_start_time; + sd_uid_get_login_time; } LIBSYSTEMD_253; diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c index 12cb4e67922..a81b21062a7 100644 --- a/src/libsystemd/sd-login/sd-login.c +++ b/src/libsystemd/sd-login/sd-login.c @@ -503,6 +503,36 @@ _public_ int sd_uid_get_display(uid_t uid, char **session) { return 0; } +_public_ int sd_uid_get_login_time(uid_t uid, uint64_t *usec) { + _cleanup_free_ char *p = NULL, *s = NULL, *rt = NULL; + usec_t t; + int r; + + assert_return(usec, -EINVAL); + + r = file_of_uid(uid, &p); + if (r < 0) + return r; + + r = parse_env_file(NULL, p, "STATE", &s, "REALTIME", &rt); + if (r == -ENOENT) + return -ENXIO; + if (r < 0) + return r; + if (isempty(s) || isempty(rt)) + return -EIO; + + if (!STR_IN_SET(s, "active", "online")) + return -ENXIO; + + r = safe_atou64(rt, &t); + if (r < 0) + return r; + + *usec = t; + return 0; +} + static int file_of_seat(const char *seat, char **_p) { char *p; int r; diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h index 526af34d376..7246d9f472a 100644 --- a/src/systemd/sd-login.h +++ b/src/systemd/sd-login.h @@ -130,6 +130,9 @@ int sd_uid_get_state(uid_t uid, char **state); /* Return primary session of user, if there is any */ int sd_uid_get_display(uid_t uid, char **session); +/* Determine the login time of user */ +int sd_uid_get_login_time(uid_t uid, uint64_t *usec); + /* Return 1 if UID has session on seat. If require_active is true, this will * look for active sessions only. */ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat);