]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Update the remote API
authorMarcelo Cerri <mhcerri@linux.vnet.ibm.com>
Wed, 15 Aug 2012 22:10:39 +0000 (19:10 -0300)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 20 Aug 2012 17:14:30 +0000 (19:14 +0200)
This patch updates libvirt's API to allow applications to inspect the
full list of security labels of a domain.

Signed-off-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
daemon/remote.c
include/libvirt/libvirt.h.in
python/generator.py
src/driver.h
src/libvirt.c
src/libvirt_public.syms
src/qemu/qemu_driver.c
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs

index 851bcc1cfa25d3d0f2cdbc53532c5cce825edce2..f82af86bf2d5916ecd7d929d3b1cc458158fc5b4 100644 (file)
@@ -1416,6 +1416,69 @@ cleanup:
     return rv;
 }
 
+static int
+remoteDispatchDomainGetSecurityLabelList(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                         virNetServerClientPtr client ATTRIBUTE_UNUSED,
+                                         virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                         virNetMessageErrorPtr rerr,
+                                         remote_domain_get_security_label_list_args *args,
+                                         remote_domain_get_security_label_list_ret *ret)
+{
+    virDomainPtr dom = NULL;
+    virSecurityLabelPtr seclabels = NULL;
+    int i, len, rv = -1;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
+
+    if (!priv->conn) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+        goto cleanup;
+
+    if ((len = virDomainGetSecurityLabelList(dom, &seclabels)) < 0) {
+        ret->ret = len;
+        ret->labels.labels_len = 0;
+        ret->labels.labels_val = NULL;
+        goto done;
+    }
+
+    if (VIR_ALLOC_N(ret->labels.labels_val, len) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    for (i = 0; i < len; i++) {
+        size_t label_len = strlen(seclabels[i].label) + 1;
+        remote_domain_get_security_label_ret *cur = &ret->labels.labels_val[i];
+        if (VIR_ALLOC_N(cur->label.label_val, label_len) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        if (virStrcpy(cur->label.label_val, seclabels[i].label, label_len) == NULL) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("failed to copy security label"));
+            goto cleanup;
+        }
+        cur->label.label_len = label_len;
+        cur->enforcing = seclabels[i].enforcing;
+    }
+    ret->labels.labels_len = ret->ret = len;
+
+done:
+    rv = 0;
+
+cleanup:
+    if (rv < 0)
+        virNetMessageSaveError(rerr);
+    if (dom)
+        virDomainFree(dom);
+    VIR_FREE(seclabels);
+    return rv;
+}
+
 static int
 remoteDispatchNodeGetSecurityModel(virNetServerPtr server ATTRIBUTE_UNUSED,
                                    virNetServerClientPtr client ATTRIBUTE_UNUSED,
index 91e0a29ee48fd96e36448c4357db63aaee00c749..77a061e1350197b75c6aa22a5b7625e720423ddc 100644 (file)
@@ -1593,6 +1593,8 @@ int                     virDomainGetSecurityLabel (virDomainPtr domain,
                                                    virSecurityLabelPtr seclabel);
 char *                  virDomainGetHostname    (virDomainPtr domain,
                                                  unsigned int flags);
+int                     virDomainGetSecurityLabelList (virDomainPtr domain,
+                                                       virSecurityLabelPtr* seclabels);
 
 typedef enum {
     VIR_DOMAIN_METADATA_DESCRIPTION = 0, /* Operate on <description> */
index 6559ece69aa24ed58ffe1d3652eea3a2638efc7a..1f8719532ddcba77c23cfdb17a6485f2cec24811 100755 (executable)
@@ -448,6 +448,7 @@ skip_function = (
     'virConnectOpenAuth', # Python C code is manually written
     'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
     'virDomainGetSecurityLabel', # Needs investigation...
+    'virDomainGetSecurityLabelList', # Needs investigation...
     'virNodeGetSecurityModel', # Needs investigation...
     'virConnectDomainEventRegister',   # overridden in virConnect.py
     'virConnectDomainEventDeregister', # overridden in virConnect.py
index aab97669fb1f1cc5e7e0d4d74213ba085d6f301f..203497d4f4cf073379950817f6a6e2d698341a62 100644 (file)
@@ -319,6 +319,9 @@ typedef int
 typedef int
         (*virDrvDomainGetSecurityLabel) (virDomainPtr domain,
                                          virSecurityLabelPtr seclabel);
+typedef int
+        (*virDrvDomainGetSecurityLabelList) (virDomainPtr domain,
+                                         virSecurityLabelPtr* seclabels);
 typedef int
         (*virDrvNodeGetSecurityModel)   (virConnectPtr conn,
                                          virSecurityModelPtr secmodel);
@@ -941,6 +944,7 @@ struct _virDriver {
     virDrvDomainGetVcpus                domainGetVcpus;
     virDrvDomainGetMaxVcpus             domainGetMaxVcpus;
     virDrvDomainGetSecurityLabel        domainGetSecurityLabel;
+    virDrvDomainGetSecurityLabelList     domainGetSecurityLabelList;
     virDrvNodeGetSecurityModel          nodeGetSecurityModel;
     virDrvDomainGetXMLDesc              domainGetXMLDesc;
     virDrvConnectDomainXMLFromNative    domainXMLFromNative;
index 893d380c8be8961c3201ffbe39148c0a4993568c..b3fc8a8a2e43fb286934c575844fc0a8f3f29787 100644 (file)
@@ -9020,6 +9020,53 @@ error:
     return -1;
 }
 
+/**
+ * virDomainGetSecurityLabelList:
+ * @domain: a domain object
+ * @seclabels: will be auto-allocated and filled with domains' security labels.
+ * Caller must free memory on return.
+ *
+ * Extract the security labels of an active domain. The 'label' field
+ * in the @seclabels argument will be initialized to the empty
+ * string if the domain is not running under a security model.
+ *
+ * Returns number of elemnets in @seclabels on success, -1 in case of failure.
+ */
+int
+virDomainGetSecurityLabelList(virDomainPtr domain,
+                              virSecurityLabelPtr* seclabels)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "seclabels=%p", seclabels);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    if (seclabels == NULL) {
+        virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+        goto error;
+    }
+
+    conn = domain->conn;
+
+    if (conn->driver->domainGetSecurityLabelList) {
+        int ret;
+        ret = conn->driver->domainGetSecurityLabelList(domain, seclabels);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(domain->conn);
+    return -1;
+}
 /**
  * virDomainSetMetadata:
  * @domain: a domain object
index e3ba119ade708e6ac9cf55dbe7a748fda8221f5c..43f2cf28a9a954285c7b9ae20aabaf5d771b296d 100644 (file)
@@ -549,6 +549,7 @@ LIBVIRT_0.10.0 {
         virDomainGetHostname;
         virConnectRegisterCloseCallback;
         virConnectUnregisterCloseCallback;
+        virDomainGetSecurityLabelList;
 } LIBVIRT_0.9.13;
 
 # .... define new API here using predicted next version number ....
index 116d447cb8af0a2334d564ee99f72d78a3950e95..109d18dbbbe5cf94192d0e3f29a1434e9f9d9aea 100644 (file)
@@ -4119,6 +4119,78 @@ cleanup:
     return ret;
 }
 
+static int qemuDomainGetSecurityLabelList(virDomainPtr dom,
+                                          virSecurityLabelPtr* seclabels)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int i, ret = -1;
+
+    /* Protect domain data with qemu lock */
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        virReportError(VIR_ERR_NO_DOMAIN,
+                       _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    if (!virDomainVirtTypeToString(vm->def->virtType)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unknown virt type in domain definition '%d'"),
+                       vm->def->virtType);
+        goto cleanup;
+    }
+
+    /*
+     * Check the comment in qemudDomainGetSecurityLabel function.
+     */
+    if (!virDomainObjIsActive(vm)) {
+        /* No seclabels */
+        *seclabels = NULL;
+        ret = 0;
+    } else {
+        int len = 0;
+        virSecurityManagerPtr* mgrs = virSecurityManagerGetNested(
+                                            driver->securityManager);
+        if (!mgrs)
+            goto cleanup;
+
+        /* Allocate seclabels array */
+        for (i = 0; mgrs[i]; i++)
+            len++;
+
+        if (VIR_ALLOC_N((*seclabels), len) < 0) {
+            virReportOOMError();
+            VIR_FREE(mgrs);
+            goto cleanup;
+        }
+        memset(*seclabels, 0, sizeof(**seclabels) * len);
+
+        /* Fill the array */
+        for (i = 0; i < len; i++) {
+            if (virSecurityManagerGetProcessLabel(mgrs[i], vm->def, vm->pid,
+                                                  &(*seclabels)[i]) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               "%s", _("Failed to get security label"));
+                VIR_FREE(mgrs);
+                VIR_FREE(*seclabels);
+                goto cleanup;
+            }
+        }
+        ret = len;
+        VIR_FREE(mgrs);
+    }
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    qemuDriverUnlock(driver);
+    return ret;
+}
 static int qemudNodeGetSecurityModel(virConnectPtr conn,
                                      virSecurityModelPtr secmodel)
 {
@@ -13422,6 +13494,7 @@ static virDriver qemuDriver = {
     .domainGetVcpus = qemudDomainGetVcpus, /* 0.4.4 */
     .domainGetMaxVcpus = qemudDomainGetMaxVcpus, /* 0.4.4 */
     .domainGetSecurityLabel = qemudDomainGetSecurityLabel, /* 0.6.1 */
+    .domainGetSecurityLabelList = qemuDomainGetSecurityLabelList, /* 0.10.0 */
     .nodeGetSecurityModel = qemudNodeGetSecurityModel, /* 0.6.1 */
     .domainGetXMLDesc = qemuDomainGetXMLDesc, /* 0.2.0 */
     .domainXMLFromNative = qemuDomainXMLFromNative, /* 0.6.4 */
index c4941c537882018b6a4a11695694e8650e60c77c..977d13959d16da3bd8e65a1e2dfd806de6ea575d 100644 (file)
@@ -1957,6 +1957,51 @@ done:
     return rv;
 }
 
+static int
+remoteDomainGetSecurityLabelList (virDomainPtr domain, virSecurityLabelPtr* seclabels)
+{
+    remote_domain_get_security_label_list_args args;
+    remote_domain_get_security_label_list_ret ret;
+    struct private_data *priv = domain->conn->privateData;
+    int i, rv = -1;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_domain (&args.dom, domain);
+    memset(&ret, 0, sizeof(ret));
+
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_LIST,
+              (xdrproc_t) xdr_remote_domain_get_security_label_list_args, (char *)&args,
+              (xdrproc_t) xdr_remote_domain_get_security_label_list_ret, (char *)&ret) == -1) {
+        goto done;
+    }
+
+    if (VIR_ALLOC_N(*seclabels, ret.labels.labels_len) < 0)
+        goto cleanup;
+
+    for (i = 0; i < ret.labels.labels_len; i++) {
+        remote_domain_get_security_label_ret *cur = &ret.labels.labels_val[i];
+        if (cur->label.label_val != NULL) {
+            if (strlen(cur->label.label_val) >= sizeof((*seclabels)->label)) {
+                virReportError(VIR_ERR_RPC, _("security label exceeds maximum: %zd"),
+                               sizeof((*seclabels)->label) - 1);
+                VIR_FREE(*seclabels);
+                goto cleanup;
+            }
+            strcpy((*seclabels)[i].label, cur->label.label_val);
+            (*seclabels)[i].enforcing = cur->enforcing;
+        }
+    }
+    rv = ret.ret;
+
+cleanup:
+    xdr_free((xdrproc_t) xdr_remote_domain_get_security_label_list_ret, (char *)&ret);
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
 static int
 remoteDomainGetState(virDomainPtr domain,
                      int *state,
@@ -5260,6 +5305,7 @@ static virDriver remote_driver = {
     .domainGetVcpus = remoteDomainGetVcpus, /* 0.3.0 */
     .domainGetMaxVcpus = remoteDomainGetMaxVcpus, /* 0.3.0 */
     .domainGetSecurityLabel = remoteDomainGetSecurityLabel, /* 0.6.1 */
+    .domainGetSecurityLabelList = remoteDomainGetSecurityLabelList, /* 0.10.0 */
     .nodeGetSecurityModel = remoteNodeGetSecurityModel, /* 0.6.1 */
     .domainGetXMLDesc = remoteDomainGetXMLDesc, /* 0.3.0 */
     .domainXMLFromNative = remoteDomainXMLFromNative, /* 0.6.4 */
index 200fe75f99163959e4ac21120ecfc2d47cb5c7d9..3be15f5215fdc00aafa1502db6d38f28c1278aa8 100644 (file)
@@ -168,6 +168,11 @@ const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 1048576;
  */
 const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 1048576;
 
+/*
+ * Maximum length of a security label list.
+ */
+const REMOTE_SECURITY_LABEL_LIST_MAX=64;
+
 /*
  * Maximum length of a security model field.
  */
@@ -1082,6 +1087,15 @@ struct remote_domain_get_security_label_ret {
     int enforcing;
 };
 
+struct remote_domain_get_security_label_list_args {
+    remote_nonnull_domain dom;
+};
+
+struct remote_domain_get_security_label_list_ret {
+    remote_domain_get_security_label_ret labels<REMOTE_SECURITY_LABEL_LIST_MAX>;
+    int ret;
+};
+
 struct remote_node_get_security_model_ret {
     char model<REMOTE_SECURITY_MODEL_MAX>;
     char doi<REMOTE_SECURITY_DOI_MAX>;
@@ -2854,7 +2868,8 @@ enum remote_procedure {
     REMOTE_PROC_DOMAIN_LIST_ALL_SNAPSHOTS = 274, /* skipgen skipgen priority:high */
     REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275, /* skipgen skipgen priority:high */
     REMOTE_PROC_DOMAIN_EVENT_BALLOON_CHANGE = 276, /* autogen autogen */
-    REMOTE_PROC_DOMAIN_GET_HOSTNAME = 277 /* autogen autogen */
+    REMOTE_PROC_DOMAIN_GET_HOSTNAME = 277, /* autogen autogen */
+    REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_LIST = 278 /* skipgen skipgen priority:high */
 
     /*
      * Notice how the entries are grouped in sets of 10 ?
index 8d09138ee5f0aa1e2500f8ab612a435b57831c2e..c180e6e401bc2d81bc2f9780253d628347d2201e 100644 (file)
@@ -749,6 +749,16 @@ struct remote_domain_get_security_label_ret {
         } label;
         int                        enforcing;
 };
+struct remote_domain_get_security_label_list_args {
+        remote_nonnull_domain      dom;
+};
+struct remote_domain_get_security_label_list_ret {
+        struct {
+                u_int              labels_len;
+                remote_domain_get_security_label_ret * labels_val;
+        } labels;
+        int                        ret;
+};
 struct remote_node_get_security_model_ret {
         struct {
                 u_int              model_len;
@@ -2259,4 +2269,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_ALL_CHILDREN = 275,
         REMOTE_PROC_DOMAIN_EVENT_BALLOON_CHANGE = 276,
         REMOTE_PROC_DOMAIN_GET_HOSTNAME = 277,
+        REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_LIST = 278,
 };