From 4633164857580a5e5e52a8a2106fa2b4627bc8f6 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 28 Nov 2018 14:57:16 +0100 Subject: [PATCH] login.defs: Add LASTLOG_UID_MAX variable to limit lastlog to small uids. As the large uids are usually provided by remote user identity and authentication service, which also provide user login tracking, there is no need to create a huge sparse file for them on every local machine. fixup! login.defs: Add LASTLOG_UID_MAX variable to limit lastlog to small uids. --- lib/getdef.c | 1 + man/Makefile.am | 1 + man/lastlog.8.xml | 13 ++++++++ man/login.defs.5.xml | 13 ++++++-- man/login.defs.d/LASTLOG_UID_MAX.xml | 46 ++++++++++++++++++++++++++++ man/useradd.8.xml | 2 ++ man/usermod.8.xml | 2 ++ src/lastlog.c | 21 +++++++++++++ src/login.c | 5 ++- src/useradd.c | 7 +++++ src/usermod.c | 7 +++++ 11 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 man/login.defs.d/LASTLOG_UID_MAX.xml diff --git a/lib/getdef.c b/lib/getdef.c index d57b12de..ece33a78 100644 --- a/lib/getdef.c +++ b/lib/getdef.c @@ -92,6 +92,7 @@ static struct itemdef def_table[] = { {"GID_MIN", NULL}, {"HUSHLOGIN_FILE", NULL}, {"KILLCHAR", NULL}, + {"LASTLOG_UID_MAX", NULL}, {"LOGIN_RETRIES", NULL}, {"LOGIN_TIMEOUT", NULL}, {"LOG_OK_LOGINS", NULL}, diff --git a/man/Makefile.am b/man/Makefile.am index 4c340229..3f040e05 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -137,6 +137,7 @@ login_defs_v = \ ISSUE_FILE.xml \ KILLCHAR.xml \ LASTLOG_ENAB.xml \ + LASTLOG_UID_MAX.xml \ LOGIN_RETRIES.xml \ LOGIN_STRING.xml \ LOGIN_TIMEOUT.xml \ diff --git a/man/lastlog.8.xml b/man/lastlog.8.xml index 3ee1b3a8..fc096c8f 100644 --- a/man/lastlog.8.xml +++ b/man/lastlog.8.xml @@ -31,6 +31,7 @@ --> ]> @@ -200,6 +201,18 @@ + + CONFIGURATION + + The following configuration variables in + /etc/login.defs change the behavior of this + tool: + + + &LASTLOG_UID_MAX; + + + FILES diff --git a/man/login.defs.5.xml b/man/login.defs.5.xml index 98d37fdc..ebf60ba3 100644 --- a/man/login.defs.5.xml +++ b/man/login.defs.5.xml @@ -54,6 +54,7 @@ + @@ -188,6 +189,7 @@ &ISSUE_FILE; &KILLCHAR; &LASTLOG_ENAB; + &LASTLOG_UID_MAX; &LOG_OK_LOGINS; &LOG_UNKFAIL_ENAB; &LOGIN_RETRIES; @@ -349,7 +351,12 @@ - + + lastlog + + LASTLOG_UID_MAX + + login @@ -365,7 +372,7 @@ HUSHLOGIN_FILE ISSUE_FILE KILLCHAR - LASTLOG_ENAB + LASTLOG_ENAB LASTLOG_UID_MAX LOGIN_RETRIES LOGIN_STRING LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB @@ -474,6 +481,7 @@ CREATE_HOME GID_MAX GID_MIN + LASTLOG_UID_MAX MAIL_DIR MAX_MEMBERS_PER_GROUP PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN @@ -498,6 +506,7 @@ usermod + LASTLOG_UID_MAX MAIL_DIR MAIL_FILE MAX_MEMBERS_PER_GROUP TCB_SYMLINKS USE_TCB diff --git a/man/login.defs.d/LASTLOG_UID_MAX.xml b/man/login.defs.d/LASTLOG_UID_MAX.xml new file mode 100644 index 00000000..ba3025a6 --- /dev/null +++ b/man/login.defs.d/LASTLOG_UID_MAX.xml @@ -0,0 +1,46 @@ + + + (number) + + + Highest user ID number for which the lastlog entries should be + updated. As higher user IDs are usually tracked by remote user + identity and authentication services there is no need to create + a huge sparse lastlog file for them. + + + No option present in the configuration + means that there is no user ID limit for writing lastlog entries. + + + diff --git a/man/useradd.8.xml b/man/useradd.8.xml index 582b39c7..59e53c1f 100644 --- a/man/useradd.8.xml +++ b/man/useradd.8.xml @@ -32,6 +32,7 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ + @@ -670,6 +671,7 @@ &CREATE_HOME; &GID_MAX; + &LASTLOG_UID_MAX; &MAIL_DIR; &MAX_MEMBERS_PER_GROUP; &PASS_MAX_DAYS; diff --git a/man/usermod.8.xml b/man/usermod.8.xml index 7fea2981..bb8312db 100644 --- a/man/usermod.8.xml +++ b/man/usermod.8.xml @@ -30,6 +30,7 @@ --> @@ -517,6 +518,7 @@ tool: + &LASTLOG_UID_MAX; &MAIL_DIR; &MAX_MEMBERS_PER_GROUP; &SUB_GID_COUNT; diff --git a/src/lastlog.c b/src/lastlog.c index 965691db..c1caedb0 100644 --- a/src/lastlog.c +++ b/src/lastlog.c @@ -44,6 +44,7 @@ #include #include "defines.h" #include "prototypes.h" +#include "getdef.h" /*@-exitarg@*/ #include "exitcodes.h" @@ -182,6 +183,15 @@ static void print_one (/*@null@*/const struct passwd *pw) static void print (void) { const struct passwd *pwent; + unsigned long lastlog_uid_max; + + lastlog_uid_max = getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL); + if ( (has_umin && umin > lastlog_uid_max) + || (has_umax && umax > lastlog_uid_max)) { + fprintf (stderr, _("%s: Selected uid(s) are higher than LASTLOG_UID_MAX (%lu),\n" + "\tthe output might be incorrect.\n"), Prog, lastlog_uid_max); + } + if (uflg && has_umin && has_umax && (umin == umax)) { print_one (getpwuid ((uid_t)umin)); } else { @@ -191,6 +201,8 @@ static void print (void) && ( (has_umin && (pwent->pw_uid < (uid_t)umin)) || (has_umax && (pwent->pw_uid > (uid_t)umax)))) { continue; + } else if ( !uflg && pwent->pw_uid > (uid_t) lastlog_uid_max) { + continue; } print_one (pwent); } @@ -246,10 +258,19 @@ static void update_one (/*@null@*/const struct passwd *pw) static void update (void) { const struct passwd *pwent; + unsigned long lastlog_uid_max; if (!uflg) /* safety measure */ return; + lastlog_uid_max = getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL); + if ( (has_umin && umin > lastlog_uid_max) + || (has_umax && umax > lastlog_uid_max)) { + fprintf (stderr, _("%s: Selected uid(s) are higher than LASTLOG_UID_MAX (%lu),\n" + "\tthey will not be updated.\n"), Prog, lastlog_uid_max); + return; + } + if (has_umin && has_umax && (umin == umax)) { update_one (getpwuid ((uid_t)umin)); } else { diff --git a/src/login.c b/src/login.c index 7677adf1..492021a1 100644 --- a/src/login.c +++ b/src/login.c @@ -1162,7 +1162,9 @@ int main (int argc, char **argv) #endif /* WITH_AUDIT */ #ifndef USE_PAM /* pam_lastlog handles this */ - if (getdef_bool ("LASTLOG_ENAB")) { /* give last login and log this one */ + if ( getdef_bool ("LASTLOG_ENAB") + && pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL)) { + /* give last login and log this one */ dolastlog (&ll, pwd, tty, hostname); } #endif @@ -1298,6 +1300,7 @@ int main (int argc, char **argv) } } if ( getdef_bool ("LASTLOG_ENAB") + && pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL) && (ll.ll_time != 0)) { time_t ll_time = ll.ll_time; diff --git a/src/useradd.c b/src/useradd.c index e074844d..41e2ace4 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -1863,11 +1863,18 @@ static void lastlog_reset (uid_t uid) struct lastlog ll; int fd; off_t offset_uid = (off_t) (sizeof ll) * uid; + uid_t max_uid; if (access (LASTLOG_FILE, F_OK) != 0) { return; } + max_uid = (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL); + if (uid > max_uid) { + /* do not touch lastlog for large uids */ + return; + } + memzero (&ll, sizeof (ll)); fd = open (LASTLOG_FILE, O_RDWR); diff --git a/src/usermod.c b/src/usermod.c index fd9a98a6..72eeb8b2 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -1864,11 +1864,18 @@ static void update_lastlog (void) int fd; off_t off_uid = (off_t) user_id * sizeof ll; off_t off_newuid = (off_t) user_newid * sizeof ll; + uid_t max_uid; if (access (LASTLOG_FILE, F_OK) != 0) { return; } + max_uid = (uid_t) getdef_ulong ("LASTLOG_MAX_UID", 0xFFFFFFFFUL); + if (user_newid > max_uid) { + /* do not touch lastlog for large uids */ + return; + } + fd = open (LASTLOG_FILE, O_RDWR); if (-1 == fd) {