From 0997d7a72de1aa892397b594e17004d3439f8675 Mon Sep 17 00:00:00 2001 From: Alexey Tikhonov Date: Sat, 2 Sep 2023 14:51:52 +0200 Subject: [PATCH] UTILS: add capabilities management helpers --- Makefile.am | 3 +++ configure.ac | 7 +++++++ contrib/ci/deps.sh | 2 ++ contrib/sssd.spec.in | 1 + src/util/become_user.c | 45 ++++++++++++++++++++++++++++++++++++++++++ src/util/util.h | 2 ++ 6 files changed, 60 insertions(+) diff --git a/Makefile.am b/Makefile.am index 3b72e456c69..52360010c09 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1306,6 +1306,7 @@ libsss_util_la_CFLAGS = \ libsss_util_la_LIBADD = \ $(LIBADD_TIMER) \ $(SSSD_LIBS) \ + $(CAP_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ $(UNICODE_LIBS) \ $(PCRE_LIBS) \ @@ -4698,6 +4699,7 @@ krb5_child_LDADD = \ $(CLIENT_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ $(JANSSON_LIBS) \ + $(CAP_LIBS) \ $(NULL) ldap_child_SOURCES = \ @@ -4723,6 +4725,7 @@ ldap_child_LDADD = \ libsss_debug.la \ $(TALLOC_LIBS) \ $(POPT_LIBS) \ + $(CAP_LIBS) \ $(DHASH_LIBS) \ $(KRB5_LIBS) diff --git a/configure.ac b/configure.ac index 270b8ef376d..47f27569675 100644 --- a/configure.ac +++ b/configure.ac @@ -516,6 +516,13 @@ AS_IF([test x$have_check = x], [ AC_CHECK_HEADERS([check.h],,AC_MSG_ERROR([Could not find CHECK headers])) ]) +PKG_CHECK_MODULES([CAP], [libcap], [have_libcap=1], [have_libcap=]) +AS_IF([test x$have_libcap = x], [ + AC_MSG_ERROR([libcap is missing]) +], [ + AC_CHECK_HEADERS([sys/capability.h],,AC_MSG_ERROR([Could not find sys/capability.h headers])) +]) + AC_PATH_PROG([DOXYGEN], [doxygen], [false]) AM_CONDITIONAL([HAVE_DOXYGEN], [test x$DOXYGEN != xfalse ]) diff --git a/contrib/ci/deps.sh b/contrib/ci/deps.sh index c49ddb51e5f..c65e0e3289b 100644 --- a/contrib/ci/deps.sh +++ b/contrib/ci/deps.sh @@ -47,6 +47,7 @@ if [[ "$DISTRO_BRANCH" == -redhat-* ]]; then krb5-server krb5-workstation libunistring-devel + libcap-devel ) if [[ "$DISTRO_BRANCH" == -redhat-fedora-31* || @@ -183,6 +184,7 @@ if [[ "$DISTRO_BRANCH" == -debian-* ]]; then libp11-kit-dev bc libunistring-dev + libcap-dev ) DEPS_INTGCHECK_SATISFIED=true diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index 99b835653a7..024deb02662 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -104,6 +104,7 @@ BuildRequires: gettext-devel # required for p11_child smartcard tests BuildRequires: gnutls-utils BuildRequires: jansson-devel +BuildRequires: libcap-devel BuildRequires: libcurl-devel BuildRequires: libjose-devel BuildRequires: keyutils-libs-devel diff --git a/src/util/become_user.c b/src/util/become_user.c index c3f726d1894..f9ae4ed6209 100644 --- a/src/util/become_user.c +++ b/src/util/become_user.c @@ -210,3 +210,48 @@ errno_t restore_creds(struct sss_creds *saved_creds) saved_creds->num_gids, saved_creds->gids, NULL); } + +errno_t sss_drop_cap(cap_value_t cap) +{ + int ret; + + cap_t caps = cap_get_proc(); + if (caps == NULL) { + ret = errno; + DEBUG(SSSDBG_TRACE_FUNC, "cap_get_proc() failed: %d ('%s')\n", + ret, strerror(ret)); + return ret; + } + if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, 0) == -1) { + ret = errno; + DEBUG(SSSDBG_TRACE_FUNC, + "cap_set_flag(CAP_EFFECTIVE) failed: %d ('%s')\n", + ret, strerror(ret)); + goto done; + } + if (cap_set_flag(caps, CAP_PERMITTED, 1, &cap, 0) == -1) { + ret = errno; + DEBUG(SSSDBG_TRACE_FUNC, + "cap_set_flag(CAP_PERMITTED) failed: %d ('%s')\n", + ret, strerror(ret)); + goto done; + } + if (cap_set_proc(caps) == -1) { + ret = errno; + DEBUG(SSSDBG_TRACE_FUNC, "cap_set_proc() failed: %d ('%s')\n", + ret, strerror(ret)); + goto done; + } + + ret = 0; + +done: + if (cap_free(caps) == -1) { + if (ret == 0) { + ret = errno; + } + DEBUG(SSSDBG_TRACE_FUNC, "cap_free() failed\n"); + } + + return ret; +} diff --git a/src/util/util.h b/src/util/util.h index 76086315f77..a3ef2af55c4 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -751,6 +752,7 @@ errno_t switch_creds(TALLOC_CTX *mem_ctx, int num_gids, gid_t *gids, struct sss_creds **saved_creds); errno_t restore_creds(struct sss_creds *saved_creds); +errno_t sss_drop_cap(cap_value_t cap); /* from sss_semanage.c */ /* Please note that libsemange relies on files and directories created with