chiark / gitweb /
nspawn: introduce new --capabilities= flag and make use of it in the nspawn test...
authorLennart Poettering <lennart@poettering.net>
Thu, 28 Jun 2012 11:44:39 +0000 (13:44 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 28 Jun 2012 12:05:16 +0000 (14:05 +0200)
man/systemd-nspawn.xml
src/nspawn/nspawn.c
test/TEST-01-BASIC/test.sh

index a926a7e..76e2918 100644 (file)
                                 container.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><option>--capability=</option></term>
+
+                                <listitem><para>List one or more
+                                additional capabilities to grant the
+                                container. Takes a comma separated
+                                list of capability names, see
+                                <citerefentry><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                                for more information. Note that the
+                                the following capabilities will be
+                                granted in any way: CAP_CHOWN,
+                                CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH,
+                                CAP_FOWNER, CAP_FSETID, CAP_IPC_OWNER,
+                                CAP_KILL, CAP_LEASE,
+                                CAP_LINUX_IMMUTABLE,
+                                CAP_NET_BIND_SERVICE,
+                                CAP_NET_BROADCAST, CAP_NET_RAW,
+                                CAP_SETGID, CAP_SETFCAP, CAP_SETPCAP,
+                                CAP_SETUID, CAP_SYS_ADMIN,
+                                CAP_SYS_CHROOT, CAP_SYS_NICE,
+                                CAP_SYS_PTRACE, CAP_SYS_TTY_CONFIG,
+                                CAP_SYS_RESOURCE.</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
 
         </refsect1>
index fec39d6..ffd8fd4 100644 (file)
@@ -60,6 +60,29 @@ static char *arg_uuid = NULL;
 static bool arg_private_network = false;
 static bool arg_read_only = false;
 static bool arg_boot = false;
+static uint64_t arg_retain =
+        (1ULL << CAP_CHOWN) |
+        (1ULL << CAP_DAC_OVERRIDE) |
+        (1ULL << CAP_DAC_READ_SEARCH) |
+        (1ULL << CAP_FOWNER) |
+        (1ULL << CAP_FSETID) |
+        (1ULL << CAP_IPC_OWNER) |
+        (1ULL << CAP_KILL) |
+        (1ULL << CAP_LEASE) |
+        (1ULL << CAP_LINUX_IMMUTABLE) |
+        (1ULL << CAP_NET_BIND_SERVICE) |
+        (1ULL << CAP_NET_BROADCAST) |
+        (1ULL << CAP_NET_RAW) |
+        (1ULL << CAP_SETGID) |
+        (1ULL << CAP_SETFCAP) |
+        (1ULL << CAP_SETPCAP) |
+        (1ULL << CAP_SETUID) |
+        (1ULL << CAP_SYS_ADMIN) |
+        (1ULL << CAP_SYS_CHROOT) |
+        (1ULL << CAP_SYS_NICE) |
+        (1ULL << CAP_SYS_PTRACE) |
+        (1ULL << CAP_SYS_TTY_CONFIG) |
+        (1ULL << CAP_SYS_RESOURCE);
 
 static int help(void) {
 
@@ -72,7 +95,8 @@ static int help(void) {
                "  -C --controllers=LIST Put the container in specified comma-separated cgroup hierarchies\n"
                "     --uuid=UUID        Set a specific machine UUID for the container\n"
                "     --private-network  Disable network in container\n"
-               "     --read-only        Mount the root directory read-only\n",
+               "     --read-only        Mount the root directory read-only\n"
+               "     --capability=CAP   In addition to the default, retain specified capability\n",
                program_invocation_short_name);
 
         return 0;
@@ -83,7 +107,8 @@ static int parse_argv(int argc, char *argv[]) {
         enum {
                 ARG_PRIVATE_NETWORK = 0x100,
                 ARG_UUID,
-                ARG_READ_ONLY
+                ARG_READ_ONLY,
+                ARG_CAPABILITY
         };
 
         static const struct option options[] = {
@@ -95,6 +120,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "boot",            no_argument,       NULL, 'b'                 },
                 { "uuid",            required_argument, NULL, ARG_UUID            },
                 { "read-only",       no_argument,       NULL, ARG_READ_ONLY       },
+                { "capability",      required_argument, NULL, ARG_CAPABILITY      },
                 { NULL,              0,                 NULL, 0                   }
         };
 
@@ -157,6 +183,33 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_read_only = true;
                         break;
 
+                case ARG_CAPABILITY: {
+                        char *state, *word;
+                        size_t length;
+
+                        FOREACH_WORD_SEPARATOR(word, length, optarg, ",", state) {
+                                cap_value_t cap;
+                                char *t;
+
+                                t = strndup(word, length);
+                                if (!t) {
+                                        log_error("Out of memory.");
+                                        return -ENOMEM;
+                                }
+
+                                if (cap_from_name(t, &cap) < 0) {
+                                        log_error("Failed to parse capability %s.", t);
+                                        free(t);
+                                        return -EINVAL;
+                                }
+
+                                free(t);
+                                arg_retain |= 1ULL << (uint64_t) cap;
+                        }
+
+                        break;
+                }
+
                 case '?':
                         return -EINVAL;
 
@@ -544,31 +597,7 @@ static int setup_hostname(void) {
 }
 
 static int drop_capabilities(void) {
-
-        static const uint64_t retain =
-                (1ULL << CAP_CHOWN) |
-                (1ULL << CAP_DAC_OVERRIDE) |
-                (1ULL << CAP_DAC_READ_SEARCH) |
-                (1ULL << CAP_FOWNER) |
-                (1ULL << CAP_FSETID) |
-                (1ULL << CAP_IPC_OWNER) |
-                (1ULL << CAP_KILL) |
-                (1ULL << CAP_LEASE) |
-                (1ULL << CAP_LINUX_IMMUTABLE) |
-                (1ULL << CAP_NET_BIND_SERVICE) |
-                (1ULL << CAP_NET_BROADCAST) |
-                (1ULL << CAP_NET_RAW) |
-                (1ULL << CAP_SETGID) |
-                (1ULL << CAP_SETFCAP) |
-                (1ULL << CAP_SETPCAP) |
-                (1ULL << CAP_SETUID) |
-                (1ULL << CAP_SYS_ADMIN) |
-                (1ULL << CAP_SYS_CHROOT) |
-                (1ULL << CAP_SYS_NICE) |
-                (1ULL << CAP_SYS_PTRACE) |
-                (1ULL << CAP_SYS_TTY_CONFIG);
-
-        return capability_bounding_set_drop(~retain, false);
+        return capability_bounding_set_drop(~arg_retain, false);
 }
 
 static int is_os_tree(const char *path) {
index 06b80c2..8979872 100755 (executable)
@@ -37,7 +37,7 @@ run_qemu() {
 
 
 run_nspawn() {
-    systemd-nspawn -b -D $TESTDIR/nspawn-root /usr/lib/systemd/systemd
+    systemd-nspawn -b -D $TESTDIR/nspawn-root --capability=CAP_AUDIT_CONTROL,CAP_AUDIT_WRITE /usr/lib/systemd/systemd
     ret=1
     [[ -e $TESTDIR/nspawn-root/testok ]] && ret=0
     cp -a $TESTDIR/nspawn-root/var/log/journal $TESTDIR