1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
From: Christian Kastner <ckk@kvr.at>
Date: Tue, 22 Dec 2015 18:42:49 +0100
Subject: Drop privileges when sending mail
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
Drop privileges when sending mail. It is unnecessary to send them as root.
Extension of a fix originally provided by Steve Greenland <stevegr@debian.org>
and extended by Javier Fernández-Sanguino Peña <jfs@debian.org>.
Forwarded: no
Last-Update: 2015-12-22
---
cron.h | 2 +-
do_command.c | 2 +-
popen.c | 34 +++++++++++++++++++++++++++++++++-
3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/cron.h b/cron.h
index d1861be..2fcc94d 100644
--- a/cron.h
+++ b/cron.h
@@ -226,7 +226,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/do_command.c b/do_command.c
index 294b177..6f6590b 100644
--- a/do_command.c
+++ b/do_command.c
@@ -385,7 +385,7 @@ child_process(e, u)
(void) gethostname(hostname, MAXHOSTNAMELEN);
(void) snprintf(mailcmd, sizeof(mailcmd),
MAILARGS, MAILCMD, mailto);
- if (!(mail = cron_popen(mailcmd, "w"))) {
+ if (!(mail = cron_popen(mailcmd, "w", e))) {
perror(MAILCMD);
(void) _exit(ERROR_EXIT);
}
diff --git a/popen.c b/popen.c
index d0c2621..b5c3242 100644
--- a/popen.c
+++ b/popen.c
@@ -31,6 +31,10 @@ static char sccsid[] = "@(#)popen.c 5.7 (Berkeley) 2/14/89";
#include "cron.h"
#include <signal.h>
+#if defined(BSD) || defined(POSIX)
+# include <grp.h>
+#endif
+
#define MAX_ARGS 100
#define WANT_GLOBBING 0
@@ -44,8 +48,9 @@ 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;
@@ -116,6 +121,33 @@ cron_popen(program, type)
}
(void)close(pdes[1]);
}
+ /* set our directory, uid and gid. Set gid first, since once
+ * we set uid, we've lost root privleges.
+ */
+ if (setgid(e->gid) !=0) {
+ char msg[256];
+ snprintf(msg, 256, "popen:setgid(%lu) failed: %s",
+ (unsigned long) e->gid, strerror(errno));
+ log_it("CRON",getpid(),"error",msg);
+ exit(ERROR_EXIT);
+ }
+# if defined(BSD) || defined(POSIX)
+ if (initgroups(env_get("LOGNAME", e->envp), e->gid) !=0) {
+ char msg[256];
+ snprintf(msg, 256, "popen:initgroups(%lu) failed: %s",
+ (unsigned long) e->gid, strerror(errno));
+ log_it("CRON",getpid(),"error",msg);
+ exit(ERROR_EXIT);
+ }
+# endif
+ if (setuid(e->uid) !=0) {
+ char msg[256];
+ snprintf(msg, 256, "popen: setuid(%lu) failed: %s",
+ (unsigned long) e->uid, strerror(errno));
+ log_it("CRON",getpid(),"error",msg);
+ exit(ERROR_EXIT);
+ }
+ chdir(env_get("HOME", e->envp));
#if WANT_GLOBBING
execvp(gargv[0], gargv);
#else
|