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)
This commit is contained in:
Lennart Poettering 2019-05-17 15:52:35 +02:00
parent 8241f785f4
commit 95244ceb9c
2 changed files with 22 additions and 22 deletions

View File

@ -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)

View File

@ -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()