--- src/security/security_dac.c | 116 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 4b8f0a2..f2d8c67 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -42,6 +42,7 @@ struct _virSecurityDACData { uid_t user; gid_t group; bool dynamicOwnership; + bool updated; /* has the state changed since last virSecurityDACSaveStatus? */ virHashTablePtr oldOwners; /* to hold pairs <path, virOldLabelPtr> */ }; @@ -65,6 +66,15 @@ hashDataFree(void *payload, const void *name ATTRIBUTE_UNUSED) virOldLabelFree(payload); } +static void +hashDataToXML(void *payload, const void *name, void *data) +{ + virOldLabelPtr label = payload; + + virBufferAsprintf(data, "<label path='%s' owner='%s' refCount='%d'/>\n", + (const char *)name, label->owner, label->refCount); +} + /** * virSecurityDACRememberLabel: * @priv: private DAC driver data @@ -114,7 +124,7 @@ virSecurityDACRememberLabel(virSecurityDACDataPtr priv, cleanup: VIR_FREE(user); VIR_FREE(group); - return oldLabel ? oldLabel->refCount : -1; + return oldLabel ? priv->updated = true, oldLabel->refCount : -1; } static int parseIds(const char *label, uid_t *uidPtr, gid_t *gidPtr); @@ -147,6 +157,7 @@ virSecurityDACGetRememberedLabel(virSecurityDACDataPtr priv, goto cleanup; ret = --oldLabel->refCount; + priv->updated = true; if (!ret) { ret = parseIds(oldLabel->owner, user, group); @@ -372,6 +383,106 @@ virSecurityDACClose(virSecurityManagerPtr mgr) return 0; } +static int +virSecurityDACSaveStatus(virSecurityManagerPtr mgr, + virBufferPtr *buf, + bool force) +{ + virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + int ret = -1; + + if (!force && !priv->updated) { + *buf = NULL; + return 0; + } + + priv->updated = false; + + virBufferAddLit(*buf, "<securityDriver>\n"); + virBufferAddLit(*buf, " <oldLabel>\n"); + virBufferAdjustIndent(*buf, 4); + + ret = virHashForEach(priv->oldOwners, hashDataToXML, *buf); + + virBufferAdjustIndent(*buf, -4); + virBufferAddLit(*buf, " </oldLabel>\n"); + virBufferAddLit(*buf, "</securityDriver>\n"); + return ret; +} + +static int +virSecurityDACLoadStatus(virSecurityManagerPtr mgr, + xmlDocPtr doc) +{ + virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); + int i, n, ret = -1; + xmlNodePtr *nodes = NULL, root = xmlDocGetRootElement(doc); + xmlXPathContextPtr ctxt = NULL; + char *path = NULL,*owner = NULL, *refCountStr = NULL; + virOldLabelPtr oldLabel = NULL; + + if (!xmlStrEqual(root->name, BAD_CAST "securityDriver")) { + virReportError(VIR_ERR_XML_ERROR, + _("unexpected root element <%s>, " + "expecting <securityDriver>"), + root->name); + return ret; + } + + if (!(ctxt = xmlXPathNewContext(doc))) { + virReportOOMError(); + return ret; + } + + ctxt->node = root; + + n = virXPathNodeSet("./oldLabel/label", ctxt, &nodes); + if (n < 0) + goto cleanup; + + for (i = 0; i < n; i++) { + path = virXMLPropString(nodes[i], "path"); + owner = virXMLPropString(nodes[i], "owner"); + refCountStr = virXMLPropString(nodes[i], "refCount"); + + if (!path || !owner || !refCountStr) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Malformed security driver xml")); + goto cleanup; + } + if (VIR_ALLOC(oldLabel) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (virStrToLong_i(refCountStr, NULL, 10, &oldLabel->refCount) < 0) { + virReportError(VIR_ERR_XML_DETAIL, + _("Malformed refCount attribute: %s"), + refCountStr); + goto cleanup; + } + + oldLabel->owner = owner; + owner = NULL; + + if (virHashUpdateEntry(priv->oldOwners, path, oldLabel) < 0) + goto cleanup; + + path = NULL; + oldLabel = NULL; + VIR_FREE(refCountStr); + } + + ret = 0; +cleanup: + virOldLabelFree(oldLabel); + VIR_FREE(path); + VIR_FREE(owner); + VIR_FREE(refCountStr); + VIR_FREE(nodes); + xmlXPathFreeContext(ctxt); + return ret; +} static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED) { @@ -1304,6 +1415,9 @@ virSecurityDriver virSecurityDriverDAC = { .open = virSecurityDACOpen, .close = virSecurityDACClose, + .saveStatus = virSecurityDACSaveStatus, + .loadStatus = virSecurityDACLoadStatus, + .getModel = virSecurityDACGetModel, .getDOI = virSecurityDACGetDOI, -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list