test-util: add test_is_capable() to check for capabilities and use it
authorDjalal Harouni <tixxdz@opendz.org>
Tue, 14 Oct 2014 13:22:57 +0000 (14:22 +0100)
committerDjalal Harouni <tixxdz@opendz.org>
Tue, 14 Oct 2014 19:50:32 +0000 (20:50 +0100)
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
test/kdbus-util.c
test/kdbus-util.h
test/test-metadata-ns.c
test/test-policy-priv.c

index 2993b56cc434d590eb602a45f93d5f1cd39c2b05..90e9e47e4c6e65f1f2e6fb450e1eba1b650df2e3 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <stdio.h>
+#include <stdarg.h>
 #include <string.h>
 #include <time.h>
 #include <fcntl.h>
@@ -22,6 +23,7 @@
 #include <assert.h>
 #include <poll.h>
 #include <grp.h>
+#include <sys/capability.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -1099,3 +1101,57 @@ int userns_map_uid_gid(pid_t pid,
 
        return do_userns_map_id(pid, file_id, map_gid);
 }
+
+static int do_cap_get_flag(cap_t caps, cap_value_t cap)
+{
+       int ret;
+       cap_flag_value_t flag_set;
+
+       ret = cap_get_flag(caps, cap, CAP_EFFECTIVE, &flag_set);
+       if (ret < 0) {
+               ret = -errno;
+               kdbus_printf("error cap_get_flag(): %d (%m)\n", ret);
+               return ret;
+       }
+
+       return (flag_set == CAP_SET);
+}
+
+/*
+ * Returns:
+ *  1 in case all the requested effective capabilities are set.
+ *  0 in case we do not have the requested capabilities. This value
+ *    will be used to abort tests with TEST_SKIP
+ *  Negative errno on failure.
+ *
+ *  Terminate args with a negative value.
+ */
+int test_is_capable(int cap, ...)
+{
+       int ret;
+       va_list ap;
+       cap_t caps;
+
+       caps = cap_get_proc();
+       if (!cap) {
+               ret = -errno;
+               kdbus_printf("error cap_get_proc(): %d (%m)\n", ret);
+               return ret;
+       }
+
+       ret = do_cap_get_flag(caps, (cap_value_t)cap);
+       if (ret <= 0)
+               goto out;
+
+       va_start(ap, cap);
+       while ((cap = va_arg(ap, int)) > 0) {
+               ret = do_cap_get_flag(caps, (cap_value_t)cap);
+               if (ret <= 0)
+                       break;
+       }
+       va_end(ap);
+
+out:
+       cap_free(caps);
+       return ret;
+}
index 9e48e72d2d8d2881f3b2d97eec8ac68ae0bc8239..962620bb82826bc4a4a1e776398f26e7d0725d7a 100644 (file)
@@ -136,3 +136,4 @@ int drop_privileges(uid_t uid, gid_t gid);
 int userns_map_uid_gid(pid_t pid,
                       const char *map_uid,
                       const char *map_gid);
+int test_is_capable(int cap, ...);
index 91de6c91934ae8a39f3f6d8e59409897770e967b..2c165a538edff03d7105898e51907364ad10b936 100644 (file)
@@ -194,8 +194,6 @@ int kdbus_test_metadata_ns(struct kdbus_test_env *env)
 {
        int ret;
        struct kdbus_conn *holder, *conn;
-       cap_t cap;
-       cap_flag_value_t flag_setuid, flag_setgid, flag_sys_admin;
        struct kdbus_policy_access policy_access = {
                /* Allow world so we can inspect metadata in namespace */
                .type = KDBUS_POLICY_ACCESS_WORLD,
@@ -207,19 +205,11 @@ int kdbus_test_metadata_ns(struct kdbus_test_env *env)
        if (access("/proc/self/uid_map", F_OK) != 0)
                return TEST_SKIP;
 
-       cap = cap_get_proc();
-       ASSERT_RETURN(cap);
-
-       ret = cap_get_flag(cap, CAP_SETUID, CAP_EFFECTIVE, &flag_setuid);
-       ASSERT_RETURN(ret >= 0);
-       ret = cap_get_flag(cap, CAP_SETGID, CAP_EFFECTIVE, &flag_setgid);
-       ASSERT_RETURN(ret >= 0);
-       ret = cap_get_flag(cap, CAP_SYS_ADMIN, CAP_EFFECTIVE, &flag_sys_admin);
+       ret = test_is_capable(CAP_SETUID, CAP_SETGID, CAP_SYS_ADMIN, -1);
        ASSERT_RETURN(ret >= 0);
 
        /* no enough privileges, SKIP test */
-       if (flag_setuid != CAP_SET || flag_setgid != CAP_SET ||
-           flag_sys_admin != CAP_SET)
+       if (!ret)
                return TEST_SKIP;
 
        holder = kdbus_hello_registrar(env->buspath, "com.example.metadata",
index cf73f72909997300824c4b95ef61b2f152712e94..3463792c0f58d3c9d058401af140b9bd3268acf5 100644 (file)
@@ -600,25 +600,18 @@ static int test_policy_priv(struct kdbus_test_env *env)
 {
        struct kdbus_conn *conn_a, *conn_b, *conn, *owner;
        struct kdbus_policy_access access, *acc;
-       cap_flag_value_t flag_setuid, flag_setgid;
        sigset_t sset;
        size_t num;
-       cap_t cap;
        int ret;
 
        /*
         * Make sure we have CAP_SETUID/SETGID so we can drop privileges
         */
 
-       cap = cap_get_proc();
-       ASSERT_RETURN(cap);
-
-       ret = cap_get_flag(cap, CAP_SETUID, CAP_EFFECTIVE, &flag_setuid);
-       ASSERT_RETURN(ret >= 0);
-       ret = cap_get_flag(cap, CAP_SETGID, CAP_EFFECTIVE, &flag_setgid);
+       ret = test_is_capable(CAP_SETUID, CAP_SETGID, -1);
        ASSERT_RETURN(ret >= 0);
 
-       if (flag_setuid != CAP_SET || flag_setgid != CAP_SET)
+       if (!ret)
                return TEST_SKIP;
 
        /*