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,
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> */
'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
typedef int
(*virDrvDomainGetSecurityLabel) (virDomainPtr domain,
virSecurityLabelPtr seclabel);
+typedef int
+ (*virDrvDomainGetSecurityLabelList) (virDomainPtr domain,
+ virSecurityLabelPtr* seclabels);
typedef int
(*virDrvNodeGetSecurityModel) (virConnectPtr conn,
virSecurityModelPtr secmodel);
virDrvDomainGetVcpus domainGetVcpus;
virDrvDomainGetMaxVcpus domainGetMaxVcpus;
virDrvDomainGetSecurityLabel domainGetSecurityLabel;
+ virDrvDomainGetSecurityLabelList domainGetSecurityLabelList;
virDrvNodeGetSecurityModel nodeGetSecurityModel;
virDrvDomainGetXMLDesc domainGetXMLDesc;
virDrvConnectDomainXMLFromNative domainXMLFromNative;
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
virDomainGetHostname;
virConnectRegisterCloseCallback;
virConnectUnregisterCloseCallback;
+ virDomainGetSecurityLabelList;
} LIBVIRT_0.9.13;
# .... define new API here using predicted next version number ....
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)
{
.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 */
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,
.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 */
*/
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.
*/
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>;
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 ?
} 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;
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,
};