#endif])
dnl Check for libcap header (assume its not broken unless
-use_caps=yes
-AC_ARG_ENABLE(caps, AS_HELP_STRING([--disable-caps],[disable usage of Linux capabilities library to control privileges]),
-[ if test "x$enableval" = "xyes" ; then
- AC_MSG_RESULT(forced yes)
+use_libcap=auto
+AC_ARG_WITH(libcap, AS_HELP_STRING([--without-libcap],[disable usage of Linux capabilities library to control privileges]),
+[ if test "x$withval" = "xyes" ; then
+ AC_MSG_RESULT(libcap forced enabled)
+ use_libcap=yes
else
- AC_MSG_RESULT(no)
- use_caps=no
+ AC_MSG_RESULT(libcap forced disabled)
+ use_libcap=no
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)
- libcap_broken=1
+])
+if test "x$use_libcap" != "xno"; then
+ # cap_clear_flag is the most recent libcap function we require
+ AC_CHECK_LIB(cap, cap_clear_flag)
+ if test "x$ac_cv_lib_cap_cap_clear_flag" = xyes; then
+ use_libcap=yes
+ else
+ if test "x$use_libcap" = "xyes"; then
+ AC_MSG_ERROR([libcap forced enabled but not available or not usable, requires libcap-2.09 or later])
+ fi
+ use_libcap=no
+ fi
+fi
+
+if test "x$use_libcap" = "xyes"; then
+ AC_DEFINE(USE_LIBCAP, 1, [use libcap to set capabilities required for TPROXY])
+ dnl Check for libcap headader breakage.
AC_CHECK_HEADERS(sys/capability.h)
- AC_CACHE_CHECK([for operational libcap2], $libcap_broken,
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/capability.h>]], [[
- capget(NULL, NULL);
- capset(NULL, NULL);
- ]])],[libcap_broken=0],[])
+ AC_CACHE_CHECK([for operational libcap2 headers], squid_cv_sys_capability_works,
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/capability.h>
+]], [[
+capget(NULL, NULL);
+capset(NULL, NULL);
+ ]])],[squid_cv_sys_capability_works=yes],[squid_cv_sys_capability_works=no])
)
- AC_DEFINE_UNQUOTED([LIBCAP_BROKEN],$libcap_broken,[if libcap2 is available and not clashing with libc])
+ if test x$squid_cv_sys_capability_works != xyes; then
+ AC_DEFINE([LIBCAP_BROKEN],1,[if libcap2 headers are broken and clashing with glibc])
+ fi
fi
+
AC_CHECK_TYPE(mtyp_t,AC_DEFINE(HAVE_MTYP_T,1,[mtyp_t is defined by the system headers]),,[#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>])
sleep 10
fi
dnl Netfilter TPROXY depends on libcap but the NAT parts can still work.
-if test "$LINUX_NETFILTER" = "yes" && test "$use_caps" != "yes" ; then
+if test "$LINUX_NETFILTER" = "yes" && test "$use_libcap" != "yes" ; then
AC_MSG_WARN([Missing needed capabilities (libcap or libcap2) for TPROXY])
AC_MSG_WARN([Linux Transparent Proxy support WILL NOT be enabled])
AC_MSG_WARN([Reduced support to Interception Proxy])
dnl Linux Netfilter/TPROXYv2 support requires some specific header files
dnl Shamelessly copied from above
if test "$LINUX_TPROXY2"; then
- if test "$use_caps" = "yes"; then
+ if test "$use_libcap" = "yes"; then
AC_MSG_CHECKING(if TPROXYv2 header files are installed)
# hold on to your hats...
if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then
void
keepCapabilities(void)
{
-#if HAVE_PRCTL && defined(PR_SET_KEEPCAPS) && HAVE_SYS_CAPABILITY_H
+#if HAVE_PRCTL && defined(PR_SET_KEEPCAPS) && USE_LIBCAP
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
IpInterceptor.StopTransparency("capability setting has failed.");
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 USE_LIBCAP
+ 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);
+ int ncaps = 0;
+ int rc = 0;
+ cap_value_t cap_list[10];
+ cap_list[ncaps++] = CAP_NET_BIND_SERVICE;
if (IpInterceptor.TransparentActive()) {
- cap->effective |= (1 << CAP_NET_ADMIN);
+ cap_list[ncaps++] = CAP_NET_ADMIN;
#if LINUX_TPROXY2
- cap->effective |= (1 << CAP_NET_BROADCAST);
+ cap_list[ncaps++] = CAP_NET_BROADCAST;
#endif
}
- 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
+#elif defined(_SQUID_LINUX_)
IpInterceptor.StopTransparency("Missing needed capability support.");
#endif /* HAVE_SYS_CAPABILITY_H */
-
-#endif /* !defined(_SQUID_LINUX_) */
}
void *