From: Stefan Schubert Date: Thu, 25 Jan 2024 17:12:53 +0000 (+0100) Subject: lslogins: Add support for lastlog2 X-Git-Tag: v2.42-start~535^2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bf7f26be8db9207149cff414f86b37f8f615a77a;p=thirdparty%2Futil-linux.git lslogins: Add support for lastlog2 --- diff --git a/login-utils/Makemodule.am b/login-utils/Makemodule.am index 1c5a11d846..3b844472b0 100644 --- a/login-utils/Makemodule.am +++ b/login-utils/Makemodule.am @@ -249,6 +249,10 @@ endif if HAVE_ECONF lslogins_LDADD += -leconf endif +if BUILD_LIBLASTLOG2 +lslogins_CFLAGS += -I$(ul_liblastlog2_incdir) +lslogins_LDADD += -llastlog2 +endif endif # BUILD_LSLOGINS diff --git a/login-utils/lslogins.c b/login-utils/lslogins.c index 217f3f3aed..7ba78f0995 100644 --- a/login-utils/lslogins.c +++ b/login-utils/lslogins.c @@ -47,6 +47,10 @@ # include #endif +#ifdef HAVE_LIBLASTLOG2 +# include "lastlog2.h" +#endif + #include "c.h" #include "nls.h" #include "closestream.h" @@ -262,6 +266,10 @@ struct lslogins_control { int lastlogin_fd; +#ifdef HAVE_LIBLASTLOG2 + const char *lastlog2_path; +#endif + void *usertree; uid_t uid; @@ -524,10 +532,71 @@ fail: return -EINVAL; } -static void get_lastlog(struct lslogins_control *ctl, uid_t uid, void *dst, int what) +#ifdef HAVE_LIBLASTLOG2 +static int get_lastlog2(struct lslogins_control *ctl, const char *user, void *dst, int what) +{ + struct ll2_context *context = ll2_new_context(ctl->lastlog2_path); /* LL2_DEFAULT_DATABASE is default path */ + + switch (what) { + case LASTLOG_TIME: { + time_t *t = dst; + int64_t res_time = 0; + + if (ll2_read_entry(context, user, &res_time, NULL, NULL, NULL, NULL) != 0) { + ll2_unref_context(context); + return -1; + } + *t = res_time; + break; + } + case LASTLOG_LINE: { + char *res_tty = NULL; + + if (ll2_read_entry(context, user, NULL, &res_tty, NULL, NULL, NULL) != 0) { + ll2_unref_context(context); + return -1; + } + if (res_tty) { + mem2strcpy(dst, res_tty, strlen(res_tty), strlen(res_tty) + 1); + free (res_tty); + } + break; + } + case LASTLOG_HOST: { + char *res_host = NULL; + + if (ll2_read_entry(context, user, NULL, NULL, &res_host, NULL, NULL) != 0) { + ll2_unref_context(context); + return -1; + } + if (res_host) { + mem2strcpy(dst, res_host, strlen(res_host), strlen(res_host) + 1); + free (res_host); + } + break; + } + default: + abort(); + } + ll2_unref_context(context); + return 0; +} +#endif + +static void get_lastlog(struct lslogins_control *ctl, uid_t uid, +#ifdef HAVE_LIBLASTLOG2 + const char *user, +#else + const char *user __attribute__((__unused__)), +#endif + void *dst, int what) { struct lastlog ll; +#ifdef HAVE_LIBLASTLOG2 + if (get_lastlog2(ctl, user, dst, LASTLOG_TIME) >= 0) + return; +#endif if (ctl->lastlogin_fd < 0 || pread(ctl->lastlogin_fd, (void *)&ll, sizeof(ll), uid * sizeof(ll)) != sizeof(ll)) return; @@ -797,7 +866,7 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c user->last_login = make_time(ctl->time_mode, time); } else { time = 0; - get_lastlog(ctl, pwd->pw_uid, &time, LASTLOG_TIME); + get_lastlog(ctl, pwd->pw_uid, pwd->pw_name, &time, LASTLOG_TIME); if (time) user->last_login = make_time(ctl->time_mode, time); } @@ -809,7 +878,7 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c sizeof(user_wtmp->ut_line), sizeof(user_wtmp->ut_line) + 1);; } else - get_lastlog(ctl, user->uid, user->last_tty, LASTLOG_LINE); + get_lastlog(ctl, user->uid, user->login, user->last_tty, LASTLOG_LINE); break; case COL_LAST_HOSTNAME: user->last_hostname = xcalloc(1, sizeof(user_wtmp->ut_host) + 1); @@ -818,7 +887,7 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c sizeof(user_wtmp->ut_host), sizeof(user_wtmp->ut_host) + 1);; } else - get_lastlog(ctl, user->uid, user->last_hostname, LASTLOG_HOST); + get_lastlog(ctl, user->uid, user->login, user->last_hostname, LASTLOG_HOST); break; case COL_FAILED_LOGIN: if (user_btmp) { @@ -1469,6 +1538,9 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" --wtmp-file set an alternate path for wtmp\n"), out); fputs(_(" --btmp-file set an alternate path for btmp\n"), out); fputs(_(" --lastlog set an alternate path for lastlog\n"), out); +#ifdef HAVE_LIBLASTLOG2 + fputs(_(" --lastlog2 set an alternate path for lastlog2\n"), out); +#endif fputs(USAGE_SEPARATOR, out); fprintf(out, USAGE_HELP_OPTIONS(26)); @@ -1494,6 +1566,9 @@ int main(int argc, char *argv[]) OPT_WTMP = CHAR_MAX + 1, OPT_BTMP, OPT_LASTLOG, +#ifdef HAVE_LIBLASTLOG2 + OPT_LASTLOG2, +#endif OPT_NOTRUNC, OPT_NOHEAD, OPT_TIME_FMT, @@ -1526,6 +1601,9 @@ int main(int argc, char *argv[]) { "wtmp-file", required_argument, 0, OPT_WTMP }, { "btmp-file", required_argument, 0, OPT_BTMP }, { "lastlog-file", required_argument, 0, OPT_LASTLOG }, +#ifdef HAVE_LIBLASTLOG2 + { "lastlog2-file", required_argument, 0, OPT_LASTLOG2 }, +#endif #ifdef HAVE_LIBSELINUX { "context", no_argument, 0, 'Z' }, #endif @@ -1639,6 +1717,11 @@ int main(int argc, char *argv[]) case OPT_LASTLOG: path_lastlog = optarg; break; +#ifdef HAVE_LIBLASTLOG2 + case OPT_LASTLOG2: + ctl->lastlog2_path = optarg; + break; +#endif case OPT_WTMP: path_wtmp = optarg; break; diff --git a/meson.build b/meson.build index 4f85cee154..05c0c992c0 100644 --- a/meson.build +++ b/meson.build @@ -1097,6 +1097,7 @@ exe = executable( include_directories : includes, link_with : [lib_common, lib_smartcols, + lib_lastlog2, logindefs_c], dependencies : [lib_selinux, lib_systemd],