From: Lennart Poettering Date: Mon, 20 Feb 2023 10:46:08 +0000 (+0100) Subject: cap-list: add capability_set_to_strv() X-Git-Tag: v254-rc1~1183^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8cf4674d8673f692e548361dc4352e02244862ed;p=thirdparty%2Fsystemd.git cap-list: add capability_set_to_strv() --- diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c index 45a5b371e84..b95b9b140ee 100644 --- a/src/basic/cap-list.c +++ b/src/basic/cap-list.c @@ -11,6 +11,7 @@ #include "parse-util.h" #include "stdio-util.h" #include "string-util.h" +#include "strv.h" static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len); @@ -102,6 +103,30 @@ int capability_set_to_string(uint64_t set, char **ret) { return 0; } +int capability_set_to_strv(uint64_t set, char ***ret) { + _cleanup_strv_free_ char **l = NULL; + int r; + + assert(ret); + + for (unsigned i = 0; i <= cap_last_cap(); i++) { + const char *p; + + if (!FLAGS_SET(set, UINT64_C(1) << i)) + continue; + + p = CAPABILITY_TO_STRING(i); + assert(p); + + r = strv_extend(&l, p); + if (r < 0) + return r; + } + + *ret = TAKE_PTR(l); + return 0; +} + int capability_set_from_string(const char *s, uint64_t *ret) { uint64_t val = 0; bool good = true; diff --git a/src/basic/cap-list.h b/src/basic/cap-list.h index bddadcbae5f..fdf4366de0e 100644 --- a/src/basic/cap-list.h +++ b/src/basic/cap-list.h @@ -16,4 +16,5 @@ int capability_from_name(const char *name); int capability_list_length(void); int capability_set_to_string(uint64_t set, char **ret); +int capability_set_to_strv(uint64_t set, char ***ret); int capability_set_from_string(const char *s, uint64_t *ret); diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c index 8df425bdd29..42503d294c6 100644 --- a/src/test/test-cap-list.c +++ b/src/test/test-cap-list.c @@ -8,6 +8,7 @@ #include "capability-util.h" #include "parse-util.h" #include "string-util.h" +#include "strv.h" #include "tests.h" /* verify the capability parser */ @@ -99,6 +100,23 @@ TEST(capability_set_from_string) { assert_se(c == (UINT64_C(1) << 4) - 1); } +static void test_capability_set_to_strv_one(uint64_t m, char **l) { + _cleanup_strv_free_ char **b = NULL; + + assert_se(capability_set_to_strv(m, &b) >= 0); + assert_se(strv_equal(l, b)); +} + +TEST(capability_set_to_strv) { + test_capability_set_to_strv_one(0, STRV_MAKE(NULL)); + test_capability_set_to_strv_one(UINT64_C(1) << CAP_MKNOD, STRV_MAKE("cap_mknod")); + test_capability_set_to_strv_one((UINT64_C(1) << CAP_MKNOD) | + (UINT64_C(1) << CAP_NET_BIND_SERVICE), STRV_MAKE("cap_net_bind_service", "cap_mknod")); + test_capability_set_to_strv_one((UINT64_C(1) << CAP_MKNOD) | + (UINT64_C(1) << CAP_NET_BIND_SERVICE) | + (UINT64_C(1) << CAP_IPC_OWNER), STRV_MAKE("cap_net_bind_service", "cap_ipc_owner", "cap_mknod")); +} + static void test_capability_set_to_string_invalid(uint64_t invalid_cap_set) { uint64_t c;