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
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)

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
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
Polipo-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/polipo-users

Reply via email to