/src/systemd/src/basic/cap-list.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | | |
3 | | #include <errno.h> |
4 | | #include <string.h> |
5 | | |
6 | | #include "alloc-util.h" |
7 | | #include "capability-util.h" |
8 | | #include "cap-list.h" |
9 | | #include "extract-word.h" |
10 | | #include "macro.h" |
11 | | #include "missing.h" |
12 | | #include "parse-util.h" |
13 | | #include "util.h" |
14 | | |
15 | | static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len); |
16 | | |
17 | | #include "cap-from-name.h" |
18 | | #include "cap-to-name.h" |
19 | | |
20 | 0 | const char *capability_to_name(int id) { |
21 | 0 |
|
22 | 0 | if (id < 0) |
23 | 0 | return NULL; |
24 | 0 | |
25 | 0 | if ((size_t) id >= ELEMENTSOF(capability_names)) |
26 | 0 | return NULL; |
27 | 0 | |
28 | 0 | return capability_names[id]; |
29 | 0 | } |
30 | | |
31 | 13.0k | int capability_from_name(const char *name) { |
32 | 13.0k | const struct capability_name *sc; |
33 | 13.0k | int r, i; |
34 | 13.0k | |
35 | 13.0k | assert(name); |
36 | 13.0k | |
37 | 13.0k | /* Try to parse numeric capability */ |
38 | 13.0k | r = safe_atoi(name, &i); |
39 | 13.0k | if (r >= 0) { |
40 | 4.70k | if (i >= 0 && (size_t) i < ELEMENTSOF(capability_names)) |
41 | 4.70k | return i; |
42 | 1.07k | else |
43 | 1.07k | return -EINVAL; |
44 | 8.34k | } |
45 | 8.34k | |
46 | 8.34k | /* Try to parse string capability */ |
47 | 8.34k | sc = lookup_capability(name, strlen(name)); |
48 | 8.34k | if (!sc) |
49 | 7.73k | return -EINVAL; |
50 | 611 | |
51 | 611 | return sc->id; |
52 | 611 | } |
53 | | |
54 | 0 | int capability_list_length(void) { |
55 | 0 | return (int) ELEMENTSOF(capability_names); |
56 | 0 | } |
57 | | |
58 | 0 | int capability_set_to_string_alloc(uint64_t set, char **s) { |
59 | 0 | _cleanup_free_ char *str = NULL; |
60 | 0 | unsigned long i; |
61 | 0 | size_t allocated = 0, n = 0; |
62 | 0 |
|
63 | 0 | assert(s); |
64 | 0 |
|
65 | 0 | for (i = 0; i < cap_last_cap(); i++) |
66 | 0 | if (set & (UINT64_C(1) << i)) { |
67 | 0 | const char *p; |
68 | 0 | size_t add; |
69 | 0 |
|
70 | 0 | p = capability_to_name(i); |
71 | 0 | if (!p) |
72 | 0 | return -EINVAL; |
73 | 0 | |
74 | 0 | add = strlen(p); |
75 | 0 |
|
76 | 0 | if (!GREEDY_REALLOC(str, allocated, n + add + 2)) |
77 | 0 | return -ENOMEM; |
78 | 0 | |
79 | 0 | strcpy(mempcpy(str + n, p, add), " "); |
80 | 0 | n += add + 1; |
81 | 0 | } |
82 | 0 |
|
83 | 0 | if (!GREEDY_REALLOC(str, allocated, n + 1)) |
84 | 0 | return -ENOMEM; |
85 | 0 | |
86 | 0 | str[n > 0 ? n - 1 : 0] = '\0'; /* truncate the last space, if it's there */ |
87 | 0 |
|
88 | 0 | *s = TAKE_PTR(str); |
89 | 0 |
|
90 | 0 | return 0; |
91 | 0 | } |
92 | | |
93 | 1.56k | int capability_set_from_string(const char *s, uint64_t *set) { |
94 | 1.56k | uint64_t val = 0; |
95 | 1.56k | const char *p; |
96 | 1.56k | |
97 | 1.56k | assert(set); |
98 | 1.56k | |
99 | 9.01k | for (p = s;;) { |
100 | 9.01k | _cleanup_free_ char *word = NULL; |
101 | 9.01k | int r; |
102 | 9.01k | |
103 | 9.01k | r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); |
104 | 9.01k | if (r == -ENOMEM) |
105 | 9.01k | return r; |
106 | 9.01k | if (r <= 0) |
107 | 1.56k | break; |
108 | 7.45k | |
109 | 7.45k | r = capability_from_name(word); |
110 | 7.45k | if (r < 0) |
111 | 4.94k | continue; |
112 | 2.50k | |
113 | 2.50k | val |= ((uint64_t) UINT64_C(1)) << (uint64_t) r; |
114 | 2.50k | } |
115 | 1.56k | |
116 | 1.56k | *set = val; |
117 | 1.56k | |
118 | 1.56k | return 0; |
119 | 1.56k | } |