virFileRewrite: Allow setting owner

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>
This commit is contained in:
Michal Privoznik 2022-02-09 12:22:00 +01:00
parent 70f8299285
commit 04ed251850
3 changed files with 28 additions and 4 deletions

View 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);
}

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

View 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);
}
/**