summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2000-07-01 22:58:16 +0000
committerache <ache@FreeBSD.org>2000-07-01 22:58:16 +0000
commit487d171b653a111b9771d51c4bb59e54d8feb3b2 (patch)
tree3c4ecc4cac3666c397631329290fda096b8c28b2
parent3f913e3f23ce69d4d8c9b41c85f66bd45949f9cf (diff)
downloadFreeBSD-src-487d171b653a111b9771d51c4bb59e54d8feb3b2.zip
FreeBSD-src-487d171b653a111b9771d51c4bb59e54d8feb3b2.tar.gz
Prevent user from breaking his limits and restrictions or
abusing sendmail by any other way via MAILTO tag (since sendmail is running from daemon). Now run sendmail from user, as any other cron user command. Obtained from: Inspired by OpenBSD, but implementation is different
-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