From: fatbob313 Date: Sun, 23 Jan 2011 11:58:12 +0000 (+0000) Subject: Issue 15 - Patch by tilman2: Drop privileges optionally X-Git-Url: http://git.code-monkey.de/?p=umurmur.git;a=commitdiff_plain;h=454ad122eb158b4391e2690fe6a7e127d24c525b Issue 15 - Patch by tilman2: Drop privileges optionally --- diff --git a/src/conf.c b/src/conf.c index 72fd8f1..3592647 100644 --- a/src/conf.c +++ b/src/conf.c @@ -136,6 +136,28 @@ const char *getStrConf(param_t param) return ""; } break; + case USERNAME: + setting = config_lookup(&configuration, "username"); + if (!setting) + return ""; + else { + if ((strsetting = config_setting_get_string(setting)) != NULL) + return strsetting; + else + return ""; + } + break; + case GROUPNAME: + setting = config_lookup(&configuration, "groupname"); + if (!setting) + return ""; + else { + if ((strsetting = config_setting_get_string(setting)) != NULL) + return strsetting; + else + return ""; + } + break; default: doAssert(false); break; diff --git a/src/conf.h b/src/conf.h index 1b9b21e..6e0a666 100644 --- a/src/conf.h +++ b/src/conf.h @@ -43,6 +43,8 @@ typedef enum param { MAX_BANDWIDTH, MAX_CLIENTS, DEFAULT_CHANNEL, + USERNAME, + GROUPNAME, } param_t; typedef struct { diff --git a/src/main.c b/src/main.c index 7bd8a0b..36c5f88 100644 --- a/src/main.c +++ b/src/main.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include @@ -70,6 +72,59 @@ void lockfile(const char *pidfile) Log_info("PID-file: %s", pidfile); } +/* Drops privileges (if configured to do so). */ +static void switch_user(void) +{ + struct passwd *pwd; + struct group *grp = NULL; + const char *username, *groupname; + gid_t gid; + + username = getStrConf(USERNAME); + groupname = getStrConf(GROUPNAME); + + if (!*username) { + /* It's an error to specify groupname + * but leave username empty. + */ + if (*groupname) + Log_fatal("username missing"); + + /* Nothing to do. */ + return; + } + + pwd = getpwnam(username); + if (!pwd) + Log_fatal("Unknown user '%s'", username); + + if (!*groupname) + gid = pwd->pw_gid; + else { + grp = getgrnam(groupname); + + if (!grp) + Log_fatal("Unknown group '%s'", groupname); + + gid = grp->gr_gid; + } + + if (initgroups(pwd->pw_name, gid)) + Log_fatal("initgroups() failed: %s", strerror(errno)); + + if (setgid(gid)) + Log_fatal("setgid() failed: %s", strerror(errno)); + + if (setuid(pwd->pw_uid)) + Log_fatal("setuid() failed: %s", strerror(errno)); + + if (!grp) + grp = getgrgid(gid); + if (!grp) + Log_fatal("getgrgid() failed: %s", strerror(errno)); + + Log_info("Switch to user '%s' group '%s'", pwd->pw_name, grp->gr_name); +} void signal_handler(int sig) { @@ -189,18 +244,28 @@ int main(int argc, char **argv) break; } } + + /* Logging to terminal if not daemonizing, otherwise to syslog. + * Need to initialize logging before calling Conf_init() + */ + if (!nodaemon) + Log_init(false); + else + Log_init(true); + /* Initialize the config subsystem early; + * switch_user() will need to read some config variables. + */ + Conf_init(conffile); + if (!nodaemon) { - Log_init(false); daemonize(); if (pidfile != NULL) lockfile(pidfile); + + switch_user(); } - else - Log_init(true); - Conf_init(conffile); - signal(SIGCHLD, SIG_IGN); /* ignore child */ signal(SIGTSTP, SIG_IGN); /* ignore tty signals */ signal(SIGTTOU, SIG_IGN); diff --git a/umurmur.conf.example b/umurmur.conf.example index 47c0dea..09b49c5 100644 --- a/umurmur.conf.example +++ b/umurmur.conf.example @@ -4,6 +4,8 @@ certificate = "/etc/umurmur/cert.crt"; private_key = "/etc/umurmur/key.key"; password = ""; max_users = 10; +username = ""; +groupname = ""; # Root channel must always be defined first. # If a channel has a parent, the parent must be defined before the child channel(s).