pcp
[Top] [All Lists]

RFC: allow running pmproxy as non-root user

To: pcp@xxxxxxxxxxx
Subject: RFC: allow running pmproxy as non-root user
From: Nathan Scott <nscott@xxxxxxxxxx>
Date: Thu, 18 Sep 2008 14:03:22 +1000
Sender: pcp-bounce@xxxxxxxxxxx
Hi all,

Looking for feedback on this patch - its fairly self explanatory,
works for me, and would seem to be a no-brainer, but thought I'd
solicit for other thoughts/objections before committing it.

thanks!

--
Nathan

 configure.in                   |    4 ++--
 man/man1/pmproxy.1             |    6 ++++++
 src/include/platform_defs.h.in |    2 ++
 src/pmproxy/pmproxy.c          |   30 +++++++++++++++++++++++++++++-
 src/pmproxy/pmproxy.options    |    3 +++
 5 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/configure.in b/configure.in
index e0c360f..6da4f38 100644
--- a/configure.in
+++ b/configure.in
@@ -625,7 +625,7 @@ AC_CHECK_HEADERS(unistd.h stddef.h sched.h dlfcn.h
dl.h ieeefp.h)
 AC_CHECK_HEADERS(sys/time.h sys/times.h sys/resource.h sys/prctl.h)
 AC_CHECK_HEADERS(endian.h standards.h sys/byteorder.h pthread.h
getopt.h)
 AC_CHECK_HEADERS(values.h libgen.h sys/param.h sys/mman.h sys/un.h
stdint.h)
-AC_CHECK_HEADERS(regex.h termios.h sys/termios.h sys/wait.h)
+AC_CHECK_HEADERS(pwd.h regex.h termios.h sys/termios.h sys/wait.h)
 AC_CHECK_HEADERS(windows.h winsock2.h ws2tcpip.h iptypes.h)
 AC_CHECK_HEADERS(netdb.h sys/socket.h netinet/in.h netinet/tcp.h
arpa/inet.h)
 
@@ -692,7 +692,7 @@ AC_CHECK_FUNCS(gettimeofday mktime putenv unsetenv)
 AC_CHECK_FUNCS(gethostname hstrerror select socket)
 AC_CHECK_FUNCS(uname syslog brk sbrk __clone fcntl)
 AC_CHECK_FUNCS(prctl setlinebuf waitpid atexit kill)
-AC_CHECK_FUNCS(chown getcwd scandir mkstemp)
+AC_CHECK_FUNCS(chown getcwd scandir mkstemp getpwnam)
 AC_CHECK_FUNCS(memalign valloc)
 AC_CHECK_FUNCS(nanosleep usleep)
 AC_CHECK_FUNCS(signal sighold sigrelse tcgetattr)
diff --git a/man/man1/pmproxy.1 b/man/man1/pmproxy.1
index a2560dc..791ca28 100644
--- a/man/man1/pmproxy.1
+++ b/man/man1/pmproxy.1
@@ -39,6 +39,7 @@
 [\f3\-i\f1 \f2ipaddress\f1]
 [\f3\-l\f1 \f2logfile\f1]
 [\f3\-L\f1 \f2bytes\f1]
+[\f3\-U\f1 \f2username\f1]
 [\f3\-x\f1 \f2file\f1]
 .SH DESCRIPTION
 .B pmproxy
@@ -141,6 +142,11 @@ option may be used to change the maximum incoming
 .I PDU 
 size.
 .TP
+\f3\-U\f1 \f2username\f1
+Assume the identity of
+.I username
+before starting to accept incoming packets from PCP monitoring clients.
+.TP
 \f3\-x\f1 \f2file\f1
 Before the
 .B pmproxy
diff --git a/src/include/platform_defs.h.in
b/src/include/platform_defs.h.in
index 7ba1d7c..29ba956 100644
--- a/src/include/platform_defs.h.in
+++ b/src/include/platform_defs.h.in
@@ -123,6 +123,7 @@ extern "C" {
 #undef HAVE_SYS_MMAN_H
 #undef HAVE_SYS_UN_H
 #undef HAVE_STDINT_H
+#undef HAVE_PWD_H
 #undef HAVE_REGEX_H
 #undef HAVE_TERMIOS_H
 #undef HAVE_SYS_TERMIOS_H
@@ -221,6 +222,7 @@ extern "C" {
 #undef HAVE_GETCWD
 #undef HAVE_SCANDIR
 #undef HAVE_MKSTEMP
+#undef HAVE_GETPWNAM
 
 #undef HAVE_MEMALIGN
 #undef HAVE_VALLOC
diff --git a/src/pmproxy/pmproxy.c b/src/pmproxy/pmproxy.c
index d7fcb63..804fdce 100644
--- a/src/pmproxy/pmproxy.c
+++ b/src/pmproxy/pmproxy.c
@@ -21,6 +21,9 @@
 
 #include "pmproxy.h"
 #include <sys/stat.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
 
 int            proxy_hi_openfds = -1;   /* Highest known file descriptor for
pmproxy */
 
@@ -28,6 +31,7 @@ static int    timeToDie;              /* For SIGINT handling 
*/
 static char    *logfile = "pmproxy.log";       /* log file name */
 static int     run_daemon = 1;         /* run as a daemon, see -f */
 static char    *fatalfile = "/dev/tty";/* fatal messages at startup go
here */
+static char    *username;
 
 /*
  * For maintaining info about a request port that clients may connect
to
@@ -140,7 +144,7 @@ ParseOptions(int argc, char *argv[])
     int                usage = 0;
     int                val;
 
-    while ((c = getopt(argc, argv, "D:fi:l:L:x:?")) != EOF)
+    while ((c = getopt(argc, argv, "D:fi:l:L:U:x:?")) != EOF)
        switch (c) {
 
            case 'D':   /* debug flag */
@@ -181,6 +185,11 @@ ParseOptions(int argc, char *argv[])
                }
                break;
 
+           case 'U':
+               /* run as user username */
+               username = optarg;
+               break;
+
            case 'x':
                fatalfile = optarg;
                break;
@@ -202,6 +211,7 @@ ParseOptions(int argc, char *argv[])
 "  -i ipaddress    accept connections on this IP address\n"
 "  -l logfile      redirect diagnostics and trace output\n"
 "  -L bytes        maximum size for PDUs from clients [default
65536]\n"
+"  -U username     assume identity of username (only when run as
root)\n"
 "  -x file         fatal messages at startup sent to file
[default /dev/tty]\n",
                        pmProgname);
        if (usage)
@@ -612,6 +622,24 @@ main(int argc, char *argv[])
     }
     fflush(stderr);
 
+#ifdef HAVE_GETPWNAM
+    /* lose root privileges if we have them */
+    if (username) {
+       struct passwd   *pw;
+
+       if ((pw = getpwnam(username)) == 0) {
+           __pmNotifyErr(LOG_WARNING,
+                       "cannot find the user %s to switch to\n", username);
+           DontStart();
+       }
+       if (setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) {
+           __pmNotifyErr(LOG_WARNING,
+                       "cannot find the user %s to switch to\n", username);
+           DontStart();
+       }
+    }
+#endif
+
     /* all the work is done here */
     ClientLoop();
 
diff --git a/src/pmproxy/pmproxy.options b/src/pmproxy/pmproxy.options
index 1207cdd..298c767 100644
--- a/src/pmproxy/pmproxy.options
+++ b/src/pmproxy/pmproxy.options
@@ -14,6 +14,9 @@
 # restricting incomming PDU size to prevent DOS attacks
 # -L 16384 
 
+# assume identity of some user other than root
+-U nobody
+
 # emergency messages before logfile created
 # -x /tmp/desperate.log
 



<Prev in Thread] Current Thread [Next in Thread>
  • RFC: allow running pmproxy as non-root user, Nathan Scott <=