summaryrefslogtreecommitdiff
path: root/modules/pam_lastlog
diff options
context:
space:
mode:
authorTomas Mraz <tmraz@fedoraproject.org>2018-12-11 09:08:20 +0100
committerTomas Mraz <tmraz@fedoraproject.org>2018-12-20 13:54:17 +0100
commit1daa323234982df4d7bbb8a13d4eb447106657d1 (patch)
treedb1bd94f31801dfc86eae8ac41d584c2b09017d8 /modules/pam_lastlog
parent00b38702c70ad3847a2b3d38930a6a390df81645 (diff)
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.
Diffstat (limited to 'modules/pam_lastlog')
-rw-r--r--modules/pam_lastlog/pam_lastlog.8.xml10
-rw-r--r--modules/pam_lastlog/pam_lastlog.c42
2 files changed, 50 insertions, 2 deletions
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
@@ -65,10 +65,18 @@
cases, this module is not necessary.
</para>
<para>
+ The module checks <option>LASTLOG_UID_MAX</option> option in
+ <filename>/etc/login.defs</filename> 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.
+ </para>
+ <para>
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 <option>LASTLOG_UID_MAX</option> value.
</para>
</refsect1>
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 */