diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index 117147d..40f9184 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -42,6 +42,7 @@ enum { ARG_DUMP_CONF, ARG_DUMP_MODULES, ARG_DAEMONIZE, + ARG_DROP_PRIVILEGES, ARG_FAIL, ARG_LOG_LEVEL, ARG_HIGH_PRIORITY, @@ -76,6 +77,7 @@ static const struct option long_options[] = { {"dump-conf", 0, 0, ARG_DUMP_CONF}, {"dump-modules", 0, 0, ARG_DUMP_MODULES}, {"daemonize", 2, 0, ARG_DAEMONIZE}, + {"drop-privileges", 2, 0, ARG_DROP_PRIVILEGES}, {"fail", 2, 0, ARG_FAIL}, {"verbose", 2, 0, ARG_LOG_LEVEL}, {"log-level", 2, 0, ARG_LOG_LEVEL}, @@ -122,6 +124,7 @@ void pa_cmdline_help(const char *argv0) { "OPTIONS:\n" " --system[=BOOL] Run as system-wide instance\n" + " --drop-privileges[=BOOL] When running as system-wide, drop privileges after startup (DANGEROUS)\n" " -D, --daemonize[=BOOL] Daemonize after startup\n" " --fail[=BOOL] Quit when startup fails\n" " --high-priority[=BOOL] Try to set high nice level\n" @@ -246,6 +249,14 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d conf->daemonize = !!b; break; + case ARG_DROP_PRIVILEGES: + if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { + pa_log(_("--drop-privileges expects boolean argument")); + goto fail; + } + conf->drop_privileges = !!b; + break; + case ARG_FAIL: if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { pa_log(_("--fail expects boolean argument")); diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index f94cdeb..5247808 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -93,6 +93,7 @@ static const pa_daemon_conf default_conf = { .no_cpu_limit = true, .disable_shm = false, .lock_memory = false, + .drop_privileges = true, .deferred_volume = true, .default_n_fragments = 4, .default_fragment_size_msec = 25, diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index 458784c..2e53992 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -74,6 +74,7 @@ typedef struct pa_daemon_conf { log_time, flat_volumes, lock_memory, + drop_privileges, deferred_volume; pa_server_type_t local_server_type; int exit_idle_time, diff --git a/src/daemon/main.c b/src/daemon/main.c index c7b15e7..cec8890 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -147,7 +147,7 @@ static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H) -static int change_user(void) { +static int change_user(bool drop_privileges) { struct passwd *pw; struct group * gr; int r; @@ -195,6 +195,9 @@ static int change_user(void) { return -1; } + + if (drop_privileges) { + #if defined(HAVE_SETRESGID) r = setresgid(gr->gr_gid, gr->gr_gid, gr->gr_gid); #elif defined(HAVE_SETEGID) @@ -229,6 +232,8 @@ static int change_user(void) { pa_drop_caps(); + } + pa_set_env("USER", PA_SYSTEM_USER); pa_set_env("USERNAME", PA_SYSTEM_USER); pa_set_env("LOGNAME", PA_SYSTEM_USER); @@ -244,6 +249,7 @@ static int change_user(void) { if (!getenv("PULSE_STATE_PATH")) pa_set_env("PULSE_STATE_PATH", PA_SYSTEM_STATE_PATH); + if (drop_privileges) pa_log_info("Successfully changed user to \"" PA_SYSTEM_USER "\"."); return 0; @@ -251,7 +257,7 @@ static int change_user(void) { #else /* HAVE_PWD_H && HAVE_GRP_H */ -static int change_user(void) { +static int change_user(bool drop_privileges) { pa_log(_("System wide mode unsupported on this platform.")); return -1; } @@ -899,7 +905,7 @@ int main(int argc, char *argv[]) { pa_raise_priority(conf->nice_level); if (conf->system_instance) - if (change_user() < 0) + if (change_user(conf->drop_privileges) < 0) goto finish; pa_set_env_and_record("PULSE_SYSTEM", conf->system_instance ? "1" : "0");