summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-07-27 16:16:22 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-07 19:51:12 +0200
commiteadfbd97c9fbf9beb7c6b358e44e0e1e4a5628ae (patch)
tree365ba40b3e5b6fc3bcc8cb8c47a968a3318009cf /src
parent4a2259de5f7366e911a42bebfe8e8582cadf2de9 (diff)
downloadsssd-eadfbd97c9fbf9beb7c6b358e44e0e1e4a5628ae.tar.gz
sssd-eadfbd97c9fbf9beb7c6b358e44e0e1e4a5628ae.tar.xz
sssd-eadfbd97c9fbf9beb7c6b358e44e0e1e4a5628ae.zip
UTIL: Prefer libcap-ng for privilege drop operations
Diffstat (limited to 'src')
-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
4 files changed, 54 insertions, 6 deletions
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;