https://bugzilla.redhat.com/show_bug.cgi?id=547546
So now that we have the whole infrastructure prepared, we can
remember and recall the DAC security labels.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/Makefile.am | 1 +
src/security/security_dac.c | 90 ++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 81 insertions(+), 10 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index e706166..51b4af0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2738,6 +2738,7 @@ libvirt_lxc_LDADD = \
libvirt-net-rpc-server.la \
libvirt-net-rpc.la \
libvirt_security_manager.la \
+ libvirt_driver.la \
libvirt_conf.la \
libvirt_util.la \
../gnulib/lib/libgnu.la
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 463b459..5c99dfa 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -206,12 +206,38 @@ virSecurityDACGetImageIds(virSecurityLabelDefPtr seclabel,
* Returns: 0 on success, -1 on failure
*/
static int
-virSecurityDACRememberLabel(virSecurityDACDataPtr priv ATTRIBUTE_UNUSED,
- const char *path ATTRIBUTE_UNUSED,
- uid_t uid ATTRIBUTE_UNUSED,
- gid_t gid ATTRIBUTE_UNUSED)
+virSecurityDACRememberLabel(virSecurityDACDataPtr priv,
+ const char *path,
+ uid_t uid,
+ gid_t gid)
{
- return 0;
+ int ret = -1;
+ virLockManagerPtr lockManager = NULL;
+ char *label;
+
+ if (!priv->lockPlugin)
+ return 0;
+
+ if (virAsprintf(&label, "+%u:+%u",
+ (unsigned int) uid,
+ (unsigned int) gid) < 0)
+ goto cleanup;
+
+ lockManager = virLockManagerNew(virLockManagerPluginGetDriver(priv->lockPlugin),
+ VIR_LOCK_MANAGER_OBJECT_TYPE_SECLABEL,
+ 0, NULL, 0);
+ if (!lockManager)
+ goto cleanup;
+
+ if (virLockManagerRememberSeclabel(lockManager, path,
+ SECURITY_DAC_NAME, label) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(label);
+ virLockManagerFree(lockManager);
+ return ret;
}
/**
@@ -230,12 +256,56 @@ virSecurityDACRememberLabel(virSecurityDACDataPtr priv
ATTRIBUTE_UNUSED,
* -1 on failure (@uid and @gid not touched)
*/
static int
-virSecurityDACRecallLabel(virSecurityDACDataPtr priv ATTRIBUTE_UNUSED,
- const char *path ATTRIBUTE_UNUSED,
- uid_t *uid ATTRIBUTE_UNUSED,
- gid_t *gid ATTRIBUTE_UNUSED)
+virSecurityDACRecallLabel(virSecurityDACDataPtr priv,
+ const char *path,
+ uid_t *uid,
+ gid_t *gid)
{
- return 0;
+ int rv, ret = -1;
+ virLockManagerPtr lockManager = NULL;
+ char *label = NULL;
+
+ if (!priv->lockPlugin)
+ return 0;
+
+ lockManager = virLockManagerNew(virLockManagerPluginGetDriver(priv->lockPlugin),
+ VIR_LOCK_MANAGER_OBJECT_TYPE_SECLABEL,
+ 0, NULL, 0);
+ if (!lockManager)
+ goto cleanup;
+
+ rv = virLockManagerRecallSeclabel(lockManager, path,
+ SECURITY_DAC_NAME, &label);
+
+ VIR_DEBUG("path=%s label=%s", path, label);
+
+ if (rv < 0) {
+ /* Okay, path was not found, or there was some other error. At any
+ * rate, claim success here. */
+ ret = 0;
+ goto cleanup;
+ } else if (rv > 0) {
+ /* Okay, path was found, but is still in use. Notify caller so that we
+ * don't relabel anything. */
+ ret = 1;
+ goto cleanup;
+ }
+
+ if (!label) {
+ /* Okay, underlying lock driver does not know how to store seclabels.
+ * Fall back to defaults. */
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (virParseOwnershipIds(label, uid, gid) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(label);
+ virLockManagerFree(lockManager);
+ return ret;
}
static virSecurityDriverStatus
--
2.4.9