]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/tmpfiles/tmpfiles.c
3fdbfca9a2773e31ad807eeef7a9312bb7e53fb9
[thirdparty/systemd.git] / src / tmpfiles / tmpfiles.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering, Kay Sievers
6 Copyright 2015 Zbigniew Jędrzejewski-Szmek
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 <errno.h>
23 #include <fcntl.h>
24 #include <fnmatch.h>
25 #include <getopt.h>
26 #include <glob.h>
27 #include <limits.h>
28 #include <linux/fs.h>
29 #include <stdbool.h>
30 #include <stddef.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/xattr.h>
36 #include <sysexits.h>
37 #include <time.h>
38 #include <unistd.h>
39
40 #include "sd-path.h"
41
42 #include "acl-util.h"
43 #include "alloc-util.h"
44 #include "btrfs-util.h"
45 #include "capability-util.h"
46 #include "chattr-util.h"
47 #include "conf-files.h"
48 #include "copy.h"
49 #include "def.h"
50 #include "dirent-util.h"
51 #include "escape.h"
52 #include "fd-util.h"
53 #include "fileio.h"
54 #include "format-util.h"
55 #include "fs-util.h"
56 #include "glob-util.h"
57 #include "io-util.h"
58 #include "label.h"
59 #include "log.h"
60 #include "macro.h"
61 #include "missing.h"
62 #include "mkdir.h"
63 #include "mount-util.h"
64 #include "parse-util.h"
65 #include "path-lookup.h"
66 #include "path-util.h"
67 #include "rm-rf.h"
68 #include "selinux-util.h"
69 #include "set.h"
70 #include "specifier.h"
71 #include "stat-util.h"
72 #include "stdio-util.h"
73 #include "string-table.h"
74 #include "string-util.h"
75 #include "strv.h"
76 #include "umask-util.h"
77 #include "user-util.h"
78 #include "util.h"
79
80 /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
81 * them in the file system. This is intended to be used to create
82 * properly owned directories beneath /tmp, /var/tmp, /run, which are
83 * volatile and hence need to be recreated on bootup. */
84
85 typedef enum ItemType {
86 /* These ones take file names */
87 CREATE_FILE = 'f',
88 TRUNCATE_FILE = 'F',
89 CREATE_DIRECTORY = 'd',
90 TRUNCATE_DIRECTORY = 'D',
91 CREATE_SUBVOLUME = 'v',
92 CREATE_SUBVOLUME_INHERIT_QUOTA = 'q',
93 CREATE_SUBVOLUME_NEW_QUOTA = 'Q',
94 CREATE_FIFO = 'p',
95 CREATE_SYMLINK = 'L',
96 CREATE_CHAR_DEVICE = 'c',
97 CREATE_BLOCK_DEVICE = 'b',
98 COPY_FILES = 'C',
99
100 /* These ones take globs */
101 WRITE_FILE = 'w',
102 EMPTY_DIRECTORY = 'e',
103 SET_XATTR = 't',
104 RECURSIVE_SET_XATTR = 'T',
105 SET_ACL = 'a',
106 RECURSIVE_SET_ACL = 'A',
107 SET_ATTRIBUTE = 'h',
108 RECURSIVE_SET_ATTRIBUTE = 'H',
109 IGNORE_PATH = 'x',
110 IGNORE_DIRECTORY_PATH = 'X',
111 REMOVE_PATH = 'r',
112 RECURSIVE_REMOVE_PATH = 'R',
113 RELABEL_PATH = 'z',
114 RECURSIVE_RELABEL_PATH = 'Z',
115 ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
116 } ItemType;
117
118 typedef struct Item {
119 ItemType type;
120
121 char *path;
122 char *argument;
123 char **xattrs;
124 #if HAVE_ACL
125 acl_t acl_access;
126 acl_t acl_default;
127 #endif
128 uid_t uid;
129 gid_t gid;
130 mode_t mode;
131 usec_t age;
132
133 dev_t major_minor;
134 unsigned attribute_value;
135 unsigned attribute_mask;
136
137 bool uid_set:1;
138 bool gid_set:1;
139 bool mode_set:1;
140 bool age_set:1;
141 bool mask_perms:1;
142 bool attribute_set:1;
143
144 bool keep_first_level:1;
145
146 bool force:1;
147
148 bool done:1;
149 } Item;
150
151 typedef struct ItemArray {
152 Item *items;
153 size_t count;
154 size_t size;
155 } ItemArray;
156
157 typedef enum DirectoryType {
158 DIRECTORY_RUNTIME = 0,
159 DIRECTORY_STATE,
160 DIRECTORY_CACHE,
161 DIRECTORY_LOGS,
162 _DIRECTORY_TYPE_MAX,
163 } DirectoryType;
164
165 static bool arg_user = false;
166 static bool arg_create = false;
167 static bool arg_clean = false;
168 static bool arg_remove = false;
169 static bool arg_boot = false;
170
171 static char **arg_include_prefixes = NULL;
172 static char **arg_exclude_prefixes = NULL;
173 static char *arg_root = NULL;
174
175 #define MAX_DEPTH 256
176
177 static OrderedHashmap *items = NULL, *globs = NULL;
178 static Set *unix_sockets = NULL;
179
180 static int specifier_machine_id_safe(char specifier, void *data, void *userdata, char **ret);
181 static int specifier_directory(char specifier, void *data, void *userdata, char **ret);
182
183 static const Specifier specifier_table[] = {
184 { 'm', specifier_machine_id_safe, NULL },
185 { 'b', specifier_boot_id, NULL },
186 { 'H', specifier_host_name, NULL },
187 { 'v', specifier_kernel_release, NULL },
188
189 { 'U', specifier_user_id, NULL },
190 { 'u', specifier_user_name, NULL },
191 { 'h', specifier_user_home, NULL },
192 { 't', specifier_directory, UINT_TO_PTR(DIRECTORY_RUNTIME) },
193 { 'S', specifier_directory, UINT_TO_PTR(DIRECTORY_STATE) },
194 { 'C', specifier_directory, UINT_TO_PTR(DIRECTORY_CACHE) },
195 { 'L', specifier_directory, UINT_TO_PTR(DIRECTORY_LOGS) },
196 {}
197 };
198
199 static int specifier_machine_id_safe(char specifier, void *data, void *userdata, char **ret) {
200 int r;
201
202 /* If /etc/machine_id is missing or empty (e.g. in a chroot environment)
203 * return a recognizable error so that the caller can skip the rule
204 * gracefully. */
205
206 r = specifier_machine_id(specifier, data, userdata, ret);
207 if (IN_SET(r, -ENOENT, -ENOMEDIUM))
208 return -ENXIO;
209
210 return r;
211 }
212
213 static int specifier_directory(char specifier, void *data, void *userdata, char **ret) {
214 struct table_entry {
215 uint64_t type;
216 const char *suffix;
217 };
218
219 static const struct table_entry paths_system[] = {
220 [DIRECTORY_RUNTIME] = { SD_PATH_SYSTEM_RUNTIME },
221 [DIRECTORY_STATE] = { SD_PATH_SYSTEM_STATE_PRIVATE },
222 [DIRECTORY_CACHE] = { SD_PATH_SYSTEM_STATE_CACHE },
223 [DIRECTORY_LOGS] = { SD_PATH_SYSTEM_STATE_LOGS },
224 };
225
226 static const struct table_entry paths_user[] = {
227 [DIRECTORY_RUNTIME] = { SD_PATH_USER_RUNTIME },
228 [DIRECTORY_STATE] = { SD_PATH_USER_CONFIGURATION },
229 [DIRECTORY_CACHE] = { SD_PATH_USER_STATE_CACHE },
230 [DIRECTORY_LOGS] = { SD_PATH_USER_CONFIGURATION, "log" },
231 };
232
233 unsigned i;
234 const struct table_entry *paths;
235
236 assert_cc(ELEMENTSOF(paths_system) == ELEMENTSOF(paths_user));
237 paths = arg_user ? paths_user : paths_system;
238
239 i = PTR_TO_UINT(data);
240 assert(i < ELEMENTSOF(paths_system));
241
242 return sd_path_home(paths[i].type, paths[i].suffix, ret);
243 }
244
245 static int log_unresolvable_specifier(const char *filename, unsigned line) {
246 static bool notified = false;
247
248 /* In system mode, this is called when /etc is not fully initialized (e.g.
249 * in a chroot environment) where some specifiers are unresolvable. In user
250 * mode, this is called when some variables are not defined. These cases are
251 * not considered as an error so log at LOG_NOTICE only for the first time
252 * and then downgrade this to LOG_DEBUG for the rest. */
253
254 log_full(notified ? LOG_DEBUG : LOG_NOTICE,
255 "[%s:%u] Failed to resolve specifier: %s, skipping",
256 filename, line,
257 arg_user ? "Required $XDG_... variable not defined" : "uninitialized /etc detected");
258
259 if (!notified)
260 log_notice("All rules containing unresolvable specifiers will be skipped.");
261
262 notified = true;
263 return 0;
264 }
265
266 static int user_config_paths(char*** ret) {
267 _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
268 _cleanup_free_ char *persistent_config = NULL, *runtime_config = NULL, *data_home = NULL;
269 _cleanup_strv_free_ char **res = NULL;
270 int r;
271
272 r = xdg_user_dirs(&config_dirs, &data_dirs);
273 if (r < 0)
274 return r;
275
276 r = xdg_user_config_dir(&persistent_config, "/user-tmpfiles.d");
277 if (r < 0 && r != -ENXIO)
278 return r;
279
280 r = xdg_user_runtime_dir(&runtime_config, "/user-tmpfiles.d");
281 if (r < 0 && r != -ENXIO)
282 return r;
283
284 r = xdg_user_data_dir(&data_home, "/user-tmpfiles.d");
285 if (r < 0 && r != -ENXIO)
286 return r;
287
288 r = strv_extend_strv_concat(&res, config_dirs, "/user-tmpfiles.d");
289 if (r < 0)
290 return r;
291
292 r = strv_extend(&res, persistent_config);
293 if (r < 0)
294 return r;
295
296 r = strv_extend(&res, runtime_config);
297 if (r < 0)
298 return r;
299
300 r = strv_extend(&res, data_home);
301 if (r < 0)
302 return r;
303
304 r = strv_extend_strv_concat(&res, data_dirs, "/user-tmpfiles.d");
305 if (r < 0)
306 return r;
307
308 r = path_strv_make_absolute_cwd(res);
309 if (r < 0)
310 return r;
311
312 *ret = res;
313 res = NULL;
314 return 0;
315 }
316
317 static bool needs_glob(ItemType t) {
318 return IN_SET(t,
319 WRITE_FILE,
320 IGNORE_PATH,
321 IGNORE_DIRECTORY_PATH,
322 REMOVE_PATH,
323 RECURSIVE_REMOVE_PATH,
324 EMPTY_DIRECTORY,
325 ADJUST_MODE,
326 RELABEL_PATH,
327 RECURSIVE_RELABEL_PATH,
328 SET_XATTR,
329 RECURSIVE_SET_XATTR,
330 SET_ACL,
331 RECURSIVE_SET_ACL,
332 SET_ATTRIBUTE,
333 RECURSIVE_SET_ATTRIBUTE);
334 }
335
336 static bool takes_ownership(ItemType t) {
337 return IN_SET(t,
338 CREATE_FILE,
339 TRUNCATE_FILE,
340 CREATE_DIRECTORY,
341 EMPTY_DIRECTORY,
342 TRUNCATE_DIRECTORY,
343 CREATE_SUBVOLUME,
344 CREATE_SUBVOLUME_INHERIT_QUOTA,
345 CREATE_SUBVOLUME_NEW_QUOTA,
346 CREATE_FIFO,
347 CREATE_SYMLINK,
348 CREATE_CHAR_DEVICE,
349 CREATE_BLOCK_DEVICE,
350 COPY_FILES,
351 WRITE_FILE,
352 IGNORE_PATH,
353 IGNORE_DIRECTORY_PATH,
354 REMOVE_PATH,
355 RECURSIVE_REMOVE_PATH);
356 }
357
358 static struct Item* find_glob(OrderedHashmap *h, const char *match) {
359 ItemArray *j;
360 Iterator i;
361
362 ORDERED_HASHMAP_FOREACH(j, h, i) {
363 unsigned n;
364
365 for (n = 0; n < j->count; n++) {
366 Item *item = j->items + n;
367
368 if (fnmatch(item->path, match, FNM_PATHNAME|FNM_PERIOD) == 0)
369 return item;
370 }
371 }
372
373 return NULL;
374 }
375
376 static void load_unix_sockets(void) {
377 _cleanup_fclose_ FILE *f = NULL;
378 int r;
379
380 if (unix_sockets)
381 return;
382
383 /* We maintain a cache of the sockets we found in /proc/net/unix to speed things up a little. */
384
385 unix_sockets = set_new(&string_hash_ops);
386 if (!unix_sockets)
387 return;
388
389 f = fopen("/proc/net/unix", "re");
390 if (!f) {
391 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
392 "Failed to open /proc/net/unix, ignoring: %m");
393 goto fail;
394 }
395
396 /* Skip header */
397 r = read_line(f, LONG_LINE_MAX, NULL);
398 if (r < 0) {
399 log_warning_errno(r, "Failed to skip /proc/net/unix header line: %m");
400 goto fail;
401 }
402 if (r == 0) {
403 log_warning("Premature end of file reading /proc/net/unix.");
404 goto fail;
405 }
406
407 for (;;) {
408 _cleanup_free_ char *line = NULL;
409 char *p, *s;
410
411 r = read_line(f, LONG_LINE_MAX, &line);
412 if (r < 0) {
413 log_warning_errno(r, "Failed to read /proc/net/unix line, ignoring: %m");
414 goto fail;
415 }
416 if (r == 0) /* EOF */
417 break;
418
419 p = strchr(line, ':');
420 if (!p)
421 continue;
422
423 if (strlen(p) < 37)
424 continue;
425
426 p += 37;
427 p += strspn(p, WHITESPACE);
428 p += strcspn(p, WHITESPACE); /* skip one more word */
429 p += strspn(p, WHITESPACE);
430
431 if (*p != '/')
432 continue;
433
434 s = strdup(p);
435 if (!s) {
436 log_oom();
437 goto fail;
438 }
439
440 path_kill_slashes(s);
441
442 r = set_consume(unix_sockets, s);
443 if (r < 0 && r != -EEXIST) {
444 log_warning_errno(r, "Failed to add AF_UNIX socket to set, ignoring: %m");
445 goto fail;
446 }
447 }
448
449 return;
450
451 fail:
452 unix_sockets = set_free_free(unix_sockets);
453 }
454
455 static bool unix_socket_alive(const char *fn) {
456 assert(fn);
457
458 load_unix_sockets();
459
460 if (unix_sockets)
461 return !!set_get(unix_sockets, (char*) fn);
462
463 /* We don't know, so assume yes */
464 return true;
465 }
466
467 static int dir_is_mount_point(DIR *d, const char *subdir) {
468
469 int mount_id_parent, mount_id;
470 int r_p, r;
471
472 r_p = name_to_handle_at_loop(dirfd(d), ".", NULL, &mount_id_parent, 0);
473 if (r_p < 0)
474 r_p = -errno;
475
476 r = name_to_handle_at_loop(dirfd(d), subdir, NULL, &mount_id, 0);
477 if (r < 0)
478 r = -errno;
479
480 /* got no handle; make no assumptions, return error */
481 if (r_p < 0 && r < 0)
482 return r_p;
483
484 /* got both handles; if they differ, it is a mount point */
485 if (r_p >= 0 && r >= 0)
486 return mount_id_parent != mount_id;
487
488 /* got only one handle; assume different mount points if one
489 * of both queries was not supported by the filesystem */
490 if (IN_SET(r_p, -ENOSYS, -EOPNOTSUPP) || IN_SET(r, -ENOSYS, -EOPNOTSUPP))
491 return true;
492
493 /* return error */
494 if (r_p < 0)
495 return r_p;
496 return r;
497 }
498
499 static DIR* xopendirat_nomod(int dirfd, const char *path) {
500 DIR *dir;
501
502 dir = xopendirat(dirfd, path, O_NOFOLLOW|O_NOATIME);
503 if (dir)
504 return dir;
505
506 log_debug_errno(errno, "Cannot open %sdirectory \"%s\": %m", dirfd == AT_FDCWD ? "" : "sub", path);
507 if (errno != EPERM)
508 return NULL;
509
510 dir = xopendirat(dirfd, path, O_NOFOLLOW);
511 if (!dir)
512 log_debug_errno(errno, "Cannot open %sdirectory \"%s\": %m", dirfd == AT_FDCWD ? "" : "sub", path);
513
514 return dir;
515 }
516
517 static DIR* opendir_nomod(const char *path) {
518 return xopendirat_nomod(AT_FDCWD, path);
519 }
520
521 static int dir_cleanup(
522 Item *i,
523 const char *p,
524 DIR *d,
525 const struct stat *ds,
526 usec_t cutoff,
527 dev_t rootdev,
528 bool mountpoint,
529 int maxdepth,
530 bool keep_this_level) {
531
532 struct dirent *dent;
533 struct timespec times[2];
534 bool deleted = false;
535 int r = 0;
536
537 FOREACH_DIRENT_ALL(dent, d, break) {
538 struct stat s;
539 usec_t age;
540 _cleanup_free_ char *sub_path = NULL;
541
542 if (dot_or_dot_dot(dent->d_name))
543 continue;
544
545 if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
546 if (errno == ENOENT)
547 continue;
548
549 /* FUSE, NFS mounts, SELinux might return EACCES */
550 r = log_full_errno(errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
551 "stat(%s/%s) failed: %m", p, dent->d_name);
552 continue;
553 }
554
555 /* Stay on the same filesystem */
556 if (s.st_dev != rootdev) {
557 log_debug("Ignoring \"%s/%s\": different filesystem.", p, dent->d_name);
558 continue;
559 }
560
561 /* Try to detect bind mounts of the same filesystem instance; they
562 * do not differ in device major/minors. This type of query is not
563 * supported on all kernels or filesystem types though. */
564 if (S_ISDIR(s.st_mode) && dir_is_mount_point(d, dent->d_name) > 0) {
565 log_debug("Ignoring \"%s/%s\": different mount of the same filesystem.",
566 p, dent->d_name);
567 continue;
568 }
569
570 /* Do not delete read-only files owned by root */
571 if (s.st_uid == 0 && !(s.st_mode & S_IWUSR)) {
572 log_debug("Ignoring \"%s/%s\": read-only and owner by root.", p, dent->d_name);
573 continue;
574 }
575
576 sub_path = strjoin(p, "/", dent->d_name);
577 if (!sub_path) {
578 r = log_oom();
579 goto finish;
580 }
581
582 /* Is there an item configured for this path? */
583 if (ordered_hashmap_get(items, sub_path)) {
584 log_debug("Ignoring \"%s\": a separate entry exists.", sub_path);
585 continue;
586 }
587
588 if (find_glob(globs, sub_path)) {
589 log_debug("Ignoring \"%s\": a separate glob exists.", sub_path);
590 continue;
591 }
592
593 if (S_ISDIR(s.st_mode)) {
594
595 if (mountpoint &&
596 streq(dent->d_name, "lost+found") &&
597 s.st_uid == 0) {
598 log_debug("Ignoring \"%s\".", sub_path);
599 continue;
600 }
601
602 if (maxdepth <= 0)
603 log_warning("Reached max depth on \"%s\".", sub_path);
604 else {
605 _cleanup_closedir_ DIR *sub_dir;
606 int q;
607
608 sub_dir = xopendirat_nomod(dirfd(d), dent->d_name);
609 if (!sub_dir) {
610 if (errno != ENOENT)
611 r = log_error_errno(errno, "opendir(%s) failed: %m", sub_path);
612
613 continue;
614 }
615
616 q = dir_cleanup(i, sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false);
617 if (q < 0)
618 r = q;
619 }
620
621 /* Note: if you are wondering why we don't
622 * support the sticky bit for excluding
623 * directories from cleaning like we do it for
624 * other file system objects: well, the sticky
625 * bit already has a meaning for directories,
626 * so we don't want to overload that. */
627
628 if (keep_this_level) {
629 log_debug("Keeping \"%s\".", sub_path);
630 continue;
631 }
632
633 /* Ignore ctime, we change it when deleting */
634 age = timespec_load(&s.st_mtim);
635 if (age >= cutoff) {
636 char a[FORMAT_TIMESTAMP_MAX];
637 /* Follows spelling in stat(1). */
638 log_debug("Directory \"%s\": modify time %s is too new.",
639 sub_path,
640 format_timestamp_us(a, sizeof(a), age));
641 continue;
642 }
643
644 age = timespec_load(&s.st_atim);
645 if (age >= cutoff) {
646 char a[FORMAT_TIMESTAMP_MAX];
647 log_debug("Directory \"%s\": access time %s is too new.",
648 sub_path,
649 format_timestamp_us(a, sizeof(a), age));
650 continue;
651 }
652
653 log_debug("Removing directory \"%s\".", sub_path);
654 if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0)
655 if (!IN_SET(errno, ENOENT, ENOTEMPTY))
656 r = log_error_errno(errno, "rmdir(%s): %m", sub_path);
657
658 } else {
659 /* Skip files for which the sticky bit is
660 * set. These are semantics we define, and are
661 * unknown elsewhere. See XDG_RUNTIME_DIR
662 * specification for details. */
663 if (s.st_mode & S_ISVTX) {
664 log_debug("Skipping \"%s\": sticky bit set.", sub_path);
665 continue;
666 }
667
668 if (mountpoint && S_ISREG(s.st_mode))
669 if (s.st_uid == 0 && STR_IN_SET(dent->d_name,
670 ".journal",
671 "aquota.user",
672 "aquota.group")) {
673 log_debug("Skipping \"%s\".", sub_path);
674 continue;
675 }
676
677 /* Ignore sockets that are listed in /proc/net/unix */
678 if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path)) {
679 log_debug("Skipping \"%s\": live socket.", sub_path);
680 continue;
681 }
682
683 /* Ignore device nodes */
684 if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode)) {
685 log_debug("Skipping \"%s\": a device.", sub_path);
686 continue;
687 }
688
689 /* Keep files on this level around if this is
690 * requested */
691 if (keep_this_level) {
692 log_debug("Keeping \"%s\".", sub_path);
693 continue;
694 }
695
696 age = timespec_load(&s.st_mtim);
697 if (age >= cutoff) {
698 char a[FORMAT_TIMESTAMP_MAX];
699 /* Follows spelling in stat(1). */
700 log_debug("File \"%s\": modify time %s is too new.",
701 sub_path,
702 format_timestamp_us(a, sizeof(a), age));
703 continue;
704 }
705
706 age = timespec_load(&s.st_atim);
707 if (age >= cutoff) {
708 char a[FORMAT_TIMESTAMP_MAX];
709 log_debug("File \"%s\": access time %s is too new.",
710 sub_path,
711 format_timestamp_us(a, sizeof(a), age));
712 continue;
713 }
714
715 age = timespec_load(&s.st_ctim);
716 if (age >= cutoff) {
717 char a[FORMAT_TIMESTAMP_MAX];
718 log_debug("File \"%s\": change time %s is too new.",
719 sub_path,
720 format_timestamp_us(a, sizeof(a), age));
721 continue;
722 }
723
724 log_debug("unlink \"%s\"", sub_path);
725
726 if (unlinkat(dirfd(d), dent->d_name, 0) < 0)
727 if (errno != ENOENT)
728 r = log_error_errno(errno, "unlink(%s): %m", sub_path);
729
730 deleted = true;
731 }
732 }
733
734 finish:
735 if (deleted) {
736 usec_t age1, age2;
737 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
738
739 /* Restore original directory timestamps */
740 times[0] = ds->st_atim;
741 times[1] = ds->st_mtim;
742
743 age1 = timespec_load(&ds->st_atim);
744 age2 = timespec_load(&ds->st_mtim);
745 log_debug("Restoring access and modification time on \"%s\": %s, %s",
746 p,
747 format_timestamp_us(a, sizeof(a), age1),
748 format_timestamp_us(b, sizeof(b), age2));
749 if (futimens(dirfd(d), times) < 0)
750 log_error_errno(errno, "utimensat(%s): %m", p);
751 }
752
753 return r;
754 }
755
756 static int path_set_perms(Item *i, const char *path) {
757 char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
758 _cleanup_close_ int fd = -1;
759 struct stat st;
760
761 assert(i);
762 assert(path);
763
764 /* We open the file with O_PATH here, to make the operation
765 * somewhat atomic. Also there's unfortunately no fchmodat()
766 * with AT_SYMLINK_NOFOLLOW, hence we emulate it here via
767 * O_PATH. */
768
769 fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
770 if (fd < 0) {
771 int level = LOG_ERR, r = -errno;
772
773 /* Option "e" operates only on existing objects. Do not
774 * print errors about non-existent files or directories */
775 if (i->type == EMPTY_DIRECTORY && errno == ENOENT) {
776 level = LOG_DEBUG;
777 r = 0;
778 }
779
780 log_full_errno(level, errno, "Adjusting owner and mode for %s failed: %m", path);
781
782 return r;
783 }
784
785 if (fstatat(fd, "", &st, AT_EMPTY_PATH) < 0)
786 return log_error_errno(errno, "Failed to fstat() file %s: %m", path);
787
788 xsprintf(fn, "/proc/self/fd/%i", fd);
789
790 if (i->mode_set) {
791 if (S_ISLNK(st.st_mode))
792 log_debug("Skipping mode fix for symlink %s.", path);
793 else {
794 mode_t m = i->mode;
795
796 if (i->mask_perms) {
797 if (!(st.st_mode & 0111))
798 m &= ~0111;
799 if (!(st.st_mode & 0222))
800 m &= ~0222;
801 if (!(st.st_mode & 0444))
802 m &= ~0444;
803 if (!S_ISDIR(st.st_mode))
804 m &= ~07000; /* remove sticky/sgid/suid bit, unless directory */
805 }
806
807 if (m == (st.st_mode & 07777))
808 log_debug("\"%s\" has correct mode %o already.", path, st.st_mode);
809 else {
810 log_debug("Changing \"%s\" to mode %o.", path, m);
811
812 if (chmod(fn, m) < 0)
813 return log_error_errno(errno, "chmod() of %s via %s failed: %m", path, fn);
814 }
815 }
816 }
817
818 if ((i->uid != st.st_uid || i->gid != st.st_gid) &&
819 (i->uid_set || i->gid_set)) {
820 log_debug("Changing \"%s\" to owner "UID_FMT":"GID_FMT,
821 path,
822 i->uid_set ? i->uid : UID_INVALID,
823 i->gid_set ? i->gid : GID_INVALID);
824
825 if (chown(fn,
826 i->uid_set ? i->uid : UID_INVALID,
827 i->gid_set ? i->gid : GID_INVALID) < 0)
828 return log_error_errno(errno, "chown() of %s via %s failed: %m", path, fn);
829 }
830
831 fd = safe_close(fd);
832
833 return label_fix(path, false, false);
834 }
835
836 static int parse_xattrs_from_arg(Item *i) {
837 const char *p;
838 int r;
839
840 assert(i);
841 assert(i->argument);
842
843 p = i->argument;
844
845 for (;;) {
846 _cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL;
847
848 r = extract_first_word(&p, &xattr, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
849 if (r < 0)
850 log_warning_errno(r, "Failed to parse extended attribute '%s', ignoring: %m", p);
851 if (r <= 0)
852 break;
853
854 r = split_pair(xattr, "=", &name, &value);
855 if (r < 0) {
856 log_warning_errno(r, "Failed to parse extended attribute, ignoring: %s", xattr);
857 continue;
858 }
859
860 if (isempty(name) || isempty(value)) {
861 log_warning("Malformed extended attribute found, ignoring: %s", xattr);
862 continue;
863 }
864
865 if (strv_push_pair(&i->xattrs, name, value) < 0)
866 return log_oom();
867
868 name = value = NULL;
869 }
870
871 return 0;
872 }
873
874 static int path_set_xattrs(Item *i, const char *path) {
875 char **name, **value;
876
877 assert(i);
878 assert(path);
879
880 STRV_FOREACH_PAIR(name, value, i->xattrs) {
881 log_debug("Setting extended attribute '%s=%s' on %s.", *name, *value, path);
882 if (lsetxattr(path, *name, *value, strlen(*value), 0) < 0)
883 return log_error_errno(errno, "Setting extended attribute %s=%s on %s failed: %m",
884 *name, *value, path);
885 }
886 return 0;
887 }
888
889 static int parse_acls_from_arg(Item *item) {
890 #if HAVE_ACL
891 int r;
892
893 assert(item);
894
895 /* If force (= modify) is set, we will not modify the acl
896 * afterwards, so the mask can be added now if necessary. */
897
898 r = parse_acl(item->argument, &item->acl_access, &item->acl_default, !item->force);
899 if (r < 0)
900 log_warning_errno(r, "Failed to parse ACL \"%s\": %m. Ignoring", item->argument);
901 #else
902 log_warning_errno(ENOSYS, "ACLs are not supported. Ignoring");
903 #endif
904
905 return 0;
906 }
907
908 #if HAVE_ACL
909 static int path_set_acl(const char *path, const char *pretty, acl_type_t type, acl_t acl, bool modify) {
910 _cleanup_(acl_free_charpp) char *t = NULL;
911 _cleanup_(acl_freep) acl_t dup = NULL;
912 int r;
913
914 /* Returns 0 for success, positive error if already warned,
915 * negative error otherwise. */
916
917 if (modify) {
918 r = acls_for_file(path, type, acl, &dup);
919 if (r < 0)
920 return r;
921
922 r = calc_acl_mask_if_needed(&dup);
923 if (r < 0)
924 return r;
925 } else {
926 dup = acl_dup(acl);
927 if (!dup)
928 return -errno;
929
930 /* the mask was already added earlier if needed */
931 }
932
933 r = add_base_acls_if_needed(&dup, path);
934 if (r < 0)
935 return r;
936
937 t = acl_to_any_text(dup, NULL, ',', TEXT_ABBREVIATE);
938 log_debug("Setting %s ACL %s on %s.",
939 type == ACL_TYPE_ACCESS ? "access" : "default",
940 strna(t), pretty);
941
942 r = acl_set_file(path, type, dup);
943 if (r < 0)
944 /* Return positive to indicate we already warned */
945 return -log_error_errno(errno,
946 "Setting %s ACL \"%s\" on %s failed: %m",
947 type == ACL_TYPE_ACCESS ? "access" : "default",
948 strna(t), pretty);
949
950 return 0;
951 }
952 #endif
953
954 static int path_set_acls(Item *item, const char *path) {
955 int r = 0;
956 #if HAVE_ACL
957 char fn[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
958 _cleanup_close_ int fd = -1;
959 struct stat st;
960
961 assert(item);
962 assert(path);
963
964 fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
965 if (fd < 0)
966 return log_error_errno(errno, "Adjusting ACL of %s failed: %m", path);
967
968 if (fstatat(fd, "", &st, AT_EMPTY_PATH) < 0)
969 return log_error_errno(errno, "Failed to fstat() file %s: %m", path);
970
971 if (S_ISLNK(st.st_mode)) {
972 log_debug("Skipping ACL fix for symlink %s.", path);
973 return 0;
974 }
975
976 xsprintf(fn, "/proc/self/fd/%i", fd);
977
978 if (item->acl_access)
979 r = path_set_acl(fn, path, ACL_TYPE_ACCESS, item->acl_access, item->force);
980
981 if (r == 0 && item->acl_default)
982 r = path_set_acl(fn, path, ACL_TYPE_DEFAULT, item->acl_default, item->force);
983
984 if (r > 0)
985 return -r; /* already warned */
986 else if (r == -EOPNOTSUPP) {
987 log_debug_errno(r, "ACLs not supported by file system at %s", path);
988 return 0;
989 } else if (r < 0)
990 log_error_errno(r, "ACL operation on \"%s\" failed: %m", path);
991 #endif
992 return r;
993 }
994
995 #define ATTRIBUTES_ALL \
996 (FS_NOATIME_FL | \
997 FS_SYNC_FL | \
998 FS_DIRSYNC_FL | \
999 FS_APPEND_FL | \
1000 FS_COMPR_FL | \
1001 FS_NODUMP_FL | \
1002 FS_EXTENT_FL | \
1003 FS_IMMUTABLE_FL | \
1004 FS_JOURNAL_DATA_FL | \
1005 FS_SECRM_FL | \
1006 FS_UNRM_FL | \
1007 FS_NOTAIL_FL | \
1008 FS_TOPDIR_FL | \
1009 FS_NOCOW_FL)
1010
1011 static int parse_attribute_from_arg(Item *item) {
1012
1013 static const struct {
1014 char character;
1015 unsigned value;
1016 } attributes[] = {
1017 { 'A', FS_NOATIME_FL }, /* do not update atime */
1018 { 'S', FS_SYNC_FL }, /* Synchronous updates */
1019 { 'D', FS_DIRSYNC_FL }, /* dirsync behaviour (directories only) */
1020 { 'a', FS_APPEND_FL }, /* writes to file may only append */
1021 { 'c', FS_COMPR_FL }, /* Compress file */
1022 { 'd', FS_NODUMP_FL }, /* do not dump file */
1023 { 'e', FS_EXTENT_FL }, /* Extents */
1024 { 'i', FS_IMMUTABLE_FL }, /* Immutable file */
1025 { 'j', FS_JOURNAL_DATA_FL }, /* Reserved for ext3 */
1026 { 's', FS_SECRM_FL }, /* Secure deletion */
1027 { 'u', FS_UNRM_FL }, /* Undelete */
1028 { 't', FS_NOTAIL_FL }, /* file tail should not be merged */
1029 { 'T', FS_TOPDIR_FL }, /* Top of directory hierarchies */
1030 { 'C', FS_NOCOW_FL }, /* Do not cow file */
1031 };
1032
1033 enum {
1034 MODE_ADD,
1035 MODE_DEL,
1036 MODE_SET
1037 } mode = MODE_ADD;
1038
1039 unsigned value = 0, mask = 0;
1040 const char *p;
1041
1042 assert(item);
1043
1044 p = item->argument;
1045 if (p) {
1046 if (*p == '+') {
1047 mode = MODE_ADD;
1048 p++;
1049 } else if (*p == '-') {
1050 mode = MODE_DEL;
1051 p++;
1052 } else if (*p == '=') {
1053 mode = MODE_SET;
1054 p++;
1055 }
1056 }
1057
1058 if (isempty(p) && mode != MODE_SET) {
1059 log_error("Setting file attribute on '%s' needs an attribute specification.", item->path);
1060 return -EINVAL;
1061 }
1062
1063 for (; p && *p ; p++) {
1064 unsigned i, v;
1065
1066 for (i = 0; i < ELEMENTSOF(attributes); i++)
1067 if (*p == attributes[i].character)
1068 break;
1069
1070 if (i >= ELEMENTSOF(attributes)) {
1071 log_error("Unknown file attribute '%c' on '%s'.", *p, item->path);
1072 return -EINVAL;
1073 }
1074
1075 v = attributes[i].value;
1076
1077 SET_FLAG(value, v, IN_SET(mode, MODE_ADD, MODE_SET));
1078
1079 mask |= v;
1080 }
1081
1082 if (mode == MODE_SET)
1083 mask |= ATTRIBUTES_ALL;
1084
1085 assert(mask != 0);
1086
1087 item->attribute_mask = mask;
1088 item->attribute_value = value;
1089 item->attribute_set = true;
1090
1091 return 0;
1092 }
1093
1094 static int path_set_attribute(Item *item, const char *path) {
1095 _cleanup_close_ int fd = -1;
1096 struct stat st;
1097 unsigned f;
1098 int r;
1099
1100 if (!item->attribute_set || item->attribute_mask == 0)
1101 return 0;
1102
1103 fd = open(path, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOATIME|O_NOFOLLOW);
1104 if (fd < 0) {
1105 if (errno == ELOOP)
1106 return log_error_errno(errno, "Skipping file attributes adjustment on symlink %s.", path);
1107
1108 return log_error_errno(errno, "Cannot open '%s': %m", path);
1109 }
1110
1111 if (fstat(fd, &st) < 0)
1112 return log_error_errno(errno, "Cannot stat '%s': %m", path);
1113
1114 /* Issuing the file attribute ioctls on device nodes is not
1115 * safe, as that will be delivered to the drivers, not the
1116 * file system containing the device node. */
1117 if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
1118 log_error("Setting file flags is only supported on regular files and directories, cannot set on '%s'.", path);
1119 return -EINVAL;
1120 }
1121
1122 f = item->attribute_value & item->attribute_mask;
1123
1124 /* Mask away directory-specific flags */
1125 if (!S_ISDIR(st.st_mode))
1126 f &= ~FS_DIRSYNC_FL;
1127
1128 r = chattr_fd(fd, f, item->attribute_mask);
1129 if (r < 0)
1130 log_full_errno(IN_SET(r, -ENOTTY, -EOPNOTSUPP) ? LOG_DEBUG : LOG_WARNING,
1131 r,
1132 "Cannot set file attribute for '%s', value=0x%08x, mask=0x%08x: %m",
1133 path, item->attribute_value, item->attribute_mask);
1134
1135 return 0;
1136 }
1137
1138 static int write_one_file(Item *i, const char *path) {
1139 _cleanup_close_ int fd = -1;
1140 int flags, r = 0;
1141 struct stat st;
1142
1143 assert(i);
1144 assert(path);
1145
1146 flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND|O_NOFOLLOW :
1147 i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0;
1148
1149 RUN_WITH_UMASK(0000) {
1150 mac_selinux_create_file_prepare(path, S_IFREG);
1151 fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode);
1152 mac_selinux_create_file_clear();
1153 }
1154
1155 if (fd < 0) {
1156 if (i->type == WRITE_FILE && errno == ENOENT) {
1157 log_debug_errno(errno, "Not writing \"%s\": %m", path);
1158 return 0;
1159 }
1160
1161 r = -errno;
1162 if (!i->argument && errno == EROFS && stat(path, &st) == 0 &&
1163 (i->type == CREATE_FILE || st.st_size == 0))
1164 goto check_mode;
1165
1166 return log_error_errno(r, "Failed to create file %s: %m", path);
1167 }
1168
1169 if (i->argument) {
1170 log_debug("%s to \"%s\".", i->type == CREATE_FILE ? "Appending" : "Writing", path);
1171
1172 r = loop_write(fd, i->argument, strlen(i->argument), false);
1173 if (r < 0)
1174 return log_error_errno(r, "Failed to write file \"%s\": %m", path);
1175 } else
1176 log_debug("\"%s\" has been created.", path);
1177
1178 fd = safe_close(fd);
1179
1180 if (stat(path, &st) < 0)
1181 return log_error_errno(errno, "stat(%s) failed: %m", path);
1182
1183 check_mode:
1184 if (!S_ISREG(st.st_mode)) {
1185 log_error("%s is not a file.", path);
1186 return -EEXIST;
1187 }
1188
1189 r = path_set_perms(i, path);
1190 if (r < 0)
1191 return r;
1192
1193 return 0;
1194 }
1195
1196 typedef int (*action_t)(Item *, const char *);
1197
1198 static int item_do_children(Item *i, const char *path, action_t action) {
1199 _cleanup_closedir_ DIR *d;
1200 struct dirent *de;
1201 int r = 0;
1202
1203 assert(i);
1204 assert(path);
1205
1206 /* This returns the first error we run into, but nevertheless
1207 * tries to go on */
1208
1209 d = opendir_nomod(path);
1210 if (!d)
1211 return IN_SET(errno, ENOENT, ENOTDIR, ELOOP) ? 0 : -errno;
1212
1213 FOREACH_DIRENT_ALL(de, d, r = -errno) {
1214 _cleanup_free_ char *p = NULL;
1215 int q;
1216
1217 if (dot_or_dot_dot(de->d_name))
1218 continue;
1219
1220 p = strjoin(path, "/", de->d_name);
1221 if (!p)
1222 return -ENOMEM;
1223
1224 q = action(i, p);
1225 if (q < 0 && q != -ENOENT && r == 0)
1226 r = q;
1227
1228 if (IN_SET(de->d_type, DT_UNKNOWN, DT_DIR)) {
1229 q = item_do_children(i, p, action);
1230 if (q < 0 && r == 0)
1231 r = q;
1232 }
1233 }
1234
1235 return r;
1236 }
1237
1238 static int glob_item(Item *i, action_t action, bool recursive) {
1239 _cleanup_globfree_ glob_t g = {
1240 .gl_opendir = (void *(*)(const char *)) opendir_nomod,
1241 };
1242 int r = 0, k;
1243 char **fn;
1244
1245 k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
1246 if (k < 0 && k != -ENOENT)
1247 return log_error_errno(k, "glob(%s) failed: %m", i->path);
1248
1249 STRV_FOREACH(fn, g.gl_pathv) {
1250 k = action(i, *fn);
1251 if (k < 0 && r == 0)
1252 r = k;
1253
1254 if (recursive) {
1255 k = item_do_children(i, *fn, action);
1256 if (k < 0 && r == 0)
1257 r = k;
1258 }
1259 }
1260
1261 return r;
1262 }
1263
1264 typedef enum {
1265 CREATION_NORMAL,
1266 CREATION_EXISTING,
1267 CREATION_FORCE,
1268 _CREATION_MODE_MAX,
1269 _CREATION_MODE_INVALID = -1
1270 } CreationMode;
1271
1272 static const char *creation_mode_verb_table[_CREATION_MODE_MAX] = {
1273 [CREATION_NORMAL] = "Created",
1274 [CREATION_EXISTING] = "Found existing",
1275 [CREATION_FORCE] = "Created replacement",
1276 };
1277
1278 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(creation_mode_verb, CreationMode);
1279
1280 static int create_item(Item *i) {
1281 struct stat st;
1282 int r = 0;
1283 int q = 0;
1284 CreationMode creation;
1285
1286 assert(i);
1287
1288 log_debug("Running create action for entry %c %s", (char) i->type, i->path);
1289
1290 switch (i->type) {
1291
1292 case IGNORE_PATH:
1293 case IGNORE_DIRECTORY_PATH:
1294 case REMOVE_PATH:
1295 case RECURSIVE_REMOVE_PATH:
1296 return 0;
1297
1298 case CREATE_FILE:
1299 case TRUNCATE_FILE:
1300 r = write_one_file(i, i->path);
1301 if (r < 0)
1302 return r;
1303 break;
1304
1305 case COPY_FILES: {
1306 log_debug("Copying tree \"%s\" to \"%s\".", i->argument, i->path);
1307 r = copy_tree(i->argument, i->path, i->uid_set ? i->uid : UID_INVALID, i->gid_set ? i->gid : GID_INVALID, COPY_REFLINK);
1308
1309 if (r == -EROFS && stat(i->path, &st) == 0)
1310 r = -EEXIST;
1311
1312 if (r < 0) {
1313 struct stat a, b;
1314
1315 if (r != -EEXIST)
1316 return log_error_errno(r, "Failed to copy files to %s: %m", i->path);
1317
1318 if (stat(i->argument, &a) < 0)
1319 return log_error_errno(errno, "stat(%s) failed: %m", i->argument);
1320
1321 if (stat(i->path, &b) < 0)
1322 return log_error_errno(errno, "stat(%s) failed: %m", i->path);
1323
1324 if ((a.st_mode ^ b.st_mode) & S_IFMT) {
1325 log_debug("Can't copy to %s, file exists already and is of different type", i->path);
1326 return 0;
1327 }
1328 }
1329
1330 r = path_set_perms(i, i->path);
1331 if (r < 0)
1332 return r;
1333
1334 break;
1335
1336 case WRITE_FILE:
1337 r = glob_item(i, write_one_file, false);
1338 if (r < 0)
1339 return r;
1340
1341 break;
1342
1343 case CREATE_DIRECTORY:
1344 case TRUNCATE_DIRECTORY:
1345 case CREATE_SUBVOLUME:
1346 case CREATE_SUBVOLUME_INHERIT_QUOTA:
1347 case CREATE_SUBVOLUME_NEW_QUOTA:
1348 RUN_WITH_UMASK(0000)
1349 mkdir_parents_label(i->path, 0755);
1350
1351 if (IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) {
1352
1353 if (btrfs_is_subvol(isempty(arg_root) ? "/" : arg_root) <= 0)
1354
1355 /* Don't create a subvolume unless the
1356 * root directory is one, too. We do
1357 * this under the assumption that if
1358 * the root directory is just a plain
1359 * directory (i.e. very light-weight),
1360 * we shouldn't try to split it up
1361 * into subvolumes (i.e. more
1362 * heavy-weight). Thus, chroot()
1363 * environments and suchlike will get
1364 * a full brtfs subvolume set up below
1365 * their tree only if they
1366 * specifically set up a btrfs
1367 * subvolume for the root dir too. */
1368
1369 r = -ENOTTY;
1370 else {
1371 RUN_WITH_UMASK((~i->mode) & 0777)
1372 r = btrfs_subvol_make(i->path);
1373 }
1374 } else
1375 r = 0;
1376
1377 if (IN_SET(i->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY) || r == -ENOTTY)
1378 RUN_WITH_UMASK(0000)
1379 r = mkdir_label(i->path, i->mode);
1380
1381 if (r < 0) {
1382 int k;
1383
1384 if (!IN_SET(r, -EEXIST, -EROFS))
1385 return log_error_errno(r, "Failed to create directory or subvolume \"%s\": %m", i->path);
1386
1387 k = is_dir(i->path, false);
1388 if (k == -ENOENT && r == -EROFS)
1389 return log_error_errno(r, "%s does not exist and cannot be created as the file system is read-only.", i->path);
1390 if (k < 0)
1391 return log_error_errno(k, "Failed to check if %s exists: %m", i->path);
1392 if (!k) {
1393 log_warning("\"%s\" already exists and is not a directory.", i->path);
1394 return 0;
1395 }
1396
1397 creation = CREATION_EXISTING;
1398 } else
1399 creation = CREATION_NORMAL;
1400
1401 log_debug("%s directory \"%s\".", creation_mode_verb_to_string(creation), i->path);
1402
1403 if (IN_SET(i->type, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA)) {
1404 r = btrfs_subvol_auto_qgroup(i->path, 0, i->type == CREATE_SUBVOLUME_NEW_QUOTA);
1405 if (r == -ENOTTY)
1406 log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (unsupported fs or dir not a subvolume): %m", i->path);
1407 else if (r == -EROFS)
1408 log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (fs is read-only).", i->path);
1409 else if (r == -ENOPROTOOPT)
1410 log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (quota support is disabled).", i->path);
1411 else if (r < 0)
1412 q = log_error_errno(r, "Failed to adjust quota for subvolume \"%s\": %m", i->path);
1413 else if (r > 0)
1414 log_debug("Adjusted quota for subvolume \"%s\".", i->path);
1415 else if (r == 0)
1416 log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path);
1417 }
1418
1419 _fallthrough_;
1420 case EMPTY_DIRECTORY:
1421 r = path_set_perms(i, i->path);
1422 if (q < 0)
1423 return q;
1424 if (r < 0)
1425 return r;
1426
1427 break;
1428
1429 case CREATE_FIFO:
1430 RUN_WITH_UMASK(0000) {
1431 mac_selinux_create_file_prepare(i->path, S_IFIFO);
1432 r = mkfifo(i->path, i->mode);
1433 mac_selinux_create_file_clear();
1434 }
1435
1436 if (r < 0) {
1437 if (errno != EEXIST)
1438 return log_error_errno(errno, "Failed to create fifo %s: %m", i->path);
1439
1440 if (lstat(i->path, &st) < 0)
1441 return log_error_errno(errno, "stat(%s) failed: %m", i->path);
1442
1443 if (!S_ISFIFO(st.st_mode)) {
1444
1445 if (i->force) {
1446 RUN_WITH_UMASK(0000) {
1447 mac_selinux_create_file_prepare(i->path, S_IFIFO);
1448 r = mkfifo_atomic(i->path, i->mode);
1449 mac_selinux_create_file_clear();
1450 }
1451
1452 if (r < 0)
1453 return log_error_errno(r, "Failed to create fifo %s: %m", i->path);
1454 creation = CREATION_FORCE;
1455 } else {
1456 log_warning("\"%s\" already exists and is not a fifo.", i->path);
1457 return 0;
1458 }
1459 } else
1460 creation = CREATION_EXISTING;
1461 } else
1462 creation = CREATION_NORMAL;
1463 log_debug("%s fifo \"%s\".", creation_mode_verb_to_string(creation), i->path);
1464
1465 r = path_set_perms(i, i->path);
1466 if (r < 0)
1467 return r;
1468
1469 break;
1470 }
1471
1472 case CREATE_SYMLINK: {
1473 mac_selinux_create_file_prepare(i->path, S_IFLNK);
1474 r = symlink(i->argument, i->path);
1475 mac_selinux_create_file_clear();
1476
1477 if (r < 0) {
1478 _cleanup_free_ char *x = NULL;
1479
1480 if (errno != EEXIST)
1481 return log_error_errno(errno, "symlink(%s, %s) failed: %m", i->argument, i->path);
1482
1483 r = readlink_malloc(i->path, &x);
1484 if (r < 0 || !streq(i->argument, x)) {
1485
1486 if (i->force) {
1487 mac_selinux_create_file_prepare(i->path, S_IFLNK);
1488 r = symlink_atomic(i->argument, i->path);
1489 mac_selinux_create_file_clear();
1490
1491 if (IN_SET(r, -EEXIST, -ENOTEMPTY)) {
1492 r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL);
1493 if (r < 0)
1494 return log_error_errno(r, "rm -fr %s failed: %m", i->path);
1495
1496 mac_selinux_create_file_prepare(i->path, S_IFLNK);
1497 r = symlink(i->argument, i->path) < 0 ? -errno : 0;
1498 mac_selinux_create_file_clear();
1499 }
1500 if (r < 0)
1501 return log_error_errno(r, "symlink(%s, %s) failed: %m", i->argument, i->path);
1502
1503 creation = CREATION_FORCE;
1504 } else {
1505 log_debug("\"%s\" is not a symlink or does not point to the correct path.", i->path);
1506 return 0;
1507 }
1508 } else
1509 creation = CREATION_EXISTING;
1510 } else
1511
1512 creation = CREATION_NORMAL;
1513 log_debug("%s symlink \"%s\".", creation_mode_verb_to_string(creation), i->path);
1514 break;
1515 }
1516
1517 case CREATE_BLOCK_DEVICE:
1518 case CREATE_CHAR_DEVICE: {
1519 mode_t file_type;
1520
1521 if (have_effective_cap(CAP_MKNOD) == 0) {
1522 /* In a container we lack CAP_MKNOD. We
1523 shouldn't attempt to create the device node in
1524 that case to avoid noise, and we don't support
1525 virtualized devices in containers anyway. */
1526
1527 log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path);
1528 return 0;
1529 }
1530
1531 file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
1532
1533 RUN_WITH_UMASK(0000) {
1534 mac_selinux_create_file_prepare(i->path, file_type);
1535 r = mknod(i->path, i->mode | file_type, i->major_minor);
1536 mac_selinux_create_file_clear();
1537 }
1538
1539 if (r < 0) {
1540 if (errno == EPERM) {
1541 log_debug("We lack permissions, possibly because of cgroup configuration; "
1542 "skipping creation of device node %s.", i->path);
1543 return 0;
1544 }
1545
1546 if (errno != EEXIST)
1547 return log_error_errno(errno, "Failed to create device node %s: %m", i->path);
1548
1549 if (lstat(i->path, &st) < 0)
1550 return log_error_errno(errno, "stat(%s) failed: %m", i->path);
1551
1552 if ((st.st_mode & S_IFMT) != file_type) {
1553
1554 if (i->force) {
1555
1556 RUN_WITH_UMASK(0000) {
1557 mac_selinux_create_file_prepare(i->path, file_type);
1558 r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
1559 mac_selinux_create_file_clear();
1560 }
1561
1562 if (r < 0)
1563 return log_error_errno(r, "Failed to create device node \"%s\": %m", i->path);
1564 creation = CREATION_FORCE;
1565 } else {
1566 log_debug("%s is not a device node.", i->path);
1567 return 0;
1568 }
1569 } else
1570 creation = CREATION_EXISTING;
1571 } else
1572 creation = CREATION_NORMAL;
1573
1574 log_debug("%s %s device node \"%s\" %u:%u.",
1575 creation_mode_verb_to_string(creation),
1576 i->type == CREATE_BLOCK_DEVICE ? "block" : "char",
1577 i->path, major(i->mode), minor(i->mode));
1578
1579 r = path_set_perms(i, i->path);
1580 if (r < 0)
1581 return r;
1582
1583 break;
1584 }
1585
1586 case ADJUST_MODE:
1587 case RELABEL_PATH:
1588 r = glob_item(i, path_set_perms, false);
1589 if (r < 0)
1590 return r;
1591 break;
1592
1593 case RECURSIVE_RELABEL_PATH:
1594 r = glob_item(i, path_set_perms, true);
1595 if (r < 0)
1596 return r;
1597 break;
1598
1599 case SET_XATTR:
1600 r = glob_item(i, path_set_xattrs, false);
1601 if (r < 0)
1602 return r;
1603 break;
1604
1605 case RECURSIVE_SET_XATTR:
1606 r = glob_item(i, path_set_xattrs, true);
1607 if (r < 0)
1608 return r;
1609 break;
1610
1611 case SET_ACL:
1612 r = glob_item(i, path_set_acls, false);
1613 if (r < 0)
1614 return r;
1615 break;
1616
1617 case RECURSIVE_SET_ACL:
1618 r = glob_item(i, path_set_acls, true);
1619 if (r < 0)
1620 return r;
1621 break;
1622
1623 case SET_ATTRIBUTE:
1624 r = glob_item(i, path_set_attribute, false);
1625 if (r < 0)
1626 return r;
1627 break;
1628
1629 case RECURSIVE_SET_ATTRIBUTE:
1630 r = glob_item(i, path_set_attribute, true);
1631 if (r < 0)
1632 return r;
1633 break;
1634 }
1635
1636 return 0;
1637 }
1638
1639 static int remove_item_instance(Item *i, const char *instance) {
1640 int r;
1641
1642 assert(i);
1643
1644 switch (i->type) {
1645
1646 case REMOVE_PATH:
1647 if (remove(instance) < 0 && errno != ENOENT)
1648 return log_error_errno(errno, "rm(%s): %m", instance);
1649
1650 break;
1651
1652 case TRUNCATE_DIRECTORY:
1653 case RECURSIVE_REMOVE_PATH:
1654 /* FIXME: we probably should use dir_cleanup() here
1655 * instead of rm_rf() so that 'x' is honoured. */
1656 log_debug("rm -rf \"%s\"", instance);
1657 r = rm_rf(instance, (i->type == RECURSIVE_REMOVE_PATH ? REMOVE_ROOT|REMOVE_SUBVOLUME : 0) | REMOVE_PHYSICAL);
1658 if (r < 0 && r != -ENOENT)
1659 return log_error_errno(r, "rm_rf(%s): %m", instance);
1660
1661 break;
1662
1663 default:
1664 assert_not_reached("wut?");
1665 }
1666
1667 return 0;
1668 }
1669
1670 static int remove_item(Item *i) {
1671 assert(i);
1672
1673 log_debug("Running remove action for entry %c %s", (char) i->type, i->path);
1674
1675 switch (i->type) {
1676
1677 case REMOVE_PATH:
1678 case TRUNCATE_DIRECTORY:
1679 case RECURSIVE_REMOVE_PATH:
1680 return glob_item(i, remove_item_instance, false);
1681
1682 default:
1683 return 0;
1684 }
1685 }
1686
1687 static int clean_item_instance(Item *i, const char* instance) {
1688 _cleanup_closedir_ DIR *d = NULL;
1689 struct stat s, ps;
1690 bool mountpoint;
1691 usec_t cutoff, n;
1692 char timestamp[FORMAT_TIMESTAMP_MAX];
1693
1694 assert(i);
1695
1696 if (!i->age_set)
1697 return 0;
1698
1699 n = now(CLOCK_REALTIME);
1700 if (n < i->age)
1701 return 0;
1702
1703 cutoff = n - i->age;
1704
1705 d = opendir_nomod(instance);
1706 if (!d) {
1707 if (IN_SET(errno, ENOENT, ENOTDIR)) {
1708 log_debug_errno(errno, "Directory \"%s\": %m", instance);
1709 return 0;
1710 }
1711
1712 return log_error_errno(errno, "Failed to open directory %s: %m", instance);
1713 }
1714
1715 if (fstat(dirfd(d), &s) < 0)
1716 return log_error_errno(errno, "stat(%s) failed: %m", i->path);
1717
1718 if (!S_ISDIR(s.st_mode)) {
1719 log_error("%s is not a directory.", i->path);
1720 return -ENOTDIR;
1721 }
1722
1723 if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0)
1724 return log_error_errno(errno, "stat(%s/..) failed: %m", i->path);
1725
1726 mountpoint = s.st_dev != ps.st_dev || s.st_ino == ps.st_ino;
1727
1728 log_debug("Cleanup threshold for %s \"%s\" is %s",
1729 mountpoint ? "mount point" : "directory",
1730 instance,
1731 format_timestamp_us(timestamp, sizeof(timestamp), cutoff));
1732
1733 return dir_cleanup(i, instance, d, &s, cutoff, s.st_dev, mountpoint,
1734 MAX_DEPTH, i->keep_first_level);
1735 }
1736
1737 static int clean_item(Item *i) {
1738 assert(i);
1739
1740 log_debug("Running clean action for entry %c %s", (char) i->type, i->path);
1741
1742 switch (i->type) {
1743 case CREATE_DIRECTORY:
1744 case CREATE_SUBVOLUME:
1745 case CREATE_SUBVOLUME_INHERIT_QUOTA:
1746 case CREATE_SUBVOLUME_NEW_QUOTA:
1747 case TRUNCATE_DIRECTORY:
1748 case IGNORE_PATH:
1749 case COPY_FILES:
1750 clean_item_instance(i, i->path);
1751 return 0;
1752 case EMPTY_DIRECTORY:
1753 case IGNORE_DIRECTORY_PATH:
1754 return glob_item(i, clean_item_instance, false);
1755 default:
1756 return 0;
1757 }
1758 }
1759
1760 static int process_item_array(ItemArray *array);
1761
1762 static int process_item(Item *i) {
1763 int r, q, p, t = 0;
1764 _cleanup_free_ char *prefix = NULL;
1765
1766 assert(i);
1767
1768 if (i->done)
1769 return 0;
1770
1771 i->done = true;
1772
1773 prefix = malloc(strlen(i->path) + 1);
1774 if (!prefix)
1775 return log_oom();
1776
1777 PATH_FOREACH_PREFIX(prefix, i->path) {
1778 ItemArray *j;
1779
1780 j = ordered_hashmap_get(items, prefix);
1781 if (j) {
1782 int s;
1783
1784 s = process_item_array(j);
1785 if (s < 0 && t == 0)
1786 t = s;
1787 }
1788 }
1789
1790 if (chase_symlinks(i->path, NULL, CHASE_NO_AUTOFS, NULL) == -EREMOTE)
1791 return t;
1792
1793 r = arg_create ? create_item(i) : 0;
1794 q = arg_remove ? remove_item(i) : 0;
1795 p = arg_clean ? clean_item(i) : 0;
1796
1797 return t < 0 ? t :
1798 r < 0 ? r :
1799 q < 0 ? q :
1800 p;
1801 }
1802
1803 static int process_item_array(ItemArray *array) {
1804 unsigned n;
1805 int r = 0, k;
1806
1807 assert(array);
1808
1809 for (n = 0; n < array->count; n++) {
1810 k = process_item(array->items + n);
1811 if (k < 0 && r == 0)
1812 r = k;
1813 }
1814
1815 return r;
1816 }
1817
1818 static void item_free_contents(Item *i) {
1819 assert(i);
1820 free(i->path);
1821 free(i->argument);
1822 strv_free(i->xattrs);
1823
1824 #if HAVE_ACL
1825 acl_free(i->acl_access);
1826 acl_free(i->acl_default);
1827 #endif
1828 }
1829
1830 static void item_array_free(ItemArray *a) {
1831 unsigned n;
1832
1833 if (!a)
1834 return;
1835
1836 for (n = 0; n < a->count; n++)
1837 item_free_contents(a->items + n);
1838 free(a->items);
1839 free(a);
1840 }
1841
1842 static int item_compare(const void *a, const void *b) {
1843 const Item *x = a, *y = b;
1844
1845 /* Make sure that the ownership taking item is put first, so
1846 * that we first create the node, and then can adjust it */
1847
1848 if (takes_ownership(x->type) && !takes_ownership(y->type))
1849 return -1;
1850 if (!takes_ownership(x->type) && takes_ownership(y->type))
1851 return 1;
1852
1853 return (int) x->type - (int) y->type;
1854 }
1855
1856 static bool item_compatible(Item *a, Item *b) {
1857 assert(a);
1858 assert(b);
1859 assert(streq(a->path, b->path));
1860
1861 if (takes_ownership(a->type) && takes_ownership(b->type))
1862 /* check if the items are the same */
1863 return streq_ptr(a->argument, b->argument) &&
1864
1865 a->uid_set == b->uid_set &&
1866 a->uid == b->uid &&
1867
1868 a->gid_set == b->gid_set &&
1869 a->gid == b->gid &&
1870
1871 a->mode_set == b->mode_set &&
1872 a->mode == b->mode &&
1873
1874 a->age_set == b->age_set &&
1875 a->age == b->age &&
1876
1877 a->mask_perms == b->mask_perms &&
1878
1879 a->keep_first_level == b->keep_first_level &&
1880
1881 a->major_minor == b->major_minor;
1882
1883 return true;
1884 }
1885
1886 static bool should_include_path(const char *path) {
1887 char **prefix;
1888
1889 STRV_FOREACH(prefix, arg_exclude_prefixes)
1890 if (path_startswith(path, *prefix)) {
1891 log_debug("Entry \"%s\" matches exclude prefix \"%s\", skipping.",
1892 path, *prefix);
1893 return false;
1894 }
1895
1896 STRV_FOREACH(prefix, arg_include_prefixes)
1897 if (path_startswith(path, *prefix)) {
1898 log_debug("Entry \"%s\" matches include prefix \"%s\".", path, *prefix);
1899 return true;
1900 }
1901
1902 /* no matches, so we should include this path only if we
1903 * have no whitelist at all */
1904 if (strv_isempty(arg_include_prefixes))
1905 return true;
1906
1907 log_debug("Entry \"%s\" does not match any include prefix, skipping.", path);
1908 return false;
1909 }
1910
1911 static int specifier_expansion_from_arg(Item *i) {
1912 _cleanup_free_ char *unescaped = NULL, *resolved = NULL;
1913 char **xattr;
1914 int r;
1915
1916 assert(i);
1917
1918 if (i->argument == NULL)
1919 return 0;
1920
1921 switch (i->type) {
1922 case COPY_FILES:
1923 case CREATE_SYMLINK:
1924 case CREATE_FILE:
1925 case TRUNCATE_FILE:
1926 case WRITE_FILE:
1927 r = cunescape(i->argument, 0, &unescaped);
1928 if (r < 0)
1929 return log_error_errno(r, "Failed to unescape parameter to write: %s", i->argument);
1930
1931 r = specifier_printf(unescaped, specifier_table, NULL, &resolved);
1932 if (r < 0)
1933 return r;
1934
1935 free_and_replace(i->argument, resolved);
1936 break;
1937
1938 case SET_XATTR:
1939 case RECURSIVE_SET_XATTR:
1940 assert(i->xattrs);
1941
1942 STRV_FOREACH (xattr, i->xattrs) {
1943 r = specifier_printf(*xattr, specifier_table, NULL, &resolved);
1944 if (r < 0)
1945 return r;
1946
1947 free_and_replace(*xattr, resolved);
1948 }
1949 break;
1950
1951 default:
1952 break;
1953 }
1954 return 0;
1955 }
1956
1957 static int parse_line(const char *fname, unsigned line, const char *buffer, bool *invalid_config) {
1958
1959 _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
1960 _cleanup_(item_free_contents) Item i = {};
1961 ItemArray *existing;
1962 OrderedHashmap *h;
1963 int r, pos;
1964 bool force = false, boot = false;
1965
1966 assert(fname);
1967 assert(line >= 1);
1968 assert(buffer);
1969
1970 r = extract_many_words(
1971 &buffer,
1972 NULL,
1973 EXTRACT_QUOTES,
1974 &action,
1975 &path,
1976 &mode,
1977 &user,
1978 &group,
1979 &age,
1980 NULL);
1981 if (r < 0) {
1982 if (IN_SET(r, -EINVAL, -EBADSLT))
1983 /* invalid quoting and such or an unknown specifier */
1984 *invalid_config = true;
1985 return log_error_errno(r, "[%s:%u] Failed to parse line: %m", fname, line);
1986 }
1987
1988 else if (r < 2) {
1989 *invalid_config = true;
1990 log_error("[%s:%u] Syntax error.", fname, line);
1991 return -EIO;
1992 }
1993
1994 if (!isempty(buffer) && !streq(buffer, "-")) {
1995 i.argument = strdup(buffer);
1996 if (!i.argument)
1997 return log_oom();
1998 }
1999
2000 if (isempty(action)) {
2001 *invalid_config = true;
2002 log_error("[%s:%u] Command too short '%s'.", fname, line, action);
2003 return -EINVAL;
2004 }
2005
2006 for (pos = 1; action[pos]; pos++) {
2007 if (action[pos] == '!' && !boot)
2008 boot = true;
2009 else if (action[pos] == '+' && !force)
2010 force = true;
2011 else {
2012 *invalid_config = true;
2013 log_error("[%s:%u] Unknown modifiers in command '%s'",
2014 fname, line, action);
2015 return -EINVAL;
2016 }
2017 }
2018
2019 if (boot && !arg_boot) {
2020 log_debug("Ignoring entry %s \"%s\" because --boot is not specified.",
2021 action, path);
2022 return 0;
2023 }
2024
2025 i.type = action[0];
2026 i.force = force;
2027
2028 r = specifier_printf(path, specifier_table, NULL, &i.path);
2029 if (r == -ENXIO)
2030 return log_unresolvable_specifier(fname, line);
2031 if (r < 0) {
2032 if (IN_SET(r, -EINVAL, -EBADSLT))
2033 *invalid_config = true;
2034 return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, path);
2035 }
2036
2037 switch (i.type) {
2038
2039 case CREATE_DIRECTORY:
2040 case CREATE_SUBVOLUME:
2041 case CREATE_SUBVOLUME_INHERIT_QUOTA:
2042 case CREATE_SUBVOLUME_NEW_QUOTA:
2043 case EMPTY_DIRECTORY:
2044 case TRUNCATE_DIRECTORY:
2045 case CREATE_FIFO:
2046 case IGNORE_PATH:
2047 case IGNORE_DIRECTORY_PATH:
2048 case REMOVE_PATH:
2049 case RECURSIVE_REMOVE_PATH:
2050 case ADJUST_MODE:
2051 case RELABEL_PATH:
2052 case RECURSIVE_RELABEL_PATH:
2053 if (i.argument)
2054 log_warning("[%s:%u] %c lines don't take argument fields, ignoring.", fname, line, i.type);
2055
2056 break;
2057
2058 case CREATE_FILE:
2059 case TRUNCATE_FILE:
2060 break;
2061
2062 case CREATE_SYMLINK:
2063 if (!i.argument) {
2064 i.argument = strappend("/usr/share/factory/", i.path);
2065 if (!i.argument)
2066 return log_oom();
2067 }
2068 break;
2069
2070 case WRITE_FILE:
2071 if (!i.argument) {
2072 *invalid_config = true;
2073 log_error("[%s:%u] Write file requires argument.", fname, line);
2074 return -EBADMSG;
2075 }
2076 break;
2077
2078 case COPY_FILES:
2079 if (!i.argument) {
2080 i.argument = strappend("/usr/share/factory/", i.path);
2081 if (!i.argument)
2082 return log_oom();
2083 } else if (!path_is_absolute(i.argument)) {
2084 *invalid_config = true;
2085 log_error("[%s:%u] Source path is not absolute.", fname, line);
2086 return -EBADMSG;
2087 }
2088
2089 path_kill_slashes(i.argument);
2090 break;
2091
2092 case CREATE_CHAR_DEVICE:
2093 case CREATE_BLOCK_DEVICE: {
2094 unsigned major, minor;
2095
2096 if (!i.argument) {
2097 *invalid_config = true;
2098 log_error("[%s:%u] Device file requires argument.", fname, line);
2099 return -EBADMSG;
2100 }
2101
2102 if (sscanf(i.argument, "%u:%u", &major, &minor) != 2) {
2103 *invalid_config = true;
2104 log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i.argument);
2105 return -EBADMSG;
2106 }
2107
2108 i.major_minor = makedev(major, minor);
2109 break;
2110 }
2111
2112 case SET_XATTR:
2113 case RECURSIVE_SET_XATTR:
2114 if (!i.argument) {
2115 *invalid_config = true;
2116 log_error("[%s:%u] Set extended attribute requires argument.", fname, line);
2117 return -EBADMSG;
2118 }
2119 r = parse_xattrs_from_arg(&i);
2120 if (r < 0)
2121 return r;
2122 break;
2123
2124 case SET_ACL:
2125 case RECURSIVE_SET_ACL:
2126 if (!i.argument) {
2127 *invalid_config = true;
2128 log_error("[%s:%u] Set ACLs requires argument.", fname, line);
2129 return -EBADMSG;
2130 }
2131 r = parse_acls_from_arg(&i);
2132 if (r < 0)
2133 return r;
2134 break;
2135
2136 case SET_ATTRIBUTE:
2137 case RECURSIVE_SET_ATTRIBUTE:
2138 if (!i.argument) {
2139 *invalid_config = true;
2140 log_error("[%s:%u] Set file attribute requires argument.", fname, line);
2141 return -EBADMSG;
2142 }
2143 r = parse_attribute_from_arg(&i);
2144 if (IN_SET(r, -EINVAL, -EBADSLT))
2145 *invalid_config = true;
2146 if (r < 0)
2147 return r;
2148 break;
2149
2150 default:
2151 log_error("[%s:%u] Unknown command type '%c'.", fname, line, (char) i.type);
2152 *invalid_config = true;
2153 return -EBADMSG;
2154 }
2155
2156 if (!path_is_absolute(i.path)) {
2157 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i.path);
2158 *invalid_config = true;
2159 return -EBADMSG;
2160 }
2161
2162 path_kill_slashes(i.path);
2163
2164 if (!should_include_path(i.path))
2165 return 0;
2166
2167 r = specifier_expansion_from_arg(&i);
2168 if (r == -ENXIO)
2169 return log_unresolvable_specifier(fname, line);
2170 if (r < 0) {
2171 if (IN_SET(r, -EINVAL, -EBADSLT))
2172 *invalid_config = true;
2173 return log_error_errno(r, "[%s:%u] Failed to substitute specifiers in argument: %m",
2174 fname, line);
2175 }
2176
2177 if (arg_root) {
2178 char *p;
2179
2180 p = prefix_root(arg_root, i.path);
2181 if (!p)
2182 return log_oom();
2183
2184 free(i.path);
2185 i.path = p;
2186 }
2187
2188 if (!isempty(user) && !streq(user, "-")) {
2189 const char *u = user;
2190
2191 r = get_user_creds(&u, &i.uid, NULL, NULL, NULL);
2192 if (r < 0) {
2193 *invalid_config = true;
2194 return log_error_errno(r, "[%s:%u] Unknown user '%s'.", fname, line, user);
2195 }
2196
2197 i.uid_set = true;
2198 }
2199
2200 if (!isempty(group) && !streq(group, "-")) {
2201 const char *g = group;
2202
2203 r = get_group_creds(&g, &i.gid);
2204 if (r < 0) {
2205 *invalid_config = true;
2206 log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
2207 return r;
2208 }
2209
2210 i.gid_set = true;
2211 }
2212
2213 if (!isempty(mode) && !streq(mode, "-")) {
2214 const char *mm = mode;
2215 unsigned m;
2216
2217 if (*mm == '~') {
2218 i.mask_perms = true;
2219 mm++;
2220 }
2221
2222 if (parse_mode(mm, &m) < 0) {
2223 *invalid_config = true;
2224 log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
2225 return -EBADMSG;
2226 }
2227
2228 i.mode = m;
2229 i.mode_set = true;
2230 } else
2231 i.mode = IN_SET(i.type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA) ? 0755 : 0644;
2232
2233 if (!isempty(age) && !streq(age, "-")) {
2234 const char *a = age;
2235
2236 if (*a == '~') {
2237 i.keep_first_level = true;
2238 a++;
2239 }
2240
2241 if (parse_sec(a, &i.age) < 0) {
2242 *invalid_config = true;
2243 log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
2244 return -EBADMSG;
2245 }
2246
2247 i.age_set = true;
2248 }
2249
2250 h = needs_glob(i.type) ? globs : items;
2251
2252 existing = ordered_hashmap_get(h, i.path);
2253 if (existing) {
2254 unsigned n;
2255
2256 for (n = 0; n < existing->count; n++) {
2257 if (!item_compatible(existing->items + n, &i)) {
2258 log_notice("[%s:%u] Duplicate line for path \"%s\", ignoring.",
2259 fname, line, i.path);
2260 return 0;
2261 }
2262 }
2263 } else {
2264 existing = new0(ItemArray, 1);
2265 if (!existing)
2266 return log_oom();
2267
2268 r = ordered_hashmap_put(h, i.path, existing);
2269 if (r < 0)
2270 return log_oom();
2271 }
2272
2273 if (!GREEDY_REALLOC(existing->items, existing->size, existing->count + 1))
2274 return log_oom();
2275
2276 memcpy(existing->items + existing->count++, &i, sizeof(i));
2277
2278 /* Sort item array, to enforce stable ordering of application */
2279 qsort_safe(existing->items, existing->count, sizeof(Item), item_compare);
2280
2281 zero(i);
2282 return 0;
2283 }
2284
2285 static void help(void) {
2286 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
2287 "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
2288 " -h --help Show this help\n"
2289 " --user Execute user configuration\n"
2290 " --version Show package version\n"
2291 " --create Create marked files/directories\n"
2292 " --clean Clean up marked directories\n"
2293 " --remove Remove marked files/directories\n"
2294 " --boot Execute actions only safe at boot\n"
2295 " --prefix=PATH Only apply rules with the specified prefix\n"
2296 " --exclude-prefix=PATH Ignore rules with the specified prefix\n"
2297 " --root=PATH Operate on an alternate filesystem root\n"
2298 , program_invocation_short_name);
2299 }
2300
2301 static int parse_argv(int argc, char *argv[]) {
2302
2303 enum {
2304 ARG_VERSION = 0x100,
2305 ARG_USER,
2306 ARG_CREATE,
2307 ARG_CLEAN,
2308 ARG_REMOVE,
2309 ARG_BOOT,
2310 ARG_PREFIX,
2311 ARG_EXCLUDE_PREFIX,
2312 ARG_ROOT,
2313 };
2314
2315 static const struct option options[] = {
2316 { "help", no_argument, NULL, 'h' },
2317 { "user", no_argument, NULL, ARG_USER },
2318 { "version", no_argument, NULL, ARG_VERSION },
2319 { "create", no_argument, NULL, ARG_CREATE },
2320 { "clean", no_argument, NULL, ARG_CLEAN },
2321 { "remove", no_argument, NULL, ARG_REMOVE },
2322 { "boot", no_argument, NULL, ARG_BOOT },
2323 { "prefix", required_argument, NULL, ARG_PREFIX },
2324 { "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
2325 { "root", required_argument, NULL, ARG_ROOT },
2326 {}
2327 };
2328
2329 int c, r;
2330
2331 assert(argc >= 0);
2332 assert(argv);
2333
2334 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
2335
2336 switch (c) {
2337
2338 case 'h':
2339 help();
2340 return 0;
2341
2342 case ARG_VERSION:
2343 return version();
2344
2345 case ARG_USER:
2346 arg_user = true;
2347 break;
2348
2349 case ARG_CREATE:
2350 arg_create = true;
2351 break;
2352
2353 case ARG_CLEAN:
2354 arg_clean = true;
2355 break;
2356
2357 case ARG_REMOVE:
2358 arg_remove = true;
2359 break;
2360
2361 case ARG_BOOT:
2362 arg_boot = true;
2363 break;
2364
2365 case ARG_PREFIX:
2366 if (strv_push(&arg_include_prefixes, optarg) < 0)
2367 return log_oom();
2368 break;
2369
2370 case ARG_EXCLUDE_PREFIX:
2371 if (strv_push(&arg_exclude_prefixes, optarg) < 0)
2372 return log_oom();
2373 break;
2374
2375 case ARG_ROOT:
2376 r = parse_path_argument_and_warn(optarg, true, &arg_root);
2377 if (r < 0)
2378 return r;
2379 break;
2380
2381 case '?':
2382 return -EINVAL;
2383
2384 default:
2385 assert_not_reached("Unhandled option");
2386 }
2387
2388 if (!arg_clean && !arg_create && !arg_remove) {
2389 log_error("You need to specify at least one of --clean, --create or --remove.");
2390 return -EINVAL;
2391 }
2392
2393 return 1;
2394 }
2395
2396 static int read_config_file(const char **config_dirs, const char *fn, bool ignore_enoent, bool *invalid_config) {
2397 _cleanup_fclose_ FILE *_f = NULL;
2398 FILE *f;
2399 char line[LINE_MAX];
2400 Iterator iterator;
2401 unsigned v = 0;
2402 Item *i;
2403 int r = 0;
2404
2405 assert(fn);
2406
2407 if (streq(fn, "-")) {
2408 log_debug("Reading config from stdin.");
2409 fn = "<stdin>";
2410 f = stdin;
2411 } else {
2412 r = search_and_fopen(fn, "re", arg_root, config_dirs, &_f);
2413 if (r < 0) {
2414 if (ignore_enoent && r == -ENOENT) {
2415 log_debug_errno(r, "Failed to open \"%s\", ignoring: %m", fn);
2416 return 0;
2417 }
2418
2419 return log_error_errno(r, "Failed to open '%s': %m", fn);
2420 }
2421 log_debug("Reading config file \"%s\".", fn);
2422 f = _f;
2423 }
2424
2425 FOREACH_LINE(line, f, break) {
2426 char *l;
2427 int k;
2428 bool invalid_line = false;
2429
2430 v++;
2431
2432 l = strstrip(line);
2433 if (IN_SET(*l, 0, '#'))
2434 continue;
2435
2436 k = parse_line(fn, v, l, &invalid_line);
2437 if (k < 0) {
2438 if (invalid_line)
2439 /* Allow reporting with a special code if the caller requested this */
2440 *invalid_config = true;
2441 else if (r == 0)
2442 /* The first error becomes our return value */
2443 r = k;
2444 }
2445 }
2446
2447 /* we have to determine age parameter for each entry of type X */
2448 ORDERED_HASHMAP_FOREACH(i, globs, iterator) {
2449 Iterator iter;
2450 Item *j, *candidate_item = NULL;
2451
2452 if (i->type != IGNORE_DIRECTORY_PATH)
2453 continue;
2454
2455 ORDERED_HASHMAP_FOREACH(j, items, iter) {
2456 if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA))
2457 continue;
2458
2459 if (path_equal(j->path, i->path)) {
2460 candidate_item = j;
2461 break;
2462 }
2463
2464 if ((!candidate_item && path_startswith(i->path, j->path)) ||
2465 (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0)))
2466 candidate_item = j;
2467 }
2468
2469 if (candidate_item && candidate_item->age_set) {
2470 i->age = candidate_item->age;
2471 i->age_set = true;
2472 }
2473 }
2474
2475 if (ferror(f)) {
2476 log_error_errno(errno, "Failed to read from file %s: %m", fn);
2477 if (r == 0)
2478 r = -EIO;
2479 }
2480
2481 return r;
2482 }
2483
2484 int main(int argc, char *argv[]) {
2485 int r, k;
2486 ItemArray *a;
2487 Iterator iterator;
2488 _cleanup_strv_free_ char **config_dirs = NULL;
2489 bool invalid_config = false;
2490 char **f;
2491
2492 r = parse_argv(argc, argv);
2493 if (r <= 0)
2494 goto finish;
2495
2496 log_set_target(LOG_TARGET_AUTO);
2497 log_parse_environment();
2498 log_open();
2499
2500 umask(0022);
2501
2502 mac_selinux_init();
2503
2504 items = ordered_hashmap_new(&string_hash_ops);
2505 globs = ordered_hashmap_new(&string_hash_ops);
2506
2507 if (!items || !globs) {
2508 r = log_oom();
2509 goto finish;
2510 }
2511
2512 r = 0;
2513
2514 if (arg_user) {
2515 r = user_config_paths(&config_dirs);
2516 if (r < 0) {
2517 log_error_errno(r, "Failed to initialize configuration directory list: %m");
2518 goto finish;
2519 }
2520 } else {
2521 config_dirs = strv_split_nulstr(CONF_PATHS_NULSTR("tmpfiles.d"));
2522 if (!config_dirs) {
2523 r = log_oom();
2524 goto finish;
2525 }
2526 }
2527
2528 if (DEBUG_LOGGING) {
2529 _cleanup_free_ char *t = NULL;
2530
2531 t = strv_join(config_dirs, "\n\t");
2532 if (t)
2533 log_debug("Looking for configuration files in (higher priority first:\n\t%s", t);
2534 }
2535
2536 if (optind < argc) {
2537 int j;
2538
2539 for (j = optind; j < argc; j++) {
2540 k = read_config_file((const char**) config_dirs, argv[j], false, &invalid_config);
2541 if (k < 0 && r == 0)
2542 r = k;
2543 }
2544
2545 } else {
2546 _cleanup_strv_free_ char **files = NULL;
2547
2548 r = conf_files_list_strv(&files, ".conf", arg_root, 0, (const char* const*) config_dirs);
2549 if (r < 0) {
2550 log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
2551 goto finish;
2552 }
2553
2554 STRV_FOREACH(f, files) {
2555 k = read_config_file((const char**) config_dirs, *f, true, &invalid_config);
2556 if (k < 0 && r == 0)
2557 r = k;
2558 }
2559 }
2560
2561 /* The non-globbing ones usually create things, hence we apply
2562 * them first */
2563 ORDERED_HASHMAP_FOREACH(a, items, iterator) {
2564 k = process_item_array(a);
2565 if (k < 0 && r == 0)
2566 r = k;
2567 }
2568
2569 /* The globbing ones usually alter things, hence we apply them
2570 * second. */
2571 ORDERED_HASHMAP_FOREACH(a, globs, iterator) {
2572 k = process_item_array(a);
2573 if (k < 0 && r == 0)
2574 r = k;
2575 }
2576
2577 finish:
2578 ordered_hashmap_free_with_destructor(items, item_array_free);
2579 ordered_hashmap_free_with_destructor(globs, item_array_free);
2580
2581 free(arg_include_prefixes);
2582 free(arg_exclude_prefixes);
2583 free(arg_root);
2584
2585 set_free_free(unix_sockets);
2586
2587 mac_selinux_finish();
2588
2589 if (r < 0)
2590 return EXIT_FAILURE;
2591 else if (invalid_config)
2592 return EX_DATAERR;
2593 else
2594 return EXIT_SUCCESS;
2595 }