chiark / gitweb /
1a4f02db33da3f6c6b8e3a1bbb772f9146e56dd8
[elogind.git] / src / tmpfiles / tmpfiles.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering, Kay Sievers
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <limits.h>
28 #include <dirent.h>
29 #include <grp.h>
30 #include <pwd.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <stddef.h>
34 #include <getopt.h>
35 #include <stdbool.h>
36 #include <time.h>
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <glob.h>
40 #include <fnmatch.h>
41 #include <sys/capability.h>
42
43 #include "log.h"
44 #include "util.h"
45 #include "macro.h"
46 #include "missing.h"
47 #include "mkdir.h"
48 #include "path-util.h"
49 #include "strv.h"
50 #include "label.h"
51 #include "set.h"
52 #include "conf-files.h"
53 #include "capability.h"
54 #include "specifier.h"
55 #include "build.h"
56 #include "copy.h"
57
58 /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
59  * them in the file system. This is intended to be used to create
60  * properly owned directories beneath /tmp, /var/tmp, /run, which are
61  * volatile and hence need to be recreated on bootup. */
62
63 typedef enum ItemType {
64         /* These ones take file names */
65         CREATE_FILE = 'f',
66         TRUNCATE_FILE = 'F',
67         CREATE_DIRECTORY = 'd',
68         TRUNCATE_DIRECTORY = 'D',
69         CREATE_FIFO = 'p',
70         CREATE_SYMLINK = 'L',
71         CREATE_CHAR_DEVICE = 'c',
72         CREATE_BLOCK_DEVICE = 'b',
73         COPY_FILES = 'C',
74
75         /* These ones take globs */
76         WRITE_FILE = 'w',
77         IGNORE_PATH = 'x',
78         IGNORE_DIRECTORY_PATH = 'X',
79         REMOVE_PATH = 'r',
80         RECURSIVE_REMOVE_PATH = 'R',
81         ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
82         RELABEL_PATH = 'z',
83         RECURSIVE_RELABEL_PATH = 'Z',
84 } ItemType;
85
86 typedef struct Item {
87         ItemType type;
88
89         char *path;
90         char *argument;
91         uid_t uid;
92         gid_t gid;
93         mode_t mode;
94         usec_t age;
95
96         dev_t major_minor;
97
98         bool uid_set:1;
99         bool gid_set:1;
100         bool mode_set:1;
101         bool age_set:1;
102         bool mask_perms:1;
103
104         bool keep_first_level:1;
105
106         bool force:1;
107
108         bool done:1;
109 } Item;
110
111 static bool arg_create = false;
112 static bool arg_clean = false;
113 static bool arg_remove = false;
114 static bool arg_boot = false;
115
116 static char **arg_include_prefixes = NULL;
117 static char **arg_exclude_prefixes = NULL;
118 static char *arg_root = NULL;
119
120 static const char conf_file_dirs[] = CONF_DIRS_NULSTR("tmpfiles");
121
122 #define MAX_DEPTH 256
123
124 static Hashmap *items = NULL, *globs = NULL;
125 static Set *unix_sockets = NULL;
126
127 static bool needs_glob(ItemType t) {
128         return IN_SET(t,
129                       WRITE_FILE,
130                       IGNORE_PATH,
131                       IGNORE_DIRECTORY_PATH,
132                       REMOVE_PATH,
133                       RECURSIVE_REMOVE_PATH,
134                       ADJUST_MODE,
135                       RELABEL_PATH,
136                       RECURSIVE_RELABEL_PATH);
137 }
138
139 static struct Item* find_glob(Hashmap *h, const char *match) {
140         Item *j;
141         Iterator i;
142
143         HASHMAP_FOREACH(j, h, i)
144                 if (fnmatch(j->path, match, FNM_PATHNAME|FNM_PERIOD) == 0)
145                         return j;
146
147         return NULL;
148 }
149
150 static void load_unix_sockets(void) {
151         _cleanup_fclose_ FILE *f = NULL;
152         char line[LINE_MAX];
153
154         if (unix_sockets)
155                 return;
156
157         /* We maintain a cache of the sockets we found in
158          * /proc/net/unix to speed things up a little. */
159
160         unix_sockets = set_new(&string_hash_ops);
161         if (!unix_sockets)
162                 return;
163
164         f = fopen("/proc/net/unix", "re");
165         if (!f)
166                 return;
167
168         /* Skip header */
169         if (!fgets(line, sizeof(line), f))
170                 goto fail;
171
172         for (;;) {
173                 char *p, *s;
174                 int k;
175
176                 if (!fgets(line, sizeof(line), f))
177                         break;
178
179                 truncate_nl(line);
180
181                 p = strchr(line, ':');
182                 if (!p)
183                         continue;
184
185                 if (strlen(p) < 37)
186                         continue;
187
188                 p += 37;
189                 p += strspn(p, WHITESPACE);
190                 p += strcspn(p, WHITESPACE); /* skip one more word */
191                 p += strspn(p, WHITESPACE);
192
193                 if (*p != '/')
194                         continue;
195
196                 s = strdup(p);
197                 if (!s)
198                         goto fail;
199
200                 path_kill_slashes(s);
201
202                 k = set_consume(unix_sockets, s);
203                 if (k < 0 && k != -EEXIST)
204                         goto fail;
205         }
206
207         return;
208
209 fail:
210         set_free_free(unix_sockets);
211         unix_sockets = NULL;
212 }
213
214 static bool unix_socket_alive(const char *fn) {
215         assert(fn);
216
217         load_unix_sockets();
218
219         if (unix_sockets)
220                 return !!set_get(unix_sockets, (char*) fn);
221
222         /* We don't know, so assume yes */
223         return true;
224 }
225
226 static int dir_is_mount_point(DIR *d, const char *subdir) {
227
228         union file_handle_union h = {
229                 .handle.handle_bytes = MAX_HANDLE_SZ
230         };
231
232         int mount_id_parent, mount_id;
233         int r_p, r;
234
235         r_p = name_to_handle_at(dirfd(d), ".", &h.handle, &mount_id_parent, 0);
236         if (r_p < 0)
237                 r_p = -errno;
238
239         h.handle.handle_bytes = MAX_HANDLE_SZ;
240         r = name_to_handle_at(dirfd(d), subdir, &h.handle, &mount_id, 0);
241         if (r < 0)
242                 r = -errno;
243
244         /* got no handle; make no assumptions, return error */
245         if (r_p < 0 && r < 0)
246                 return r_p;
247
248         /* got both handles; if they differ, it is a mount point */
249         if (r_p >= 0 && r >= 0)
250                 return mount_id_parent != mount_id;
251
252         /* got only one handle; assume different mount points if one
253          * of both queries was not supported by the filesystem */
254         if (r_p == -ENOSYS || r_p == -EOPNOTSUPP || r == -ENOSYS || r == -EOPNOTSUPP)
255                 return true;
256
257         /* return error */
258         if (r_p < 0)
259                 return r_p;
260         return r;
261 }
262
263 static int dir_cleanup(
264                 Item *i,
265                 const char *p,
266                 DIR *d,
267                 const struct stat *ds,
268                 usec_t cutoff,
269                 dev_t rootdev,
270                 bool mountpoint,
271                 int maxdepth,
272                 bool keep_this_level) {
273
274         struct dirent *dent;
275         struct timespec times[2];
276         bool deleted = false;
277         int r = 0;
278
279         while ((dent = readdir(d))) {
280                 struct stat s;
281                 usec_t age;
282                 _cleanup_free_ char *sub_path = NULL;
283
284                 if (streq(dent->d_name, ".") ||
285                     streq(dent->d_name, ".."))
286                         continue;
287
288                 if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
289                         if (errno == ENOENT)
290                                 continue;
291
292                         /* FUSE, NFS mounts, SELinux might return EACCES */
293                         if (errno == EACCES)
294                                 log_debug("stat(%s/%s) failed: %m", p, dent->d_name);
295                         else
296                                 log_error("stat(%s/%s) failed: %m", p, dent->d_name);
297                         r = -errno;
298                         continue;
299                 }
300
301                 /* Stay on the same filesystem */
302                 if (s.st_dev != rootdev)
303                         continue;
304
305                 /* Try to detect bind mounts of the same filesystem instance; they
306                  * do not differ in device major/minors. This type of query is not
307                  * supported on all kernels or filesystem types though. */
308                 if (S_ISDIR(s.st_mode) && dir_is_mount_point(d, dent->d_name) > 0)
309                         continue;
310
311                 /* Do not delete read-only files owned by root */
312                 if (s.st_uid == 0 && !(s.st_mode & S_IWUSR))
313                         continue;
314
315                 sub_path = strjoin(p, "/", dent->d_name, NULL);
316                 if (!sub_path) {
317                         r = log_oom();
318                         goto finish;
319                 }
320
321                 /* Is there an item configured for this path? */
322                 if (hashmap_get(items, sub_path))
323                         continue;
324
325                 if (find_glob(globs, sub_path))
326                         continue;
327
328                 if (S_ISDIR(s.st_mode)) {
329
330                         if (mountpoint &&
331                             streq(dent->d_name, "lost+found") &&
332                             s.st_uid == 0)
333                                 continue;
334
335                         if (maxdepth <= 0)
336                                 log_warning("Reached max depth on %s.", sub_path);
337                         else {
338                                 _cleanup_closedir_ DIR *sub_dir;
339                                 int q;
340
341                                 sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW|O_NOATIME);
342                                 if (!sub_dir) {
343                                         if (errno != ENOENT) {
344                                                 log_error("opendir(%s/%s) failed: %m", p, dent->d_name);
345                                                 r = -errno;
346                                         }
347
348                                         continue;
349                                 }
350
351                                 q = dir_cleanup(i, sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false);
352                                 if (q < 0)
353                                         r = q;
354                         }
355
356                         /* Note: if you are wondering why we don't
357                          * support the sticky bit for excluding
358                          * directories from cleaning like we do it for
359                          * other file system objects: well, the sticky
360                          * bit already has a meaning for directories,
361                          * so we don't want to overload that. */
362
363                         if (keep_this_level)
364                                 continue;
365
366                         /* Ignore ctime, we change it when deleting */
367                         age = MAX(timespec_load(&s.st_mtim),
368                                   timespec_load(&s.st_atim));
369                         if (age >= cutoff)
370                                 continue;
371
372                         if (i->type != IGNORE_DIRECTORY_PATH || !streq(dent->d_name, p)) {
373                                 log_debug("rmdir '%s'", sub_path);
374
375                                 if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) {
376                                         if (errno != ENOENT && errno != ENOTEMPTY) {
377                                                 log_error("rmdir(%s): %m", sub_path);
378                                                 r = -errno;
379                                         }
380                                 }
381                         }
382
383                 } else {
384                         /* Skip files for which the sticky bit is
385                          * set. These are semantics we define, and are
386                          * unknown elsewhere. See XDG_RUNTIME_DIR
387                          * specification for details. */
388                         if (s.st_mode & S_ISVTX)
389                                 continue;
390
391                         if (mountpoint && S_ISREG(s.st_mode)) {
392                                 if (streq(dent->d_name, ".journal") &&
393                                     s.st_uid == 0)
394                                         continue;
395
396                                 if (streq(dent->d_name, "aquota.user") ||
397                                     streq(dent->d_name, "aquota.group"))
398                                         continue;
399                         }
400
401                         /* Ignore sockets that are listed in /proc/net/unix */
402                         if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path))
403                                 continue;
404
405                         /* Ignore device nodes */
406                         if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
407                                 continue;
408
409                         /* Keep files on this level around if this is
410                          * requested */
411                         if (keep_this_level)
412                                 continue;
413
414                         age = MAX3(timespec_load(&s.st_mtim),
415                                    timespec_load(&s.st_atim),
416                                    timespec_load(&s.st_ctim));
417
418                         if (age >= cutoff)
419                                 continue;
420
421                         log_debug("unlink '%s'", sub_path);
422
423                         if (unlinkat(dirfd(d), dent->d_name, 0) < 0) {
424                                 if (errno != ENOENT) {
425                                         log_error("unlink(%s): %m", sub_path);
426                                         r = -errno;
427                                 }
428                         }
429
430                         deleted = true;
431                 }
432         }
433
434 finish:
435         if (deleted) {
436                 /* Restore original directory timestamps */
437                 times[0] = ds->st_atim;
438                 times[1] = ds->st_mtim;
439
440                 if (futimens(dirfd(d), times) < 0)
441                         log_error("utimensat(%s): %m", p);
442         }
443
444         return r;
445 }
446
447 static int item_set_perms(Item *i, const char *path) {
448         struct stat st;
449         bool st_valid;
450
451         assert(i);
452         assert(path);
453
454         st_valid = stat(path, &st) == 0;
455
456         /* not using i->path directly because it may be a glob */
457         if (i->mode_set) {
458                 mode_t m = i->mode;
459
460                 if (i->mask_perms && st_valid) {
461                         if (!(st.st_mode & 0111))
462                                 m &= ~0111;
463                         if (!(st.st_mode & 0222))
464                                 m &= ~0222;
465                         if (!(st.st_mode & 0444))
466                                 m &= ~0444;
467                         if (!S_ISDIR(st.st_mode))
468                                 m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */
469                 }
470
471                 if (!st_valid || m != (st.st_mode & 07777)) {
472                         if (chmod(path, m) < 0) {
473                                 log_error("chmod(%s) failed: %m", path);
474                                 return -errno;
475                         }
476                 }
477         }
478
479         if ((!st_valid || (i->uid != st.st_uid || i->gid != st.st_gid)) &&
480             (i->uid_set || i->gid_set))
481                 if (chown(path,
482                           i->uid_set ? i->uid : (uid_t) -1,
483                           i->gid_set ? i->gid : (gid_t) -1) < 0) {
484
485                         log_error("chown(%s) failed: %m", path);
486                         return -errno;
487                 }
488
489         return label_fix(path, false, false);
490 }
491
492 static int write_one_file(Item *i, const char *path) {
493         _cleanup_close_ int fd = -1;
494         int flags, r = 0;
495         struct stat st;
496
497         assert(i);
498         assert(path);
499
500         flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND|O_NOFOLLOW :
501                 i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0;
502
503         RUN_WITH_UMASK(0000) {
504                 mac_selinux_create_file_prepare(path, S_IFREG);
505                 fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode);
506                 mac_selinux_create_file_clear();
507         }
508
509         if (fd < 0) {
510                 if (i->type == WRITE_FILE && errno == ENOENT)
511                         return 0;
512
513                 log_error("Failed to create file %s: %m", path);
514                 return -errno;
515         }
516
517         if (i->argument) {
518                 _cleanup_free_ char *unescaped;
519                 ssize_t n;
520                 size_t l;
521
522                 unescaped = cunescape(i->argument);
523                 if (!unescaped)
524                         return log_oom();
525
526                 l = strlen(unescaped);
527                 n = write(fd, unescaped, l);
528
529                 if (n < 0 || (size_t) n < l) {
530                         log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
531                         return n < 0 ? n : -EIO;
532                 }
533         }
534
535         fd = safe_close(fd);
536
537         if (stat(path, &st) < 0) {
538                 log_error("stat(%s) failed: %m", path);
539                 return -errno;
540         }
541
542         if (!S_ISREG(st.st_mode)) {
543                 log_error("%s is not a file.", path);
544                 return -EEXIST;
545         }
546
547         r = item_set_perms(i, path);
548         if (r < 0)
549                 return r;
550
551         return 0;
552 }
553
554 static int item_set_perms_children(Item *i, const char *path) {
555         _cleanup_closedir_ DIR *d;
556         int r = 0;
557
558         assert(i);
559         assert(path);
560
561         /* This returns the first error we run into, but nevertheless
562          * tries to go on */
563
564         d = opendir(path);
565         if (!d)
566                 return errno == ENOENT || errno == ENOTDIR ? 0 : -errno;
567
568         for (;;) {
569                 _cleanup_free_ char *p = NULL;
570                 struct dirent *de;
571                 int q;
572
573                 errno = 0;
574                 de = readdir(d);
575                 if (!de) {
576                         if (errno != 0 && r == 0)
577                                 r = -errno;
578
579                         break;
580                 }
581
582                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
583                         continue;
584
585                 p = strjoin(path, "/", de->d_name, NULL);
586                 if (!p)
587                         return -ENOMEM;
588
589                 q = item_set_perms(i, p);
590                 if (q < 0 && q != -ENOENT && r == 0)
591                         r = q;
592
593                 if (IN_SET(de->d_type, DT_UNKNOWN, DT_DIR)) {
594                         q = item_set_perms_children(i, p);
595                         if (q < 0 && r == 0)
596                                 r = q;
597                 }
598         }
599
600         return r;
601 }
602
603 static int item_set_perms_recursive(Item *i, const char *path) {
604         int r, q;
605
606         assert(i);
607         assert(path);
608
609         r = item_set_perms(i, path);
610         if (r < 0)
611                 return r;
612
613         q = item_set_perms_children(i, path);
614         if (q < 0 && r == 0)
615                 r = q;
616
617         return r;
618 }
619
620 static int glob_item(Item *i, int (*action)(Item *, const char *)) {
621         _cleanup_globfree_ glob_t g = {};
622         int r = 0, k;
623         char **fn;
624
625         errno = 0;
626         k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
627         if (k != 0 && k != GLOB_NOMATCH) {
628                 if (errno == 0)
629                         errno = EIO;
630
631                 log_error("glob(%s) failed: %m", i->path);
632                 return -errno;
633         }
634
635         STRV_FOREACH(fn, g.gl_pathv) {
636                 k = action(i, *fn);
637                 if (k < 0 && r == 0)
638                         r = k;
639         }
640
641         return r;
642 }
643
644 static int create_item(Item *i) {
645         struct stat st;
646         int r = 0;
647
648         assert(i);
649
650         switch (i->type) {
651
652         case IGNORE_PATH:
653         case IGNORE_DIRECTORY_PATH:
654         case REMOVE_PATH:
655         case RECURSIVE_REMOVE_PATH:
656                 return 0;
657
658         case CREATE_FILE:
659         case TRUNCATE_FILE:
660                 r = write_one_file(i, i->path);
661                 if (r < 0)
662                         return r;
663                 break;
664
665         case COPY_FILES:
666                 r = copy_tree(i->argument, i->path, false);
667                 if (r < 0) {
668                         struct stat a, b;
669
670                         if (r != -EEXIST) {
671                                 log_error_errno(r, "Failed to copy files to %s: %m", i->path);
672                                 return -r;
673                         }
674
675                         if (stat(i->argument, &a) < 0) {
676                                 log_error("stat(%s) failed: %m", i->argument);
677                                 return -errno;
678                         }
679
680                         if (stat(i->path, &b) < 0) {
681                                 log_error("stat(%s) failed: %m", i->path);
682                                 return -errno;
683                         }
684
685                         if ((a.st_mode ^ b.st_mode) & S_IFMT) {
686                                 log_debug("Can't copy to %s, file exists already and is of different type", i->path);
687                                 return 0;
688                         }
689                 }
690
691                 r = item_set_perms(i, i->path);
692                 if (r < 0)
693                         return r;
694
695                 break;
696
697         case WRITE_FILE:
698                 r = glob_item(i, write_one_file);
699                 if (r < 0)
700                         return r;
701
702                 break;
703
704         case TRUNCATE_DIRECTORY:
705         case CREATE_DIRECTORY:
706
707                 RUN_WITH_UMASK(0000) {
708                         mkdir_parents_label(i->path, 0755);
709                         r = mkdir_label(i->path, i->mode);
710                 }
711
712                 if (r < 0) {
713                         if (r != -EEXIST)
714                                 return log_error_errno(r, "Failed to create directory %s: %m", i->path);
715
716                         if (stat(i->path, &st) < 0) {
717                                 log_error("stat(%s) failed: %m", i->path);
718                                 return -errno;
719                         }
720
721                         if (!S_ISDIR(st.st_mode)) {
722                                 log_debug("%s already exists and is not a directory.", i->path);
723                                 return 0;
724                         }
725                 }
726
727                 r = item_set_perms(i, i->path);
728                 if (r < 0)
729                         return r;
730
731                 break;
732
733         case CREATE_FIFO:
734
735                 RUN_WITH_UMASK(0000) {
736                         mac_selinux_create_file_prepare(i->path, S_IFIFO);
737                         r = mkfifo(i->path, i->mode);
738                         mac_selinux_create_file_clear();
739                 }
740
741                 if (r < 0) {
742                         if (errno != EEXIST) {
743                                 log_error("Failed to create fifo %s: %m", i->path);
744                                 return -errno;
745                         }
746
747                         if (stat(i->path, &st) < 0) {
748                                 log_error("stat(%s) failed: %m", i->path);
749                                 return -errno;
750                         }
751
752                         if (!S_ISFIFO(st.st_mode)) {
753
754                                 if (i->force) {
755
756                                         RUN_WITH_UMASK(0000) {
757                                                 mac_selinux_create_file_prepare(i->path, S_IFIFO);
758                                                 r = mkfifo_atomic(i->path, i->mode);
759                                                 mac_selinux_create_file_clear();
760                                         }
761
762                                         if (r < 0)
763                                                 return log_error_errno(r, "Failed to create fifo %s: %m", i->path);
764                                 } else {
765                                         log_debug("%s is not a fifo.", i->path);
766                                         return 0;
767                                 }
768                         }
769                 }
770
771                 r = item_set_perms(i, i->path);
772                 if (r < 0)
773                         return r;
774
775                 break;
776
777         case CREATE_SYMLINK:
778
779                 mac_selinux_create_file_prepare(i->path, S_IFLNK);
780                 r = symlink(i->argument, i->path);
781                 mac_selinux_create_file_clear();
782
783                 if (r < 0) {
784                         _cleanup_free_ char *x = NULL;
785
786                         if (errno != EEXIST) {
787                                 log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
788                                 return -errno;
789                         }
790
791                         r = readlink_malloc(i->path, &x);
792                         if (r < 0 || !streq(i->argument, x)) {
793
794                                 if (i->force) {
795                                         mac_selinux_create_file_prepare(i->path, S_IFLNK);
796                                         r = symlink_atomic(i->argument, i->path);
797                                         mac_selinux_create_file_clear();
798
799                                         if (r < 0)
800                                                 return log_error_errno(r, "symlink(%s, %s) failed: %m", i->argument, i->path);
801                                 } else {
802                                         log_debug("%s is not a symlink or does not point to the correct path.", i->path);
803                                         return 0;
804                                 }
805                         }
806                 }
807
808                 break;
809
810         case CREATE_BLOCK_DEVICE:
811         case CREATE_CHAR_DEVICE: {
812                 mode_t file_type;
813
814                 if (have_effective_cap(CAP_MKNOD) == 0) {
815                         /* In a container we lack CAP_MKNOD. We
816                         shouldn't attempt to create the device node in
817                         that case to avoid noise, and we don't support
818                         virtualized devices in containers anyway. */
819
820                         log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path);
821                         return 0;
822                 }
823
824                 file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
825
826                 RUN_WITH_UMASK(0000) {
827                         mac_selinux_create_file_prepare(i->path, file_type);
828                         r = mknod(i->path, i->mode | file_type, i->major_minor);
829                         mac_selinux_create_file_clear();
830                 }
831
832                 if (r < 0) {
833                         if (errno == EPERM) {
834                                 log_debug("We lack permissions, possibly because of cgroup configuration; "
835                                           "skipping creation of device node %s.", i->path);
836                                 return 0;
837                         }
838
839                         if (errno != EEXIST) {
840                                 log_error("Failed to create device node %s: %m", i->path);
841                                 return -errno;
842                         }
843
844                         if (stat(i->path, &st) < 0) {
845                                 log_error("stat(%s) failed: %m", i->path);
846                                 return -errno;
847                         }
848
849                         if ((st.st_mode & S_IFMT) != file_type) {
850
851                                 if (i->force) {
852
853                                         RUN_WITH_UMASK(0000) {
854                                                 mac_selinux_create_file_prepare(i->path, file_type);
855                                                 r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
856                                                 mac_selinux_create_file_clear();
857                                         }
858
859                                         if (r < 0)
860                                                 return log_error_errno(r, "Failed to create device node %s: %m", i->path);
861                                 } else {
862                                         log_debug("%s is not a device node.", i->path);
863                                         return 0;
864                                 }
865                         }
866                 }
867
868                 r = item_set_perms(i, i->path);
869                 if (r < 0)
870                         return r;
871
872                 break;
873         }
874
875         case ADJUST_MODE:
876         case RELABEL_PATH:
877
878                 r = glob_item(i, item_set_perms);
879                 if (r < 0)
880                         return r;
881                 break;
882
883         case RECURSIVE_RELABEL_PATH:
884
885                 r = glob_item(i, item_set_perms_recursive);
886                 if (r < 0)
887                         return r;
888
889                 break;
890         }
891
892         log_debug("%s created successfully.", i->path);
893
894         return 0;
895 }
896
897 static int remove_item_instance(Item *i, const char *instance) {
898         int r;
899
900         assert(i);
901
902         switch (i->type) {
903
904         case CREATE_FILE:
905         case TRUNCATE_FILE:
906         case CREATE_DIRECTORY:
907         case CREATE_FIFO:
908         case CREATE_SYMLINK:
909         case CREATE_BLOCK_DEVICE:
910         case CREATE_CHAR_DEVICE:
911         case IGNORE_PATH:
912         case IGNORE_DIRECTORY_PATH:
913         case ADJUST_MODE:
914         case RELABEL_PATH:
915         case RECURSIVE_RELABEL_PATH:
916         case WRITE_FILE:
917         case COPY_FILES:
918                 break;
919
920         case REMOVE_PATH:
921                 if (remove(instance) < 0 && errno != ENOENT) {
922                         log_error("remove(%s): %m", instance);
923                         return -errno;
924                 }
925
926                 break;
927
928         case TRUNCATE_DIRECTORY:
929         case RECURSIVE_REMOVE_PATH:
930                 /* FIXME: we probably should use dir_cleanup() here
931                  * instead of rm_rf() so that 'x' is honoured. */
932                 r = rm_rf_dangerous(instance, false, i->type == RECURSIVE_REMOVE_PATH, false);
933                 if (r < 0 && r != -ENOENT)
934                         return log_error_errno(r, "rm_rf(%s): %m", instance);
935
936                 break;
937         }
938
939         return 0;
940 }
941
942 static int remove_item(Item *i) {
943         int r = 0;
944
945         assert(i);
946
947         switch (i->type) {
948
949         case CREATE_FILE:
950         case TRUNCATE_FILE:
951         case CREATE_DIRECTORY:
952         case CREATE_FIFO:
953         case CREATE_SYMLINK:
954         case CREATE_CHAR_DEVICE:
955         case CREATE_BLOCK_DEVICE:
956         case IGNORE_PATH:
957         case IGNORE_DIRECTORY_PATH:
958         case ADJUST_MODE:
959         case RELABEL_PATH:
960         case RECURSIVE_RELABEL_PATH:
961         case WRITE_FILE:
962         case COPY_FILES:
963                 break;
964
965         case REMOVE_PATH:
966         case TRUNCATE_DIRECTORY:
967         case RECURSIVE_REMOVE_PATH:
968                 r = glob_item(i, remove_item_instance);
969                 break;
970         }
971
972         return r;
973 }
974
975 static int clean_item_instance(Item *i, const char* instance) {
976         _cleanup_closedir_ DIR *d = NULL;
977         struct stat s, ps;
978         bool mountpoint;
979         int r;
980         usec_t cutoff, n;
981
982         assert(i);
983
984         if (!i->age_set)
985                 return 0;
986
987         n = now(CLOCK_REALTIME);
988         if (n < i->age)
989                 return 0;
990
991         cutoff = n - i->age;
992
993         d = opendir(instance);
994         if (!d) {
995                 if (errno == ENOENT || errno == ENOTDIR)
996                         return 0;
997
998                 log_error("Failed to open directory %s: %m", i->path);
999                 return -errno;
1000         }
1001
1002         if (fstat(dirfd(d), &s) < 0) {
1003                 log_error("stat(%s) failed: %m", i->path);
1004                 return -errno;
1005         }
1006
1007         if (!S_ISDIR(s.st_mode)) {
1008                 log_error("%s is not a directory.", i->path);
1009                 return -ENOTDIR;
1010         }
1011
1012         if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) {
1013                 log_error("stat(%s/..) failed: %m", i->path);
1014                 return -errno;
1015         }
1016
1017         mountpoint = s.st_dev != ps.st_dev ||
1018                      (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino);
1019
1020         r = dir_cleanup(i, instance, d, &s, cutoff, s.st_dev, mountpoint,
1021                         MAX_DEPTH, i->keep_first_level);
1022         return r;
1023 }
1024
1025 static int clean_item(Item *i) {
1026         int r = 0;
1027
1028         assert(i);
1029
1030         switch (i->type) {
1031         case CREATE_DIRECTORY:
1032         case TRUNCATE_DIRECTORY:
1033         case IGNORE_PATH:
1034         case COPY_FILES:
1035                 clean_item_instance(i, i->path);
1036                 break;
1037         case IGNORE_DIRECTORY_PATH:
1038                 r = glob_item(i, clean_item_instance);
1039                 break;
1040         default:
1041                 break;
1042         }
1043
1044         return r;
1045 }
1046
1047 static int process_item(Item *i) {
1048         int r, q, p;
1049         _cleanup_free_ char *prefix = NULL;
1050
1051         assert(i);
1052
1053         if (i->done)
1054                 return 0;
1055
1056         i->done = true;
1057
1058         prefix = malloc(strlen(i->path) + 1);
1059         if (!prefix)
1060                 return log_oom();
1061
1062         PATH_FOREACH_PREFIX(prefix, i->path) {
1063                 Item *j;
1064
1065                 j = hashmap_get(items, prefix);
1066                 if (j)
1067                         process_item(j);
1068         }
1069
1070         r = arg_create ? create_item(i) : 0;
1071         q = arg_remove ? remove_item(i) : 0;
1072         p = arg_clean ? clean_item(i) : 0;
1073
1074         if (r < 0)
1075                 return r;
1076
1077         if (q < 0)
1078                 return q;
1079
1080         return p;
1081 }
1082
1083 static void item_free(Item *i) {
1084
1085         if (!i)
1086                 return;
1087
1088         free(i->path);
1089         free(i->argument);
1090         free(i);
1091 }
1092
1093 DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
1094
1095 static bool item_equal(Item *a, Item *b) {
1096         assert(a);
1097         assert(b);
1098
1099         if (!streq_ptr(a->path, b->path))
1100                 return false;
1101
1102         if (a->type != b->type)
1103                 return false;
1104
1105         if (a->uid_set != b->uid_set ||
1106             (a->uid_set && a->uid != b->uid))
1107             return false;
1108
1109         if (a->gid_set != b->gid_set ||
1110             (a->gid_set && a->gid != b->gid))
1111             return false;
1112
1113         if (a->mode_set != b->mode_set ||
1114             (a->mode_set && a->mode != b->mode))
1115             return false;
1116
1117         if (a->age_set != b->age_set ||
1118             (a->age_set && a->age != b->age))
1119             return false;
1120
1121         if ((a->type == CREATE_FILE ||
1122              a->type == TRUNCATE_FILE ||
1123              a->type == WRITE_FILE ||
1124              a->type == CREATE_SYMLINK ||
1125              a->type == COPY_FILES) &&
1126             !streq_ptr(a->argument, b->argument))
1127                 return false;
1128
1129         if ((a->type == CREATE_CHAR_DEVICE ||
1130              a->type == CREATE_BLOCK_DEVICE) &&
1131             a->major_minor != b->major_minor)
1132                 return false;
1133
1134         return true;
1135 }
1136
1137 static bool should_include_path(const char *path) {
1138         char **prefix;
1139
1140         STRV_FOREACH(prefix, arg_exclude_prefixes)
1141                 if (path_startswith(path, *prefix))
1142                         return false;
1143
1144         STRV_FOREACH(prefix, arg_include_prefixes)
1145                 if (path_startswith(path, *prefix))
1146                         return true;
1147
1148         /* no matches, so we should include this path only if we
1149          * have no whitelist at all */
1150         return strv_length(arg_include_prefixes) == 0;
1151 }
1152
1153 static int parse_line(const char *fname, unsigned line, const char *buffer) {
1154
1155         static const Specifier specifier_table[] = {
1156                 { 'm', specifier_machine_id, NULL },
1157                 { 'b', specifier_boot_id, NULL },
1158                 { 'H', specifier_host_name, NULL },
1159                 { 'v', specifier_kernel_release, NULL },
1160                 {}
1161         };
1162
1163         _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
1164         _cleanup_(item_freep) Item *i = NULL;
1165         Item *existing;
1166         char type;
1167         Hashmap *h;
1168         int r, n = -1;
1169
1170         assert(fname);
1171         assert(line >= 1);
1172         assert(buffer);
1173
1174         r = sscanf(buffer,
1175                    "%ms %ms %ms %ms %ms %ms %n",
1176                    &action,
1177                    &path,
1178                    &mode,
1179                    &user,
1180                    &group,
1181                    &age,
1182                    &n);
1183         if (r < 2) {
1184                 log_error("[%s:%u] Syntax error.", fname, line);
1185                 return -EIO;
1186         }
1187
1188         if (isempty(action)) {
1189                 log_error("[%s:%u] Command too short '%s'.", fname, line, action);
1190                 return -EINVAL;
1191         }
1192
1193         if (strlen(action) > 1 && !in_charset(action+1, "!+")) {
1194                 log_error("[%s:%u] Unknown modifiers in command '%s'", fname, line, action);
1195                 return -EINVAL;
1196         }
1197
1198         if (strchr(action+1, '!') && !arg_boot)
1199                 return 0;
1200
1201         type = action[0];
1202
1203         i = new0(Item, 1);
1204         if (!i)
1205                 return log_oom();
1206
1207         i->force = !!strchr(action+1, '+');
1208
1209         r = specifier_printf(path, specifier_table, NULL, &i->path);
1210         if (r < 0) {
1211                 log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, path);
1212                 return r;
1213         }
1214
1215         if (n >= 0)  {
1216                 n += strspn(buffer+n, WHITESPACE);
1217                 if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) {
1218                         i->argument = unquote(buffer+n, "\"");
1219                         if (!i->argument)
1220                                 return log_oom();
1221                 }
1222         }
1223
1224         switch (type) {
1225
1226         case CREATE_FILE:
1227         case TRUNCATE_FILE:
1228         case CREATE_DIRECTORY:
1229         case TRUNCATE_DIRECTORY:
1230         case CREATE_FIFO:
1231         case IGNORE_PATH:
1232         case IGNORE_DIRECTORY_PATH:
1233         case REMOVE_PATH:
1234         case RECURSIVE_REMOVE_PATH:
1235         case ADJUST_MODE:
1236         case RELABEL_PATH:
1237         case RECURSIVE_RELABEL_PATH:
1238                 break;
1239
1240         case CREATE_SYMLINK:
1241                 if (!i->argument) {
1242                         i->argument = strappend("/usr/share/factory", i->path);
1243                         if (!i->argument)
1244                                 return log_oom();
1245                 }
1246                 break;
1247
1248         case WRITE_FILE:
1249                 if (!i->argument) {
1250                         log_error("[%s:%u] Write file requires argument.", fname, line);
1251                         return -EBADMSG;
1252                 }
1253                 break;
1254
1255         case COPY_FILES:
1256                 if (!i->argument) {
1257                         i->argument = strappend("/usr/share/factory", i->path);
1258                         if (!i->argument)
1259                                 return log_oom();
1260                 }
1261
1262                 if (!path_is_absolute(i->argument)) {
1263                         log_error("[%s:%u] Source path is not absolute.", fname, line);
1264                         return -EBADMSG;
1265                 }
1266
1267                 path_kill_slashes(i->argument);
1268                 break;
1269
1270         case CREATE_CHAR_DEVICE:
1271         case CREATE_BLOCK_DEVICE: {
1272                 unsigned major, minor;
1273
1274                 if (!i->argument) {
1275                         log_error("[%s:%u] Device file requires argument.", fname, line);
1276                         return -EBADMSG;
1277                 }
1278
1279                 if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
1280                         log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
1281                         return -EBADMSG;
1282                 }
1283
1284                 i->major_minor = makedev(major, minor);
1285                 break;
1286         }
1287
1288         default:
1289                 log_error("[%s:%u] Unknown command type '%c'.", fname, line, type);
1290                 return -EBADMSG;
1291         }
1292
1293         i->type = type;
1294
1295         if (!path_is_absolute(i->path)) {
1296                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
1297                 return -EBADMSG;
1298         }
1299
1300         path_kill_slashes(i->path);
1301
1302         if (!should_include_path(i->path))
1303                 return 0;
1304
1305         if (arg_root) {
1306                 char *p;
1307
1308                 p = strappend(arg_root, i->path);
1309                 if (!p)
1310                         return log_oom();
1311
1312                 free(i->path);
1313                 i->path = p;
1314         }
1315
1316         if (user && !streq(user, "-")) {
1317                 const char *u = user;
1318
1319                 r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
1320                 if (r < 0) {
1321                         log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
1322                         return r;
1323                 }
1324
1325                 i->uid_set = true;
1326         }
1327
1328         if (group && !streq(group, "-")) {
1329                 const char *g = group;
1330
1331                 r = get_group_creds(&g, &i->gid);
1332                 if (r < 0) {
1333                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
1334                         return r;
1335                 }
1336
1337                 i->gid_set = true;
1338         }
1339
1340         if (mode && !streq(mode, "-")) {
1341                 const char *mm = mode;
1342                 unsigned m;
1343
1344                 if (*mm == '~') {
1345                         i->mask_perms = true;
1346                         mm++;
1347                 }
1348
1349                 if (sscanf(mm, "%o", &m) != 1) {
1350                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
1351                         return -ENOENT;
1352                 }
1353
1354                 i->mode = m;
1355                 i->mode_set = true;
1356         } else
1357                 i->mode =
1358                         i->type == CREATE_DIRECTORY ||
1359                         i->type == TRUNCATE_DIRECTORY ? 0755 : 0644;
1360
1361         if (age && !streq(age, "-")) {
1362                 const char *a = age;
1363
1364                 if (*a == '~') {
1365                         i->keep_first_level = true;
1366                         a++;
1367                 }
1368
1369                 if (parse_sec(a, &i->age) < 0) {
1370                         log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
1371                         return -EBADMSG;
1372                 }
1373
1374                 i->age_set = true;
1375         }
1376
1377         h = needs_glob(i->type) ? globs : items;
1378
1379         existing = hashmap_get(h, i->path);
1380         if (existing) {
1381
1382                 /* Two identical items are fine */
1383                 if (!item_equal(existing, i))
1384                         log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
1385
1386                 return 0;
1387         }
1388
1389         r = hashmap_put(h, i->path, i);
1390         if (r < 0)
1391                 return log_error_errno(r, "Failed to insert item %s: %m", i->path);
1392
1393         i = NULL; /* avoid cleanup */
1394
1395         return 0;
1396 }
1397
1398 static void help(void) {
1399         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
1400                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
1401                "  -h --help                 Show this help\n"
1402                "     --version              Show package version\n"
1403                "     --create               Create marked files/directories\n"
1404                "     --clean                Clean up marked directories\n"
1405                "     --remove               Remove marked files/directories\n"
1406                "     --boot                 Execute actions only safe at boot\n"
1407                "     --prefix=PATH          Only apply rules that apply to paths with the specified prefix\n"
1408                "     --exclude-prefix=PATH  Ignore rules that apply to paths with the specified prefix\n"
1409                "     --root=PATH            Operate on an alternate filesystem root\n",
1410                program_invocation_short_name);
1411 }
1412
1413 static int parse_argv(int argc, char *argv[]) {
1414
1415         enum {
1416                 ARG_VERSION = 0x100,
1417                 ARG_CREATE,
1418                 ARG_CLEAN,
1419                 ARG_REMOVE,
1420                 ARG_BOOT,
1421                 ARG_PREFIX,
1422                 ARG_EXCLUDE_PREFIX,
1423                 ARG_ROOT,
1424         };
1425
1426         static const struct option options[] = {
1427                 { "help",           no_argument,         NULL, 'h'                },
1428                 { "version",        no_argument,         NULL, ARG_VERSION        },
1429                 { "create",         no_argument,         NULL, ARG_CREATE         },
1430                 { "clean",          no_argument,         NULL, ARG_CLEAN          },
1431                 { "remove",         no_argument,         NULL, ARG_REMOVE         },
1432                 { "boot",           no_argument,         NULL, ARG_BOOT           },
1433                 { "prefix",         required_argument,   NULL, ARG_PREFIX         },
1434                 { "exclude-prefix", required_argument,   NULL, ARG_EXCLUDE_PREFIX },
1435                 { "root",           required_argument,   NULL, ARG_ROOT           },
1436                 {}
1437         };
1438
1439         int c;
1440
1441         assert(argc >= 0);
1442         assert(argv);
1443
1444         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
1445
1446                 switch (c) {
1447
1448                 case 'h':
1449                         help();
1450                         return 0;
1451
1452                 case ARG_VERSION:
1453                         puts(PACKAGE_STRING);
1454                         puts(SYSTEMD_FEATURES);
1455                         return 0;
1456
1457                 case ARG_CREATE:
1458                         arg_create = true;
1459                         break;
1460
1461                 case ARG_CLEAN:
1462                         arg_clean = true;
1463                         break;
1464
1465                 case ARG_REMOVE:
1466                         arg_remove = true;
1467                         break;
1468
1469                 case ARG_BOOT:
1470                         arg_boot = true;
1471                         break;
1472
1473                 case ARG_PREFIX:
1474                         if (strv_push(&arg_include_prefixes, optarg) < 0)
1475                                 return log_oom();
1476                         break;
1477
1478                 case ARG_EXCLUDE_PREFIX:
1479                         if (strv_push(&arg_exclude_prefixes, optarg) < 0)
1480                                 return log_oom();
1481                         break;
1482
1483                 case ARG_ROOT:
1484                         free(arg_root);
1485                         arg_root = path_make_absolute_cwd(optarg);
1486                         if (!arg_root)
1487                                 return log_oom();
1488
1489                         path_kill_slashes(arg_root);
1490                         break;
1491
1492                 case '?':
1493                         return -EINVAL;
1494
1495                 default:
1496                         assert_not_reached("Unhandled option");
1497                 }
1498
1499         if (!arg_clean && !arg_create && !arg_remove) {
1500                 log_error("You need to specify at least one of --clean, --create or --remove.");
1501                 return -EINVAL;
1502         }
1503
1504         return 1;
1505 }
1506
1507 static int read_config_file(const char *fn, bool ignore_enoent) {
1508         _cleanup_fclose_ FILE *f = NULL;
1509         char line[LINE_MAX];
1510         Iterator iterator;
1511         unsigned v = 0;
1512         Item *i;
1513         int r;
1514
1515         assert(fn);
1516
1517         r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
1518         if (r < 0) {
1519                 if (ignore_enoent && r == -ENOENT)
1520                         return 0;
1521
1522                 log_error_errno(r, "Failed to open '%s', ignoring: %m", fn);
1523                 return r;
1524         }
1525
1526         FOREACH_LINE(line, f, break) {
1527                 char *l;
1528                 int k;
1529
1530                 v++;
1531
1532                 l = strstrip(line);
1533                 if (*l == '#' || *l == 0)
1534                         continue;
1535
1536                 k = parse_line(fn, v, l);
1537                 if (k < 0 && r == 0)
1538                         r = k;
1539         }
1540
1541         /* we have to determine age parameter for each entry of type X */
1542         HASHMAP_FOREACH(i, globs, iterator) {
1543                 Iterator iter;
1544                 Item *j, *candidate_item = NULL;
1545
1546                 if (i->type != IGNORE_DIRECTORY_PATH)
1547                         continue;
1548
1549                 HASHMAP_FOREACH(j, items, iter) {
1550                         if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY)
1551                                 continue;
1552
1553                         if (path_equal(j->path, i->path)) {
1554                                 candidate_item = j;
1555                                 break;
1556                         }
1557
1558                         if ((!candidate_item && path_startswith(i->path, j->path)) ||
1559                             (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0)))
1560                                 candidate_item = j;
1561                 }
1562
1563                 if (candidate_item && candidate_item->age_set) {
1564                         i->age = candidate_item->age;
1565                         i->age_set = true;
1566                 }
1567         }
1568
1569         if (ferror(f)) {
1570                 log_error("Failed to read from file %s: %m", fn);
1571                 if (r == 0)
1572                         r = -EIO;
1573         }
1574
1575         return r;
1576 }
1577
1578 int main(int argc, char *argv[]) {
1579         int r, k;
1580         Item *i;
1581         Iterator iterator;
1582
1583         r = parse_argv(argc, argv);
1584         if (r <= 0)
1585                 goto finish;
1586
1587         log_set_target(LOG_TARGET_AUTO);
1588         log_parse_environment();
1589         log_open();
1590
1591         umask(0022);
1592
1593         mac_selinux_init(NULL);
1594
1595         items = hashmap_new(&string_hash_ops);
1596         globs = hashmap_new(&string_hash_ops);
1597
1598         if (!items || !globs) {
1599                 r = log_oom();
1600                 goto finish;
1601         }
1602
1603         r = 0;
1604
1605         if (optind < argc) {
1606                 int j;
1607
1608                 for (j = optind; j < argc; j++) {
1609                         k = read_config_file(argv[j], false);
1610                         if (k < 0 && r == 0)
1611                                 r = k;
1612                 }
1613
1614         } else {
1615                 _cleanup_strv_free_ char **files = NULL;
1616                 char **f;
1617
1618                 r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
1619                 if (r < 0) {
1620                         log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
1621                         goto finish;
1622                 }
1623
1624                 STRV_FOREACH(f, files) {
1625                         k = read_config_file(*f, true);
1626                         if (k < 0 && r == 0)
1627                                 r = k;
1628                 }
1629         }
1630
1631         HASHMAP_FOREACH(i, globs, iterator)
1632                 process_item(i);
1633
1634         HASHMAP_FOREACH(i, items, iterator)
1635                 process_item(i);
1636
1637 finish:
1638         while ((i = hashmap_steal_first(items)))
1639                 item_free(i);
1640
1641         while ((i = hashmap_steal_first(globs)))
1642                 item_free(i);
1643
1644         hashmap_free(items);
1645         hashmap_free(globs);
1646
1647         free(arg_include_prefixes);
1648         free(arg_exclude_prefixes);
1649         free(arg_root);
1650
1651         set_free_free(unix_sockets);
1652
1653         mac_selinux_finish();
1654
1655         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1656 }