From 3d7adfbe0788f33a67c3ed65e12ba9d32074a674 Mon Sep 17 00:00:00 2001 From: Ade Lee Date: Mon, 15 Jan 2018 15:25:36 -0500 Subject: [PATCH] Add parameter to set the uid of the invoked process --- src/com/redhat/nuxwdog/watchdog.cpp | 36 ++++++++++++++++++++++++++++++++++-- src/com/redhat/nuxwdog/wdconf.cpp | 7 +++++++ src/com/redhat/nuxwdog/wdconf.h | 3 ++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/com/redhat/nuxwdog/watchdog.cpp b/src/com/redhat/nuxwdog/watchdog.cpp index a4d6a77..36b13e4 100644 --- a/src/com/redhat/nuxwdog/watchdog.cpp +++ b/src/com/redhat/nuxwdog/watchdog.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -280,7 +281,7 @@ watchdog_exit(int status) int _watchdog_exec(int server_starts, char *server_exe, char *args[], - char * envp[], int *spid) + char * envp[], int *spid, int uid) { int server_background = 0; char *server_out = NULL; @@ -412,6 +413,14 @@ _watchdog_exec(int server_starts, char *server_exe, char *args[], free(server_context); } + if (uid >= 0) { + rv = setuid(uid); + if (rv != 0) { + watchdog_error("unable to setuid"); + watchdog_exit(1); + } + } + rv = execv(server_exe, args); if (rv < 0) { watchdog_error("could not execute server binary"); @@ -757,10 +766,12 @@ int main(int argc, char **argv, char **envp) int ver=0; int server_starts; int server_stat; + int uid=-1; char *server_exe = NULL; char *server_args = NULL; char *conffile = NULL; char *pch; + char *user = NULL; char *args[100]; struct stat statbuf; UDS_NAME[0]=0; @@ -833,6 +844,11 @@ int main(int argc, char **argv, char **envp) watchdog_exit(1); } + /* user */ + if (confinfo->user) { + user = strdup(confinfo->user); + } + if (detach) { parent_watchdog_create_signal_handlers(); @@ -883,6 +899,22 @@ int main(int argc, char **argv, char **envp) watchdog_exit(1); } + if (user != NULL) { + struct passwd *pw = getpwnam(user); + if (pw == NULL) { + sprintf(errmsgstr, "user %s does not exist", user); + watchdog_error(errmsgstr); + watchdog_exit(1); + } + + if (chown(UDS_NAME, pw->pw_uid, pw->pw_gid) != 0) { + sprintf(errmsgstr, "chown failed errno %d %s", errno, strerror(errno)); + watchdog_error(errmsgstr); + watchdog_exit(1); + } + uid = pw->pw_uid; + } + for (server_starts = 0;; ++server_starts) { _watchdog_death = 0; @@ -895,7 +927,7 @@ int main(int argc, char **argv, char **envp) watchdog_create_signal_handlers(); - rv = _watchdog_exec(server_starts, server_exe, args, envp, &server_pid); + rv = _watchdog_exec(server_starts, server_exe, args, envp, &server_pid, uid); if (server_pid < 0) { // exec failed: kill parent if it's still waiting diff --git a/src/com/redhat/nuxwdog/wdconf.cpp b/src/com/redhat/nuxwdog/wdconf.cpp index 95603c9..2d50575 100644 --- a/src/com/redhat/nuxwdog/wdconf.cpp +++ b/src/com/redhat/nuxwdog/wdconf.cpp @@ -158,6 +158,9 @@ _watchdog_parse_conffile(char *conffile, if (!strcasecmp(name, "ChildSecurity")) { info->childSecurity = atoi(value); } + if (!strcasecmp(name, "User")) { + info->user = strdup(value); + } if (line != NULL) { free(line); line = NULL; @@ -227,5 +230,9 @@ watchdog_confinfo_free(watchdog_conf_info_t *info) free(info->childPidFile); } + if (info->user) { + free(info->user); + } + free(info); } diff --git a/src/com/redhat/nuxwdog/wdconf.h b/src/com/redhat/nuxwdog/wdconf.h index bb2e7b1..94f02e3 100644 --- a/src/com/redhat/nuxwdog/wdconf.h +++ b/src/com/redhat/nuxwdog/wdconf.h @@ -36,7 +36,8 @@ typedef struct watchdog_conf_info_t { char *exeContext; /* selinux type context */ char *pidFile; /* pidFile */ char *childPidFile; /* child pid file */ - int childSecurity; /* enforce child security */ + int childSecurity; /* enforce child security */ + char *user; /* user to execute the process as */ } watchdog_conf_info_t; watchdog_conf_info_t *watchdog_parse(char *conf_file); -- 2.14.3