From eadfbd97c9fbf9beb7c6b358e44e0e1e4a5628ae Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Sun, 27 Jul 2014 16:16:22 +0200 Subject: UTIL: Prefer libcap-ng for privilege drop operations --- src/external/libcapng.m4 | 18 ++++++++++++++++++ src/tests/cwrap/Makefile.am | 2 ++ src/tests/cwrap/test_become_user.c | 8 ++++---- src/util/become_user.c | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/external/libcapng.m4 (limited to 'src') 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 -errno_t become_user(uid_t uid, gid_t gid) +#ifdef HAVE_LIBCAPNG +#include +#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; -- cgit