Line data Source code
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 243 : const char *capability_to_name(int id) { 21 : 22 243 : if (id < 0) 23 1 : return NULL; 24 : 25 242 : if ((size_t) id >= ELEMENTSOF(capability_names)) 26 1 : return NULL; 27 : 28 241 : return capability_names[id]; 29 : } 30 : 31 128 : int capability_from_name(const char *name) { 32 : const struct capability_name *sc; 33 : int r, i; 34 : 35 128 : assert(name); 36 : 37 : /* Try to parse numeric capability */ 38 128 : r = safe_atoi(name, &i); 39 128 : if (r >= 0) { 40 19 : if (i >= 0 && (size_t) i < ELEMENTSOF(capability_names)) 41 8 : return i; 42 : else 43 11 : return -EINVAL; 44 : } 45 : 46 : /* Try to parse string capability */ 47 109 : sc = lookup_capability(name, strlen(name)); 48 109 : if (!sc) 49 27 : return -EINVAL; 50 : 51 82 : return sc->id; 52 : } 53 : 54 87 : int capability_list_length(void) { 55 87 : return (int) ELEMENTSOF(capability_names); 56 : } 57 : 58 6 : int capability_set_to_string_alloc(uint64_t set, char **s) { 59 6 : _cleanup_free_ char *str = NULL; 60 : unsigned long i; 61 6 : size_t allocated = 0, n = 0; 62 : 63 6 : assert(s); 64 : 65 234 : for (i = 0; i <= cap_last_cap(); i++) 66 228 : if (set & (UINT64_C(1) << i)) { 67 : const char *p; 68 : size_t add; 69 : 70 13 : p = capability_to_name(i); 71 13 : if (!p) 72 0 : return -EINVAL; 73 : 74 13 : add = strlen(p); 75 : 76 13 : if (!GREEDY_REALLOC(str, allocated, n + add + 2)) 77 0 : return -ENOMEM; 78 : 79 13 : strcpy(mempcpy(str + n, p, add), " "); 80 13 : n += add + 1; 81 : } 82 : 83 6 : if (!GREEDY_REALLOC(str, allocated, n + 1)) 84 0 : return -ENOMEM; 85 : 86 6 : str[n > 0 ? n - 1 : 0] = '\0'; /* truncate the last space, if it's there */ 87 : 88 6 : *s = TAKE_PTR(str); 89 : 90 6 : return 0; 91 : } 92 : 93 21 : int capability_set_from_string(const char *s, uint64_t *set) { 94 21 : uint64_t val = 0; 95 : const char *p; 96 : 97 21 : assert(set); 98 : 99 104 : for (p = s;;) { 100 104 : _cleanup_free_ char *word = NULL; 101 : int r; 102 : 103 104 : r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE); 104 104 : if (r == -ENOMEM) 105 0 : return r; 106 104 : if (r <= 0) 107 21 : break; 108 : 109 83 : r = capability_from_name(word); 110 83 : if (r < 0) 111 36 : continue; 112 : 113 47 : val |= ((uint64_t) UINT64_C(1)) << (uint64_t) r; 114 : } 115 : 116 21 : *set = val; 117 : 118 21 : return 0; 119 : }