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:
parent
c38d808de1
commit
fe46d6a8f3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=62367
@ -237,7 +237,7 @@ user *load_user __P((int, struct passwd *, char *)),
|
|||||||
entry *load_entry __P((FILE *, void (*)(),
|
entry *load_entry __P((FILE *, void (*)(),
|
||||||
struct passwd *, char **));
|
struct passwd *, char **));
|
||||||
|
|
||||||
FILE *cron_popen __P((char *, char *));
|
FILE *cron_popen __P((char *, char *, entry *));
|
||||||
|
|
||||||
|
|
||||||
/* in the C tradition, we only create
|
/* in the C tradition, we only create
|
||||||
|
@ -418,11 +418,11 @@ child_process(e, u)
|
|||||||
(void) gethostname(hostname, MAXHOSTNAMELEN);
|
(void) gethostname(hostname, MAXHOSTNAMELEN);
|
||||||
(void) snprintf(mailcmd, sizeof(mailcmd),
|
(void) snprintf(mailcmd, sizeof(mailcmd),
|
||||||
MAILARGS, MAILCMD);
|
MAILARGS, MAILCMD);
|
||||||
if (!(mail = cron_popen(mailcmd, "w"))) {
|
if (!(mail = cron_popen(mailcmd, "w", e))) {
|
||||||
warn("%s", MAILCMD);
|
warn("%s", MAILCMD);
|
||||||
(void) _exit(ERROR_EXIT);
|
(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, "To: %s\n", mailto);
|
||||||
fprintf(mail, "Subject: Cron <%s@%s> %s\n",
|
fprintf(mail, "Subject: Cron <%s@%s> %s\n",
|
||||||
usernm, first_word(hostname, "."),
|
usernm, first_word(hostname, "."),
|
||||||
|
@ -34,6 +34,12 @@ static const char rcsid[] =
|
|||||||
#include "cron.h"
|
#include "cron.h"
|
||||||
#include <sys/signal.h>
|
#include <sys/signal.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#if defined(SYSLOG)
|
||||||
|
# include <syslog.h>
|
||||||
|
#endif
|
||||||
|
#if defined(LOGIN_CAP)
|
||||||
|
# include <login_cap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define MAX_ARGS 100
|
#define MAX_ARGS 100
|
||||||
@ -48,14 +54,20 @@ static PID_T *pids;
|
|||||||
static int fds;
|
static int fds;
|
||||||
|
|
||||||
FILE *
|
FILE *
|
||||||
cron_popen(program, type)
|
cron_popen(program, type, e)
|
||||||
char *program, *type;
|
char *program, *type;
|
||||||
|
entry *e;
|
||||||
{
|
{
|
||||||
register char *cp;
|
register char *cp;
|
||||||
FILE *iop;
|
FILE *iop;
|
||||||
int argc, pdes[2];
|
int argc, pdes[2];
|
||||||
PID_T pid;
|
PID_T pid;
|
||||||
|
char *usernm;
|
||||||
char *argv[MAX_ARGS + 1];
|
char *argv[MAX_ARGS + 1];
|
||||||
|
# if defined(LOGIN_CAP)
|
||||||
|
struct passwd *pwd;
|
||||||
|
login_cap_t *lc;
|
||||||
|
# endif
|
||||||
#if WANT_GLOBBING
|
#if WANT_GLOBBING
|
||||||
char **pop, *vv[2];
|
char **pop, *vv[2];
|
||||||
int gargc;
|
int gargc;
|
||||||
@ -106,6 +118,15 @@ cron_popen(program, type)
|
|||||||
goto pfree;
|
goto pfree;
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
case 0: /* child */
|
case 0: /* child */
|
||||||
|
if (e != NULL) {
|
||||||
|
#ifdef SYSLOG
|
||||||
|
closelog();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get new pgrp, void tty, etc.
|
||||||
|
*/
|
||||||
|
(void) setsid();
|
||||||
|
}
|
||||||
if (*type == 'r') {
|
if (*type == 'r') {
|
||||||
/* Do not share our parent's stdin */
|
/* Do not share our parent's stdin */
|
||||||
(void)close(0);
|
(void)close(0);
|
||||||
@ -128,6 +149,42 @@ cron_popen(program, type)
|
|||||||
(void)open("/dev/null", O_RDWR);
|
(void)open("/dev/null", O_RDWR);
|
||||||
(void)close(pdes[1]);
|
(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
|
#if WANT_GLOBBING
|
||||||
execvp(gargv[0], gargv);
|
execvp(gargv[0], gargv);
|
||||||
#else
|
#else
|
||||||
|
Loading…
Reference in New Issue
Block a user