From cb869b77802b536aab1716714cdd5478d891d3f4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 17 Sep 2013 16:33:30 -0500 Subject: [PATCH] tmpfiles: add a new "m" line type that adjusts user/group/mode of a file if it exists --- man/systemd-tmpfiles.xml | 2 +- man/tmpfiles.d.xml | 11 +++++++++++ src/tmpfiles/tmpfiles.c | 39 +++++++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 281ab3c..ba727e1 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -165,7 +165,7 @@ See Also systemd1, - tmpfiles.d5, + tmpfiles.d5 diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index cdc87c9..98e3690 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -152,6 +152,17 @@ L /tmp/foobar - - - - /dev/null + m + If the + specified file path exists + adjust its access mode, group + and user to the specified + values and reset the SELinux + label. If it doesn't exist do + nothing. + + + x Ignore a path during cleaning. Use this type diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index ea99920..49e6529 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -68,6 +68,7 @@ typedef enum ItemType { CREATE_SYMLINK = 'L', CREATE_CHAR_DEVICE = 'c', CREATE_BLOCK_DEVICE = 'b', + ADJUST_MODE = 'm', /* These ones take globs */ IGNORE_PATH = 'x', @@ -256,8 +257,8 @@ static int dir_cleanup( dev_t rootdev, bool mountpoint, int maxdepth, - bool keep_this_level) -{ + bool keep_this_level) { + struct dirent *dent; struct timespec times[2]; bool deleted = false; @@ -431,12 +432,16 @@ finish: return r; } -static int item_set_perms(Item *i, const char *path) { +static int item_set_perms_full(Item *i, const char *path, bool ignore_enoent) { + int r; + /* not using i->path directly because it may be a glob */ if (i->mode_set) if (chmod(path, i->mode) < 0) { - log_error("chmod(%s) failed: %m", path); - return -errno; + if (errno != ENOENT || !ignore_enoent) { + log_error("chmod(%s) failed: %m", path); + return -errno; + } } if (i->uid_set || i->gid_set) @@ -444,11 +449,18 @@ static int item_set_perms(Item *i, const char *path) { i->uid_set ? i->uid : (uid_t) -1, i->gid_set ? i->gid : (gid_t) -1) < 0) { - log_error("chown(%s) failed: %m", path); - return -errno; + if (errno != ENOENT || !ignore_enoent) { + log_error("chown(%s) failed: %m", path); + return -errno; + } } - return label_fix(path, false, false); + r = label_fix(path, false, false); + return r == -ENOENT && ignore_enoent ? 0 : r; +} + +static int item_set_perms(Item *i, const char *path) { + return item_set_perms_full(i, path, false); } static int write_one_file(Item *i, const char *path) { @@ -644,6 +656,7 @@ static int create_item(Item *i) { if (r < 0) return r; break; + case WRITE_FILE: r = glob_item(i, write_one_file); if (r < 0) @@ -651,6 +664,13 @@ static int create_item(Item *i) { break; + case ADJUST_MODE: + r = item_set_perms_full(i, i->path, true); + if (r < 0) + return r; + + break; + case TRUNCATE_DIRECTORY: case CREATE_DIRECTORY: @@ -821,6 +841,7 @@ static int remove_item_instance(Item *i, const char *instance) { case RELABEL_PATH: case RECURSIVE_RELABEL_PATH: case WRITE_FILE: + case ADJUST_MODE: break; case REMOVE_PATH: @@ -866,6 +887,7 @@ static int remove_item(Item *i) { case RELABEL_PATH: case RECURSIVE_RELABEL_PATH: case WRITE_FILE: + case ADJUST_MODE: break; case REMOVE_PATH: @@ -1093,6 +1115,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { case RECURSIVE_REMOVE_PATH: case RELABEL_PATH: case RECURSIVE_RELABEL_PATH: + case ADJUST_MODE: break; case CREATE_SYMLINK: