From 75fdf182e115db012084779baa70770cb7c2c2a7 Mon Sep 17 00:00:00 2001 From: Simon Schubert <2@0x2c.org> Date: Sun, 31 Oct 2010 17:40:31 +0100 Subject: [PATCH] drop privileges when run by root --- dma.c | 24 +++++++++++++++++++++--- dma.h | 1 + mail.c | 2 +- util.c | 15 +++++++-------- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/dma.c b/dma.c index 407ec9a..5a287fa 100644 --- a/dma.c +++ b/dma.c @@ -65,6 +65,7 @@ struct aliases aliases = LIST_HEAD_INITIALIZER(aliases); struct strlist tmpfs = SLIST_HEAD_INITIALIZER(tmpfs); struct authusers authusers = LIST_HEAD_INITIALIZER(authusers); char username[USERNAME_SIZE]; +uid_t useruid; const char *logident_base; char errmsg[ERRMSG_SIZE]; @@ -372,6 +373,26 @@ main(int argc, char **argv) int nodot = 0, doqueue = 0, showq = 0, queue_only = 0; int recp_from_header = 0; + set_username(); + + /* + * We never run as root. If called by root, drop permissions + * to the mail user. + */ + if (geteuid() == 0 || getuid() == 0) { + struct passwd *pw; + + pw = getpwnam(DMA_ROOT_USER); + if (pw == NULL) + err(1, "cannot drop root privileges"); + + if (setuid(pw->pw_uid) != 0) + err(1, "cannot drop root privileges"); + + if (geteuid() == 0 || getuid() == 0) + errx(1, "cannot drop root privileges"); + } + atexit(deltmp); init_random(); @@ -476,9 +497,6 @@ skipopts: if (logident_base == NULL) logident_base = "dma"; setlogident(NULL); - set_username(); - - /* XXX fork root here */ act.sa_handler = sighup_handler; act.sa_flags = 0; diff --git a/dma.h b/dma.h index e2ff3de..da3741c 100644 --- a/dma.h +++ b/dma.h @@ -143,6 +143,7 @@ extern struct config config; extern struct strlist tmpfs; extern struct authusers authusers; extern char username[USERNAME_SIZE]; +extern uid_t useruid; extern const char *logident_base; extern char neterr[ERRMSG_SIZE]; diff --git a/mail.c b/mail.c index b8ca54d..3c0ab1b 100644 --- a/mail.c +++ b/mail.c @@ -351,7 +351,7 @@ readmail(struct queue *queue, int nodot, int recp_from_header) "\tid %s\n" "\tby %s (%s)\n" "\t%s\n", - username, getuid(), + username, useruid, queue->sender, queue->id, hostname(), VERSION, diff --git a/util.c b/util.c index 86312eb..2f95b72 100644 --- a/util.c +++ b/util.c @@ -198,21 +198,20 @@ void set_username(void) { struct passwd *pwd; - uid_t uid; - uid = getuid(); - if (check_username(getlogin(), uid)) + useruid = getuid(); + if (check_username(getlogin(), useruid)) return; - if (check_username(getenv("LOGNAME"), uid)) + if (check_username(getenv("LOGNAME"), useruid)) return; - if (check_username(getenv("USER"), uid)) + if (check_username(getenv("USER"), useruid)) return; - pwd = getpwuid(uid); + pwd = getpwuid(useruid); if (pwd != NULL && pwd->pw_name != NULL && pwd->pw_name[0] != '\0') { - if (check_username(pwd->pw_name, uid)) + if (check_username(pwd->pw_name, useruid)) return; } - snprintf(username, sizeof(username), "uid=%ld", (long)uid); + snprintf(username, sizeof(username), "uid=%ld", (long)useruid); } void -- 2.47.3