#include "fileio.h"
#include "fs-util.h"
#include "hexdecoct.h"
+#include "label.h"
#include "log.h"
#include "macro.h"
#include "mkdir.h"
/* 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. */
+ mode_t mode = write_string_file_flags_to_mode(flags);
+
+ bool call_label_ops_post = false;
+ if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL)) {
+ r = label_ops_pre(dir_fd, fn, mode);
+ if (r < 0)
+ return r;
+
+ call_label_ops_post = true;
+ }
+
r = fopen_temporary_at(dir_fd, fn, &f, &p);
if (r < 0)
- return r;
+ goto fail;
+
+ if (call_label_ops_post) {
+ call_label_ops_post = false;
+
+ r = label_ops_post(fileno(f), /* path= */ NULL, /* created= */ true);
+ if (r < 0)
+ goto fail;
+ }
r = write_string_stream_full(f, line, flags, ts);
if (r < 0)
goto fail;
- r = fchmod_umask(fileno(f), write_string_file_flags_to_mode(flags));
+ r = fchmod_umask(fileno(f), mode);
if (r < 0)
goto fail;
- if (renameat(dir_fd, p, dir_fd, fn) < 0) {
- r = -errno;
+ r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn));
+ if (r < 0)
goto fail;
- }
if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
/* Sync the rename, too */
return 0;
fail:
- (void) unlinkat(dir_fd, p, 0);
+ if (call_label_ops_post)
+ (void) label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f);
+
+ if (f)
+ (void) unlinkat(dir_fd, p, 0);
return r;
}
WriteStringFileFlags flags,
const struct timespec *ts) {
+ bool call_label_ops_post = false;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -EBADF;
- int q, r;
+ int r;
assert(fn);
assert(line);
goto fail;
return r;
- } else
- assert(!ts);
+ }
+
+ mode_t mode = write_string_file_flags_to_mode(flags);
+
+ if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
+ r = label_ops_pre(dir_fd, fn, mode);
+ if (r < 0)
+ goto fail;
+
+ call_label_ops_post = true;
+ }
/* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
fd = openat(dir_fd, fn, O_CLOEXEC|O_NOCTTY |
(FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
- write_string_file_flags_to_mode(flags));
+ mode);
if (fd < 0) {
r = -errno;
goto fail;
}
+ if (call_label_ops_post) {
+ call_label_ops_post = false;
+
+ r = label_ops_post(fd, /* path= */ NULL, /* created= */ true);
+ if (r < 0)
+ goto fail;
+ }
+
r = take_fdopen_unlocked(&fd, "w", &f);
if (r < 0)
goto fail;
return 0;
fail:
+ if (call_label_ops_post)
+ (void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, /* created= */ true);
+
if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
return r;
f = safe_fclose(f);
+ fd = safe_close(fd);
- /* OK, the operation failed, but let's see if the right
- * contents in place already. If so, eat up the error. */
-
- q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE));
- if (q <= 0)
- return r;
+ /* OK, the operation failed, but let's see if the right contents in place already. If so, eat up the
+ * error. */
+ if (verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE)) > 0)
+ return 0;
- return 0;
+ return r;
}
int write_string_filef(
WRITE_STRING_FILE_MODE_0600 = 1 << 10,
WRITE_STRING_FILE_MODE_0444 = 1 << 11,
WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL = 1 << 12,
-
- /* 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()
- and friends. */
-
+ WRITE_STRING_FILE_LABEL = 1 << 13,
} WriteStringFileFlags;
typedef enum {
#include "bpf-socket-bind.h"
#include "bus-util.h"
#include "dbus.h"
-#include "fileio-label.h"
#include "fileio.h"
#include "format-util.h"
#include "parse-util.h"
#include "exec-credential.h"
#include "execute.h"
#include "fd-util.h"
-#include "fileio-label.h"
#include "fileio.h"
#include "format-util.h"
#include "id128-util.h"
return r;
}
- r = write_string_file_atomic_label(q, wrapped);
+ r = write_string_file(q, wrapped, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return r;
#include "dropin.h"
#include "errno-util.h"
#include "fd-util.h"
-#include "fileio-label.h"
+#include "fileio.h"
#include "generator.h"
#include "initrd-util.h"
#include "parse-util.h"
if (!p)
return log_oom();
- r = write_string_file_at_label(AT_FDCWD, p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
+ r = write_string_file(p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
if (r < 0) {
log_warning_errno(r, "Failed to write unit file '%s' from credential '%s', ignoring: %m",
unit, de->d_name);
#include "env-file-label.h"
#include "env-file.h"
#include "env-util.h"
-#include "fileio-label.h"
#include "fileio.h"
#include "hostname-setup.h"
#include "hostname-util.h"
return 0;
}
- r = write_string_file_atomic_label("/etc/hostname", c->data[PROP_STATIC_HOSTNAME]);
+ r = write_string_file("/etc/hostname", c->data[PROP_STATIC_HOSTNAME], WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return r;
#include "env-file.h"
#include "env-util.h"
#include "fd-util.h"
-#include "fileio-label.h"
#include "fileio.h"
#include "fs-util.h"
#include "kbd-util.h"
#include "escape.h"
#include "event-util.h"
#include "fd-util.h"
-#include "fileio-label.h"
#include "fileio.h"
+#include "fileio-label.h"
#include "format-util.h"
#include "fs-util.h"
#include "logind-action.h"
static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus_error *error) {
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
- _cleanup_free_ char *rule = NULL, *file = NULL;
+ _cleanup_free_ char *file = NULL;
const char *id_for_seat;
int r;
if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
return -ENOMEM;
- if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
- return -ENOMEM;
-
- (void) mkdir_p_label("/etc/udev/rules.d", 0755);
- r = write_string_file_atomic_label(file, rule);
+ r = write_string_filef(
+ file,
+ WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL,
+ "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat);
if (r < 0)
return r;
if (unlink("/run/systemd/reboot-to-boot-loader-menu") < 0 && errno != ENOENT)
return -errno;
} else {
- char buf[DECIMAL_STR_MAX(uint64_t) + 1];
-
- xsprintf(buf, "%" PRIu64, x); /* μs granularity */
-
- r = write_string_file_atomic_label("/run/systemd/reboot-to-boot-loader-menu", buf);
+ r = write_string_filef("/run/systemd/reboot-to-boot-loader-menu",
+ WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL,
+ "%" PRIu64, x); /* μs granularity */
if (r < 0)
return r;
}
if (unlink("/run/systemd/reboot-to-boot-loader-entry") < 0 && errno != ENOENT)
return -errno;
} else {
- r = write_string_file_atomic_label("/run/systemd/reboot-boot-to-loader-entry", v);
+ r = write_string_file("/run/systemd/reboot-boot-to-loader-entry", v, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return r;
}
#include "dropin.h"
#include "escape.h"
#include "fd-util.h"
-#include "fileio-label.h"
+#include "fileio.h"
#include "hashmap.h"
#include "log.h"
#include "macro.h"
if (r < 0)
return r;
- return write_string_file_at_label(AT_FDCWD, p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
+ return write_string_file(p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
}
int write_drop_in_format(
#include "fileio.h"
#include "selinux-util.h"
-int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
- int r;
-
- r = mac_selinux_create_file_prepare_at(atfd, fn, S_IFREG);
- if (r < 0)
- return r;
-
- r = write_string_file_full(atfd, fn, line, flags, ts);
-
- mac_selinux_create_file_clear();
-
- return r;
-}
-
int create_shutdown_run_nologin_or_warn(void) {
int r;
* 13 years later we stopped managing /etc/nologin, leaving it for the administrator to manage.
*/
- r = write_string_file_atomic_label("/run/nologin",
- "System is going down. Unprivileged users are not permitted to log in anymore. "
- "For technical details, see pam_nologin(8).");
+ r = write_string_file("/run/nologin",
+ "System is going down. Unprivileged users are not permitted to log in anymore. "
+ "For technical details, see pam_nologin(8).",
+ WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
if (r < 0)
return log_error_errno(r, "Failed to create /run/nologin: %m");
#include "fileio.h"
-int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
-static inline int write_string_file_at_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags) {
- return write_string_file_full_label(atfd, fn, line, flags, /* ts= */ NULL);
-}
-static inline int write_string_file_atomic_label(const char *fn, const char *line) {
- return write_string_file_at_label(AT_FDCWD, fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
-}
-
int create_shutdown_run_nologin_or_warn(void);
#include "constants.h"
#include "daemon-util.h"
#include "fd-util.h"
-#include "fileio-label.h"
#include "fileio.h"
#include "fs-util.h"
#include "hashmap.h"
if (r < 0)
return r;
- return write_string_file_atomic_label("/etc/adjtime", w);
+ return write_string_file("/etc/adjtime", w, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
}
static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m) {
#include <unistd.h>
#include "alloc-util.h"
-#include "fileio-label.h"
+#include "fileio.h"
#include "selinux-util.h"
#include "time-util.h"
timespec_load_nsec(ts)) < 0)
return log_oom();
- r = write_string_file_full_label(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC, ts);
+ r = write_string_file_full(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL, ts);
if (r == -EROFS)
log_debug_errno(r, "Cannot create \"%s\", file system is read-only.", path);
else if (r < 0)