[PATCH] Switch user ID after creating listener

Michael Gold <[email protected]>
Newsgroups gmane.comp.web.polipo.user
Message-ID <[email protected]>
Hi all,

This patch (for polipo 1.0.4) adds a new configuration option called
"setUser".  If specified, polipo will switch to the named account after
binding its listening socket.  This allows it to listen on a privileged
port, to prevent an unprivileged from binding the port while polipo
isn't running.

If setUser is blank or unspecified, nothing will change.  In polipo.h
I assume getpwnam, setgid, and setuid are available if fork is (i.e. on
all non-MINGW platforms); I'm not sure if that's correct, but otherwise
the patch should be fine.

-- Michael

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H

_______________________________________________
Polipo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/polipo-users
polipo-setuid.diff (text/x-diff, 2.8 KB)
diff -urN polipo-1.0.4-orig/main.c polipo-1.0.4-mod/main.c
--- polipo-1.0.4-orig/main.c	2008-01-08 07:56:45.000000000 -0500
+++ polipo-1.0.4-mod/main.c	2009-02-24 00:57:38.657410813 -0500
@@ -24,6 +24,7 @@
 
 AtomPtr configFile = NULL;
 AtomPtr pidFile = NULL;
+AtomPtr setUser = NULL;
 int daemonise = 0;
 
 static void
@@ -49,6 +50,7 @@
     initAtoms();
     CONFIG_VARIABLE(daemonise, CONFIG_BOOLEAN, "Run as a daemon");
     CONFIG_VARIABLE(pidFile, CONFIG_ATOM, "File with pid of running daemon.");
+    CONFIG_VARIABLE(setUser, CONFIG_ATOM, "Username to run as.");
 
     preinitChunks();
     preinitLog();
@@ -162,6 +164,9 @@
         exit(1);
     }
 
+    if(setUser && setUser->length > 0)
+        dropPrivs(setUser);
+
     eventLoop();
 
     if(pidFile) unlink(pidFile->string);
diff -urN polipo-1.0.4-orig/polipo.h polipo-1.0.4-mod/polipo.h
--- polipo-1.0.4-orig/polipo.h	2008-01-08 07:56:45.000000000 -0500
+++ polipo-1.0.4-mod/polipo.h	2009-02-23 21:35:54.973407410 -0500
@@ -164,6 +164,7 @@
 
 #ifndef MINGW
 #define HAVE_FORK
+#define HAVE_SETUID
 #ifndef NO_SYSLOG
 #define HAVE_SYSLOG
 #endif
diff -urN polipo-1.0.4-orig/util.c polipo-1.0.4-mod/util.c
--- polipo-1.0.4-orig/util.c	2008-01-08 07:56:45.000000000 -0500
+++ polipo-1.0.4-mod/util.c	2009-02-23 22:05:07.909407389 -0500
@@ -806,3 +806,49 @@
     return -1;
 }
 #endif
+
+#ifdef HAVE_SETUID
+
+#include <sys/types.h>
+#include <pwd.h>
+void
+dropPrivs(AtomPtr username)
+{
+    struct passwd *pwd;
+    int rc;
+
+    errno = 0;
+    pwd = getpwnam(atomString(username));
+    if(pwd == NULL) {
+        if(errno)
+            do_log_error(L_ERROR, errno, "Can't read user info for \"%s\"",
+                         atomString(username));
+        else
+            do_log(L_ERROR, "Unknown username \"%s\".\n", atomString(username));
+
+        exit(1);
+    }
+
+    rc = setgid(pwd->pw_gid);
+    if(rc < 0) {
+        do_log_error(L_ERROR, errno, "Can't change group ID");
+        exit(1);
+    }
+
+    rc = setuid(pwd->pw_uid);
+    if(rc < 0) {
+        do_log_error(L_ERROR, errno, "Can't change user ID");
+        exit(1);
+    }
+}
+
+#else
+
+void
+dropPrivs(AtomPtr username)
+{
+    do_log(L_ERROR, "Cannot change user ID on this platform.\n");
+    exit(1);
+}
+
+#endif
diff -urN polipo-1.0.4-orig/util.h polipo-1.0.4-mod/util.h
--- polipo-1.0.4-orig/util.h	2008-01-08 07:56:45.000000000 -0500
+++ polipo-1.0.4-mod/util.h	2009-02-23 21:35:06.317408182 -0500
@@ -97,6 +97,7 @@
 time_t mktime_gmt(struct tm *tm) ATTRIBUTE ((pure));
 AtomPtr expandTilde(AtomPtr filename);
 void do_daemonise(int noclose);
+void dropPrivs(AtomPtr username);
 void writePid(char *pidfile);
 int b64cpy(char *restrict dst, const char *restrict src, int n, int fss);
 int b64cmp(const char *restrict a, int an, const char *restrict b, int bn)
signature.asc (application/pgp-signature, 197 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)

iEYEARECAAYFAkmjoLAACgkQ+RZl+46r4TdZugCfVe4aN9OeaeK+ZYD5dAbVlgg6
Zu8An2nDNH3pjtPDRQdGpVYdt3buiuzl
=nncd
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.