summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/pam.d/Makefile1
-rw-r--r--etc/pam.d/atrun10
-rw-r--r--libexec/atrun/Makefile6
-rw-r--r--libexec/atrun/atrun.c41
4 files changed, 47 insertions, 11 deletions
diff --git a/etc/pam.d/Makefile b/etc/pam.d/Makefile
index d1ab9f4..9e5746c 100644
--- a/etc/pam.d/Makefile
+++ b/etc/pam.d/Makefile
@@ -3,6 +3,7 @@
NO_OBJ=
FILES= README \
+ atrun \
ftpd \
gdm \
imap \
diff --git a/etc/pam.d/atrun b/etc/pam.d/atrun
new file mode 100644
index 0000000..6829469
--- /dev/null
+++ b/etc/pam.d/atrun
@@ -0,0 +1,10 @@
+#
+# $FreeBSD$
+#
+# PAM configuration for the "atrun" service
+#
+
+# Note well: enabling pam_nologin for atrun will currently result
+# in jobs discarded, not just delayed, during a no-login period.
+#account required pam_nologin.so
+account required pam_unix.so
diff --git a/libexec/atrun/Makefile b/libexec/atrun/Makefile
index 40ebd06..c922dc5 100644
--- a/libexec/atrun/Makefile
+++ b/libexec/atrun/Makefile
@@ -12,11 +12,11 @@ BINDIR= ${ATLIB_DIR}
CLEANFILES= ${MAN}
CFLAGS+=-I${MAINSRC} -I${.CURDIR}
-CFLAGS+=-DLOGIN_CAP
+CFLAGS+=-DLOGIN_CAP -DPAM
WFORMAT=0
-DPADD= ${LIBUTIL}
-LDADD= -lutil
+DPADD= ${LIBPAM} ${LIBUTIL}
+LDADD= -lpam -lutil
atrun.8: atrun.man
@${ECHO} Making ${.TARGET:T} from ${.ALLSRC:T}; \
diff --git a/libexec/atrun/atrun.c b/libexec/atrun/atrun.c
index 374c10b..a7cef87 100644
--- a/libexec/atrun/atrun.c
+++ b/libexec/atrun/atrun.c
@@ -58,6 +58,10 @@ static const char rcsid[] =
#ifdef LOGIN_CAP
#include <login_cap.h>
#endif
+#ifdef PAM
+#include <security/pam_appl.h>
+#include <security/openpam.h>
+#endif
#if (MAXLOGNAME-1) > UT_NAMESIZE
#define LOGNAMESIZE UT_NAMESIZE
@@ -87,6 +91,7 @@ static const char rcsid[] =
/* File scope variables */
+static const char * const atrun = "atrun"; /* service name for syslog etc. */
static int debug = 0;
void perr(const char *fmt, ...);
@@ -135,7 +140,14 @@ run_file(const char *filename, uid_t uid, gid_t gid)
int fflags;
long nuid;
long ngid;
-
+#ifdef PAM
+ pam_handle_t *pamh = NULL;
+ int pam_err;
+ struct pam_conv pamc = {
+ .conv = openpam_nullconv,
+ .appdata_ptr = NULL
+ };
+#endif
PRIV_START
@@ -163,17 +175,30 @@ run_file(const char *filename, uid_t uid, gid_t gid)
perrx("Userid %lu not found - aborting job %s",
(unsigned long) uid, filename);
+#ifdef PAM
PRIV_START
- stream=fopen(filename, "r");
+ pam_err = pam_start(atrun, pentry->pw_name, &pamc, &pamh);
+ if (pam_err != PAM_SUCCESS)
+ perrx("cannot start PAM: %s", pam_strerror(pamh, pam_err));
+
+ pam_err = pam_acct_mgmt(pamh, PAM_SILENT);
+ /* Expired password shouldn't prevent the job from running. */
+ if (pam_err != PAM_SUCCESS && pam_err != PAM_NEW_AUTHTOK_REQD)
+ perrx("Account %s (userid %lu) unavailable for job %s: %s",
+ pentry->pw_name, (unsigned long)uid,
+ filename, pam_strerror(pamh, pam_err));
+
+ pam_end(pamh, pam_err);
PRIV_END
+#endif /* PAM */
-#ifdef __FreeBSD__
- if (pentry->pw_expire && time(NULL) >= pentry->pw_expire)
- perrx("Userid %lu is expired - aborting job %s",
- (unsigned long) uid, filename);
-#endif
+ PRIV_START
+
+ stream=fopen(filename, "r");
+
+ PRIV_END
if (stream == NULL)
perr("cannot open input file");
@@ -444,7 +469,7 @@ main(int argc, char *argv[])
RELINQUISH_PRIVS_ROOT(DAEMON_UID, DAEMON_GID)
- openlog("atrun", LOG_PID, LOG_CRON);
+ openlog(atrun, LOG_PID, LOG_CRON);
opterr = 0;
while((c=getopt(argc, argv, "dl:"))!= -1)
OpenPOWER on IntegriCloud