summaryrefslogtreecommitdiffstats
path: root/usr.sbin/cron
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/cron')
-rw-r--r--usr.sbin/cron/cron/cron.h2
-rw-r--r--usr.sbin/cron/cron/do_command.c4
-rw-r--r--usr.sbin/cron/cron/popen.c59
3 files changed, 61 insertions, 4 deletions
diff --git a/usr.sbin/cron/cron/cron.h b/usr.sbin/cron/cron/cron.h
index c125874..1effde4 100644
--- a/usr.sbin/cron/cron/cron.h
+++ b/usr.sbin/cron/cron/cron.h
@@ -237,7 +237,7 @@ user *load_user __P((int, struct passwd *, char *)),
entry *load_entry __P((FILE *, void (*)(),
struct passwd *, char **));
-FILE *cron_popen __P((char *, char *));
+FILE *cron_popen __P((char *, char *, entry *));
/* in the C tradition, we only create
diff --git a/usr.sbin/cron/cron/do_command.c b/usr.sbin/cron/cron/do_command.c
index 009d21b..1e65b41 100644
--- a/usr.sbin/cron/cron/do_command.c
+++ b/usr.sbin/cron/cron/do_command.c
@@ -418,11 +418,11 @@ child_process(e, u)
(void) gethostname(hostname, MAXHOSTNAMELEN);
(void) snprintf(mailcmd, sizeof(mailcmd),
MAILARGS, MAILCMD);
- if (!(mail = cron_popen(mailcmd, "w"))) {
+ if (!(mail = cron_popen(mailcmd, "w", e))) {
warn("%s", MAILCMD);
(void) _exit(ERROR_EXIT);
}
- fprintf(mail, "From: root (Cron Daemon)\n");
+ fprintf(mail, "From: %s (Cron Daemon)\n", usernm);
fprintf(mail, "To: %s\n", mailto);
fprintf(mail, "Subject: Cron <%s@%s> %s\n",
usernm, first_word(hostname, "."),
diff --git a/usr.sbin/cron/cron/popen.c b/usr.sbin/cron/cron/popen.c
index e0861f5..56f85e7 100644
--- a/usr.sbin/cron/cron/popen.c
+++ b/usr.sbin/cron/cron/popen.c
@@ -34,6 +34,12 @@ static const char rcsid[] =
#include "cron.h"
#include <sys/signal.h>
#include <fcntl.h>
+#if defined(SYSLOG)
+# include <syslog.h>
+#endif
+#if defined(LOGIN_CAP)
+# include <login_cap.h>
+#endif
#define MAX_ARGS 100
@@ -48,14 +54,20 @@ static PID_T *pids;
static int fds;
FILE *
-cron_popen(program, type)
+cron_popen(program, type, e)
char *program, *type;
+ entry *e;
{
register char *cp;
FILE *iop;
int argc, pdes[2];
PID_T pid;
+ char *usernm;
char *argv[MAX_ARGS + 1];
+# if defined(LOGIN_CAP)
+ struct passwd *pwd;
+ login_cap_t *lc;
+# endif
#if WANT_GLOBBING
char **pop, *vv[2];
int gargc;
@@ -106,6 +118,15 @@ cron_popen(program, type)
goto pfree;
/* NOTREACHED */
case 0: /* child */
+ if (e != NULL) {
+#ifdef SYSLOG
+ closelog();
+#endif
+
+ /* get new pgrp, void tty, etc.
+ */
+ (void) setsid();
+ }
if (*type == 'r') {
/* Do not share our parent's stdin */
(void)close(0);
@@ -128,6 +149,42 @@ cron_popen(program, type)
(void)open("/dev/null", O_RDWR);
(void)close(pdes[1]);
}
+# if defined(LOGIN_CAP)
+ if (e != NULL) {
+ /* Set user's entire context, but skip the environment
+ * as cron provides a separate interface for this
+ */
+ usernm = env_get("LOGNAME", e->envp);
+ if ((pwd = getpwnam(usernm)) == NULL)
+ pwd = getpwuid(e->uid);
+ lc = NULL;
+ if (pwd != NULL) {
+ pwd->pw_gid = e->gid;
+ if (e->class != NULL)
+ lc = login_getclass(e->class);
+ }
+ if (pwd &&
+ setusercontext(lc, pwd, e->uid,
+ LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETENV)) == 0)
+ (void) endpwent();
+ else {
+ /* fall back to the old method */
+ (void) endpwent();
+# endif
+ /* set our directory, uid and gid. Set gid first,
+ * since once we set uid, we've lost root privledges.
+ */
+ setgid(e->gid);
+# if defined(BSD)
+ initgroups(usernm, e->gid);
+# endif
+ setlogin(usernm);
+ setuid(e->uid); /* we aren't root after this..*/
+#if defined(LOGIN_CAP)
+ }
+#endif
+ chdir(env_get("HOME", e->envp));
+ }
#if WANT_GLOBBING
execvp(gargv[0], gargv);
#else
OpenPOWER on IntegriCloud