]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: dump capability list with --capabilities=help
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 20 Nov 2019 17:33:32 +0000 (18:33 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 22 Nov 2019 09:15:46 +0000 (10:15 +0100)
man/systemd-nspawn.xml
src/nspawn/nspawn.c

index 92987ff32ffbd1b9e747b10204d10a47ee2e07b3..55809934f141d1a463f747ccb64aad8f2b7c3614 100644 (file)
         CAP_SETGID, CAP_SETPCAP, CAP_SETUID, CAP_SYS_ADMIN, CAP_SYS_BOOT, CAP_SYS_CHROOT,
         CAP_SYS_NICE, CAP_SYS_PTRACE, CAP_SYS_RESOURCE, CAP_SYS_TTY_CONFIG. Also CAP_NET_ADMIN
         is retained if <option>--private-network</option> is specified.  If the special value
-        <literal>all</literal> is passed, all capabilities are retained.</para></listitem>
+        <literal>all</literal> is passed, all capabilities are retained.</para>
+
+        <para>If the special value of <literal>help</literal> is passed, the program will print known
+        capability names and exit.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <listitem><para>Specify one or more additional capabilities to
         drop for the container. This allows running the container with
         fewer capabilities than the default (see
-        above).</para></listitem>
+        above).</para>
+
+        <para>If the special value of <literal>help</literal> is passed, the program will print known
+        capability names and exit.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 6286a28f1db86032089e3bf1f175d14856c6de14..7f44272a889575518cf318a1dcf2d222c26bdfa5 100644 (file)
@@ -492,6 +492,46 @@ static int detect_unified_cgroup_hierarchy_from_image(const char *directory) {
         return 0;
 }
 
+static int parse_capability_spec(const char *spec, uint64_t *ret_mask) {
+        uint64_t mask = 0;
+        int r;
+
+        for (;;) {
+                _cleanup_free_ char *t = NULL;
+
+                r = extract_first_word(&spec, &t, ",", 0);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse capability %s.", t);
+                if (r == 0)
+                        break;
+
+                if (streq(t, "help")) {
+                        for (int i = 0; i < capability_list_length(); i++) {
+                                const char *name;
+
+                                name = capability_to_name(i);
+                                if (name)
+                                        puts(name);
+                        }
+
+                        return 0; /* quit */
+                }
+
+                if (streq(t, "all"))
+                        mask = (uint64_t) -1;
+                else {
+                        r = capability_from_name(t);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse capability %s.", t);
+
+                        mask |= 1ULL << r;
+                }
+        }
+
+        *ret_mask = mask;
+        return 1; /* continue */
+}
+
 static int parse_share_ns_env(const char *name, unsigned long ns_flag) {
         int r;
 
@@ -695,7 +735,6 @@ static int parse_argv(int argc, char *argv[]) {
         };
 
         int c, r;
-        const char *p;
         uint64_t plus = 0, minus = 0;
         bool mask_all_settings = false, mask_no_settings = false;
 
@@ -937,37 +976,18 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case ARG_CAPABILITY:
                 case ARG_DROP_CAPABILITY: {
-                        p = optarg;
-                        for (;;) {
-                                _cleanup_free_ char *t = NULL;
-
-                                r = extract_first_word(&p, &t, ",", 0);
-                                if (r < 0)
-                                        return log_error_errno(r, "Failed to parse capability %s.", t);
-                                if (r == 0)
-                                        break;
-
-                                if (streq(t, "all")) {
-                                        if (c == ARG_CAPABILITY)
-                                                plus = (uint64_t) -1;
-                                        else
-                                                minus = (uint64_t) -1;
-                                } else {
-                                        r = capability_from_name(t);
-                                        if (r < 0)
-                                                return log_error_errno(r, "Failed to parse capability %s.", t);
-
-                                        if (c == ARG_CAPABILITY)
-                                                plus |= 1ULL << r;
-                                        else
-                                                minus |= 1ULL << r;
-                                }
-                        }
+                        uint64_t m;
+                        r = parse_capability_spec(optarg, &m);
+                        if (r <= 0)
+                                return r;
 
+                        if (c == ARG_CAPABILITY)
+                                plus |= m;
+                        else
+                                minus |= m;
                         arg_settings_mask |= SETTING_CAPABILITY;
                         break;
                 }
-
                 case ARG_NO_NEW_PRIVILEGES:
                         r = parse_boolean(optarg);
                         if (r < 0)