|
|
923a60 |
From bac7488e06e379628653fb2f3ece0a30414ff84e Mon Sep 17 00:00:00 2001
|
|
|
923a60 |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
923a60 |
Date: Mon, 22 Jan 2018 21:03:53 +0100
|
|
|
923a60 |
Subject: [PATCH] tmpfiles: change ownership of symlinks too
|
|
|
923a60 |
|
|
|
923a60 |
Ownership is supported for symlinks, too, only file modes are not.
|
|
|
923a60 |
Support that too.
|
|
|
923a60 |
|
|
|
923a60 |
Fixes: #7509
|
|
|
923a60 |
(cherry picked from commit 51207ca134716a0dee5fd763a6c39204be849eb1)
|
|
|
923a60 |
|
|
|
923a60 |
Resolves: #1620110
|
|
|
923a60 |
---
|
|
|
923a60 |
src/shared/macro.h | 7 +++++++
|
|
|
923a60 |
src/tmpfiles/tmpfiles.c | 41 +++++++++++++++++++++--------------------
|
|
|
923a60 |
2 files changed, 28 insertions(+), 20 deletions(-)
|
|
|
923a60 |
|
|
|
923a60 |
diff --git a/src/shared/macro.h b/src/shared/macro.h
|
|
|
923a60 |
index 7a57f4e5b1..26df270d51 100644
|
|
|
923a60 |
--- a/src/shared/macro.h
|
|
|
923a60 |
+++ b/src/shared/macro.h
|
|
|
923a60 |
@@ -125,6 +125,13 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|
|
923a60 |
|
|
|
923a60 |
#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
|
|
|
923a60 |
|
|
|
923a60 |
+/*
|
|
|
923a60 |
+ * STRLEN - return the length of a string literal, minus the trailing NUL byte.
|
|
|
923a60 |
+ * Contrary to strlen(), this is a constant expression.
|
|
|
923a60 |
+ * @x: a string literal.
|
|
|
923a60 |
+ */
|
|
|
923a60 |
+#define STRLEN(x) (sizeof(""x"") - 1)
|
|
|
923a60 |
+
|
|
|
923a60 |
/*
|
|
|
923a60 |
* container_of - cast a member of a structure out to the containing structure
|
|
|
923a60 |
* @ptr: the pointer to the member.
|
|
|
923a60 |
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
|
|
|
923a60 |
index 0b17b5908e..663f6c8b2d 100644
|
|
|
923a60 |
--- a/src/tmpfiles/tmpfiles.c
|
|
|
923a60 |
+++ b/src/tmpfiles/tmpfiles.c
|
|
|
923a60 |
@@ -591,6 +591,7 @@ finish:
|
|
|
923a60 |
}
|
|
|
923a60 |
|
|
|
923a60 |
static int path_set_perms(Item *i, const char *path) {
|
|
|
923a60 |
+ char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
|
|
|
923a60 |
_cleanup_close_ int fd = -1;
|
|
|
923a60 |
struct stat st;
|
|
|
923a60 |
|
|
|
923a60 |
@@ -624,14 +625,12 @@ static int path_set_perms(Item *i, const char *path) {
|
|
|
923a60 |
if (i->type == EMPTY_DIRECTORY && !S_ISDIR(st.st_mode))
|
|
|
923a60 |
return log_error_errno(EEXIST, "'%s' already exists and is not a directory. ", path);
|
|
|
923a60 |
|
|
|
923a60 |
- if (S_ISLNK(st.st_mode))
|
|
|
923a60 |
- log_debug("Skipping mode an owner fix for symlink %s.", path);
|
|
|
923a60 |
- else {
|
|
|
923a60 |
- char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
|
|
|
923a60 |
- xsprintf(fn, "/proc/self/fd/%i", fd);
|
|
|
923a60 |
+ xsprintf(fn, "/proc/self/fd/%i", fd);
|
|
|
923a60 |
|
|
|
923a60 |
- /* not using i->path directly because it may be a glob */
|
|
|
923a60 |
- if (i->mode_set) {
|
|
|
923a60 |
+ if (i->mode_set) {
|
|
|
923a60 |
+ if (S_ISLNK(st.st_mode))
|
|
|
923a60 |
+ log_debug("Skipping mode fix for symlink %s.", path);
|
|
|
923a60 |
+ else {
|
|
|
923a60 |
mode_t m = i->mode;
|
|
|
923a60 |
|
|
|
923a60 |
if (i->mask_perms) {
|
|
|
923a60 |
@@ -646,25 +645,27 @@ static int path_set_perms(Item *i, const char *path) {
|
|
|
923a60 |
}
|
|
|
923a60 |
|
|
|
923a60 |
if (m == (st.st_mode & 07777))
|
|
|
923a60 |
- log_debug("\"%s\" has right mode %o", path, st.st_mode);
|
|
|
923a60 |
+ log_debug("\"%s\" has correct mode %o already.", path, st.st_mode);
|
|
|
923a60 |
else {
|
|
|
923a60 |
- log_debug("chmod \"%s\" to mode %o", path, m);
|
|
|
923a60 |
+ log_debug("Changing \"%s\" to mode %o.", path, m);
|
|
|
923a60 |
+
|
|
|
923a60 |
if (chmod(fn, m) < 0)
|
|
|
923a60 |
return log_error_errno(errno, "chmod(%s) failed: %m", path);
|
|
|
923a60 |
}
|
|
|
923a60 |
}
|
|
|
923a60 |
+ }
|
|
|
923a60 |
|
|
|
923a60 |
- if ((i->uid != st.st_uid || i->gid != st.st_gid) &&
|
|
|
923a60 |
- (i->uid_set || i->gid_set)) {
|
|
|
923a60 |
- log_debug("chown \"%s\" to "UID_FMT"."GID_FMT,
|
|
|
923a60 |
- path,
|
|
|
923a60 |
- i->uid_set ? i->uid : UID_INVALID,
|
|
|
923a60 |
- i->gid_set ? i->gid : GID_INVALID);
|
|
|
923a60 |
- if (chown(fn,
|
|
|
923a60 |
- i->uid_set ? i->uid : UID_INVALID,
|
|
|
923a60 |
- i->gid_set ? i->gid : GID_INVALID) < 0)
|
|
|
923a60 |
- return log_error_errno(errno, "chown(%s) failed: %m", path);
|
|
|
923a60 |
- }
|
|
|
923a60 |
+ if ((i->uid != st.st_uid || i->gid != st.st_gid) &&
|
|
|
923a60 |
+ (i->uid_set || i->gid_set)) {
|
|
|
923a60 |
+ log_debug("Changing \"%s\" to owner "UID_FMT":"GID_FMT,
|
|
|
923a60 |
+ path,
|
|
|
923a60 |
+ i->uid_set ? i->uid : UID_INVALID,
|
|
|
923a60 |
+ i->gid_set ? i->gid : GID_INVALID);
|
|
|
923a60 |
+
|
|
|
923a60 |
+ if (chown(fn,
|
|
|
923a60 |
+ i->uid_set ? i->uid : UID_INVALID,
|
|
|
923a60 |
+ i->gid_set ? i->gid : GID_INVALID) < 0)
|
|
|
923a60 |
+ return log_error_errno(errno, "chown() of %s via %s failed: %m", path, fn);
|
|
|
923a60 |
}
|
|
|
923a60 |
|
|
|
923a60 |
fd = safe_close(fd);
|