--- 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 +#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);