chiark / gitweb /
45d31fb5d803c03d1c78efd9de66179759851efe
[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                                 return log_error_errno(r, "Failed to copy files to %s: %m", i->path);
672
673                         if (stat(i->argument, &a) < 0) {
674                                 log_error("stat(%s) failed: %m", i->argument);
675                                 return -errno;
676                         }
677
678                         if (stat(i->path, &b) < 0) {
679                                 log_error("stat(%s) failed: %m", i->path);
680                                 return -errno;
681                         }
682
683                         if ((a.st_mode ^ b.st_mode) & S_IFMT) {
684                                 log_debug("Can't copy to %s, file exists already and is of different type", i->path);
685                                 return 0;
686                         }
687                 }
688
689                 r = item_set_perms(i, i->path);
690                 if (r < 0)
691                         return r;
692
693                 break;
694
695         case WRITE_FILE:
696                 r = glob_item(i, write_one_file);
697                 if (r < 0)
698                         return r;
699
700                 break;
701
702         case TRUNCATE_DIRECTORY:
703         case CREATE_DIRECTORY:
704
705                 RUN_WITH_UMASK(0000) {
706                         mkdir_parents_label(i->path, 0755);
707                         r = mkdir_label(i->path, i->mode);
708                 }
709
710                 if (r < 0) {
711                         if (r != -EEXIST)
712                                 return log_error_errno(r, "Failed to create directory %s: %m", i->path);
713
714                         if (stat(i->path, &st) < 0) {
715                                 log_error("stat(%s) failed: %m", i->path);
716                                 return -errno;
717                         }
718
719                         if (!S_ISDIR(st.st_mode)) {
720                                 log_debug("%s already exists and is not a directory.", i->path);
721                                 return 0;
722                         }
723                 }
724
725                 r = item_set_perms(i, i->path);
726                 if (r < 0)
727                         return r;
728
729                 break;
730
731         case CREATE_FIFO:
732
733                 RUN_WITH_UMASK(0000) {
734                         mac_selinux_create_file_prepare(i->path, S_IFIFO);
735                         r = mkfifo(i->path, i->mode);
736                         mac_selinux_create_file_clear();
737                 }
738
739                 if (r < 0) {
740                         if (errno != EEXIST) {
741                                 log_error("Failed to create fifo %s: %m", i->path);
742                                 return -errno;
743                         }
744
745                         if (stat(i->path, &st) < 0) {
746                                 log_error("stat(%s) failed: %m", i->path);
747                                 return -errno;
748                         }
749
750                         if (!S_ISFIFO(st.st_mode)) {
751
752                                 if (i->force) {
753
754                                         RUN_WITH_UMASK(0000) {
755                                                 mac_selinux_create_file_prepare(i->path, S_IFIFO);
756                                                 r = mkfifo_atomic(i->path, i->mode);
757                                                 mac_selinux_create_file_clear();
758                                         }
759
760                                         if (r < 0)
761                                                 return log_error_errno(r, "Failed to create fifo %s: %m", i->path);
762                                 } else {
763                                         log_debug("%s is not a fifo.", i->path);
764                                         return 0;
765                                 }
766                         }
767                 }
768
769                 r = item_set_perms(i, i->path);
770                 if (r < 0)
771                         return r;
772
773                 break;
774
775         case CREATE_SYMLINK:
776
777                 mac_selinux_create_file_prepare(i->path, S_IFLNK);
778                 r = symlink(i->argument, i->path);
779                 mac_selinux_create_file_clear();
780
781                 if (r < 0) {
782                         _cleanup_free_ char *x = NULL;
783
784                         if (errno != EEXIST) {
785                                 log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
786                                 return -errno;
787                         }
788
789                         r = readlink_malloc(i->path, &x);
790                         if (r < 0 || !streq(i->argument, x)) {
791
792                                 if (i->force) {
793                                         mac_selinux_create_file_prepare(i->path, S_IFLNK);
794                                         r = symlink_atomic(i->argument, i->path);
795                                         mac_selinux_create_file_clear();
796
797                                         if (r < 0)
798                                                 return log_error_errno(r, "symlink(%s, %s) failed: %m", i->argument, i->path);
799                                 } else {
800                                         log_debug("%s is not a symlink or does not point to the correct path.", i->path);
801                                         return 0;
802                                 }
803                         }
804                 }
805
806                 break;
807
808         case CREATE_BLOCK_DEVICE:
809         case CREATE_CHAR_DEVICE: {
810                 mode_t file_type;
811
812                 if (have_effective_cap(CAP_MKNOD) == 0) {
813                         /* In a container we lack CAP_MKNOD. We
814                         shouldn't attempt to create the device node in
815                         that case to avoid noise, and we don't support
816                         virtualized devices in containers anyway. */
817
818                         log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path);
819                         return 0;
820                 }
821
822                 file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
823
824                 RUN_WITH_UMASK(0000) {
825                         mac_selinux_create_file_prepare(i->path, file_type);
826                         r = mknod(i->path, i->mode | file_type, i->major_minor);
827                         mac_selinux_create_file_clear();
828                 }
829
830                 if (r < 0) {
831                         if (errno == EPERM) {
832                                 log_debug("We lack permissions, possibly because of cgroup configuration; "
833                                           "skipping creation of device node %s.", i->path);
834                                 return 0;
835                         }
836
837                         if (errno != EEXIST) {
838                                 log_error("Failed to create device node %s: %m", i->path);
839                                 return -errno;
840                         }
841
842                         if (stat(i->path, &st) < 0) {
843                                 log_error("stat(%s) failed: %m", i->path);
844                                 return -errno;
845                         }
846
847                         if ((st.st_mode & S_IFMT) != file_type) {
848
849                                 if (i->force) {
850
851                                         RUN_WITH_UMASK(0000) {
852                                                 mac_selinux_create_file_prepare(i->path, file_type);
853                                                 r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
854                                                 mac_selinux_create_file_clear();
855                                         }
856
857                                         if (r < 0)
858                                                 return log_error_errno(r, "Failed to create device node %s: %m", i->path);
859                                 } else {
860                                         log_debug("%s is not a device node.", i->path);
861                                         return 0;
862                                 }
863                         }
864                 }
865
866                 r = item_set_perms(i, i->path);
867                 if (r < 0)
868                         return r;
869
870                 break;
871         }
872
873         case ADJUST_MODE:
874         case RELABEL_PATH:
875
876                 r = glob_item(i, item_set_perms);
877                 if (r < 0)
878                         return r;
879                 break;
880
881         case RECURSIVE_RELABEL_PATH:
882
883                 r = glob_item(i, item_set_perms_recursive);
884                 if (r < 0)
885                         return r;
886
887                 break;
888         }
889
890         log_debug("%s created successfully.", i->path);
891
892         return 0;
893 }
894
895 static int remove_item_instance(Item *i, const char *instance) {
896         int r;
897
898         assert(i);
899
900         switch (i->type) {
901
902         case CREATE_FILE:
903         case TRUNCATE_FILE:
904         case CREATE_DIRECTORY:
905         case CREATE_FIFO:
906         case CREATE_SYMLINK:
907         case CREATE_BLOCK_DEVICE:
908         case CREATE_CHAR_DEVICE:
909         case IGNORE_PATH:
910         case IGNORE_DIRECTORY_PATH:
911         case ADJUST_MODE:
912         case RELABEL_PATH:
913         case RECURSIVE_RELABEL_PATH:
914         case WRITE_FILE:
915         case COPY_FILES:
916                 break;
917
918         case REMOVE_PATH:
919                 if (remove(instance) < 0 && errno != ENOENT) {
920                         log_error("remove(%s): %m", instance);
921                         return -errno;
922                 }
923
924                 break;
925
926         case TRUNCATE_DIRECTORY:
927         case RECURSIVE_REMOVE_PATH:
928                 /* FIXME: we probably should use dir_cleanup() here
929                  * instead of rm_rf() so that 'x' is honoured. */
930                 r = rm_rf_dangerous(instance, false, i->type == RECURSIVE_REMOVE_PATH, false);
931                 if (r < 0 && r != -ENOENT)
932                         return log_error_errno(r, "rm_rf(%s): %m", instance);
933
934                 break;
935         }
936
937         return 0;
938 }
939
940 static int remove_item(Item *i) {
941         int r = 0;
942
943         assert(i);
944
945         switch (i->type) {
946
947         case CREATE_FILE:
948         case TRUNCATE_FILE:
949         case CREATE_DIRECTORY:
950         case CREATE_FIFO:
951         case CREATE_SYMLINK:
952         case CREATE_CHAR_DEVICE:
953         case CREATE_BLOCK_DEVICE:
954         case IGNORE_PATH:
955         case IGNORE_DIRECTORY_PATH:
956         case ADJUST_MODE:
957         case RELABEL_PATH:
958         case RECURSIVE_RELABEL_PATH:
959         case WRITE_FILE:
960         case COPY_FILES:
961                 break;
962
963         case REMOVE_PATH:
964         case TRUNCATE_DIRECTORY:
965         case RECURSIVE_REMOVE_PATH:
966                 r = glob_item(i, remove_item_instance);
967                 break;
968         }
969
970         return r;
971 }
972
973 static int clean_item_instance(Item *i, const char* instance) {
974         _cleanup_closedir_ DIR *d = NULL;
975         struct stat s, ps;
976         bool mountpoint;
977         int r;
978         usec_t cutoff, n;
979
980         assert(i);
981
982         if (!i->age_set)
983                 return 0;
984
985         n = now(CLOCK_REALTIME);
986         if (n < i->age)
987                 return 0;
988
989         cutoff = n - i->age;
990
991         d = opendir(instance);
992         if (!d) {
993                 if (errno == ENOENT || errno == ENOTDIR)
994                         return 0;
995
996                 log_error("Failed to open directory %s: %m", i->path);
997                 return -errno;
998         }
999
1000         if (fstat(dirfd(d), &s) < 0) {
1001                 log_error("stat(%s) failed: %m", i->path);
1002                 return -errno;
1003         }
1004
1005         if (!S_ISDIR(s.st_mode)) {
1006                 log_error("%s is not a directory.", i->path);
1007                 return -ENOTDIR;
1008         }
1009
1010         if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) {
1011                 log_error("stat(%s/..) failed: %m", i->path);
1012                 return -errno;
1013         }
1014
1015         mountpoint = s.st_dev != ps.st_dev ||
1016                      (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino);
1017
1018         r = dir_cleanup(i, instance, d, &s, cutoff, s.st_dev, mountpoint,
1019                         MAX_DEPTH, i->keep_first_level);
1020         return r;
1021 }
1022
1023 static int clean_item(Item *i) {
1024         int r = 0;
1025
1026         assert(i);
1027
1028         switch (i->type) {
1029         case CREATE_DIRECTORY:
1030         case TRUNCATE_DIRECTORY:
1031         case IGNORE_PATH:
1032         case COPY_FILES:
1033                 clean_item_instance(i, i->path);
1034                 break;
1035         case IGNORE_DIRECTORY_PATH:
1036                 r = glob_item(i, clean_item_instance);
1037                 break;
1038         default:
1039                 break;
1040         }
1041
1042         return r;
1043 }
1044
1045 static int process_item(Item *i) {
1046         int r, q, p;
1047         _cleanup_free_ char *prefix = NULL;
1048
1049         assert(i);
1050
1051         if (i->done)
1052                 return 0;
1053
1054         i->done = true;
1055
1056         prefix = malloc(strlen(i->path) + 1);
1057         if (!prefix)
1058                 return log_oom();
1059
1060         PATH_FOREACH_PREFIX(prefix, i->path) {
1061                 Item *j;
1062
1063                 j = hashmap_get(items, prefix);
1064                 if (j)
1065                         process_item(j);
1066         }
1067
1068         r = arg_create ? create_item(i) : 0;
1069         q = arg_remove ? remove_item(i) : 0;
1070         p = arg_clean ? clean_item(i) : 0;
1071
1072         if (r < 0)
1073                 return r;
1074
1075         if (q < 0)
1076                 return q;
1077
1078         return p;
1079 }
1080
1081 static void item_free(Item *i) {
1082
1083         if (!i)
1084                 return;
1085
1086         free(i->path);
1087         free(i->argument);
1088         free(i);
1089 }
1090
1091 DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
1092
1093 static bool item_equal(Item *a, Item *b) {
1094         assert(a);
1095         assert(b);
1096
1097         if (!streq_ptr(a->path, b->path))
1098                 return false;
1099
1100         if (a->type != b->type)
1101                 return false;
1102
1103         if (a->uid_set != b->uid_set ||
1104             (a->uid_set && a->uid != b->uid))
1105             return false;
1106
1107         if (a->gid_set != b->gid_set ||
1108             (a->gid_set && a->gid != b->gid))
1109             return false;
1110
1111         if (a->mode_set != b->mode_set ||
1112             (a->mode_set && a->mode != b->mode))
1113             return false;
1114
1115         if (a->age_set != b->age_set ||
1116             (a->age_set && a->age != b->age))
1117             return false;
1118
1119         if ((a->type == CREATE_FILE ||
1120              a->type == TRUNCATE_FILE ||
1121              a->type == WRITE_FILE ||
1122              a->type == CREATE_SYMLINK ||
1123              a->type == COPY_FILES) &&
1124             !streq_ptr(a->argument, b->argument))
1125                 return false;
1126
1127         if ((a->type == CREATE_CHAR_DEVICE ||
1128              a->type == CREATE_BLOCK_DEVICE) &&
1129             a->major_minor != b->major_minor)
1130                 return false;
1131
1132         return true;
1133 }
1134
1135 static bool should_include_path(const char *path) {
1136         char **prefix;
1137
1138         STRV_FOREACH(prefix, arg_exclude_prefixes)
1139                 if (path_startswith(path, *prefix))
1140                         return false;
1141
1142         STRV_FOREACH(prefix, arg_include_prefixes)
1143                 if (path_startswith(path, *prefix))
1144                         return true;
1145
1146         /* no matches, so we should include this path only if we
1147          * have no whitelist at all */
1148         return strv_length(arg_include_prefixes) == 0;
1149 }
1150
1151 static int parse_line(const char *fname, unsigned line, const char *buffer) {
1152
1153         static const Specifier specifier_table[] = {
1154                 { 'm', specifier_machine_id, NULL },
1155                 { 'b', specifier_boot_id, NULL },
1156                 { 'H', specifier_host_name, NULL },
1157                 { 'v', specifier_kernel_release, NULL },
1158                 {}
1159         };
1160
1161         _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
1162         _cleanup_(item_freep) Item *i = NULL;
1163         Item *existing;
1164         char type;
1165         Hashmap *h;
1166         int r, n = -1;
1167
1168         assert(fname);
1169         assert(line >= 1);
1170         assert(buffer);
1171
1172         r = sscanf(buffer,
1173                    "%ms %ms %ms %ms %ms %ms %n",
1174                    &action,
1175                    &path,
1176                    &mode,
1177                    &user,
1178                    &group,
1179                    &age,
1180                    &n);
1181         if (r < 2) {
1182                 log_error("[%s:%u] Syntax error.", fname, line);
1183                 return -EIO;
1184         }
1185
1186         if (isempty(action)) {
1187                 log_error("[%s:%u] Command too short '%s'.", fname, line, action);
1188                 return -EINVAL;
1189         }
1190
1191         if (strlen(action) > 1 && !in_charset(action+1, "!+")) {
1192                 log_error("[%s:%u] Unknown modifiers in command '%s'", fname, line, action);
1193                 return -EINVAL;
1194         }
1195
1196         if (strchr(action+1, '!') && !arg_boot)
1197                 return 0;
1198
1199         type = action[0];
1200
1201         i = new0(Item, 1);
1202         if (!i)
1203                 return log_oom();
1204
1205         i->force = !!strchr(action+1, '+');
1206
1207         r = specifier_printf(path, specifier_table, NULL, &i->path);
1208         if (r < 0) {
1209                 log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, path);
1210                 return r;
1211         }
1212
1213         if (n >= 0)  {
1214                 n += strspn(buffer+n, WHITESPACE);
1215                 if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) {
1216                         i->argument = unquote(buffer+n, "\"");
1217                         if (!i->argument)
1218                                 return log_oom();
1219                 }
1220         }
1221
1222         switch (type) {
1223
1224         case CREATE_FILE:
1225         case TRUNCATE_FILE:
1226         case CREATE_DIRECTORY:
1227         case TRUNCATE_DIRECTORY:
1228         case CREATE_FIFO:
1229         case IGNORE_PATH:
1230         case IGNORE_DIRECTORY_PATH:
1231         case REMOVE_PATH:
1232         case RECURSIVE_REMOVE_PATH:
1233         case ADJUST_MODE:
1234         case RELABEL_PATH:
1235         case RECURSIVE_RELABEL_PATH:
1236                 break;
1237
1238         case CREATE_SYMLINK:
1239                 if (!i->argument) {
1240                         i->argument = strappend("/usr/share/factory", i->path);
1241                         if (!i->argument)
1242                                 return log_oom();
1243                 }
1244                 break;
1245
1246         case WRITE_FILE:
1247                 if (!i->argument) {
1248                         log_error("[%s:%u] Write file requires argument.", fname, line);
1249                         return -EBADMSG;
1250                 }
1251                 break;
1252
1253         case COPY_FILES:
1254                 if (!i->argument) {
1255                         i->argument = strappend("/usr/share/factory", i->path);
1256                         if (!i->argument)
1257                                 return log_oom();
1258                 }
1259
1260                 if (!path_is_absolute(i->argument)) {
1261                         log_error("[%s:%u] Source path is not absolute.", fname, line);
1262                         return -EBADMSG;
1263                 }
1264
1265                 path_kill_slashes(i->argument);
1266                 break;
1267
1268         case CREATE_CHAR_DEVICE:
1269         case CREATE_BLOCK_DEVICE: {
1270                 unsigned major, minor;
1271
1272                 if (!i->argument) {
1273                         log_error("[%s:%u] Device file requires argument.", fname, line);
1274                         return -EBADMSG;
1275                 }
1276
1277                 if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
1278                         log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
1279                         return -EBADMSG;
1280                 }
1281
1282                 i->major_minor = makedev(major, minor);
1283                 break;
1284         }
1285
1286         default:
1287                 log_error("[%s:%u] Unknown command type '%c'.", fname, line, type);
1288                 return -EBADMSG;
1289         }
1290
1291         i->type = type;
1292
1293         if (!path_is_absolute(i->path)) {
1294                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
1295                 return -EBADMSG;
1296         }
1297
1298         path_kill_slashes(i->path);
1299
1300         if (!should_include_path(i->path))
1301                 return 0;
1302
1303         if (arg_root) {
1304                 char *p;
1305
1306                 p = strappend(arg_root, i->path);
1307                 if (!p)
1308                         return log_oom();
1309
1310                 free(i->path);
1311                 i->path = p;
1312         }
1313
1314         if (user && !streq(user, "-")) {
1315                 const char *u = user;
1316
1317                 r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
1318                 if (r < 0) {
1319                         log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
1320                         return r;
1321                 }
1322
1323                 i->uid_set = true;
1324         }
1325
1326         if (group && !streq(group, "-")) {
1327                 const char *g = group;
1328
1329                 r = get_group_creds(&g, &i->gid);
1330                 if (r < 0) {
1331                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
1332                         return r;
1333                 }
1334
1335                 i->gid_set = true;
1336         }
1337
1338         if (mode && !streq(mode, "-")) {
1339                 const char *mm = mode;
1340                 unsigned m;
1341
1342                 if (*mm == '~') {
1343                         i->mask_perms = true;
1344                         mm++;
1345                 }
1346
1347                 if (sscanf(mm, "%o", &m) != 1) {
1348                         log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
1349                         return -ENOENT;
1350                 }
1351
1352                 i->mode = m;
1353                 i->mode_set = true;
1354         } else
1355                 i->mode =
1356                         i->type == CREATE_DIRECTORY ||
1357                         i->type == TRUNCATE_DIRECTORY ? 0755 : 0644;
1358
1359         if (age && !streq(age, "-")) {
1360                 const char *a = age;
1361
1362                 if (*a == '~') {
1363                         i->keep_first_level = true;
1364                         a++;
1365                 }
1366
1367                 if (parse_sec(a, &i->age) < 0) {
1368                         log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
1369                         return -EBADMSG;
1370                 }
1371
1372                 i->age_set = true;
1373         }
1374
1375         h = needs_glob(i->type) ? globs : items;
1376
1377         existing = hashmap_get(h, i->path);
1378         if (existing) {
1379
1380                 /* Two identical items are fine */
1381                 if (!item_equal(existing, i))
1382                         log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);
1383
1384                 return 0;
1385         }
1386
1387         r = hashmap_put(h, i->path, i);
1388         if (r < 0)
1389                 return log_error_errno(r, "Failed to insert item %s: %m", i->path);
1390
1391         i = NULL; /* avoid cleanup */
1392
1393         return 0;
1394 }
1395
1396 static void help(void) {
1397         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
1398                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
1399                "  -h --help                 Show this help\n"
1400                "     --version              Show package version\n"
1401                "     --create               Create marked files/directories\n"
1402                "     --clean                Clean up marked directories\n"
1403                "     --remove               Remove marked files/directories\n"
1404                "     --boot                 Execute actions only safe at boot\n"
1405                "     --prefix=PATH          Only apply rules that apply to paths with the specified prefix\n"
1406                "     --exclude-prefix=PATH  Ignore rules that apply to paths with the specified prefix\n"
1407                "     --root=PATH            Operate on an alternate filesystem root\n",
1408                program_invocation_short_name);
1409 }
1410
1411 static int parse_argv(int argc, char *argv[]) {
1412
1413         enum {
1414                 ARG_VERSION = 0x100,
1415                 ARG_CREATE,
1416                 ARG_CLEAN,
1417                 ARG_REMOVE,
1418                 ARG_BOOT,
1419                 ARG_PREFIX,
1420                 ARG_EXCLUDE_PREFIX,
1421                 ARG_ROOT,
1422         };
1423
1424         static const struct option options[] = {
1425                 { "help",           no_argument,         NULL, 'h'                },
1426                 { "version",        no_argument,         NULL, ARG_VERSION        },
1427                 { "create",         no_argument,         NULL, ARG_CREATE         },
1428                 { "clean",          no_argument,         NULL, ARG_CLEAN          },
1429                 { "remove",         no_argument,         NULL, ARG_REMOVE         },
1430                 { "boot",           no_argument,         NULL, ARG_BOOT           },
1431                 { "prefix",         required_argument,   NULL, ARG_PREFIX         },
1432                 { "exclude-prefix", required_argument,   NULL, ARG_EXCLUDE_PREFIX },
1433                 { "root",           required_argument,   NULL, ARG_ROOT           },
1434                 {}
1435         };
1436
1437         int c;
1438
1439         assert(argc >= 0);
1440         assert(argv);
1441
1442         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
1443
1444                 switch (c) {
1445
1446                 case 'h':
1447                         help();
1448                         return 0;
1449
1450                 case ARG_VERSION:
1451                         puts(PACKAGE_STRING);
1452                         puts(SYSTEMD_FEATURES);
1453                         return 0;
1454
1455                 case ARG_CREATE:
1456                         arg_create = true;
1457                         break;
1458
1459                 case ARG_CLEAN:
1460                         arg_clean = true;
1461                         break;
1462
1463                 case ARG_REMOVE:
1464                         arg_remove = true;
1465                         break;
1466
1467                 case ARG_BOOT:
1468                         arg_boot = true;
1469                         break;
1470
1471                 case ARG_PREFIX:
1472                         if (strv_push(&arg_include_prefixes, optarg) < 0)
1473                                 return log_oom();
1474                         break;
1475
1476                 case ARG_EXCLUDE_PREFIX:
1477                         if (strv_push(&arg_exclude_prefixes, optarg) < 0)
1478                                 return log_oom();
1479                         break;
1480
1481                 case ARG_ROOT:
1482                         free(arg_root);
1483                         arg_root = path_make_absolute_cwd(optarg);
1484                         if (!arg_root)
1485                                 return log_oom();
1486
1487                         path_kill_slashes(arg_root);
1488                         break;
1489
1490                 case '?':
1491                         return -EINVAL;
1492
1493                 default:
1494                         assert_not_reached("Unhandled option");
1495                 }
1496
1497         if (!arg_clean && !arg_create && !arg_remove) {
1498                 log_error("You need to specify at least one of --clean, --create or --remove.");
1499                 return -EINVAL;
1500         }
1501
1502         return 1;
1503 }
1504
1505 static int read_config_file(const char *fn, bool ignore_enoent) {
1506         _cleanup_fclose_ FILE *f = NULL;
1507         char line[LINE_MAX];
1508         Iterator iterator;
1509         unsigned v = 0;
1510         Item *i;
1511         int r;
1512
1513         assert(fn);
1514
1515         r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
1516         if (r < 0) {
1517                 if (ignore_enoent && r == -ENOENT)
1518                         return 0;
1519
1520                 return log_error_errno(r, "Failed to open '%s', ignoring: %m", fn);
1521         }
1522
1523         FOREACH_LINE(line, f, break) {
1524                 char *l;
1525                 int k;
1526
1527                 v++;
1528
1529                 l = strstrip(line);
1530                 if (*l == '#' || *l == 0)
1531                         continue;
1532
1533                 k = parse_line(fn, v, l);
1534                 if (k < 0 && r == 0)
1535                         r = k;
1536         }
1537
1538         /* we have to determine age parameter for each entry of type X */
1539         HASHMAP_FOREACH(i, globs, iterator) {
1540                 Iterator iter;
1541                 Item *j, *candidate_item = NULL;
1542
1543                 if (i->type != IGNORE_DIRECTORY_PATH)
1544                         continue;
1545
1546                 HASHMAP_FOREACH(j, items, iter) {
1547                         if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY)
1548                                 continue;
1549
1550                         if (path_equal(j->path, i->path)) {
1551                                 candidate_item = j;
1552                                 break;
1553                         }
1554
1555                         if ((!candidate_item && path_startswith(i->path, j->path)) ||
1556                             (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0)))
1557                                 candidate_item = j;
1558                 }
1559
1560                 if (candidate_item && candidate_item->age_set) {
1561                         i->age = candidate_item->age;
1562                         i->age_set = true;
1563                 }
1564         }
1565
1566         if (ferror(f)) {
1567                 log_error("Failed to read from file %s: %m", fn);
1568                 if (r == 0)
1569                         r = -EIO;
1570         }
1571
1572         return r;
1573 }
1574
1575 int main(int argc, char *argv[]) {
1576         int r, k;
1577         Item *i;
1578         Iterator iterator;
1579
1580         r = parse_argv(argc, argv);
1581         if (r <= 0)
1582                 goto finish;
1583
1584         log_set_target(LOG_TARGET_AUTO);
1585         log_parse_environment();
1586         log_open();
1587
1588         umask(0022);
1589
1590         mac_selinux_init(NULL);
1591
1592         items = hashmap_new(&string_hash_ops);
1593         globs = hashmap_new(&string_hash_ops);
1594
1595         if (!items || !globs) {
1596                 r = log_oom();
1597                 goto finish;
1598         }
1599
1600         r = 0;
1601
1602         if (optind < argc) {
1603                 int j;
1604
1605                 for (j = optind; j < argc; j++) {
1606                         k = read_config_file(argv[j], false);
1607                         if (k < 0 && r == 0)
1608                                 r = k;
1609                 }
1610
1611         } else {
1612                 _cleanup_strv_free_ char **files = NULL;
1613                 char **f;
1614
1615                 r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
1616                 if (r < 0) {
1617                         log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
1618                         goto finish;
1619                 }
1620
1621                 STRV_FOREACH(f, files) {
1622                         k = read_config_file(*f, true);
1623                         if (k < 0 && r == 0)
1624                                 r = k;
1625                 }
1626         }
1627
1628         HASHMAP_FOREACH(i, globs, iterator)
1629                 process_item(i);
1630
1631         HASHMAP_FOREACH(i, items, iterator)
1632                 process_item(i);
1633
1634 finish:
1635         while ((i = hashmap_steal_first(items)))
1636                 item_free(i);
1637
1638         while ((i = hashmap_steal_first(globs)))
1639                 item_free(i);
1640
1641         hashmap_free(items);
1642         hashmap_free(globs);
1643
1644         free(arg_include_prefixes);
1645         free(arg_exclude_prefixes);
1646         free(arg_root);
1647
1648         set_free_free(unix_sockets);
1649
1650         mac_selinux_finish();
1651
1652         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1653 }