tmpfiles: add ability to mask access mode by pre-existing access mode on files/directories

This way it makes a lot more sense to specify an access mode for "Z"
lines.
This commit is contained in:
Lennart Poettering
2014-06-11 10:14:07 +02:00
parent 1ebab2103d
commit abef3f91ce
2 changed files with 46 additions and 7 deletions
+30 -7
View File
@@ -99,6 +99,7 @@ typedef struct Item {
bool gid_set:1;
bool mode_set:1;
bool age_set:1;
bool mask_perms:1;
bool keep_first_level:1;
@@ -454,11 +455,29 @@ static int item_set_perms(Item *i, const char *path) {
assert(path);
/* not using i->path directly because it may be a glob */
if (i->mode_set)
if (chmod(path, i->mode) < 0) {
if (i->mode_set) {
mode_t m = i->mode;
if (i->mask_perms) {
struct stat st;
if (stat(path, &st) >= 0) {
if (!(st.st_mode & 0111))
m &= ~0111;
if (!(st.st_mode & 0222))
m &= ~0222;
if (!(st.st_mode & 0444))
m &= ~0444;
if (!S_ISDIR(st.st_mode))
m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */
}
}
if (chmod(path, m) < 0) {
log_error("chmod(%s) failed: %m", path);
return -errno;
}
}
if (i->uid_set || i->gid_set)
if (chown(path,
@@ -1056,15 +1075,13 @@ static bool item_equal(Item *a, Item *b) {
static bool should_include_path(const char *path) {
char **prefix;
STRV_FOREACH(prefix, arg_exclude_prefixes) {
STRV_FOREACH(prefix, arg_exclude_prefixes)
if (path_startswith(path, *prefix))
return false;
}
STRV_FOREACH(prefix, arg_include_prefixes) {
STRV_FOREACH(prefix, arg_include_prefixes)
if (path_startswith(path, *prefix))
return true;
}
/* no matches, so we should include this path only if we
* have no whitelist at all */
@@ -1249,9 +1266,15 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
}
if (mode && !streq(mode, "-")) {
const char *mm = mode;
unsigned m;
if (sscanf(mode, "%o", &m) != 1) {
if (*mm == '~') {
i->mask_perms = true;
mm++;
}
if (sscanf(mm, "%o", &m) != 1) {
log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
return -ENOENT;
}