--- daemon/remote.c | 49 ++++++++++++++++++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 3 ++ python/generator.py | 1 + src/libvirt.c | 49 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_private.syms | 3 ++ src/libvirt_public.syms | 1 + src/remote/remote_driver.c | 42 ++++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 14 ++++++++++- src/remote_protocol-structs | 1 + 9 files changed, 161 insertions(+), 2 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 16a8a05..03799bf 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1341,6 +1341,55 @@ cleanup: } 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 seclabel = NULL; + int rv = -1; + struct daemonClientPrivate *priv = + virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if (!(dom = get_nonnull_domain(priv->conn, args->dom))) + goto cleanup; + + if (VIR_ALLOC(seclabel) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (virDomainGetSecurityLabelList(dom, seclabel, args->nlabels) < 0) + goto cleanup; + + ret->label.label_len = strlen(seclabel->label) + 1; + if (VIR_ALLOC_N(ret->label.label_val, ret->label.label_len) < 0) { + virReportOOMError(); + goto cleanup; + } + strcpy(ret->label.label_val, seclabel->label); + ret->enforcing = seclabel->enforcing; + + rv = 0; + +cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + if (dom) + virDomainFree(dom); + VIR_FREE(seclabel); + return rv; +} + +static int remoteDispatchNodeGetSecurityModel(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED, diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a817db8..fdcffd1 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1539,6 +1539,9 @@ int virDomainSetMemoryFlags (virDomainPtr domain, int virDomainGetMaxVcpus (virDomainPtr domain); int virDomainGetSecurityLabel (virDomainPtr domain, virSecurityLabelPtr seclabel); +int virDomainGetSecurityLabelList (virDomainPtr domain, + virSecurityLabelPtr seclabel, + int nseclabels); typedef enum { VIR_DOMAIN_METADATA_DESCRIPTION = 0, /* Operate on <description> */ diff --git a/python/generator.py b/python/generator.py index 9530867..2753d43 100755 --- a/python/generator.py +++ b/python/generator.py @@ -446,6 +446,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 diff --git a/src/libvirt.c b/src/libvirt.c index 22fc863..9e83c05 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -9024,6 +9024,55 @@ error: } /** + * virDomainGetSecurityLabelList: + * @domain: a domain object + * @seclabels: pointer to a pre allocated array of virSecurityLabel structures + * @nseclabels: number of elements on seclabels array + * + * 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 0 in case of success, -1 in case of failure + */ +int +virDomainGetSecurityLabelList(virDomainPtr domain, + virSecurityLabelPtr seclabels, + int nseclabels) +{ + 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, + nseclabels); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(domain->conn); + return -1; +} +/** * virDomainSetMetadata: * @domain: a domain object * @type: type of description, from virDomainMetadataType diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f5c2184..edeaae1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -278,6 +278,7 @@ virDomainDefClearPCIAddresses; virDomainDefFormat; virDomainDefFormatInternal; virDomainDefFree; +virDomainDefGetSecurityLabelDef; virDomainDefParseFile; virDomainDefParseNode; virDomainDefParseString; @@ -943,6 +944,7 @@ virSecurityManagerClearSocketLabel; virSecurityManagerFree; virSecurityManagerGenLabel; virSecurityManagerGetDOI; +virSecurityManagerGetNested; virSecurityManagerGetModel; virSecurityManagerGetProcessLabel; virSecurityManagerNew; @@ -962,6 +964,7 @@ virSecurityManagerSetHostdevLabel; virSecurityManagerSetProcessLabel; virSecurityManagerSetSavedStateLabel; virSecurityManagerSetSocketLabel; +virSecurityManagerStackAddNested; virSecurityManagerVerify; virSecurityManagerGetMountOptions; diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 46c13fb..2c85d22 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -527,6 +527,7 @@ LIBVIRT_0.9.10 { virDomainShutdownFlags; virStorageVolResize; virStorageVolWipePattern; + virDomainGetSecurityLabelList; } LIBVIRT_0.9.9; LIBVIRT_0.9.11 { diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 5c87561..04b3b67 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -1858,6 +1858,47 @@ done: } static int +remoteDomainGetSecurityLabelList (virDomainPtr domain, virSecurityLabelPtr seclabel, + int nlabels ATTRIBUTE_UNUSED) +{ + remote_domain_get_security_label_list_args args; + remote_domain_get_security_label_list_ret ret; + struct private_data *priv = domain->conn->privateData; + int rv = -1; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, domain); + memset (&ret, 0, sizeof ret); + memset (seclabel, 0, sizeof (*seclabel)); + + 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 (ret.label.label_val != NULL) { + if (strlen (ret.label.label_val) >= sizeof seclabel->label) { + remoteError(VIR_ERR_RPC, _("security label exceeds maximum: %zd"), + sizeof seclabel->label - 1); + goto cleanup; + } + strcpy (seclabel->label, ret.label.label_val); + seclabel->enforcing = ret.enforcing; + } + + rv = 0; + +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, int *reason, @@ -5006,6 +5047,7 @@ static virDriver remote_driver = { .domainGetVcpus = remoteDomainGetVcpus, /* 0.3.0 */ .domainGetMaxVcpus = remoteDomainGetMaxVcpus, /* 0.3.0 */ .domainGetSecurityLabel = remoteDomainGetSecurityLabel, /* 0.6.1 */ + .domainGetSecurityLabelList = remoteDomainGetSecurityLabelList, /* ? */ .nodeGetSecurityModel = remoteNodeGetSecurityModel, /* 0.6.1 */ .domainGetXMLDesc = remoteDomainGetXMLDesc, /* 0.3.0 */ .domainXMLFromNative = remoteDomainXMLFromNative, /* 0.6.4 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2d57247..d1e3692 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1082,6 +1082,16 @@ struct remote_domain_get_security_label_ret { int enforcing; }; +struct remote_domain_get_security_label_list_args { + remote_nonnull_domain dom; + int nlabels; +}; + +struct remote_domain_get_security_label_list_ret { + char label<REMOTE_SECURITY_LABEL_MAX>; + int enforcing; +}; + struct remote_node_get_security_model_ret { char model<REMOTE_SECURITY_MODEL_MAX>; char doi<REMOTE_SECURITY_DOI_MAX>; @@ -2782,8 +2792,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_PM_WAKEUP = 267, /* autogen autogen */ REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, /* autogen autogen */ REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269, /* autogen autogen */ - REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270 /* autogen autogen */ - + REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270, /* autogen autogen */ + REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_LIST = 271 /* skipgen skipgen priority:high */ /* * Notice how the entries are grouped in sets of 10 ? * Nice isn't it. Please keep it this way when adding more. diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 9b2414f..ee08e07 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2192,4 +2192,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_EVENT_TRAY_CHANGE = 268, REMOTE_PROC_DOMAIN_EVENT_PMWAKEUP = 269, REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND = 270, + REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL_list = 271, }; -- 1.7.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list