]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Forward port of latest tproxy changes from SQUID 2:
authorserassio <>
Sun, 23 Sep 2007 15:18:08 +0000 (15:18 +0000)
committerserassio <>
Sun, 23 Sep 2007 15:18:08 +0000 (15:18 +0000)
- Automatically disable tproxy if the needed capabilities could not be set
- Keep the permitted set unless root privileges is completely dropped (chroot),
  as is normally done when not using capabilities. This fixes file permissions
  regarding the pid file.
- Test for sys/capability.h linux include file to avoid failing on systems missing libcap

configure
configure.in
include/autoconf.h.in
src/client_side.cc
src/tools.cc

index 27783d160aa7e0b52e73ca231ae307a4b804c741..028bbbaef9a95e06d615f8545acd35a7db781c08 100755 (executable)
--- a/configure
+++ b/configure
@@ -23509,7 +23509,8 @@ for ac_header in \
        nss_common.h \
        nss.h \
        db.h \
-       db_185.h
+       db_185.h \
+       sys/capability.h
 
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
index 43e7c7bea79c411d06b99e99d9cb85ef4418978b..5001b8cbd1f52feca9ab293db5f741d134e19739 100644 (file)
@@ -1,7 +1,7 @@
 
 dnl  Configuration input file for Squid
 dnl
-dnl  $Id: configure.in,v 1.480 2007/09/20 11:07:53 amosjeffries Exp $
+dnl  $Id: configure.in,v 1.481 2007/09/23 09:18:08 serassio Exp $
 dnl
 dnl
 dnl
@@ -11,7 +11,7 @@ AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
 AC_CONFIG_SRCDIR([src/main.cc])
 AM_INIT_AUTOMAKE([tar-ustar])
-AC_REVISION($Revision: 1.480 $)dnl
+AC_REVISION($Revision: 1.481 $)dnl
 AC_PREFIX_DEFAULT(/usr/local/squid)
 AM_MAINTAINER_MODE
 
@@ -1916,7 +1916,8 @@ AC_CHECK_HEADERS( \
        nss_common.h \
        nss.h \
        db.h \
-       db_185.h
+       db_185.h \
+       sys/capability.h
 )
 
 AC_CHECK_HEADERS(
index f6a9db42c5d9326a463d1ea2a8e048a38ce01eac..60eda1ce8aad75bd16ca9bdfd650b82e3b9721b9 100644 (file)
 /* Define to 1 if you have the <sys/bswap.h> header file. */
 #undef HAVE_SYS_BSWAP_H
 
+/* Define to 1 if you have the <sys/capability.h> header file. */
+#undef HAVE_SYS_CAPABILITY_H
+
 /* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
    */
 #undef HAVE_SYS_DIR_H
index 70128711710027a394b16f1ce63847f3ed055e9a..cfc7ad38d1a96c5e8403e011bf87b6af708e907b 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.765 2007/09/03 03:13:52 hno Exp $
+ * $Id: client_side.cc,v 1.766 2007/09/23 09:18:10 serassio Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -2175,7 +2175,7 @@ clientProcessRequest(ConnStateData::Pointer &conn, HttpParser *hp, ClientSocketC
 
 #if LINUX_TPROXY
 
-    request->flags.tproxy = conn->port->tproxy;
+    request->flags.tproxy = conn->port->tproxy && need_linux_tproxy;
 #endif
 
     if (internalCheck(request->urlpath.buf())) {
index 9db8c89842abf78afcd9798cce27d9969cc62c79..9f890a52c91e694e79f1d729d9fc1e0cac2f06e5 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tools.cc,v 1.278 2007/08/24 18:05:28 hno Exp $
+ * $Id: tools.cc,v 1.279 2007/09/23 09:18:10 serassio Exp $
  *
  * DEBUG: section 21    Misc Functions
  * AUTHOR: Harvest Derived
@@ -40,7 +40,8 @@
 #include "wordlist.h"
 #include "SquidTime.h"
 
-#if LINUX_TPROXY
+#ifdef _SQUID_LINUX_
+#if HAVE_SYS_CAPABILITY_H
 #undef _POSIX_SOURCE
 /* Ugly glue to get around linux header madness colliding with glibc */
 #define _LINUX_TYPES_H
@@ -48,6 +49,7 @@
 typedef uint32_t __u32;
 #include <sys/capability.h>
 #endif
+#endif
 
 #if HAVE_SYS_PRCTL_H
 #include <sys/prctl.h>
@@ -70,6 +72,7 @@ static void mail_warranty(void);
 extern void log_trace_done();
 extern void log_trace_init(char *);
 #endif
+static void restoreCapabilities(int keep);
 
 #ifdef _SQUID_LINUX_
 /* Workaround for crappy glic header files */
@@ -389,11 +392,12 @@ death(int sig)
 
         if (Config.adminEmail)
             mail_warranty();
-       puts(dead_msg());
+
+        puts(dead_msg());
     }
 
     if (shutting_down)
-       exit(1);
+        exit(1);
 
     abort();
 }
@@ -731,27 +735,9 @@ leave_suid(void)
         debugs(50, 0, "ALERT: setuid: " << xstrerror());
 
 #endif
-#if LINUX_TPROXY
 
-    if (need_linux_tproxy) {
-        cap_user_header_t head = (cap_user_header_t) xcalloc(1, sizeof(cap_user_header_t));
-        cap_user_data_t cap = (cap_user_data_t) xcalloc(1, sizeof(cap_user_data_t));
+    restoreCapabilities(1);
 
-        head->version = _LINUX_CAPABILITY_VERSION;
-        head->pid = 0;
-        cap->inheritable = cap->permitted = cap->effective = (1 << CAP_NET_ADMIN) + (1 << CAP_NET_BIND_SERVICE) + (1 << CAP_NET_BROADCAST);
-
-        if (capset(head, cap) != 0) {
-            xfree(head);
-            xfree(cap);
-            fatal("Error giving up capabilities");
-        }
-
-        xfree(head);
-        xfree(cap);
-    }
-
-#endif
 #if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
     /* Set Linux DUMPABLE flag */
     if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0)
@@ -790,20 +776,15 @@ no_suid(void)
     uid_t uid;
     leave_suid();
     uid = geteuid();
-    debugs(21, 3, "leave_suid: PID " << getpid() << " giving up root priveleges forever");
-#if HAVE_SETRESUID
-
-    if (setresuid(uid, uid, uid) < 0)
-        debugs(50, 1, "no_suid: setresuid: " << xstrerror());
-
-#else
+    debugs(21, 3, "no_suid: PID " << getpid() << " giving up root priveleges forever");
 
     setuid(0);
 
     if (setuid(uid) < 0)
         debugs(50, 1, "no_suid: setuid: " << xstrerror());
 
-#endif
+    restoreCapabilities(0);
+
 #if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
     /* Set Linux DUMPABLE flag */
     if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0)
@@ -1340,13 +1321,82 @@ strwordquote(MemBuf * mb, const char *str)
 void
 keepCapabilities(void)
 {
+#if HAVE_PRCTL && defined(PR_SET_KEEPCAPS) && HAVE_SYS_CAPABILITY_H
+
+    if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
+        /* Silent failure unless TPROXY is required. Maybe not started as root */
 #if LINUX_TPROXY
 
-    if (need_linux_tproxy) {
-        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
+        if (need_linux_tproxy)
             debugs(1, 1, "Error - tproxy support requires capability setting which has failed.  Continuing without tproxy support");
-        }
+
+        need_linux_tproxy = 0;
+
+#endif
+
     }
 
 #endif
 }
+
+static void
+restoreCapabilities(int keep)
+{
+#if defined(_SQUID_LINUX_) && HAVE_SYS_CAPABILITY_H
+    cap_user_header_t head = (cap_user_header_t) xcalloc(1, sizeof(cap_user_header_t));
+    cap_user_data_t cap = (cap_user_data_t) xcalloc(1, sizeof(cap_user_data_t));
+
+    head->version = _LINUX_CAPABILITY_VERSION;
+
+    if (capget(head, cap) != 0) {
+        debugs(50, 1, "Can't get current capabilities");
+        goto nocap;
+    }
+
+    if (head->version != _LINUX_CAPABILITY_VERSION) {
+        debugs(50, 1, "Invalid capability version " << head->version << " (expected " << _LINUX_CAPABILITY_VERSION << ")");
+        goto nocap;
+    }
+
+    head->pid = 0;
+
+    cap->inheritable = 0;
+    cap->effective = (1 << CAP_NET_BIND_SERVICE);
+#if LINUX_TPROXY
+
+    if (need_linux_tproxy)
+        cap->effective |= (1 << CAP_NET_ADMIN) | (1 << CAP_NET_BROADCAST);
+
+#endif
+
+    if (!keep)
+        cap->permitted &= cap->effective;
+
+    if (capset(head, cap) != 0) {
+        /* Silent failure unless TPROXY is required */
+#if LINUX_TPROXY
+
+        if (need_linux_tproxy)
+            debugs(50, 1, "Error enabling needed capabilities. Will continue without tproxy support");
+
+        need_linux_tproxy = 0;
+
+#endif
+
+    }
+
+nocap:
+    xfree(head);
+    xfree(cap);
+#else
+#if LINUX_TPROXY
+
+    if (need_linux_tproxy)
+        debugs(50, 1, "Missing needed capability support. Will continue without tproxy support");
+
+    need_linux_tproxy = 0;
+
+#endif
+
+#endif
+}