/src/systemd/src/shared/securebits-util.c
Line | Count | Source |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #include "alloc-util.h" |
4 | | #include "extract-word.h" |
5 | | #include "securebits-util.h" |
6 | | #include "string-util.h" |
7 | | #include "strv.h" |
8 | | |
9 | 0 | static inline const char* secure_bit_to_string(int i) { |
10 | | /* match a single bit */ |
11 | |
|
12 | 0 | switch (i) { |
13 | 0 | case SECURE_KEEP_CAPS: |
14 | 0 | return "keep-caps"; |
15 | 0 | case SECURE_KEEP_CAPS_LOCKED: |
16 | 0 | return "keep-caps-locked"; |
17 | 0 | case SECURE_NO_SETUID_FIXUP: |
18 | 0 | return "no-setuid-fixup"; |
19 | 0 | case SECURE_NO_SETUID_FIXUP_LOCKED: |
20 | 0 | return "no-setuid-fixup-locked"; |
21 | 0 | case SECURE_NOROOT: |
22 | 0 | return "noroot"; |
23 | 0 | case SECURE_NOROOT_LOCKED: |
24 | 0 | return "noroot-locked"; |
25 | 0 | default: |
26 | 0 | assert_not_reached(); |
27 | 0 | } |
28 | 0 | } |
29 | | |
30 | 0 | int secure_bits_to_string_alloc(int i, char **ret) { |
31 | 0 | _cleanup_strv_free_ char **sv = NULL; |
32 | 0 | _cleanup_free_ char *joined = NULL; |
33 | 0 | int r; |
34 | |
|
35 | 0 | assert(ret); |
36 | |
|
37 | 0 | r = secure_bits_to_strv(i, &sv); |
38 | 0 | if (r < 0) |
39 | 0 | return r; |
40 | | |
41 | 0 | joined = strv_join(sv, " "); |
42 | 0 | if (!joined) |
43 | 0 | return -ENOMEM; |
44 | | |
45 | 0 | *ret = TAKE_PTR(joined); |
46 | 0 | return 0; |
47 | 0 | } |
48 | | |
49 | 0 | int secure_bits_to_strv(int i, char ***ret) { |
50 | 0 | _cleanup_strv_free_ char **sv = NULL; |
51 | 0 | static const int bits[] = { |
52 | 0 | SECURE_KEEP_CAPS, |
53 | 0 | SECURE_KEEP_CAPS_LOCKED, |
54 | 0 | SECURE_NO_SETUID_FIXUP, |
55 | 0 | SECURE_NO_SETUID_FIXUP_LOCKED, |
56 | 0 | SECURE_NOROOT, |
57 | 0 | SECURE_NOROOT_LOCKED, |
58 | 0 | }; |
59 | 0 | int r; |
60 | |
|
61 | 0 | assert(ret); |
62 | |
|
63 | 0 | FOREACH_ELEMENT(bit, bits) { |
64 | 0 | if (i & (1 << *bit)) { |
65 | 0 | r = strv_extend(&sv, secure_bit_to_string(*bit)); |
66 | 0 | if (r < 0) |
67 | 0 | return r; |
68 | 0 | } |
69 | 0 | } |
70 | | |
71 | 0 | *ret = TAKE_PTR(sv); |
72 | 0 | return 0; |
73 | 0 | } |
74 | | |
75 | 1.24k | int secure_bits_from_string(const char *s) { |
76 | 1.24k | int secure_bits = 0; |
77 | 1.24k | const char *p; |
78 | 1.24k | int r; |
79 | | |
80 | 4.28k | for (p = s;;) { |
81 | 4.28k | _cleanup_free_ char *word = NULL; |
82 | | |
83 | 4.28k | r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE); |
84 | 4.28k | if (r == -ENOMEM) |
85 | 0 | return r; |
86 | 4.28k | if (r <= 0) |
87 | 1.24k | break; |
88 | | |
89 | 3.04k | if (streq(word, "keep-caps")) |
90 | 199 | secure_bits |= 1 << SECURE_KEEP_CAPS; |
91 | 2.84k | else if (streq(word, "keep-caps-locked")) |
92 | 256 | secure_bits |= 1 << SECURE_KEEP_CAPS_LOCKED; |
93 | 2.59k | else if (streq(word, "no-setuid-fixup")) |
94 | 204 | secure_bits |= 1 << SECURE_NO_SETUID_FIXUP; |
95 | 2.38k | else if (streq(word, "no-setuid-fixup-locked")) |
96 | 195 | secure_bits |= 1 << SECURE_NO_SETUID_FIXUP_LOCKED; |
97 | 2.19k | else if (streq(word, "noroot")) |
98 | 194 | secure_bits |= 1 << SECURE_NOROOT; |
99 | 1.99k | else if (streq(word, "noroot-locked")) |
100 | 393 | secure_bits |= 1 << SECURE_NOROOT_LOCKED; |
101 | 3.04k | } |
102 | | |
103 | 1.24k | return secure_bits; |
104 | 1.24k | } |