nspawn: rework how we determine private networking settings
authorLennart Poettering <lennart@poettering.net>
Wed, 21 Oct 2015 22:59:18 +0000 (00:59 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 21 Oct 2015 23:59:25 +0000 (01:59 +0200)
Make sure we acquire CAP_NET_ADMIN if we require virtual networking.

Make sure we imply virtual ethernet correctly when bridge is request.

Fixes: #1511
Fixes: #1554
Fixes: #1590

src/nspawn/nspawn-settings.c
src/nspawn/nspawn-settings.h
src/nspawn/nspawn.c

index b920391..f088884 100644 (file)
@@ -85,6 +85,26 @@ Settings* settings_free(Settings *s) {
         return NULL;
 }
 
+bool settings_private_network(Settings *s) {
+        assert(s);
+
+        return
+                s->private_network > 0 ||
+                s->network_veth > 0 ||
+                s->network_bridge ||
+                s->network_interfaces ||
+                s->network_macvlan ||
+                s->network_ipvlan;
+}
+
+bool settings_network_veth(Settings *s) {
+        assert(s);
+
+        return
+                s->network_veth > 0 ||
+                s->network_bridge;
+}
+
 DEFINE_CONFIG_PARSE_ENUM(config_parse_volatile_mode, volatile_mode, VolatileMode, "Failed to parse volatile mode");
 
 int config_parse_expose_port(
index 4cec40c..16e8c54 100644 (file)
@@ -75,6 +75,9 @@ typedef struct Settings {
 int settings_load(FILE *f, const char *path, Settings **ret);
 Settings* settings_free(Settings *s);
 
+bool settings_network_veth(Settings *s);
+bool settings_private_network(Settings *s);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(Settings*, settings_free);
 
 const struct ConfigPerfItem* nspawn_gperf_lookup(const char *key, unsigned length);
index ef042d5..4093f58 100644 (file)
@@ -2912,11 +2912,17 @@ static int load_settings(void) {
         }
 
         if ((arg_settings_mask & SETTING_CAPABILITY) == 0) {
+                uint64_t plus;
 
-                if (!arg_settings_trusted && settings->capability != 0)
-                        log_warning("Ignoring Capability= setting, file %s is not trusted.", p);
-                else
-                        arg_retain |= settings->capability;
+                plus = settings->capability;
+                if (settings_private_network(settings))
+                        plus |= (1ULL << CAP_NET_ADMIN);
+
+                if (!arg_settings_trusted && plus != 0) {
+                        if (settings->capability != 0)
+                                log_warning("Ignoring Capability= setting, file %s is not trusted.", p);
+                } else
+                        arg_retain |= plus;
 
                 arg_retain &= ~settings->drop_capability;
         }
@@ -2972,6 +2978,9 @@ static int load_settings(void) {
                 if (!arg_settings_trusted)
                         log_warning("Ignoring network settings, file %s is not trusted.", p);
                 else {
+                        arg_network_veth = settings_private_network(settings);
+                        arg_private_network = settings_private_network(settings);
+
                         strv_free(arg_network_interfaces);
                         arg_network_interfaces = settings->network_interfaces;
                         settings->network_interfaces = NULL;
@@ -2987,10 +2996,6 @@ static int load_settings(void) {
                         free(arg_network_bridge);
                         arg_network_bridge = settings->network_bridge;
                         settings->network_bridge = NULL;
-
-                        arg_network_veth = settings->network_veth > 0 || settings->network_bridge;
-
-                        arg_private_network = true; /* all these settings imply private networking */
                 }
         }