Hi all,

i did a quick hack and patched Solaris privileges support into pinger.c
from squid-2.6.STABLE18. This should allow to run pinger w/o setuid-root,
while still being able to access ICMP-sockets. The $SQUID_USER gets the
additional PRIV_NET_ICMPACCESS rights via:
  /usr/sbin/usermod -K defaultpriv=basic,net_icmpaccess $SQUID_USER

While probably not so interesting for the general public, could someone
with a bit more squid-code knowledge than me take a look at the patch?
I just want to make sure i didn't inadvertedly break something else ;-)

Thanks,

        Frank
--- configure.in.orig	Thu Jan 24 14:31:15 2008
+++ configure.in	Thu Jan 24 14:30:10 2008
@@ -1520,6 +1520,25 @@
   fi
 ])
 
+# ****************** Solaris Privileges Check ***********************
+# Check if usage of Solaris privileges support is possible
+AC_CHECK_HEADER(priv.h, [FOUND_PRIV_H=yes], [FOUND_PRIV_H=no])
+# If we should use the Solaris privileges support
+AC_ARG_ENABLE(solaris-priv,
+[  --enable-solaris-priv   Enable support for the Solaris process privilege
+                          model to allow pinger to run without SETUID-root
+                          (default: disabled)],
+[ if test "$enableval" = "yes" ; then
+    if test "$FOUND_PRIV_H" = "yes"; then
+        AC_MSG_RESULT([yes])
+        AC_DEFINE([SOLARIS_PRIV], [1], [If upport for Solaris privileges should be enabled])
+    else
+        AC_MSG_RESULT([no])
+    fi
+  fi
+])
+# ****************** Solaris Privileges Check ***********************
+    
 # Force some compilers to use ANSI features
 #
 case "$host" in
--- include/autoconf.h.in.orig	Thu Jan 24 14:28:29 2008
+++ include/autoconf.h.in	Thu Jan 24 14:28:45 2008
@@ -39,6 +39,9 @@
 /* Enable following X-Forwarded-For headers */
 #undef FOLLOW_X_FORWARDED_FOR
 
+/* If upport for Solaris privileges should be enabled */
+#undef SOLARIS_PRIV
+
 /* Enable Forw/Via database */
 #undef FORW_VIA_DB
 
--- include/config.h.orig	Thu Jan 24 15:53:41 2008
+++ include/config.h	Thu Jan 24 15:55:20 2008
@@ -221,4 +221,7 @@
 #define PRINTF_FORMAT_ARG3
 #endif
 
+#if SOLARIS_PRIV
+#include <priv.h>
+#endif
 #endif /* SQUID_CONFIG_H */
--- src/pinger.c.orig	Thu Jan 24 15:41:15 2008
+++ src/pinger.c	Thu Jan 24 16:09:14 2008
@@ -507,9 +507,49 @@
  * cevans - do this first. It grabs a raw socket. After this we can
  * drop privs
  */
+#ifdef SOLARIS_PRIV
+    priv_set_t *privset;
+    char *p;
+    /* Get the basic set */
+    privset = priv_str_to_set("basic", ",", NULL);
+    if (privset == NULL) {
+		debug(42, 5) ("Pinger: Could not get basic privset from priv_str_to_set().\n");
+	    exit(1);
+    }
+    else {
+        p = priv_set_to_str(privset, ',', 0);
+		debug(42, 9) ("Pinger: Basic privset is: '%s'.\n", p != NULL ? p : "Unknown");
+    }
+    /* Remove exec from the basic set */
+    if (priv_delset(privset, PRIV_PROC_EXEC) < 0 ) {
+        debug(42, 5) ("Warning: Deletion of PRIV_PROC_EXEC from privset failed: '%s'.\n", strerror(errno));
+    }
+    /* Add priviledge to send/receive ICMP packets */
+    if (priv_addset(privset, PRIV_NET_ICMPACCESS) < 0 ) {
+        debug(42, 5) ("Warning: Addition of PRIV_NET_ICMPACCESS to privset failed: '%s'.\n", strerror(errno));
+    }
+    /* Compute the set of privileges that are never needed */
+    priv_inverse(privset);
+    /* Remove the set of unneeded privs from Permitted (and by
+     * implication from Effective) */
+    if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) < 0) {
+        debug(42, 5) ("Warning: Dropping privileges from PRIV_PERMITTED failed: '%s'.\n", strerror(errno));
+    }
+    /* Remove unneeded priv set from Limit to be safe */
+    if (setppriv(PRIV_OFF, PRIV_LIMIT, privset) < 0) {
+        debug(42, 5) ("Warning: Dropping privileges from PRIV_LIMIT failed: '%s'.\n", strerror(errno));
+    }
+    boolean_t pe = priv_ineffect(PRIV_NET_ICMPACCESS);
+    debug(42, 5) ("DEBUG: Privilege PRIV_NET_ICMPACCESS is: '%s'.\n", pe != 0 ? "Enabled" : "Disabled");
+    /* Free the privset */
+    priv_freeset(privset);
+    free(p);
+#endif
     pingerOpen();
+#ifndef SOLARIS_PRIV
     setgid(getgid());
     setuid(getuid());
+#endif
 
     if ((t = getenv("SQUID_DEBUG")))
 	debug_args = xstrdup(t);

Reply via email to