diff --git a/Knot.files b/Knot.files index eb6887ba443de6dcc67a5ef27116cd9cd836aba3..f364dccaad656272b557db1cdb163ad30c457fdd 100644 --- a/Knot.files +++ b/Knot.files @@ -73,8 +73,6 @@ src/common/slab/alloc-common.h src/common/libtap/tap.c src/common/libtap/tap.h src/common/libtap/tap_unit.h -src/common/caps.h -src/common/caps.c src/common/lists.h src/common/lists.c src/common/base32.h diff --git a/configure.ac b/configure.ac index eccd82f4e09128fd02b9b7b2d720d7a9d055b0a3..027f6ecc4986a9ba89cc9c2340080d9513928beb 100644 --- a/configure.ac +++ b/configure.ac @@ -113,12 +113,12 @@ AC_SEARCH_LIBS([rcu_set_pointer_sym], [urcu], [], [AC_MSG_ERROR([liburcu not fou AC_SEARCH_LIBS([dlopen], [dl]) AC_SEARCH_LIBS([clock_gettime], [rt], [], [AC_MSG_ERROR([librt not found])]) AC_SEARCH_LIBS([OpenSSL_add_all_digests], [crypto],[], [AC_MSG_ERROR([libcrypto not found])]) -AC_SEARCH_LIBS([cap_set_flag], [cap]) +AC_SEARCH_LIBS([capng_apply], [cap-ng]) #AC_SEARCH_LIBS([ldns_rr_list_pop_rrset], [ldns], [], [AC_MSG_ERROR([libldns not found])]) # Checks for header files. AC_HEADER_RESOLV -AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in_systm.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h sys/capability.h syslog.h unistd.h urcu.h ev.h]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in_systm.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h cap-ng.h syslog.h unistd.h urcu.h ev.h]) # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL diff --git a/src/Makefile.am b/src/Makefile.am index b50c33afa6830988b0dd982d9bf6a19f2b427551..e73b2bfb4d020fc6dfed9b58f3b2e70ed7496dc8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -223,8 +223,6 @@ libknots_la_SOURCES = \ common/libtap/tap.c \ common/libtap/tap.h \ common/libtap/tap_unit.h \ - common/caps.c \ - common/caps.h \ common/lists.c \ common/base32.c \ common/lists.h \ diff --git a/src/common/caps.c b/src/common/caps.c deleted file mode 100644 index 22fb273be5663a7df0cb6b685d33fc9122df13b8..0000000000000000000000000000000000000000 --- a/src/common/caps.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "caps.h" - -int cap_drop_all() { -#ifdef USE_CAPABILITIES - cap_t caps = cap_init(); - if (caps == NULL) { - return -1; - } - int ret = cap_apply(caps); - cap_free(caps); - return ret; -#else - return -1; -#endif -} - diff --git a/src/common/caps.h b/src/common/caps.h deleted file mode 100644 index 657390a74206f0e07e804168b738480982b2151b..0000000000000000000000000000000000000000 --- a/src/common/caps.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -/*! - * \file caps.h - * - * \author Marek Vavrusa <marek.vavrusa@nic.cz> - * - * \brief POSIX 1003.1e capabilities interface. - * - * \addtogroup common_lib - * @{ - */ - -#ifndef _KNOTD_CAPS_H_ -#define _KNOTD_CAPS_H_ - -#include <unistd.h> -#include <config.h> - -/* Include required types. */ -#ifdef HAVE_SYS_CAPABILITY_H -#include <sys/capability.h> - -/* Check gettid(). */ -#ifndef HAVE_GETTID -#include <sys/syscall.h> -static pid_t gettid() { -#ifdef SYS_gettid - return (pid_t)syscall(SYS_gettid); -#define HAVE_GETTID 1 -#else - return (pid_t)0; -#endif -} -#endif -#else -/* Stub types. */ -typedef void* cap_t; -typedef int cap_value_t; -typedef int cap_flag_value_t; -#endif - -/* Summarize. */ -#ifdef HAVE_SYS_CAPABILITY_H -#ifdef HAVE_GETTID -#define USE_CAPABILITIES -#endif -#endif - -/*! - * \brief Set Permitted & Effective flag. - * \param caps Capabilities context. - * \param cp Flag to be set. - * \retval 0 if success. - * \retval -1 on error. - */ -static inline int cap_set_pe(cap_t caps, cap_value_t cp) { -#ifdef USE_CAPABILITIES - return cap_set_flag(caps, CAP_EFFECTIVE, 1, &cp, CAP_SET) + - cap_set_flag(caps, CAP_PERMITTED, 1, &cp, CAP_SET); -#else - return -1; -#endif -} - -/*! - * \brief Apply privileges. - * \param caps Capabilities context. - * \retval 0 if success. - * \retval -1 on error. - */ -static inline int cap_apply(cap_t caps) { -#ifdef USE_CAPABILITIES - return capsetp(gettid(), caps); -#else - return -1; -#endif -} - -/*! - * \brief Drop all capabilities. - * \retval 0 if success. - * \retval -1 on error. - */ -int cap_drop_all(); - -#endif //_KNOTD_CAPS_H_ diff --git a/src/knot/main.c b/src/knot/main.c index 27cbb27c3a244a4c71997033a1a5ef51dd0f81f9..a3a1db7986c96f877d13b1551a144969e748dfdd 100644 --- a/src/knot/main.c +++ b/src/knot/main.c @@ -19,10 +19,12 @@ #include <stdlib.h> #include <unistd.h> #include <getopt.h> -#include "common.h" +#ifdef HAVE_CAP_NG_H +#include <cap-ng.h> +#endif /* HAVE_CAP_NG_H */ +#include "common.h" #include "common/evqueue.h" -#include "common/caps.h" #include "knot/common.h" #include "knot/other/error.h" #include "knot/server/server.h" @@ -183,48 +185,39 @@ int main(int argc, char **argv) config_fn = abs_cfg; } - /* Linux capabilities. */ -#ifdef USE_CAPABILITIES - cap_t caps = cap_get_proc(); - if (caps != NULL) { - /* Read current and clear. */ - cap_flag_value_t set_caps = CAP_CLEAR; - cap_get_flag(caps, CAP_SETPCAP, CAP_EFFECTIVE, &set_caps); - cap_clear(caps); - - /* Retain ability to set capabilities. */ - cap_set_pe(caps, CAP_SETPCAP); - - /* Allow binding to privileged ports. - * (Not inheritable) - */ - cap_set_pe(caps, CAP_NET_BIND_SERVICE); - - /* Allow setuid/setgid. */ - cap_set_pe(caps, CAP_SETUID); - cap_set_pe(caps, CAP_SETGID); - - /* Allow priorities changing. */ - cap_set_pe(caps, CAP_SYS_NICE); - - /* Apply */ - int caps_res = 0; - if (set_caps == CAP_SET) { - caps_res = cap_apply(caps); - } else { - log_server_info("User uid=%d is not allowed to set " - "capabilities, skipping.\n", getuid()); - } - if (caps_res < 0) { + /* POSIX 1003.1e capabilities. */ +#ifdef HAVE_CAP_NG_H + + /* Drop all capabilities. */ + capng_clear(CAPNG_SELECT_BOTH); + + /* Retain ability to set capabilities. */ + capng_type_t tp = CAPNG_EFFECTIVE|CAPNG_PERMITTED; + capng_update(CAPNG_ADD, tp, CAP_SETPCAP); + + /* Allow binding to privileged ports. + * (Not inheritable) + */ + capng_update(CAPNG_ADD, tp, CAP_NET_BIND_SERVICE); + + /* Allow setuid/setgid. */ + capng_update(CAPNG_ADD, tp, CAP_SETUID); + capng_update(CAPNG_ADD, tp, CAP_SETGID); + + /* Allow priorities changing. */ + capng_update(CAPNG_ADD, tp, CAP_SYS_NICE); + + /* Apply */ + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) { + if (capng_apply(CAPNG_SELECT_BOTH) < 0) { log_server_error("Couldn't set process capabilities - " "%s.\n", strerror(errno)); } - /* Free capabilities list. */ - cap_free(caps); } else { - log_server_error("Couldn't initialize Linux capabilities.\n"); + log_server_info("User uid=%d is not allowed to set " + "capabilities, skipping.\n", getuid()); } -#endif +#endif /* HAVE_CAP_NG_H */ // Open configuration log_server_info("Parsing configuration '%s' ...\n", config_fn); diff --git a/src/knot/server/dthreads.c b/src/knot/server/dthreads.c index 3ddf4593601e0114bfeba979427550bcde86b485..83466d8fa855b7fd5aa2991b379453fc0b6ba0e9 100644 --- a/src/knot/server/dthreads.c +++ b/src/knot/server/dthreads.c @@ -21,12 +21,14 @@ #include <stdio.h> #include <unistd.h> #include <errno.h> +#ifdef HAVE_CAP_NG_H +#include <cap-ng.h> +#endif /* HAVE_CAP_NG_H */ #include "knot/common.h" #include "knot/server/dthreads.h" #include "knot/other/log.h" #include "knot/other/error.h" -#include "common/caps.h" /*! \brief Lock thread state for R/W. */ static inline void lock_thread_rw(dthread_t *thread) @@ -126,7 +128,10 @@ static void *thread_ep(void *data) dbg_dt("dthreads: [%p] entered ep\n", thread); // Drop capabilities - cap_drop_all(); +#ifdef HAVE_CAP_NG_H + capng_clear(CAPNG_SELECT_BOTH); + capng_apply(CAPNG_SELECT_BOTH); +#endif /* HAVE_CAP_NG_H */ // Run loop for (;;) {