summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am34
-rw-r--r--configure.ac2
-rw-r--r--src/external/libcapng.m418
-rw-r--r--src/tests/cwrap/Makefile.am2
-rw-r--r--src/tests/cwrap/test_become_user.c8
-rw-r--r--src/util/become_user.c32
6 files changed, 81 insertions, 15 deletions
diff --git a/Makefile.am b/Makefile.am
index 93f67c06b..01f9280ce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -394,6 +394,7 @@ AM_CPPFLAGS = \
$(OPENLDAP_CFLAGS) \
$(GLIB2_CFLAGS) \
$(JOURNALD_CFLAGS) \
+ $(LIBCAPNG_CFLAGS) \
-DLIBDIR=\"$(libdir)\" \
-DVARDIR=\"$(localstatedir)\" \
-DSHLIBEXT=\"$(SHLIBEXT)\" \
@@ -461,7 +462,9 @@ SSSD_LIBS = \
$(DHASH_LIBS) \
$(SSS_CRYPT_LIBS) \
$(OPENLDAP_LIBS) \
- $(TDB_LIBS)
+ $(TDB_LIBS) \
+ $(LIBCAPNG_LIBS) \
+ $(NULL)
PYTHON_BINDINGS_LIBS = \
$(TALLOC_LIBS) \
@@ -730,6 +733,7 @@ libsss_util_la_SOURCES = \
$(NULL)
libsss_util_la_CFLAGS = \
$(AM_CFLAGS) \
+ $(LIBCAPNG_CFLAGS) \
$(SYSTEMD_LOGIN_CFLAGS) \
$(NULL)
libsss_util_la_LIBADD = \
@@ -1319,14 +1323,16 @@ krb5_utils_tests_SOURCES = \
krb5_utils_tests_CFLAGS = \
$(AM_CFLAGS) \
$(KRB5_CFLAGS) \
- $(CHECK_CFLAGS)
+ $(CHECK_CFLAGS) \
+ $(NULL)
krb5_utils_tests_LDADD = \
$(SSSD_LIBS)\
$(CARES_LIBS) \
$(KRB5_LIBS) \
$(CHECK_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
- libsss_test_common.la
+ libsss_test_common.la \
+ $(NULL)
check_and_open_tests_SOURCES = \
@@ -1602,14 +1608,16 @@ krb5_child_test_CFLAGS = \
$(AM_CFLAGS) \
-DKRB5_CHILD_DIR=\"$(builddir)\" \
$(KRB5_CFLAGS) \
- $(CHECK_CFLAGS)
+ $(CHECK_CFLAGS) \
+ $(NULL)
krb5_child_test_LDADD = \
$(SSSD_LIBS) \
$(CARES_LIBS) \
$(KRB5_LIBS) \
$(CHECK_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
- libsss_test_common.la
+ libsss_test_common.la \
+ $(NULL)
if BUILD_DBUS_TESTS
@@ -2279,11 +2287,15 @@ libsss_krb5_common_la_SOURCES = \
src/util/become_user.c \
$(NULL)
libsss_krb5_common_la_CFLAGS = \
- $(KRB5_CFLAGS)
+ $(KRB5_CFLAGS) \
+ $(LIBCAPNG_CFLAGS) \
+ $(NULL)
libsss_krb5_common_la_LIBADD = \
$(KEYUTILS_LIBS) \
$(DHASH_LIBS) \
- $(KRB5_LIBS)
+ $(KRB5_LIBS) \
+ $(LIBCAPNG_LIBS) \
+ $(NULL)
libsss_krb5_common_la_LDFLAGS = \
-avoid-version
@@ -2471,14 +2483,18 @@ krb5_child_SOURCES = \
krb5_child_CFLAGS = \
$(AM_CFLAGS) \
$(POPT_CFLAGS) \
- $(KRB5_CFLAGS)
+ $(KRB5_CFLAGS) \
+ $(LIBCAPNG_CFLAGS) \
+ $(NULL)
krb5_child_LDADD = \
libsss_debug.la \
$(TALLOC_LIBS) \
$(POPT_LIBS) \
$(DHASH_LIBS) \
$(KRB5_LIBS) \
- $(CLIENT_LIBS)
+ $(CLIENT_LIBS) \
+ $(LIBCAPNG_LIBS) \
+ $(NULL)
ldap_child_SOURCES = \
src/providers/ldap/ldap_child.c \
diff --git a/configure.ac b/configure.ac
index 2b0b3f945..f438b5ee8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -173,6 +173,7 @@ m4_include([src/external/sasl.m4])
m4_include([src/external/configlib.m4])
m4_include([src/external/libnfsidmap.m4])
m4_include([src/external/cwrap.m4])
+m4_include([src/external/libcapng.m4])
if test x$build_config_lib = xyes; then
m4_include([src/external/libaugeas.m4])
@@ -282,6 +283,7 @@ if test x$cryptolib = xlibcrypto; then
fi
AM_CHECK_INOTIFY
+AM_CHECK_LIBCAP_NG
AC_CACHE_CHECK([whether compiler supports __attribute__((destructor))],
sss_client_cv_attribute_destructor,
diff --git a/src/external/libcapng.m4 b/src/external/libcapng.m4
new file mode 100644
index 000000000..effe25cb5
--- /dev/null
+++ b/src/external/libcapng.m4
@@ -0,0 +1,18 @@
+dnl A macro to check presence of libcap-ng on the system
+AC_DEFUN([AM_CHECK_LIBCAP_NG],
+[
+ PKG_CHECK_EXISTS(libcap-ng,
+ dnl PKG_CHECK_EXISTS ACTION-IF-FOUND
+ [ PKG_CHECK_MODULES([LIBCAPNG],
+ [libcap-ng],
+ [
+ have_libcap_ng="yes"
+ AC_DEFINE_UNQUOTED([HAVE_LIBCAPNG], 1,
+ [Use libcap-ng for privilege drop])
+ ])
+ ],
+ dnl PKG_CHECK_EXISTS ACTION-IF-NOT-FOUND
+ [AC_MSG_WARN([No libcap-ng library found, falling back to our own privilege drop ipmlementation])]
+ )
+ AM_CONDITIONAL([HAVE_LIBCAPNG], [test x$have_libcap_ng = xyes])
+])
diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am
index 6966c2e65..ec0f3aa04 100644
--- a/src/tests/cwrap/Makefile.am
+++ b/src/tests/cwrap/Makefile.am
@@ -57,6 +57,7 @@ become_user_tests_CFLAGS = \
become_user_tests_LDADD = \
$(POPT_LIBS) \
$(CMOCKA_LIBS) \
+ $(LIBCAPNG_LIBS) \
$(abs_top_builddir)/libsss_debug.la \
libsss_test_common.la \
$(NULL)
@@ -95,6 +96,7 @@ server_tests_LDADD = \
$(CMOCKA_LIBS) \
$(LIBCAPNG_LIBS) \
$(UNICODE_LIBS) \
+ $(LIBCAPNG_LIBS) \
$(SSSD_LIBS) \
$(abs_top_builddir)/libsss_debug.la \
$(abs_top_builddir)/libsss_crypt.la \
diff --git a/src/tests/cwrap/test_become_user.c b/src/tests/cwrap/test_become_user.c
index 06d3ad425..f3898e52c 100644
--- a/src/tests/cwrap/test_become_user.c
+++ b/src/tests/cwrap/test_become_user.c
@@ -27,7 +27,7 @@
#include "util/util.h"
#include "tests/cmocka/common_mock.h"
-void test_become_user(void **state)
+void test_become_user_int(void **state)
{
struct passwd *sssd;
errno_t ret;
@@ -43,7 +43,7 @@ void test_become_user(void **state)
pid = fork();
if (pid == 0) {
/* Change the UID in a child */
- ret = become_user(sssd->pw_uid, sssd->pw_gid);
+ ret = become_user_int(sssd->pw_uid, sssd->pw_gid);
assert_int_equal(ret, EOK);
/* Make sure we have the requested UID and GID now and there
@@ -55,7 +55,7 @@ void test_become_user(void **state)
assert_int_equal(getgid(), sssd->pw_gid);
/* Another become_user is a no-op */
- ret = become_user(sssd->pw_uid, sssd->pw_gid);
+ ret = become_user_int(sssd->pw_uid, sssd->pw_gid);
assert_int_equal(ret, EOK);
assert_int_equal(getgroups(0, NULL), 0);
@@ -127,7 +127,7 @@ int main(int argc, const char *argv[])
};
const UnitTest tests[] = {
- unit_test(test_become_user),
+ unit_test(test_become_user_int),
unit_test(test_switch_user),
};
diff --git a/src/util/become_user.c b/src/util/become_user.c
index b5f94f993..c8a0c77ee 100644
--- a/src/util/become_user.c
+++ b/src/util/become_user.c
@@ -25,7 +25,11 @@
#include "util/util.h"
#include <grp.h>
-errno_t become_user(uid_t uid, gid_t gid)
+#ifdef HAVE_LIBCAPNG
+#include <cap-ng.h>
+#endif
+
+static errno_t become_user_int(uid_t uid, gid_t gid)
{
uid_t cuid;
int ret;
@@ -40,7 +44,7 @@ errno_t become_user(uid_t uid, gid_t gid)
return EOK;
}
- /* drop supplmentary groups first */
+ /* drop supplementary groups first */
ret = setgroups(0, NULL);
if (ret == -1) {
ret = errno;
@@ -71,6 +75,30 @@ errno_t become_user(uid_t uid, gid_t gid)
return EOK;
}
+#ifdef HAVE_LIBCAPNG
+static errno_t become_user_libcap(uid_t uid, gid_t gid)
+{
+ int ret;
+
+ capng_clear(0);
+ ret = capng_change_id(uid, gid, CAPNG_DROP_SUPP_GRP);
+ if (ret != 0) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Cannot change UID: %d errno: %d\n", ret, errno);
+ }
+
+ return ret;
+}
+#endif
+
+errno_t become_user(uid_t uid, gid_t gid)
+{
+#ifdef HAVE_LIBCAPNG
+ return become_user_libcap(uid, gid);
+#endif
+
+ return become_user_int(uid, gid);
+}
+
struct sss_creds {
uid_t uid;
gid_t gid;