]> git.ipfire.org Git - people/ms/dma.git/commitdiff
drop privileges when run by root
authorSimon Schubert <2@0x2c.org>
Sun, 31 Oct 2010 16:40:31 +0000 (17:40 +0100)
committerSimon Schubert <2@0x2c.org>
Sun, 31 Oct 2010 17:33:17 +0000 (18:33 +0100)
dma.c
dma.h
mail.c
util.c

diff --git a/dma.c b/dma.c
index 407ec9a7ab8350051b939907da42ccd0015f9163..5a287fa9da860c63dc503d1c9870ea889e85b81c 100644 (file)
--- 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 e2ff3ded87e904f91b50bdf6494578f3e2280c43..da3741c47faeda83e30c9a763635a436ac04dc8b 100644 (file)
--- 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 b8ca54de64080d0558c4d255729e3da14e03b252..3c0ab1b7586b88f3e575c30a2954af81a420b5c3 100644 (file)
--- 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 86312eb1fef25212115e23b1ceb39bae90c0fe47..2f95b72a65909278f7cd62932b951982d3833161 100644 (file)
--- 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