Blame SOURCES/nuxwdog-set-uid.patch

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