>From 29d73f4e62c0cd9ed6a7616f4a82d6fdf0421c06 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Thu, 15 Oct 2009 12:10:15 +0100 Subject: [PATCH 5/8] Add '-u user' command line option to drop root privs. If vhostmd is run as root, you can now use the '-u user' command line option to drop root privs and run as 'user' instead. --- docs/man/vhostmd.8 | 3 +++ vhostmd/vhostmd.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/man/vhostmd.8 b/docs/man/vhostmd.8 index af02bc2..0054fc7 100644 --- a/docs/man/vhostmd.8 +++ b/docs/man/vhostmd.8 @@ -19,6 +19,9 @@ Verbose messages .B \-d, --no-daemonize Process will not daemonize .TP +.B \-u, --user +Drop root privileges and run as the named non-root user. +.TP .B \-p, --pid-file Specify an alternate path for vhostmd to record its process-id in. Normally /var/run/vhostmd.pid .TP diff --git a/vhostmd/vhostmd.c b/vhostmd/vhostmd.c index 1e3378d..5c1a975 100644 --- a/vhostmd/vhostmd.c +++ b/vhostmd/vhostmd.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -947,6 +948,7 @@ static void usage(const char *argv0) -d | --no-daemonize Process will not daemonize - useful for debugging.\n\ -f | --config Configuration file.\n\ -p | --pid-file PID file.\n\ + -u | --user Drop root privs and run as .\n\ \n\ Host metrics gathering daemon:\n\ \n", @@ -962,21 +964,23 @@ int main(int argc, char *argv[]) int no_daemonize = 0; int ret = 1; int mdisk_fd = -1; + const char *user = NULL; struct option opts[] = { { "verbose", no_argument, &verbose, 1}, - { "no-daemonize", no_argument, &no_daemonize, 1}, - { "config", required_argument, NULL, 'f'}, - { "pid-file", required_argument, NULL, 'p'}, - { "help", no_argument, NULL, '?' }, - {0, 0, 0, 0} + { "no-daemonize", no_argument, &no_daemonize, 1}, + { "config", required_argument, NULL, 'f'}, + { "pid-file", required_argument, NULL, 'p'}, + { "user", required_argument, NULL, 'u'}, + { "help", no_argument, NULL, '?' }, + {0, 0, 0, 0} }; while (1) { int optidx = 0; int c; - c = getopt_long(argc, argv, "df:p:v", opts, &optidx); + c = getopt_long(argc, argv, "df:p:u:v", opts, &optidx); if (c == -1) break; @@ -997,6 +1001,9 @@ int main(int argc, char *argv[]) case 'p': pfile = optarg; break; + case 'u': + user = optarg; + break; case '?': usage(argv[0]); return 2; @@ -1070,6 +1077,38 @@ int main(int argc, char *argv[]) goto out; } + /* Drop root privileges if requested. Note: We do this after + * opening the metrics disk, parsing the config file, etc. + */ + if (user) { + struct passwd *pw; + + errno = 0; + pw = getpwnam (user); + if (!pw) { + perror (user); + goto out; + } + + if (pw->pw_uid == 0 || pw->pw_gid == 0) { + vu_log (VHOSTMD_ERR, "Cannot switch to root using the '-u' command line flag."); + goto out; + } + + if (setgid (pw->pw_gid) == -1) { + vu_log (VHOSTMD_ERR, "setgid: %d: %m", pw->pw_gid); + goto out; + } + + if (setuid (pw->pw_uid) == -1) { + vu_log (VHOSTMD_ERR, "setuid: %d: %m", pw->pw_uid); + goto out; + } + + vu_log (VHOSTMD_INFO, "Switched to uid:gid %d:%d", + pw->pw_uid, pw->pw_gid); + } + ret = vhostmd_run(mdisk_fd); out: -- 1.6.5.rc2