aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_timestamp/pam_timestamp.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pam_timestamp/pam_timestamp.c')
-rw-r--r--modules/pam_timestamp/pam_timestamp.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/modules/pam_timestamp/pam_timestamp.c b/modules/pam_timestamp/pam_timestamp.c
index 01dd1385..572d9ff2 100644
--- a/modules/pam_timestamp/pam_timestamp.c
+++ b/modules/pam_timestamp/pam_timestamp.c
@@ -53,7 +53,6 @@
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
-#include <utmp.h>
#include <syslog.h>
#include <paths.h>
#ifdef WITH_OPENSSL
@@ -62,6 +61,12 @@
#include "hmacsha1.h"
#endif /* WITH_OPENSSL */
+#ifdef USE_LOGIND
+#include <systemd/sd-login.h>
+#else
+#include <utmp.h>
+#endif
+
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#include <security/pam_ext.h>
@@ -200,10 +205,26 @@ timestamp_good(time_t then, time_t now, time_t interval)
}
static int
-check_login_time(const char *ruser, time_t timestamp)
+check_login_time(
+#ifdef USE_LOGIND
+ uid_t uid,
+#else
+ const char *ruser,
+#endif
+ time_t timestamp)
{
- struct utmp utbuf, *ut;
time_t oldest_login = 0;
+#ifdef USE_LOGIND
+#define USEC_PER_SEC ((uint64_t) 1000000ULL)
+ uint64_t usec = 0;
+
+ if (sd_uid_get_login_time(uid, &usec) < 0) {
+ return PAM_SERVICE_ERR;
+ }
+
+ oldest_login = usec/USEC_PER_SEC;
+#else
+ struct utmp utbuf, *ut;
setutent();
while(
@@ -224,6 +245,7 @@ check_login_time(const char *ruser, time_t timestamp)
}
}
endutent();
+#endif
if(oldest_login == 0 || timestamp < oldest_login) {
return PAM_AUTH_ERR;
}
@@ -532,7 +554,15 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
close(fd);
return PAM_AUTH_ERR;
}
+#ifdef USE_LOGIND
+ struct passwd *pwd = pam_modutil_getpwnam(pamh, ruser);
+ if (pwd != NULL) {
+ return PAM_SERVICE_ERR;
+ }
+ if (check_login_time(pwd->pw_uid, then) != PAM_SUCCESS)
+#else
if (check_login_time(ruser, then) != PAM_SUCCESS)
+#endif
{
pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' is "
"older than oldest login, disallowing "
@@ -728,6 +758,9 @@ main(int argc, char **argv)
fd_set write_fds;
char path[BUFLEN];
struct stat st;
+#ifdef USE_LOGIND
+ uid_t uid;
+#endif
/* Check that there's nothing funny going on with stdio. */
if ((fstat(STDIN_FILENO, &st) == -1) ||
@@ -783,6 +816,9 @@ main(int argc, char **argv)
if (pwd == NULL) {
retval = 4;
}
+#ifdef USE_LOGIND
+ uid = pwd->pw_uid;
+#endif
/* Get the name of the target user. */
user = strdup(pwd->pw_name);
@@ -833,7 +869,11 @@ main(int argc, char **argv)
/* Check the timestamp. */
if (lstat(path, &st) != -1) {
/* Check oldest login against timestamp */
+#ifdef USE_LOGIND
+ if (check_login_time(uid, st.st_mtime) != PAM_SUCCESS) {
+#else
if (check_login_time(user, st.st_mtime) != PAM_SUCCESS) {
+#endif
retval = 7;
} else if (timestamp_good(st.st_mtime, time(NULL),
DEFAULT_TIMESTAMP_TIMEOUT) != PAM_SUCCESS) {