From 95244ceb9c827ce6762a57baf36aa229b594fd0f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 17 May 2019 15:52:35 +0200 Subject: [PATCH] fileio: add WRITE_STRING_FILE_MODE_0600 flag for writing files usually we want to create new files with mode 0666 (modulated by the umask). Sometimes we want more restrictive access though, let's add an explicit flag support for that. (Note that we don't bother with arbitrary access modes to keep things simple: just "open as umask permits" and "private to me", nothing else) --- src/basic/fileio.c | 43 +++++++++++++++++++++---------------------- src/basic/fileio.h | 1 + 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/basic/fileio.c b/src/basic/fileio.c index ef27c3f913..fe0c4f4707 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -136,16 +136,21 @@ static int write_string_file_atomic( assert(fn); assert(line); + /* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement + * semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */ + r = fopen_temporary(fn, &f, &p); if (r < 0) return r; - (void) fchmod_umask(fileno(f), 0644); - r = write_string_stream_ts(f, line, flags, ts); if (r < 0) goto fail; + r = fchmod_umask(fileno(f), FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0644); + if (r < 0) + goto fail; + if (rename(p, fn) < 0) { r = -errno; goto fail; @@ -165,7 +170,7 @@ int write_string_file_ts( struct timespec *ts) { _cleanup_fclose_ FILE *f = NULL; - int q, r; + int q, r, fd; assert(fn); assert(line); @@ -190,26 +195,20 @@ int write_string_file_ts( } else assert(!ts); - if (flags & WRITE_STRING_FILE_CREATE) { - r = fopen_unlocked(fn, "we", &f); - if (r < 0) - goto fail; - } else { - int fd; + /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */ + fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY | + (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) | + (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0), + (FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0666)); + if (fd < 0) { + r = -errno; + goto fail; + } - /* We manually build our own version of fopen(..., "we") that - * works without O_CREAT */ - fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY | ((flags & WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0)); - if (fd < 0) { - r = -errno; - goto fail; - } - - r = fdopen_unlocked(fd, "w", &f); - if (r < 0) { - safe_close(fd); - goto fail; - } + r = fdopen_unlocked(fd, "w", &f); + if (r < 0) { + safe_close(fd); + goto fail; } if (flags & WRITE_STRING_FILE_DISABLE_BUFFER) diff --git a/src/basic/fileio.h b/src/basic/fileio.h index 209a06f826..e6fea2afd4 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -23,6 +23,7 @@ typedef enum { WRITE_STRING_FILE_DISABLE_BUFFER = 1 << 5, WRITE_STRING_FILE_NOFOLLOW = 1 << 6, WRITE_STRING_FILE_MKDIR_0755 = 1 << 7, + WRITE_STRING_FILE_MODE_0600 = 1 << 8, /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()