From 1daa323234982df4d7bbb8a13d4eb447106657d1 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 11 Dec 2018 09:08:20 +0100 Subject: pam_lastlog: Limit lastlog file use by LASTLOG_UID_MAX option in login.defs. * modules/pam_lastlog/pam_lastlog.8.xml: Add the documentation of the LASTLOG_UID_MAX option. * modules/pam_lastlog/pam_lastlog.c: New function get_lastlog_uid_max(). (last_login_date): Check the uid against the get_lastlog_uid_max(). (pam_authenticate): Likewise. --- modules/pam_lastlog/pam_lastlog.8.xml | 10 ++++++++- modules/pam_lastlog/pam_lastlog.c | 42 ++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) (limited to 'modules/pam_lastlog') diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml index 77da9dbc..c8f247e9 100644 --- a/modules/pam_lastlog/pam_lastlog.8.xml +++ b/modules/pam_lastlog/pam_lastlog.8.xml @@ -64,11 +64,19 @@ Some applications may perform this function themselves. In such cases, this module is not necessary. + + The module checks option in + /etc/login.defs and does not update or display + last login records for users with UID higher than its value. + If the option is not present or its value is invalid, no user ID + limit is applied. + If the module is called in the auth or account phase, the accounts that were not used recently enough will be disallowed to log in. The check is not performed for the root account so the root is never - locked out. + locked out. It is also not performed for users with UID higher + than the value. diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c index 1a796b99..18bf7bec 100644 --- a/modules/pam_lastlog/pam_lastlog.c +++ b/modules/pam_lastlog/pam_lastlog.c @@ -20,6 +20,7 @@ #endif #include #include +#include #include #include #include @@ -50,6 +51,10 @@ struct lastlog { # define _PATH_BTMP "/var/log/btmp" #endif +#ifndef PATH_LOGIN_DEFS +# define PATH_LOGIN_DEFS "/etc/login.defs" +#endif + /* XXX - time before ignoring lock. Is 1 sec enough? */ #define LASTLOG_IGNORE_LOCK_TIME 1 @@ -187,6 +192,37 @@ get_tty(pam_handle_t *pamh) return terminal_line; } +#define MAX_UID_VALUE 0xFFFFFFFFUL + +static uid_t +get_lastlog_uid_max(pam_handle_t *pamh) +{ + uid_t uid_max = MAX_UID_VALUE; + unsigned long ul; + char *s, *ep; + + s = pam_modutil_search_key(pamh, PATH_LOGIN_DEFS, "LASTLOG_UID_MAX"); + if (s == NULL) + return uid_max; + + ep = s + strlen(s); + while (ep > s && isspace(*(--ep))) { + *ep = '\0'; + } + errno = 0; + ul = strtoul(s, &ep, 10); + if (!(ul >= MAX_UID_VALUE + || (uid_t)ul >= MAX_UID_VALUE + || (errno != 0 && ul == 0) + || s == ep + || *ep != '\0')) { + uid_max = (uid_t)ul; + } + free(s); + + return uid_max; +} + static int last_login_open(pam_handle_t *pamh, int announce, uid_t uid) { @@ -418,6 +454,10 @@ last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, t int retval; int last_fd; + if (uid > get_lastlog_uid_max(pamh)) { + return PAM_SUCCESS; + } + /* obtain the last login date and all the relevant info */ last_fd = last_login_open(pamh, announce, uid); if (last_fd < 0) { @@ -602,7 +642,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, uid = pwd->pw_uid; pwd = NULL; /* tidy up */ - if (uid == 0) + if (uid == 0 || uid > get_lastlog_uid_max(pamh)) return PAM_SUCCESS; /* obtain the last login date and all the relevant info */ -- cgit v1.2.3