return 0;
}
-int symlinkat_atomic_full(const char *from, int atfd, const char *to, bool make_relative) {
- _cleanup_free_ char *relpath = NULL, *t = NULL;
+int symlinkat_atomic_full(const char *from, int atfd, const char *to, SymlinkFlags flags) {
int r;
assert(from);
assert(to);
- if (make_relative) {
+ _cleanup_free_ char *relpath = NULL;
+ if (FLAGS_SET(flags, SYMLINK_MAKE_RELATIVE)) {
r = path_make_relative_parent(to, from, &relpath);
if (r < 0)
return r;
from = relpath;
}
+ _cleanup_free_ char *t = NULL;
r = tempfn_random(to, NULL, &t);
if (r < 0)
return r;
- if (symlinkat(from, atfd, t) < 0)
- return -errno;
+ bool call_label_ops_post = false;
+ if (FLAGS_SET(flags, SYMLINK_LABEL)) {
+ r = label_ops_pre(atfd, to, S_IFLNK);
+ if (r < 0)
+ return r;
+
+ call_label_ops_post = true;
+ }
+
+ r = RET_NERRNO(symlinkat(from, atfd, t));
+ if (call_label_ops_post)
+ RET_GATHER(r, label_ops_post(atfd, t, /* created= */ r >= 0));
+ if (r < 0)
+ return r;
r = RET_NERRNO(renameat(atfd, t, atfd, to));
if (r < 0) {
return symlinkat_idempotent(from, AT_FDCWD, to, make_relative);
}
-int symlinkat_atomic_full(const char *from, int atfd, const char *to, bool make_relative);
+typedef enum SymlinkFlags {
+ SYMLINK_MAKE_RELATIVE = 1 << 0,
+ SYMLINK_LABEL = 1 << 1,
+} SymlinkFlags;
+
+int symlinkat_atomic_full(const char *from, int atfd, const char *to, SymlinkFlags flags);
static inline int symlink_atomic(const char *from, const char *to) {
- return symlinkat_atomic_full(from, AT_FDCWD, to, false);
+ return symlinkat_atomic_full(from, AT_FDCWD, to, 0);
}
int mknodat_atomic(int atfd, const char *path, mode_t mode, dev_t dev);
if (r < 0)
return log_unit_debug_errno(u, r, "Failed to get invocation path: %m");
- r = symlink_atomic_label(u->invocation_id_string, p);
+ r = symlinkat_atomic_full(u->invocation_id_string, AT_FDCWD, p, SYMLINK_LABEL);
if (r < 0)
return log_unit_debug_errno(u, r, "Failed to create invocation ID symlink %s: %m", p);
#include "hostname-util.h"
#include "image-policy.h"
#include "kbd-util.h"
+#include "label.h"
#include "libcrypt-util.h"
#include "locale-util.h"
#include "lock-util.h"
if (r < 0)
return log_error_errno(r, "Failed to read host's /etc/localtime: %m");
- r = symlinkat_atomic_full(s, pfd, f, /* make_relative= */ false);
+ r = symlinkat_atomic_full(s, pfd, f, SYMLINK_LABEL);
if (r < 0)
return log_error_errno(r, "Failed to create /etc/localtime symlink: %m");
e = strjoina("../usr/share/zoneinfo/", arg_timezone);
- r = symlinkat_atomic_full(e, pfd, f, /* make_relative= */ false);
+ r = symlinkat_atomic_full(e, pfd, f, SYMLINK_LABEL);
if (r < 0)
return log_error_errno(r, "Failed to create /etc/localtime symlink: %m");
if (r < 0)
return log_warning_errno(r, "Failed to extract filename from path '" PRIVATE_UPLINK_RESOLV_CONF "', ignoring: %m");
- r = symlink_atomic_label(fname, PRIVATE_STUB_RESOLV_CONF);
+ r = symlinkat_atomic_full(fname, AT_FDCWD, PRIVATE_STUB_RESOLV_CONF, SYMLINK_LABEL);
if (r < 0)
log_warning_errno(r, "Failed to symlink %s, ignoring: %m", PRIVATE_STUB_RESOLV_CONF);
}
return mac_smack_fix(new_path, 0);
}
-int symlink_atomic_full_label(const char *from, const char *to, bool make_relative) {
- int r;
-
- assert(from);
- assert(to);
-
- r = mac_selinux_create_file_prepare(to, S_IFLNK);
- if (r < 0)
- return r;
-
- r = symlinkat_atomic_full(from, AT_FDCWD, to, make_relative);
- mac_selinux_create_file_clear();
-
- if (r < 0)
- return r;
-
- return mac_smack_fix(to, 0);
-}
-
int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev) {
int r;
}
int symlink_label(const char *old_path, const char *new_path);
-int symlink_atomic_full_label(const char *from, const char *to, bool make_relative);
-static inline int symlink_atomic_label(const char *from, const char *to) {
- return symlink_atomic_full_label(from, to, false);
-}
int mknodat_label(int dirfd, const char *pathname, mode_t mode, dev_t dev);
static inline int mknod_label(const char *pathname, mode_t mode, dev_t dev) {
fd = safe_close(fd);
- mac_selinux_create_file_prepare(i->path, S_IFLNK);
- r = symlinkat_atomic_full(i->argument, pfd, bn, /* make_relative= */ false);
- mac_selinux_create_file_clear();
+ r = symlinkat_atomic_full(i->argument, pfd, bn, SYMLINK_LABEL);
if (IN_SET(r, -EISDIR, -EEXIST, -ENOTEMPTY)) {
r = rm_rf_child(pfd, bn, REMOVE_PHYSICAL);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to create parent directory of '%s': %m", slink);
/* use relative link */
- r = symlink_atomic_full_label(devnode, slink, /* make_relative = */ true);
+ r = symlinkat_atomic_full(devnode, AT_FDCWD, slink, SYMLINK_MAKE_RELATIVE|SYMLINK_LABEL);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to create symlink '%s' to '%s': %m", slink, devnode);