diff src/masqmail.c @ 184:b3835b6b834b

Security fix! Correct handling of seteuid() return value See Debian bug #638002, reported by John Lightsey. When possible the (already available) set_euidgid() function is used. Additionally, it is unnecessary to change the identity when writing into an already open file descriptor. This should fix the problem.
author markus schnalke <meillo@marmaro.de>
date Sat, 27 Aug 2011 18:00:40 +0200
parents 2ac8a66ee108
children
line wrap: on
line diff
--- a/src/masqmail.c	Fri Jun 03 13:32:14 2011 +0200
+++ b/src/masqmail.c	Sat Aug 27 18:00:40 2011 +0200
@@ -62,8 +62,10 @@
 	sigterm_in_progress = 1;
 
 	if (pidfile) {
-		uid_t uid;
-		uid = seteuid(0);
+		uid_t uid = geteuid();
+		if (seteuid(0) != 0) {
+			logwrite(LOG_ALERT, "sigterm_handler: could not set euid to %d: %s\n", 0, strerror(errno));
+		}
 		if (unlink(pidfile) != 0)
 			logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", pidfile, strerror(errno));
 		seteuid(uid);  /* we exit anyway after this, just to be sure */
@@ -236,8 +238,7 @@
 	conf.do_verbose = FALSE;
 
 	if (!conf.run_as_user) {
-		seteuid(conf.orig_uid);
-		setegid(conf.orig_gid);
+		set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL);
 	}
 
 	DEBUG(5) debugf("accepting smtp message on stdin\n");
@@ -265,8 +266,7 @@
 	}
 
 	if (!conf.run_as_user) {
-		seteuid(conf.orig_uid);
-		setegid(conf.orig_gid);
+		set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL);
 	}
 
 	DEBUG(5) debugf("accepting message on stdin\n");
@@ -632,13 +632,16 @@
 	   So it is possible for a user to run his own daemon without
 	   breaking security.
 	 */
-	if (strcmp(conf_file, CONF_FILE) != 0) {
-		if (conf.orig_uid != 0) {
-			conf.run_as_user = TRUE;
-			seteuid(conf.orig_uid);
-			setegid(conf.orig_gid);
-			setuid(conf.orig_uid);
-			setgid(conf.orig_gid);
+	if ((strcmp(conf_file, CONF_FILE) != 0) && (conf.orig_uid != 0)) {
+		conf.run_as_user = TRUE;
+		set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL);
+		if (setgid(conf.orig_gid)) {
+			logwrite(LOG_ALERT, "could not set gid to %d: %s\n", conf.orig_gid, strerror(errno));
+			exit(1);
+		}
+		if (setuid(conf.orig_uid)) {
+			logwrite(LOG_ALERT, "could not set uid to %d: %s\n", conf.orig_uid, strerror(errno));
+			exit(1);
 		}
 	}