*/
#include <stdio.h>
+#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#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>
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;
+}
int userns_map_uid_gid(pid_t pid,
const char *map_uid,
const char *map_gid);
+int test_is_capable(int cap, ...);
{
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,
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",
{
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;
/*