---
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