]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lslogins: Add support for lastlog2
authorStefan Schubert <schubi@suse.de>
Thu, 25 Jan 2024 17:12:53 +0000 (18:12 +0100)
committerStefan Schubert <schubi@suse.de>
Thu, 25 Jan 2024 17:12:53 +0000 (18:12 +0100)
login-utils/Makemodule.am
login-utils/lslogins.c
meson.build

index 1c5a11d846b556868ced49e069101be05946a523..3b844472b007ff575c0d47275cc60399268a84d1 100644 (file)
@@ -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
 
 
index 217f3f3aedc9c6dc8e4df95a9c0548a0aa94f08c..7ba78f0995c707f359cfd3731a6563bf18e5d267 100644 (file)
 # include <systemd/sd-journal.h>
 #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 <path>   set an alternate path for wtmp\n"), out);
        fputs(_("     --btmp-file <path>   set an alternate path for btmp\n"), out);
        fputs(_("     --lastlog <path>     set an alternate path for lastlog\n"), out);
+#ifdef HAVE_LIBLASTLOG2
+       fputs(_("     --lastlog2 <path>    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;
index 4f85cee1548c5625d91d3a0ec77b5f92e572161c..05c0c992c0c401eb2fb1bd47b7fee973cb7f8fb4 100644 (file)
@@ -1097,6 +1097,7 @@ exe = executable(
   include_directories : includes,
   link_with : [lib_common,
                lib_smartcols,
+              lib_lastlog2,
                logindefs_c],
   dependencies : [lib_selinux,
                   lib_systemd],