From: Henrik Nordstrom Date: Thu, 15 Oct 2009 14:24:33 +0000 (+0200) Subject: Use libcap functions instead of raw kernel interface X-Git-Tag: SQUID_3_2_0_1~653^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=876326314a57aab13a43d04ce1fcb4ac1ba6c905;p=thirdparty%2Fsquid.git Use libcap functions instead of raw kernel interface --- diff --git a/configure.in b/configure.in index c4821979ca..f35d4d54cb 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/src/tools.cc b/src/tools.cc index e3e2323ee1..7144a78312 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -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 *