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,
]])],[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>
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 *