]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Support for multiple default security drivers in QEMU config
authorMarcelo Cerri <mhcerri@linux.vnet.ibm.com>
Wed, 15 Aug 2012 22:10:38 +0000 (19:10 -0300)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 20 Aug 2012 17:14:30 +0000 (19:14 +0200)
This patch updates the key "security_driver" in QEMU config to suport
both a sigle default driver or a list of default drivers. This ensures
that it will remain compatible with older versions of the config file.

Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
src/qemu/qemu.conf
src/qemu/qemu_conf.c
src/qemu/qemu_conf.h
src/qemu/qemu_driver.c

index ed4683cedd55d499352612a32e47a1cdd66496b0..257a477cccbc4baadde9b38fd535ff883f2ecdda 100644 (file)
 # on the host, then the security driver will automatically disable
 # itself. If you wish to disable QEMU SELinux security driver while
 # leaving SELinux enabled for the host in general, then set this
-# to 'none' instead.
+# to 'none' instead. It's also possible to use more than one security
+# driver at the same time, for this use a list of names separated by
+# comma and delimited by square brackets. For example:
+#
+#       security_driver = [ "selinux", "dac" ]
 #
 #security_driver = "selinux"
 
index b7db277fce3410d07b09f2597d5c35ad83769daf..ed6d8326db300e50bc12931a3869d4e047e11f65 100644 (file)
@@ -193,13 +193,45 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
     }
 
     p = virConfGetValue (conf, "security_driver");
-    CHECK_TYPE ("security_driver", VIR_CONF_STRING);
-    if (p && p->str) {
-        if (!(driver->securityDriverName = strdup(p->str))) {
+    if (p && p->type == VIR_CONF_LIST) {
+        size_t len;
+        virConfValuePtr pp;
+
+        /* Calc lenght and check items */
+        for (len = 0, pp = p->list; pp; len++, pp = pp->next) {
+            if (pp->type != VIR_CONF_STRING) {
+                VIR_ERROR(_("security_driver be a list of strings"));
+                virConfFree(conf);
+                return -1;
+            }
+        }
+
+        if (VIR_ALLOC_N(driver->securityDriverNames, len + 1) < 0) {
             virReportOOMError();
             virConfFree(conf);
             return -1;
         }
+
+        for (i = 0, pp = p->list; pp; i++, pp = pp->next) {
+            driver->securityDriverNames[i] = strdup(pp->str);
+            if (driver->securityDriverNames == NULL) {
+                virReportOOMError();
+                virConfFree(conf);
+                return -1;
+            }
+        }
+        driver->securityDriverNames[len] = NULL;
+    } else {
+        CHECK_TYPE ("security_driver", VIR_CONF_STRING);
+        if (p && p->str) {
+            if (VIR_ALLOC_N(driver->securityDriverNames, 2) < 0 ||
+                !(driver->securityDriverNames[0] = strdup(p->str))) {
+                virReportOOMError();
+                virConfFree(conf);
+                return -1;
+            }
+            driver->securityDriverNames[1] = NULL;
+        }
     }
 
     p = virConfGetValue (conf, "security_default_confined");
index 92e4968fe3c2c64b9f0bd0a0aed1aed7f6ca7920..8a5147198392504a2277c50147c17dd2b1f04f89 100644 (file)
@@ -116,7 +116,7 @@ struct qemud_driver {
 
     virDomainEventStatePtr domainEventState;
 
-    char *securityDriverName;
+    char **securityDriverNames;
     bool securityDefaultConfined;
     bool securityRequireConfined;
     virSecurityManagerPtr securityManager;
index 9f1d70b0ddf392334ff01fc928bb6ae5fda0be17..116d447cb8af0a2334d564ee99f72d78a3950e95 100644 (file)
@@ -248,36 +248,91 @@ qemuAutostartDomains(struct qemud_driver *driver)
 static int
 qemuSecurityInit(struct qemud_driver *driver)
 {
-    virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
-                                                      QEMU_DRIVER_NAME,
-                                                      driver->allowDiskFormatProbing,
-                                                      driver->securityDefaultConfined,
-                                                      driver->securityRequireConfined);
+    char **names;
+    char *primary;
+    virSecurityManagerPtr mgr, nested, stack = NULL;
 
+    if (driver->securityDriverNames == NULL)
+        primary = NULL;
+    else
+        primary = driver->securityDriverNames[0];
+
+    /* Create primary driver */
+    mgr = virSecurityManagerNew(primary,
+                                QEMU_DRIVER_NAME,
+                                driver->allowDiskFormatProbing,
+                                driver->securityDefaultConfined,
+                                driver->securityRequireConfined);
     if (!mgr)
         goto error;
 
-    if (driver->privileged) {
-        virSecurityManagerPtr dac = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
-                                                             driver->user,
-                                                             driver->group,
-                                                             driver->allowDiskFormatProbing,
-                                                             driver->securityDefaultConfined,
-                                                             driver->securityRequireConfined,
-                                                             driver->dynamicOwnership);
-        if (!dac)
+    /* If a DAC driver is required or additional drivers are provived, a stack
+     * driver should be create to group them all */
+    if (driver->privileged ||
+        (driver->securityDriverNames && driver->securityDriverNames[1])) {
+        stack = virSecurityManagerNewStack(mgr);
+        if (!stack)
             goto error;
+        mgr = stack;
+    }
+
+    /* Loop through additional driver names and add a secudary driver to each
+     * one */
+    if (driver->securityDriverNames) {
+        names = driver->securityDriverNames + 1;
+        while (names && *names) {
+            if (STREQ("dac", *names)) {
+                /* A DAC driver has specific parameters */
+                nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
+                                                  driver->user,
+                                                  driver->group,
+                                                  driver->allowDiskFormatProbing,
+                                                  driver->securityDefaultConfined,
+                                                  driver->securityRequireConfined,
+                                                  driver->dynamicOwnership);
+            } else {
+                nested = virSecurityManagerNew(*names,
+                                               QEMU_DRIVER_NAME,
+                                               driver->allowDiskFormatProbing,
+                                               driver->securityDefaultConfined,
+                                               driver->securityRequireConfined);
+            }
+            if (nested == NULL)
+                goto error;
+            if (virSecurityManagerStackAddNested(stack, nested))
+                goto error;
+            names++;
+        }
+    }
 
-        if (!(driver->securityManager = virSecurityManagerNewStack(mgr)) ||
-            !(virSecurityManagerStackAddNested(mgr, dac))) {
-
-            virSecurityManagerFree(dac);
-            goto error;
+    if (driver->privileged) {
+        /* When a DAC driver is required, check if there is already one in the
+         * additional drivers */
+        names = driver->securityDriverNames;
+        while (names && *names) {
+            if (STREQ("dac", *names)) {
+               break;
+            }
+            names++;
+        }
+        /* If there is no DAC driver, create a new one and add it to the stack
+         * manager */
+        if (names == NULL || *names == NULL) {
+            nested = virSecurityManagerNewDAC(QEMU_DRIVER_NAME,
+                                              driver->user,
+                                              driver->group,
+                                              driver->allowDiskFormatProbing,
+                                              driver->securityDefaultConfined,
+                                              driver->securityRequireConfined,
+                                              driver->dynamicOwnership);
+            if (nested == NULL)
+                goto error;
+            if (virSecurityManagerStackAddNested(stack, nested))
+                goto error;
         }
-    } else {
-        driver->securityManager = mgr;
     }
 
+    driver->securityManager = mgr;
     return 0;
 
 error: