]> xenbits.xensource.com Git - libvirt.git/commitdiff
Explicitly track static declared vs dynamically generated security labels
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 3 Mar 2009 16:53:13 +0000 (16:53 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 3 Mar 2009 16:53:13 +0000 (16:53 +0000)
ChangeLog
src/domain_conf.c
src/domain_conf.h
src/qemu_driver.c

index c295a61a62ebc4992d6b085ae191cc40ad30b501..da7f5b6f95fa90ef4582f23b68cf18fca31c03ed 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Tue Mar  3 16:43:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
+
+       Explicitly track static declared vs dynamically generated
+       security labels for VMs
+       * src/domain_conf.c, src/domain_conf.h: Add type='static|dynamic'
+       for <seclabel> to determine whether to auto-generate labels
+       * src/qemu_driver.c: Only generate security labels for type=dynamic
+
 Tue Mar  3 14:58:13 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
 
        Misc sVirt bug fixes
index 43c51eb25e807b84491a45a5ad958fb744e7794f..5bf34837f4bd22aa5d71a8e7fbe465f2bd3d5386 100644 (file)
@@ -168,6 +168,10 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1,
               "shutoff",
               "crashed")
 
+VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST,
+              "dynamic",
+              "static")
+
 #define virDomainReportError(conn, code, fmt...)                           \
         virReportErrorHelper(conn, VIR_FROM_DOMAIN, code, __FILE__,        \
                                __FUNCTION__, __LINE__, fmt)
@@ -1847,24 +1851,49 @@ static int virDomainLifecycleParseXML(virConnectPtr conn,
 static int
 virSecurityLabelDefParseXML(virConnectPtr conn,
                             const virDomainDefPtr def,
-                            xmlXPathContextPtr ctxt)
+                            xmlXPathContextPtr ctxt,
+                            int flags)
 {
     char *p;
 
     if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
         return 0;
 
-    p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
+    p = virXPathStringLimit(conn, "string(./seclabel/@type)",
                             VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
     if (p == NULL)
         goto error;
-    def->seclabel.label = p;
-
-    p = virXPathStringLimit(conn, "string(./seclabel/@model)",
-                            VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
-    if (p == NULL)
+    if ((def->seclabel.type = virDomainSeclabelTypeFromString(p)) < 0)
         goto error;
-    def->seclabel.model = p;
+    VIR_FREE(p);
+
+    /* Only parse details, if using static labels, or
+     * if the 'live' VM XML is requested
+     */
+    if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
+        !(flags & VIR_DOMAIN_XML_INACTIVE)) {
+        p = virXPathStringLimit(conn, "string(./seclabel/@model)",
+                                VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+        if (p == NULL)
+            goto error;
+        def->seclabel.model = p;
+
+        p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
+                                VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
+        if (p == NULL)
+            goto error;
+        def->seclabel.label = p;
+    }
+
+    /* Only parse imagelabel, if requested live XML for dynamic label */
+    if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
+        !(flags & VIR_DOMAIN_XML_INACTIVE)) {
+        p = virXPathStringLimit(conn, "string(./seclabel/imagelabel[1])",
+                                VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
+        if (p == NULL)
+            goto error;
+        def->seclabel.imagelabel = p;
+    }
 
     return 0;
 
@@ -2458,7 +2487,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
     VIR_FREE(nodes);
 
     /* analysis of security label */
-    if (virSecurityLabelDefParseXML(conn, def, ctxt) == -1)
+    if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1)
         goto error;
 
     return def;
@@ -3480,9 +3509,25 @@ char *virDomainDefFormat(virConnectPtr conn,
     virBufferAddLit(&buf, "  </devices>\n");
 
     if (def->seclabel.model) {
-        virBufferEscapeString(&buf, "  <seclabel model='%s'>\n", def->seclabel.model);
-        virBufferEscapeString(&buf, "    <label>%s</label>\n", def->seclabel.label);
-        virBufferAddLit(&buf, "  </seclabel>\n");
+        const char *sectype = virDomainSeclabelTypeToString(def->seclabel.type);
+        if (!sectype)
+            goto cleanup;
+        if (!def->seclabel.label ||
+            (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
+             (flags & VIR_DOMAIN_XML_INACTIVE))) {
+            virBufferVSprintf(&buf, "  <seclabel type='%s' model='%s'/>\n",
+                              sectype, def->seclabel.model);
+        } else {
+            virBufferVSprintf(&buf, "  <seclabel type='%s' model='%s'>\n",
+                                  sectype, def->seclabel.model);
+            virBufferEscapeString(&buf, "    <label>%s</label>\n",
+                                  def->seclabel.label);
+            if (def->seclabel.imagelabel &&
+                def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC)
+                virBufferEscapeString(&buf, "    <imagelabel>%s</imagelabel>\n",
+                                      def->seclabel.imagelabel);
+            virBufferAddLit(&buf, "  </seclabel>\n");
+        }
     }
 
     virBufferAddLit(&buf, "</domain>\n");
index fe83e0b19a020b0bb4a46b191edcc288a5d07b35..dd614678c6590c6810ecb26afbdee3e231d6e8e6 100644 (file)
@@ -410,6 +410,13 @@ struct _virDomainOSDef {
     char *bootloaderArgs;
 };
 
+enum virDomainSeclabelType {
+    VIR_DOMAIN_SECLABEL_DYNAMIC,
+    VIR_DOMAIN_SECLABEL_STATIC,
+
+    VIR_DOMAIN_SECLABEL_LAST,
+};
+
 /* Security configuration for domain */
 typedef struct _virSecurityLabelDef virSecurityLabelDef;
 typedef virSecurityLabelDef *virSecurityLabelDefPtr;
@@ -417,6 +424,7 @@ struct _virSecurityLabelDef {
     char *model;        /* name of security model */
     char *label;        /* security label string */
     char *imagelabel;   /* security image label string */
+    int type;
 };
 
 #define VIR_DOMAIN_CPUMASK_LEN 1024
@@ -650,5 +658,6 @@ VIR_ENUM_DECL(virDomainInputBus)
 VIR_ENUM_DECL(virDomainGraphics)
 /* from libvirt.h */
 VIR_ENUM_DECL(virDomainState)
+VIR_ENUM_DECL(virDomainSeclabel)
 
 #endif /* __DOMAIN_CONF_H */
index bb52db48b59fc7e64c86058e3f8b80e380c9bf85..e73bd3aaccb15b3227611da1f790edaf26a338c6 100644 (file)
@@ -1314,9 +1314,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
     hookData.vm = vm;
     hookData.driver = driver;
 
-   /* If you are using a SecurityDriver and there was no security label in
-      database, then generate a security label for isolation */
-    if (vm->def->seclabel.label == NULL &&
+   /* If you are using a SecurityDriver with dynamic labelling,
+      then generate a security label for isolation */
+    if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
         driver->securityDriver &&
         driver->securityDriver->domainGenSecurityLabel &&
         driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0)
@@ -1525,6 +1525,13 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
     if (driver->securityDriver)
         driver->securityDriver->domainRestoreSecurityLabel(conn, vm);
 
+    /* Clear out dynamically assigned labels */
+    if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
+        VIR_FREE(vm->def->seclabel.model);
+        VIR_FREE(vm->def->seclabel.label);
+        VIR_FREE(vm->def->seclabel.imagelabel);
+    }
+
     if (qemudRemoveDomainStatus(conn, driver, vm) < 0) {
         VIR_WARN(_("Failed to remove domain status for %s"),
                  vm->def->name);