]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virFileRewrite: Allow setting owner
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 9 Feb 2022 11:22:00 +0000 (12:22 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 11 Feb 2022 12:16:40 +0000 (13:16 +0100)
Currently, due to the way virFileRewrite() works, the rewritten
file is owned by user and group that the daemon runs under. So
far, this is not a problem, because the function is used to write
XML files or secrets for persistent objects (domains, networks,
etc.) and we don't need other users to read/write those files.

But shortly, this function is going to be used for creating files
for QEMU domains. There we want the QEMU process (i.e. different
user) to read the file.

Therefore, introduce two new arguments: @uid and @gid that allow
setting desired owner of the file. Pass -1 to preserve current
behaviour (i.e. create the file owned by the user running the
daemon).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
src/util/virfile.c
src/util/virfile.h
src/util/virxml.c

index 0b79772da706be888761ca895b77931f90d68529..f99e7f95e15c76baa58b2622bf782b6e16effd62 100644 (file)
@@ -484,9 +484,28 @@ int virFileUnlock(int fd G_GNUC_UNUSED,
 #endif /* WIN32 */
 
 
+/**
+ * virFileRewrite:
+ * @path: file to rewrite
+ * @mode: mode of the file
+ * @uid: uid that should own file
+ * @gid: gid that should own file
+ * @rewrite: callback to write file contents
+ * @opaque: opaque data to pass to the callback
+ *
+ * Rewrite given @path atomically. This is achieved by writing a
+ * temporary file on a side and renaming it to the desired name.
+ * The temporary file is created using supplied @mode and
+ * @uid:@gid (pass -1 for current uid/gid) and written by
+ * @rewrite callback.
+ *
+ * Returns: 0 on success,
+ *         -1 otherwise (with error reported)
+ */
 int
 virFileRewrite(const char *path,
                mode_t mode,
+               uid_t uid, gid_t gid,
                virFileRewriteFunc rewrite,
                const void *opaque)
 {
@@ -496,8 +515,11 @@ virFileRewrite(const char *path,
 
     newfile = g_strdup_printf("%s.new", path);
 
-    if ((fd = open(newfile, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) {
-        virReportSystemError(errno, _("cannot create file '%s'"),
+    if ((fd = virFileOpenAs(newfile, O_WRONLY | O_CREAT | O_TRUNC, mode,
+                            uid, gid,
+                            VIR_FILE_OPEN_FORCE_OWNER | VIR_FILE_OPEN_FORCE_MODE)) < 0) {
+        virReportSystemError(-fd,
+                             _("Failed to create file '%s'"),
                              newfile);
         goto cleanup;
     }
@@ -552,7 +574,7 @@ virFileRewriteStr(const char *path,
                   mode_t mode,
                   const char *str)
 {
-    return virFileRewrite(path, mode,
+    return virFileRewrite(path, mode, -1, -1,
                           virFileRewriteStrHelper, str);
 }
 
index 967c9a9b4f157b11d006368a58bc6256a1358e34..34184b32aa057e227650477613cada4af110cd2e 100644 (file)
@@ -126,6 +126,7 @@ int virFileUnlock(int fd, off_t start, off_t len)
 typedef int (*virFileRewriteFunc)(int fd, const void *opaque);
 int virFileRewrite(const char *path,
                    mode_t mode,
+                   uid_t uid, gid_t gid,
                    virFileRewriteFunc rewrite,
                    const void *opaque);
 int virFileRewriteStr(const char *path,
index bb1ae3e305b86161998f9029a64bad3b840ed7dc..a55eb9629b62388325522832ef4c8432b905df0c 100644 (file)
@@ -1195,7 +1195,8 @@ virXMLSaveFile(const char *path,
 {
     struct virXMLRewriteFileData data = { warnName, warnCommand, xml };
 
-    return virFileRewrite(path, S_IRUSR | S_IWUSR, virXMLRewriteFile, &data);
+    return virFileRewrite(path, S_IRUSR | S_IWUSR, -1, -1,
+                          virXMLRewriteFile, &data);
 }
 
 /**