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
This commit is contained in:
ache 2000-07-01 22:58:16 +00:00
parent 7dc35168ab
commit f57e074211
3 changed files with 61 additions and 4 deletions

View File

@ -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

View File

@ -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, "."),

View File

@ -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