--- man/tmpfiles.d.xml | 5 +++++ src/tmpfiles/tmpfiles.c | 42 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) Index: systemd-218/man/tmpfiles.d.xml =================================================================== --- systemd-218.orig/man/tmpfiles.d.xml +++ systemd-218/man/tmpfiles.d.xml @@ -545,6 +545,11 @@ r! /tmp/.X[0-9]*-lock and w 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 determines extended attributes to be set. Ignored for all other lines. Index: systemd-218/src/tmpfiles/tmpfiles.c =================================================================== --- systemd-218.orig/src/tmpfiles/tmpfiles.c +++ systemd-218/src/tmpfiles/tmpfiles.c @@ -278,6 +278,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; @@ -322,11 +323,44 @@ static int dir_cleanup( } /* Is there an item configured for this path? */ - if (hashmap_get(items, sub_path)) - continue; + found = hashmap_get(items, sub_path); - if (find_glob(globs, sub_path)) - continue; + if (!found) + found = find_glob(globs, sub_path); + + if (found) { + /* evaluate username arguments in ignore statements */ + if (found->type == IGNORE_PATH || found->type == IGNORE_DIRECTORY_PATH) { + if (!found->argument) { + continue; + } else { + struct passwd *pw; + char *userfound = NULL, *args = strdup(found->argument); + bool match = false; + uid_t uid = -1; + + while ((userfound = strsep(&args, ","))) { + pw = getpwnam(userfound); + + if (!pw) + log_error("Unknown user '%s' in ignore statement.", userfound); + else { + uid = pw->pw_uid; + if (s.st_uid == uid) { + match = true; + break; + } + } + } + if (match) { + found = NULL; + continue; + } + } + } else { + continue; + } + } if (S_ISDIR(s.st_mode)) {