diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c index fbd954a671d7..a9d4631d40c8 100644 --- a/usr.sbin/sendmail/src/main.c +++ b/usr.sbin/sendmail/src/main.c @@ -165,6 +165,7 @@ main(argc, argv, envp) extern void printqueue __P((void)); extern void sendtoargv __P((char **, ENVELOPE *)); extern void resetlimits __P((void)); + extern void drop_privileges __P((void)); /* ** Check to see if we reentered. @@ -228,6 +229,9 @@ main(argc, argv, envp) tTsetup(tTdvect, sizeof tTdvect, "0-99.1"); + /* drop group id privileges (RunAsUser not yet set) */ + drop_privileges(); + /* Handle any non-getoptable constructions. */ obsolete(argv); @@ -806,10 +810,7 @@ main(argc, argv, envp) if (OpMode != MD_DAEMON && OpMode != MD_FGDAEMON) { /* drop privileges -- daemon mode done after socket/bind */ - if (RunAsGid != 0) - (void) setgid(RunAsGid); - if (RunAsUid != 0) - (void) setuid(RunAsUid); + drop_privileges(); } /* @@ -1318,10 +1319,7 @@ main(argc, argv, envp) nullserver = getrequests(CurEnv); /* drop privileges */ - if (RunAsGid != 0) - (void) setgid(RunAsGid); - if (RunAsUid != 0) - (void) setuid(RunAsUid); + drop_privileges(); /* at this point we are in a child: reset state */ (void) newenvelope(CurEnv, CurEnv); @@ -1984,6 +1982,30 @@ sighup() exit(EX_OSFILE); } /* +** DROP_PRIVILEGES -- reduce privileges to those of the RunAsUser option +** +** Parameters: +** none. +** +** Returns: +** none. +*/ +void +drop_privileges() +{ +#ifdef NGROUPS_MAX + /* reset group permissions; these can be set later */ + GIDSET_T emptygidset[NGROUPS_MAX]; + + emptygidset[0] = RunAsGid == 0 ? geteuid() : RunAsGid; + (void) setgroups(1, emptygidset); +#endif + if (RunAsGid != 0) + (void) setgid(RunAsGid); + if (RunAsUid != 0) + (void) setuid(RunAsUid); +} + /* ** TESTMODELINE -- process a test mode input line ** ** Parameters: diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c index 5d00b9f73c26..c5100364000d 100644 --- a/usr.sbin/sendmail/src/queue.c +++ b/usr.sbin/sendmail/src/queue.c @@ -553,6 +553,7 @@ runqueue(forkflag, verbose) extern ENVELOPE BlankEnvelope; extern void clrdaemon __P((void)); extern void runqueueevent __P((bool)); + extern void drop_privileges __P((void)); /* ** If no work will ever be selected, don't even bother reading @@ -657,12 +658,7 @@ runqueue(forkflag, verbose) /* drop privileges */ if (geteuid() == (uid_t) 0) - { - if (RunAsGid != (gid_t) 0) - (void) setgid(RunAsGid); - if (RunAsUid != (uid_t) 0) - (void) setuid(RunAsUid); - } + drop_privileges(); /* ** Create ourselves an envelope