---
man/tmpfiles.d.xml | 3 +++
src/tmpfiles/tmpfiles.c | 46 ++++++++++++++++++++++++++++++++++++++++------
2 files changed, 43 insertions(+), 6 deletions(-)
Index: systemd-228/man/tmpfiles.d.xml
===================================================================
--- systemd-228.orig/man/tmpfiles.d.xml
+++ systemd-228/man/tmpfiles.d.xml
@@ -599,6 +599,9 @@
f, F, and
w, the argument may be used to specify a short string that
is written to the file, suffixed by a newline. For
+ x, X, a comma separated list of
+ usernames. If given, only paths belonging to these users will be excluded
+ during directory cleanup. Ignored for all other lines. For
C, specifies the source file or
directory. For t and T,
determines extended attributes to be set. For
Index: systemd-228/src/tmpfiles/tmpfiles.c
===================================================================
--- systemd-228.orig/src/tmpfiles/tmpfiles.c
+++ systemd-228/src/tmpfiles/tmpfiles.c
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include "acl-util.h"
#include "alloc-util.h"
@@ -378,6 +379,7 @@ static int dir_cleanup(
struct timespec times[2];
bool deleted = false;
int r = 0;
+ Item *found = NULL;
while ((dent = readdir(d))) {
struct stat s;
@@ -428,14 +430,46 @@ static int dir_cleanup(
}
/* Is there an item configured for this path? */
- if (ordered_hashmap_get(items, sub_path)) {
- log_debug("Ignoring \"%s\": a separate entry exists.", sub_path);
- continue;
+ bool found_glob = false;
+ found = ordered_hashmap_get(items, sub_path);
+ if (!found) {
+ found_glob = true;
+ found = find_glob(globs, sub_path);
}
- if (find_glob(globs, sub_path)) {
- log_debug("Ignoring \"%s\": a separate glob exists.", sub_path);
- continue;
+ if (found) {
+ struct passwd *pw;
+ char *userfound = NULL, *args;
+ bool match = false;
+ uid_t uid = -1;
+
+ /* evaluate username arguments in ignore statements */
+ if ((found->type != IGNORE_PATH && found->type != IGNORE_DIRECTORY_PATH) ||
+ !found->argument) {
+ if (found_glob)
+ log_debug("Ignoring \"%s\": a separate glob exists.", sub_path);
+ else
+ log_debug("Ignoring \"%s\": a separate entry exists.", sub_path);
+ continue;
+ }
+ args = strdup(found->argument);
+ assert_se(args != NULL);
+ while ((userfound = strsep(&args, ",")) != NULL) {
+ pw = getpwnam(userfound);
+ if (pw == NULL) {
+ log_error("Unknown user '%s' in ignore statement.", userfound);
+ continue;
+ }
+ uid = pw->pw_uid;
+ if (s.st_uid == uid) {
+ match = true;
+ break;
+ }
+ }
+ if (match) {
+ found = NULL;
+ continue;
+ }
}
if (S_ISDIR(s.st_mode)) {