cap-list: add capability_set_{from_string,to_string_alloc}()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 7 Aug 2017 14:25:11 +0000 (23:25 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 7 Aug 2017 14:25:11 +0000 (23:25 +0900)
src/basic/cap-list.c
src/basic/cap-list.h
src/core/execute.c
src/core/load-fragment.c

index d68cc78..124641f 100644 (file)
 #include <errno.h>
 #include <string.h>
 
+#include "alloc-util.h"
+#include "capability-util.h"
 #include "cap-list.h"
+#include "extract-word.h"
 #include "macro.h"
 #include "missing.h"
 #include "parse-util.h"
@@ -64,3 +67,65 @@ int capability_from_name(const char *name) {
 int capability_list_length(void) {
         return (int) ELEMENTSOF(capability_names);
 }
+
+int capability_set_to_string_alloc(uint64_t set, char **s) {
+        _cleanup_free_ char *str = NULL;
+        unsigned long i;
+        size_t allocated = 0, n = 0;
+
+        assert(s);
+
+        for (i = 0; i < cap_last_cap(); i++)
+                if (set & (UINT64_C(1) << i)) {
+                        const char *p;
+                        size_t add;
+
+                        p = capability_to_name(i);
+                        if (!p)
+                                return -EINVAL;
+
+                        add = strlen(p);
+
+                        if (!GREEDY_REALLOC0(str, allocated, n + add + 2))
+                                return -ENOMEM;
+
+                        strcpy(mempcpy(str + n, p, add), " ");
+                        n += add + 1;
+                }
+
+        if (n != 0)
+                str[n - 1] = '\0';
+
+        *s = str;
+        str = NULL;
+
+        return 0;
+}
+
+int capability_set_from_string(const char *s, uint64_t *set) {
+        uint64_t val = 0;
+        const char *p;
+
+        assert(set);
+
+        for (p = s;;) {
+                _cleanup_free_ char *word = NULL;
+                int r;
+
+                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+                if (r == -ENOMEM)
+                        return r;
+                if (r <= 0)
+                        break;
+
+                r = capability_from_name(word);
+                if (r < 0)
+                        continue;
+
+                val |= ((uint64_t) UINT64_C(1)) << (uint64_t) r;
+        }
+
+        *set = val;
+
+        return 0;
+}
index c1f6b94..f9f6b70 100644 (file)
@@ -22,3 +22,6 @@
 const char *capability_to_name(int id);
 int capability_from_name(const char *name);
 int capability_list_length(void);
+
+int capability_set_to_string_alloc(uint64_t set, char **s);
+int capability_set_from_string(const char *s, uint64_t *set);
index 3b10fa1..ca17942 100644 (file)
@@ -3610,25 +3610,19 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                         (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
 
         if (c->capability_bounding_set != CAP_ALL) {
-                unsigned long l;
-                fprintf(f, "%sCapabilityBoundingSet:", prefix);
+                _cleanup_free_ char *str = NULL;
 
-                for (l = 0; l <= cap_last_cap(); l++)
-                        if (c->capability_bounding_set & (UINT64_C(1) << l))
-                                fprintf(f, " %s", strna(capability_to_name(l)));
-
-                fputs("\n", f);
+                r = capability_set_to_string_alloc(c->capability_bounding_set, &str);
+                if (r >= 0)
+                        fprintf(f, "%sCapabilityBoundingSet: %s\n", prefix, str);
         }
 
         if (c->capability_ambient_set != 0) {
-                unsigned long l;
-                fprintf(f, "%sAmbientCapabilities:", prefix);
+                _cleanup_free_ char *str = NULL;
 
-                for (l = 0; l <= cap_last_cap(); l++)
-                        if (c->capability_ambient_set & (UINT64_C(1) << l))
-                                fprintf(f, " %s", strna(capability_to_name(l)));
-
-                fputs("\n", f);
+                r = capability_set_to_string_alloc(c->capability_ambient_set, &str);
+                if (r >= 0)
+                        fprintf(f, "%sAmbientCapabilities: %s\n", prefix, str);
         }
 
         if (c->user)
index ac94656..63144c4 100644 (file)
@@ -1157,7 +1157,7 @@ int config_parse_capability_set(
         uint64_t *capability_set = data;
         uint64_t sum = 0, initial = 0;
         bool invert = false;
-        const char *p;
+        int r;
 
         assert(filename);
         assert(lvalue);
@@ -1173,28 +1173,12 @@ int config_parse_capability_set(
                 initial = CAP_ALL; /* initialized to all bits on */
         /* else "AmbientCapabilities" initialized to all bits off */
 
-        p = rvalue;
-        for (;;) {
-                _cleanup_free_ char *word = NULL;
-                int cap, r;
-
-                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
-                if (r == 0)
-                        break;
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse word, ignoring: %s", rvalue);
-                        break;
-                }
-
-                cap = capability_from_name(word);
-                if (cap < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability in bounding/ambient set, ignoring: %s", word);
-                        continue;
-                }
-
-                sum |= ((uint64_t) UINT64_C(1)) << (uint64_t) cap;
+        r = capability_set_from_string(rvalue, &sum);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse word: %s", rvalue);
+                return 0;
         }
 
         sum = invert ? ~sum : sum;