From 2d4f737c35cfcb4c1b5bd1f03461919e0cd57dc4 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Le Bail Date: Sun, 15 Feb 2015 15:32:23 +0100 Subject: [PATCH] configure: add support for cap-ng package It uses '--with-cap-ng', for using libcap-ng [default=yes, if available] --- config.h.in | 6 ++++ configure | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++- configure.in | 31 ++++++++++++++++- tcpdump.c | 33 +++++++++++------- 4 files changed, 152 insertions(+), 14 deletions(-) diff --git a/config.h.in b/config.h.in index 43a6bc1b7..11ce977b5 100644 --- a/config.h.in +++ b/config.h.in @@ -18,6 +18,9 @@ /* Define to 1 if you have the `cap_ioctls_limit' function. */ #undef HAVE_CAP_IOCTLS_LIMIT +/* Define to 1 if you have the header file. */ +#undef HAVE_CAP_NG_H + /* Define to 1 if you have the `cap_rights_limit' function. */ #undef HAVE_CAP_RIGHTS_LIMIT @@ -52,6 +55,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the `cap-ng' library (-lcap-ng). */ +#undef HAVE_LIBCAP_NG + /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO diff --git a/configure b/configure index 87d6992bd..293edb14c 100755 --- a/configure +++ b/configure @@ -707,6 +707,7 @@ with_sandbox_capsicum enable_ipv6 with_system_libpcap with_crypto +with_cap_ng ' ac_precious_vars='build_alias host_alias @@ -1346,6 +1347,7 @@ Optional Packages: available] --with-system-libpcap don't use local pcap library --with-crypto use OpenSSL libcrypto [default=yes, if available] + --with-cap-ng use libcap-ng [default=yes, if available] Some influential environment variables: CC C compiler command @@ -6736,7 +6738,7 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$ac_lbl_cv_pcap_version_defined" = yes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_PCAP_VERSION 1" >>confdefs.h @@ -8176,6 +8178,98 @@ done fi +# Check for libcap-ng +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libcap-ng" >&5 +$as_echo_n "checking whether to use libcap-ng... " >&6; } +# Specify location for both includes and libraries. +want_libcap_ng=ifavailable + +# Check whether --with-cap_ng was given. +if test "${with_cap_ng+set}" = set; then : + withval=$with_cap_ng; + if test $withval = no + then + want_libcap_ng=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + elif test $withval = yes + then + want_libcap_ng=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + +else + + # + # Use libcap-ng if it's present, otherwise don't. + # + want_libcap_ng=ifavailable + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes, if available" >&5 +$as_echo "yes, if available" >&6; } + +fi + +if test "$want_libcap_ng" != "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for capng_change_id in -lcap-ng" >&5 +$as_echo_n "checking for capng_change_id in -lcap-ng... " >&6; } +if ${ac_cv_lib_cap_ng_capng_change_id+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcap-ng $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char capng_change_id (); +int +main () +{ +return capng_change_id (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_cap_ng_capng_change_id=yes +else + ac_cv_lib_cap_ng_capng_change_id=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_ng_capng_change_id" >&5 +$as_echo "$ac_cv_lib_cap_ng_capng_change_id" >&6; } +if test "x$ac_cv_lib_cap_ng_capng_change_id" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBCAP_NG 1 +_ACEOF + + LIBS="-lcap-ng $LIBS" + +fi + + for ac_header in cap-ng.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "cap-ng.h" "ac_cv_header_cap_ng_h" "$ac_includes_default" +if test "x$ac_cv_header_cap_ng_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CAP_NG_H 1 +_ACEOF + +fi + +done + +fi + if test "$missing_includes" = "yes"; then CPPFLAGS="$CPPFLAGS -I$srcdir/missing" V_INCLS="$V_INCLS -I$srcdir/missing" diff --git a/configure.in b/configure.in index 7c860dc07..1f10dc5e7 100644 --- a/configure.in +++ b/configure.in @@ -854,7 +854,7 @@ if test $ac_cv_func_pcap_lib_version = "no" ; then ac_lbl_cv_pcap_version_defined=yes, ac_lbl_cv_pcap_version_defined=no) if test "$ac_lbl_cv_pcap_version_defined" = yes ; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PCAP_VERSION, 1, [define if libpcap has pcap_version]) else AC_MSG_RESULT(no) @@ -1110,6 +1110,35 @@ if test "$want_libcrypto" != "no"; then AC_CHECK_HEADERS(openssl/evp.h) fi +# Check for libcap-ng +AC_MSG_CHECKING(whether to use libcap-ng) +# Specify location for both includes and libraries. +want_libcap_ng=ifavailable +AC_ARG_WITH(cap_ng, + AS_HELP_STRING([--with-cap-ng], + [use libcap-ng @<:@default=yes, if available@:>@]), +[ + if test $withval = no + then + want_libcap_ng=no + AC_MSG_RESULT(no) + elif test $withval = yes + then + want_libcap_ng=yes + AC_MSG_RESULT(yes) + fi +],[ + # + # Use libcap-ng if it's present, otherwise don't. + # + want_libcap_ng=ifavailable + AC_MSG_RESULT([yes, if available]) +]) +if test "$want_libcap_ng" != "no"; then + AC_CHECK_LIB(cap-ng, capng_change_id) + AC_CHECK_HEADERS(cap-ng.h) +fi + dnl dnl set additional include path if necessary if test "$missing_includes" = "yes"; then diff --git a/tcpdump.c b/tcpdump.c index 1eb2e206b..bd1664c53 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -101,10 +101,18 @@ extern int SIZE_BUF; #include #endif /* WIN32 */ -/* capabilities convinience library */ +/* capabilities convenience library */ +/* If a code depends on HAVE_LIBCAP_NG, it depends also on HAVE_CAP_NG_H. + * If HAVE_CAP_NG_H is not defined, undefine HAVE_LIBCAP_NG. + * Thus, the later tests are done only on HAVE_LIBCAP_NG. + */ +#ifdef HAVE_LIBCAP_NG #ifdef HAVE_CAP_NG_H #include +#else +#undef HAVE_LIBCAP_NG #endif /* HAVE_CAP_NG_H */ +#endif /* HAVE_LIBCAP_NG */ #include "netdissect.h" #include "interface.h" @@ -734,7 +742,7 @@ droproot(const char *username, const char *chroot_dir) exit(1); } } -#ifdef HAVE_CAP_NG_H +#ifdef HAVE_LIBCAP_NG int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG); if (ret < 0) { fprintf(stderr, "error : ret %d\n", ret); @@ -749,6 +757,7 @@ droproot(const char *username, const char *chroot_dir) CAP_SETUID, CAP_SETGID, -1); + capng_apply(CAPNG_SELECT_BOTH); #else @@ -764,7 +773,7 @@ droproot(const char *username, const char *chroot_dir) else { fprintf(stderr, "dropped privs to %s\n", username); } -#endif /* HAVE_CAP_NG_H */ +#endif /* HAVE_LIBCAP_NG */ } else { fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n", @@ -1582,7 +1591,7 @@ main(int argc, char **argv) status = pcap_set_tstamp_type(pd, jflag); if (status < 0) error("%s: Can't set time stamp type: %s", - device, pcap_statustostr(status)); + device, pcap_statustostr(status)); } #endif status = pcap_activate(pd); @@ -1729,7 +1738,7 @@ main(int argc, char **argv) */ if (getuid() == 0 || geteuid() == 0) { -#ifdef HAVE_CAP_NG_H +#ifdef HAVE_LIBCAP_NG /* Drop all capabilities from effective set */ capng_clear(CAPNG_EFFECTIVE); /* We are running as root and we will be writing to savefile */ @@ -1744,7 +1753,7 @@ main(int argc, char **argv) -1); capng_apply(CAPNG_SELECT_BOTH); } -#endif /* HAVE_CAP_NG_H */ +#endif /* HAVE_LIBCAP_NG */ if (username || chroot_dir) droproot(username, chroot_dir); @@ -1783,10 +1792,10 @@ main(int argc, char **argv) MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); p = pcap_dump_open(pd, dumpinfo.CurrentFileName); -#ifdef HAVE_CAP_NG_H +#ifdef HAVE_LIBCAP_NG /* Give up capabilities, clear Effective set */ capng_clear(CAPNG_EFFECTIVE); -#endif +#endif /* HAVE_LIBCAP_NG */ if (p == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM @@ -2200,10 +2209,10 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s else MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, 0); -#ifdef HAVE_CAP_NG_H +#ifdef HAVE_LIBCAP_NG capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_EFFECTIVE); -#endif /* HAVE_CAP_NG_H */ +#endif /* HAVE_LIBCAP_NG */ #ifdef HAVE_CAPSICUM fd = openat(dump_info->dirfd, dump_info->CurrentFileName, @@ -2221,10 +2230,10 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s #else /* !HAVE_CAPSICUM */ dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif -#ifdef HAVE_CAP_NG_H +#ifdef HAVE_LIBCAP_NG capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_EFFECTIVE); -#endif /* HAVE_CAP_NG_H */ +#endif /* HAVE_LIBCAP_NG */ if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM