static int last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, time_t *lltime) { int retval; int last_fd; /* obtain the last login date and all the relevant info */ last_fd = last_login_open(pamh, announce, uid); if (last_fd < 0) { return PAM_SERVICE_ERR; } retval = last_login_read(pamh, announce, last_fd, uid, lltime); if (retval != PAM_SUCCESS) { close(last_fd); D(("error while reading lastlog file")); return retval; } if (announce & LASTLOG_UPDATE) { retval = last_login_write(pamh, announce, last_fd, uid, user); } close(last_fd); D(("all done with last login")); return retval; }
static int last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, time_t *lltime) { int retval; int last_fd; /* obtain the last login date and all the relevant info */ last_fd = open(_PATH_LASTLOG, announce&LASTLOG_UPDATE ? O_RDWR : O_RDONLY); if (last_fd < 0) { if (errno == ENOENT) { last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (last_fd < 0) { pam_syslog(pamh, LOG_ERR, "unable to create %s: %m", _PATH_LASTLOG); D(("unable to create %s file", _PATH_LASTLOG)); return PAM_SERVICE_ERR; } pam_syslog(pamh, LOG_WARNING, "file %s created", _PATH_LASTLOG); D(("file %s created", _PATH_LASTLOG)); } else { pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_LASTLOG); D(("unable to open %s file", _PATH_LASTLOG)); return PAM_SERVICE_ERR; } } if (lseek(last_fd, sizeof(struct lastlog) * (off_t) uid, SEEK_SET) < 0) { pam_syslog(pamh, LOG_ERR, "failed to lseek %s: %m", _PATH_LASTLOG); D(("unable to lseek %s file", _PATH_LASTLOG)); return PAM_SERVICE_ERR; } retval = last_login_read(pamh, announce, last_fd, uid, lltime); if (retval != PAM_SUCCESS) { close(last_fd); D(("error while reading lastlog file")); return retval; } if (announce & LASTLOG_UPDATE) { retval = last_login_write(pamh, announce, last_fd, uid, user); } close(last_fd); D(("all done with last login")); return retval; }
/* --- authentication (locking out inactive users) functions --- */ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retval, ctrl; const char *user = NULL; const struct passwd *pwd; uid_t uid; time_t lltime = 0; time_t inactive_days = 0; int last_fd; /* * Lock out the user if he did not login recently enough. */ ctrl = _pam_auth_parse(pamh, flags, argc, argv, &inactive_days); /* which user? */ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL || *user == '\0') { pam_syslog(pamh, LOG_ERR, "cannot determine the user's name"); return PAM_USER_UNKNOWN; } /* what uid? */ pwd = pam_modutil_getpwnam (pamh, user); if (pwd == NULL) { pam_syslog(pamh, LOG_ERR, "user unknown"); return PAM_USER_UNKNOWN; } uid = pwd->pw_uid; pwd = NULL; /* tidy up */ if (uid == 0) return PAM_SUCCESS; /* obtain the last login date and all the relevant info */ last_fd = last_login_open(pamh, ctrl, uid); if (last_fd < 0) { return PAM_IGNORE; } retval = last_login_read(pamh, ctrl|LASTLOG_QUIET, last_fd, uid, &lltime); close(last_fd); if (retval != PAM_SUCCESS) { D(("error while reading lastlog file")); return PAM_IGNORE; } if (lltime == 0) { /* user never logged in before */ if (ctrl & LASTLOG_DEBUG) pam_syslog(pamh, LOG_DEBUG, "user never logged in - pass"); return PAM_SUCCESS; } lltime = (time(NULL) - lltime) / (24*60*60); if (lltime > inactive_days) { pam_syslog(pamh, LOG_INFO, "user %s inactive for %ld days - denied", user, (long) lltime); return PAM_AUTH_ERR; } return PAM_SUCCESS; }