return 0;
}
+/**
+ * virSecurityDACRememberLabel:
+ * @priv: driver's private data
+ * @path: path to the file
+ * @uid: user owning the @path
+ * @gid: group owning the @path
+ *
+ * Remember the owner of @path (represented by @uid:@gid).
+ *
+ * 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)
+{
+ return 0;
+}
+
+/**
+ * virSecurityDACRecallLabel:
+ * @priv: driver's private data
+ * @path: path to the file
+ * @uid: user owning the @path
+ * @gid: group owning the @path
+ *
+ * Recall the previously recorded owner for the @path. However, it may happen
+ * that @path is still in use (e.g. by another domain). In that case, 1 is
+ * returned and caller should not relabel the @path.
+ *
+ * Returns: 1 if @path is still in use (@uid and @gid not touched)
+ * 0 if @path should be restored (@uid and @gid set)
+ * -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)
+{
+ return 0;
+}
static virSecurityDriverStatus
virSecurityDACProbe(const char *virtDriver ATTRIBUTE_UNUSED)
uid_t uid,
gid_t gid)
{
- /* XXX record previous ownership */
+ struct stat sb;
+
+ if (!path && src && src->path &&
+ virStorageSourceIsLocalStorage(src))
+ path = src->path;
+
+ if (path) {
+ if (stat(path, &sb) < 0) {
+ virReportSystemError(errno, _("unable to stat: %s"), path);
+ return -1;
+ }
+
+ if (virSecurityDACRememberLabel(priv, path, sb.st_uid, sb.st_gid) < 0)
+ return -1;
+ }
+
return virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid);
}
virStorageSourcePtr src,
const char *path)
{
+ int rv;
+ uid_t uid = 0; /* By default return to root:root */
+ gid_t gid = 0;
+
VIR_INFO("Restoring DAC user and group on '%s'",
NULLSTR(src ? src->path : path));
- /* XXX recall previous ownership */
- return virSecurityDACSetOwnershipInternal(priv, src, path, 0, 0);
+ if (!path && src && src->path &&
+ virStorageSourceIsLocalStorage(src))
+ path = src->path;
+
+ if (path) {
+ rv = virSecurityDACRecallLabel(priv, path, &uid, &gid);
+ if (rv < 0)
+ return -1;
+ if (rv > 0)
+ return 0;
+ }
+
+ return virSecurityDACSetOwnershipInternal(priv, src, path, uid, gid);
}