Mercurial > masqmail-0.2
comparison 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 |
comparison
equal
deleted
inserted
replaced
183:ee2e92148aca | 184:b3835b6b834b |
---|---|
60 if (sigterm_in_progress) | 60 if (sigterm_in_progress) |
61 raise(sig); | 61 raise(sig); |
62 sigterm_in_progress = 1; | 62 sigterm_in_progress = 1; |
63 | 63 |
64 if (pidfile) { | 64 if (pidfile) { |
65 uid_t uid; | 65 uid_t uid = geteuid(); |
66 uid = seteuid(0); | 66 if (seteuid(0) != 0) { |
67 logwrite(LOG_ALERT, "sigterm_handler: could not set euid to %d: %s\n", 0, strerror(errno)); | |
68 } | |
67 if (unlink(pidfile) != 0) | 69 if (unlink(pidfile) != 0) |
68 logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", pidfile, strerror(errno)); | 70 logwrite(LOG_WARNING, "could not delete pid file %s: %s\n", pidfile, strerror(errno)); |
69 seteuid(uid); /* we exit anyway after this, just to be sure */ | 71 seteuid(uid); /* we exit anyway after this, just to be sure */ |
70 } | 72 } |
71 | 73 |
234 int dummy = sizeof(saddr); | 236 int dummy = sizeof(saddr); |
235 | 237 |
236 conf.do_verbose = FALSE; | 238 conf.do_verbose = FALSE; |
237 | 239 |
238 if (!conf.run_as_user) { | 240 if (!conf.run_as_user) { |
239 seteuid(conf.orig_uid); | 241 set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL); |
240 setegid(conf.orig_gid); | |
241 } | 242 } |
242 | 243 |
243 DEBUG(5) debugf("accepting smtp message on stdin\n"); | 244 DEBUG(5) debugf("accepting smtp message on stdin\n"); |
244 | 245 |
245 if (getpeername(0, (struct sockaddr *) (&saddr), &dummy) == 0) { | 246 if (getpeername(0, (struct sockaddr *) (&saddr), &dummy) == 0) { |
263 fprintf(stderr, "must be root, %s or in group %s for setting return path.\n", DEF_MAIL_USER, DEF_MAIL_GROUP); | 264 fprintf(stderr, "must be root, %s or in group %s for setting return path.\n", DEF_MAIL_USER, DEF_MAIL_GROUP); |
264 exit(EXIT_FAILURE); | 265 exit(EXIT_FAILURE); |
265 } | 266 } |
266 | 267 |
267 if (!conf.run_as_user) { | 268 if (!conf.run_as_user) { |
268 seteuid(conf.orig_uid); | 269 set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL); |
269 setegid(conf.orig_gid); | |
270 } | 270 } |
271 | 271 |
272 DEBUG(5) debugf("accepting message on stdin\n"); | 272 DEBUG(5) debugf("accepting message on stdin\n"); |
273 | 273 |
274 msg->received_prot = PROT_LOCAL; | 274 msg->received_prot = PROT_LOCAL; |
630 privileges. | 630 privileges. |
631 | 631 |
632 So it is possible for a user to run his own daemon without | 632 So it is possible for a user to run his own daemon without |
633 breaking security. | 633 breaking security. |
634 */ | 634 */ |
635 if (strcmp(conf_file, CONF_FILE) != 0) { | 635 if ((strcmp(conf_file, CONF_FILE) != 0) && (conf.orig_uid != 0)) { |
636 if (conf.orig_uid != 0) { | 636 conf.run_as_user = TRUE; |
637 conf.run_as_user = TRUE; | 637 set_euidgid(conf.orig_uid, conf.orig_gid, NULL, NULL); |
638 seteuid(conf.orig_uid); | 638 if (setgid(conf.orig_gid)) { |
639 setegid(conf.orig_gid); | 639 logwrite(LOG_ALERT, "could not set gid to %d: %s\n", conf.orig_gid, strerror(errno)); |
640 setuid(conf.orig_uid); | 640 exit(1); |
641 setgid(conf.orig_gid); | 641 } |
642 if (setuid(conf.orig_uid)) { | |
643 logwrite(LOG_ALERT, "could not set uid to %d: %s\n", conf.orig_uid, strerror(errno)); | |
644 exit(1); | |
642 } | 645 } |
643 } | 646 } |
644 | 647 |
645 read_conf(conf_file); | 648 read_conf(conf_file); |
646 | 649 |