]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Use libcap functions instead of raw kernel interface
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Thu, 15 Oct 2009 14:24:33 +0000 (16:24 +0200)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Thu, 15 Oct 2009 14:24:33 +0000 (16:24 +0200)
configure.in
src/tools.cc

index c4821979cafa89449cd7f7cc0d1228d7cdd0c9a8..f35d4d54cb7082f1101d8a717ef61da57c0115c2 100644 (file)
@@ -2752,7 +2752,7 @@ AC_ARG_ENABLE(caps, AS_HELP_STRING([--disable-caps],[disable usage of Linux capa
   fi
 ],[AC_MSG_RESULT(yes)])
 if test "x$use_caps" = "xyes"; then
-  dnl Check for libcap1 breakage or libcap2 fixed (assume broken unless found working)
+  dnl Check for libcap1 header breakage or libcap2 fixed (assume broken unless found working)
   libcap_broken=1
   AC_CHECK_HEADERS(sys/capability.h)
   AC_CACHE_CHECK([for operational libcap2], $libcap_broken,
@@ -2762,6 +2762,7 @@ if test "x$use_caps" = "xyes"; then
                    ]])],[libcap_broken=0],[])
   )
   AC_DEFINE_UNQUOTED([LIBCAP_BROKEN],$libcap_broken,[if libcap2 is available and not clashing with libc])
+  AC_CHECK_LIB(cap, cap_get_proc)
 fi
 
 AC_CHECK_TYPE(mtyp_t,AC_DEFINE(HAVE_MTYP_T,1,[mtyp_t is defined by the system headers]),,[#include <sys/types.h>
index e3e2323ee140c4b4bef46f7e9827c4f126de9c6f..7144a78312c20952afaa4c589dcba755afec5d56 100644 (file)
@@ -1240,51 +1240,41 @@ static void
 restoreCapabilities(int keep)
 {
     /* NP: keep these two if-endif separate. Non-Linux work perfectly well without Linux syscap support. */
-#if defined(_SQUID_LINUX_)
-
-#if HAVE_SYS_CAPABILITY_H
-#ifndef _LINUX_CAPABILITY_VERSION_1
-#define _LINUX_CAPABILITY_VERSION_1 _LINUX_CAPABILITY_VERSION
-#endif
-    cap_user_header_t head = (cap_user_header_t) xcalloc(1, sizeof(*head));
-    cap_user_data_t cap = (cap_user_data_t) xcalloc(1, sizeof(*cap));
-
-    head->version = _LINUX_CAPABILITY_VERSION_1;
-
-    if (capget(head, cap) != 0) {
-        debugs(50, DBG_IMPORTANT, "Can't get current capabilities");
-    } else if (head->version != _LINUX_CAPABILITY_VERSION_1) {
-        debugs(50, DBG_IMPORTANT, "Invalid capability version " << head->version << " (expected " << _LINUX_CAPABILITY_VERSION_1 << ")");
+#if defined(_SQUID_LINUX_) && HAVE_SYS_CAPABILITY_H
+    cap_t caps;
+    if (keep)
+       caps = cap_get_proc();
+    else
+       caps = cap_init();
+    if (!caps) {
+       IpInterceptor.StopTransparency("Can't get current capabilities");
     } else {
-
-        head->pid = 0;
-
-        cap->inheritable = 0;
-        cap->effective = (1 << CAP_NET_BIND_SERVICE);
-
-        if (IpInterceptor.TransparentActive()) {
-            cap->effective |= (1 << CAP_NET_ADMIN);
+#define PUSH_CAP(cap) cap_list[ncaps++] = (cap)
+       int ncaps = 0;
+       int rc = 0;
+       cap_value_t cap_list[10];
+       PUSH_CAP(CAP_NET_BIND_SERVICE);
+
+       if (IpInterceptor.TransparentActive()) {
+           PUSH_CAP(CAP_NET_ADMIN);
 #if LINUX_TPROXY2
-            cap->effective |= (1 << CAP_NET_BROADCAST);
+           PUSH_CAP(CAP_NET_BROADCAST);
 #endif
-        }
+       }
+#undef PUSH_CAP
 
-        if (!keep)
-            cap->permitted &= cap->effective;
+       cap_clear_flag(caps, CAP_EFFECTIVE);
+       rc |= cap_set_flag(caps, CAP_EFFECTIVE, ncaps, cap_list, CAP_SET);
+       rc |= cap_set_flag(caps, CAP_PERMITTED, ncaps, cap_list, CAP_SET);
 
-        if (capset(head, cap) != 0) {
+        if (rc || cap_set_proc(caps) != 0) {
             IpInterceptor.StopTransparency("Error enabling needed capabilities.");
         }
+       cap_free(caps);
     }
-
-    xfree(head);
-    xfree(cap);
-
 #else
     IpInterceptor.StopTransparency("Missing needed capability support.");
 #endif /* HAVE_SYS_CAPABILITY_H */
-
-#endif /* !defined(_SQUID_LINUX_) */
 }
 
 void *