From: Tomas Mraz Date: Wed, 28 Nov 2018 13:57:16 +0000 (+0100) Subject: login.defs: Add LASTLOG_UID_MAX variable to limit lastlog to small uids. X-Git-Tag: 4.7~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=46331648;p=thirdparty%2Fshadow.git 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. --- diff --git a/lib/getdef.c b/lib/getdef.c index d57b12dec..ece33a78c 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 4c3402299..3f040e053 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 3ee1b3a89..fc096c8f9 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 98d37fdc1..ebf60ba3b 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 000000000..ba3025a6e --- /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 582b39c7e..59e53c1fe 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 7fea2981b..bb8312dbf 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 965691db1..c1caedb06 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 7677adf16..492021a13 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 e074844d0..41e2ace4a 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 fd9a98a63..72eeb8b2e 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) {