diff options
Diffstat (limited to 'modules/pam_lastlog/pam_lastlog.c')
-rw-r--r-- | modules/pam_lastlog/pam_lastlog.c | 42 |
1 files changed, 41 insertions, 1 deletions
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 <pwd.h> #include <stdlib.h> +#include <ctype.h> #include <stdarg.h> #include <stdio.h> #include <string.h> @@ -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 */ |