chiark / gitweb /
tree-wide: use IN_SET macro (#6977)
[elogind.git] / src / basic / fs-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <linux/magic.h>
27 #include <time.h>
28 #include <unistd.h>
29
30 #include "alloc-util.h"
31 #include "dirent-util.h"
32 #include "fd-util.h"
33 #include "fileio.h"
34 #include "fs-util.h"
35 //#include "log.h"
36 //#include "macro.h"
37 //#include "missing.h"
38 #include "mkdir.h"
39 #include "parse-util.h"
40 #include "path-util.h"
41 #include "stat-util.h"
42 #include "stdio-util.h"
43 #include "string-util.h"
44 #include "strv.h"
45 //#include "time-util.h"
46 #include "user-util.h"
47 #include "util.h"
48
49 /// Additional includes needed by elogind
50 #include "process-util.h"
51
52 int unlink_noerrno(const char *path) {
53         PROTECT_ERRNO;
54         int r;
55
56         r = unlink(path);
57         if (r < 0)
58                 return -errno;
59
60         return 0;
61 }
62
63 #if 0 /// UNNEEDED by elogind
64 int rmdir_parents(const char *path, const char *stop) {
65         size_t l;
66         int r = 0;
67
68         assert(path);
69         assert(stop);
70
71         l = strlen(path);
72
73         /* Skip trailing slashes */
74         while (l > 0 && path[l-1] == '/')
75                 l--;
76
77         while (l > 0) {
78                 char *t;
79
80                 /* Skip last component */
81                 while (l > 0 && path[l-1] != '/')
82                         l--;
83
84                 /* Skip trailing slashes */
85                 while (l > 0 && path[l-1] == '/')
86                         l--;
87
88                 if (l <= 0)
89                         break;
90
91                 t = strndup(path, l);
92                 if (!t)
93                         return -ENOMEM;
94
95                 if (path_startswith(stop, t)) {
96                         free(t);
97                         return 0;
98                 }
99
100                 r = rmdir(t);
101                 free(t);
102
103                 if (r < 0)
104                         if (errno != ENOENT)
105                                 return -errno;
106         }
107
108         return 0;
109 }
110
111
112 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
113         struct stat buf;
114         int ret;
115
116         ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
117         if (ret >= 0)
118                 return 0;
119
120         /* renameat2() exists since Linux 3.15, btrfs added support for it later.
121          * If it is not implemented, fallback to another method. */
122         if (!IN_SET(errno, EINVAL, ENOSYS))
123                 return -errno;
124
125         /* The link()/unlink() fallback does not work on directories. But
126          * renameat() without RENAME_NOREPLACE gives the same semantics on
127          * directories, except when newpath is an *empty* directory. This is
128          * good enough. */
129         ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
130         if (ret >= 0 && S_ISDIR(buf.st_mode)) {
131                 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
132                 return ret >= 0 ? 0 : -errno;
133         }
134
135         /* If it is not a directory, use the link()/unlink() fallback. */
136         ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
137         if (ret < 0)
138                 return -errno;
139
140         ret = unlinkat(olddirfd, oldpath, 0);
141         if (ret < 0) {
142                 /* backup errno before the following unlinkat() alters it */
143                 ret = errno;
144                 (void) unlinkat(newdirfd, newpath, 0);
145                 errno = ret;
146                 return -errno;
147         }
148
149         return 0;
150 }
151 #endif // 0
152
153 int readlinkat_malloc(int fd, const char *p, char **ret) {
154         size_t l = 100;
155         int r;
156
157         assert(p);
158         assert(ret);
159
160         for (;;) {
161                 char *c;
162                 ssize_t n;
163
164                 c = new(char, l);
165                 if (!c)
166                         return -ENOMEM;
167
168                 n = readlinkat(fd, p, c, l-1);
169                 if (n < 0) {
170                         r = -errno;
171                         free(c);
172                         return r;
173                 }
174
175                 if ((size_t) n < l-1) {
176                         c[n] = 0;
177                         *ret = c;
178                         return 0;
179                 }
180
181                 free(c);
182                 l *= 2;
183         }
184 }
185
186 int readlink_malloc(const char *p, char **ret) {
187         return readlinkat_malloc(AT_FDCWD, p, ret);
188 }
189
190 #if 0 /// UNNEEDED by elogind
191 int readlink_value(const char *p, char **ret) {
192         _cleanup_free_ char *link = NULL;
193         char *value;
194         int r;
195
196         r = readlink_malloc(p, &link);
197         if (r < 0)
198                 return r;
199
200         value = basename(link);
201         if (!value)
202                 return -ENOENT;
203
204         value = strdup(value);
205         if (!value)
206                 return -ENOMEM;
207
208         *ret = value;
209
210         return 0;
211 }
212 #endif // 0
213
214 int readlink_and_make_absolute(const char *p, char **r) {
215         _cleanup_free_ char *target = NULL;
216         char *k;
217         int j;
218
219         assert(p);
220         assert(r);
221
222         j = readlink_malloc(p, &target);
223         if (j < 0)
224                 return j;
225
226         k = file_in_same_dir(p, target);
227         if (!k)
228                 return -ENOMEM;
229
230         *r = k;
231         return 0;
232 }
233
234 #if 0 /// UNNEEDED by elogind
235 int readlink_and_canonicalize(const char *p, const char *root, char **ret) {
236         char *t, *s;
237         int r;
238
239         assert(p);
240         assert(ret);
241
242         r = readlink_and_make_absolute(p, &t);
243         if (r < 0)
244                 return r;
245
246         r = chase_symlinks(t, root, 0, &s);
247         if (r < 0)
248                 /* If we can't follow up, then let's return the original string, slightly cleaned up. */
249                 *ret = path_kill_slashes(t);
250         else {
251                 *ret = s;
252                 free(t);
253         }
254
255         return 0;
256 }
257
258 int readlink_and_make_absolute_root(const char *root, const char *path, char **ret) {
259         _cleanup_free_ char *target = NULL, *t = NULL;
260         const char *full;
261         int r;
262
263         full = prefix_roota(root, path);
264         r = readlink_malloc(full, &target);
265         if (r < 0)
266                 return r;
267
268         t = file_in_same_dir(path, target);
269         if (!t)
270                 return -ENOMEM;
271
272         *ret = t;
273         t = NULL;
274
275         return 0;
276 }
277 #endif // 0
278
279 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
280         assert(path);
281
282         /* Under the assumption that we are running privileged we
283          * first change the access mode and only then hand out
284          * ownership to avoid a window where access is too open. */
285
286         if (mode != MODE_INVALID)
287                 if (chmod(path, mode) < 0)
288                         return -errno;
289
290         if (uid != UID_INVALID || gid != GID_INVALID)
291                 if (chown(path, uid, gid) < 0)
292                         return -errno;
293
294         return 0;
295 }
296
297 int fchmod_umask(int fd, mode_t m) {
298         mode_t u;
299         int r;
300
301         u = umask(0777);
302         r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
303         umask(u);
304
305         return r;
306 }
307
308 int fd_warn_permissions(const char *path, int fd) {
309         struct stat st;
310
311         if (fstat(fd, &st) < 0)
312                 return -errno;
313
314         if (st.st_mode & 0111)
315                 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
316
317         if (st.st_mode & 0002)
318                 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
319
320         if (getpid_cached() == 1 && (st.st_mode & 0044) != 0044)
321                 log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
322
323         return 0;
324 }
325
326 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
327         _cleanup_close_ int fd;
328         int r;
329
330         assert(path);
331
332         if (parents)
333                 mkdir_parents(path, 0755);
334
335         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
336                   IN_SET(mode, 0, MODE_INVALID) ? 0644 : mode);
337         if (fd < 0)
338                 return -errno;
339
340         if (mode != MODE_INVALID) {
341                 r = fchmod(fd, mode);
342                 if (r < 0)
343                         return -errno;
344         }
345
346         if (uid != UID_INVALID || gid != GID_INVALID) {
347                 r = fchown(fd, uid, gid);
348                 if (r < 0)
349                         return -errno;
350         }
351
352         if (stamp != USEC_INFINITY) {
353                 struct timespec ts[2];
354
355                 timespec_store(&ts[0], stamp);
356                 ts[1] = ts[0];
357                 r = futimens(fd, ts);
358         } else
359                 r = futimens(fd, NULL);
360         if (r < 0)
361                 return -errno;
362
363         return 0;
364 }
365
366 int touch(const char *path) {
367         return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
368 }
369
370 #if 0 /// UNNEEDED by elogind
371 int symlink_idempotent(const char *from, const char *to) {
372         int r;
373
374         assert(from);
375         assert(to);
376
377         if (symlink(from, to) < 0) {
378                 _cleanup_free_ char *p = NULL;
379
380                 if (errno != EEXIST)
381                         return -errno;
382
383                 r = readlink_malloc(to, &p);
384                 if (r == -EINVAL) /* Not a symlink? In that case return the original error we encountered: -EEXIST */
385                         return -EEXIST;
386                 if (r < 0) /* Any other error? In that case propagate it as is */
387                         return r;
388
389                 if (!streq(p, from)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */
390                         return -EEXIST;
391         }
392
393         return 0;
394 }
395
396 int symlink_atomic(const char *from, const char *to) {
397         _cleanup_free_ char *t = NULL;
398         int r;
399
400         assert(from);
401         assert(to);
402
403         r = tempfn_random(to, NULL, &t);
404         if (r < 0)
405                 return r;
406
407         if (symlink(from, t) < 0)
408                 return -errno;
409
410         if (rename(t, to) < 0) {
411                 unlink_noerrno(t);
412                 return -errno;
413         }
414
415         return 0;
416 }
417
418 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
419         _cleanup_free_ char *t = NULL;
420         int r;
421
422         assert(path);
423
424         r = tempfn_random(path, NULL, &t);
425         if (r < 0)
426                 return r;
427
428         if (mknod(t, mode, dev) < 0)
429                 return -errno;
430
431         if (rename(t, path) < 0) {
432                 unlink_noerrno(t);
433                 return -errno;
434         }
435
436         return 0;
437 }
438
439 int mkfifo_atomic(const char *path, mode_t mode) {
440         _cleanup_free_ char *t = NULL;
441         int r;
442
443         assert(path);
444
445         r = tempfn_random(path, NULL, &t);
446         if (r < 0)
447                 return r;
448
449         if (mkfifo(t, mode) < 0)
450                 return -errno;
451
452         if (rename(t, path) < 0) {
453                 unlink_noerrno(t);
454                 return -errno;
455         }
456
457         return 0;
458 }
459 #endif // 0
460
461 int get_files_in_directory(const char *path, char ***list) {
462         _cleanup_closedir_ DIR *d = NULL;
463         struct dirent *de;
464         size_t bufsize = 0, n = 0;
465         _cleanup_strv_free_ char **l = NULL;
466
467         assert(path);
468
469         /* Returns all files in a directory in *list, and the number
470          * of files as return value. If list is NULL returns only the
471          * number. */
472
473         d = opendir(path);
474         if (!d)
475                 return -errno;
476
477         FOREACH_DIRENT_ALL(de, d, return -errno) {
478                 dirent_ensure_type(d, de);
479
480                 if (!dirent_is_file(de))
481                         continue;
482
483                 if (list) {
484                         /* one extra slot is needed for the terminating NULL */
485                         if (!GREEDY_REALLOC(l, bufsize, n + 2))
486                                 return -ENOMEM;
487
488                         l[n] = strdup(de->d_name);
489                         if (!l[n])
490                                 return -ENOMEM;
491
492                         l[++n] = NULL;
493                 } else
494                         n++;
495         }
496
497         if (list) {
498                 *list = l;
499                 l = NULL; /* avoid freeing */
500         }
501
502         return n;
503 }
504
505 static int getenv_tmp_dir(const char **ret_path) {
506         const char *n;
507         int r, ret = 0;
508
509         assert(ret_path);
510
511         /* We use the same order of environment variables python uses in tempfile.gettempdir():
512          * https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */
513         FOREACH_STRING(n, "TMPDIR", "TEMP", "TMP") {
514                 const char *e;
515
516                 e = secure_getenv(n);
517                 if (!e)
518                         continue;
519                 if (!path_is_absolute(e)) {
520                         r = -ENOTDIR;
521                         goto next;
522                 }
523                 if (!path_is_safe(e)) {
524                         r = -EPERM;
525                         goto next;
526                 }
527
528                 r = is_dir(e, true);
529                 if (r < 0)
530                         goto next;
531                 if (r == 0) {
532                         r = -ENOTDIR;
533                         goto next;
534                 }
535
536                 *ret_path = e;
537                 return 1;
538
539         next:
540                 /* Remember first error, to make this more debuggable */
541                 if (ret >= 0)
542                         ret = r;
543         }
544
545         if (ret < 0)
546                 return ret;
547
548         *ret_path = NULL;
549         return ret;
550 }
551
552 static int tmp_dir_internal(const char *def, const char **ret) {
553         const char *e;
554         int r, k;
555
556         assert(def);
557         assert(ret);
558
559         r = getenv_tmp_dir(&e);
560         if (r > 0) {
561                 *ret = e;
562                 return 0;
563         }
564
565         k = is_dir(def, true);
566         if (k == 0)
567                 k = -ENOTDIR;
568         if (k < 0)
569                 return r < 0 ? r : k;
570
571         *ret = def;
572         return 0;
573 }
574
575 #if 0 /// UNNEEDED by elogind
576 int var_tmp_dir(const char **ret) {
577
578         /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus
579          * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is
580          * returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR,
581          * making it a variable that overrides all temporary file storage locations. */
582
583         return tmp_dir_internal("/var/tmp", ret);
584 }
585 #endif // 0
586
587 int tmp_dir(const char **ret) {
588
589         /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually
590          * backed by an in-memory file system: /tmp. */
591
592         return tmp_dir_internal("/tmp", ret);
593 }
594
595 #if 0 /// UNNEEDED by elogind
596 int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
597         char path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
598         int r;
599
600         /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
601         xsprintf(path, "/proc/self/fd/%i", what);
602
603         r = inotify_add_watch(fd, path, mask);
604         if (r < 0)
605                 return -errno;
606
607         return r;
608 }
609 #endif // 0
610
611 int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
612         _cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
613         _cleanup_close_ int fd = -1;
614         unsigned max_follow = 32; /* how many symlinks to follow before giving up and returning ELOOP */
615         bool exists = true;
616         char *todo;
617         int r;
618
619         assert(path);
620
621         /* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following
622          * symlinks relative to a root directory, instead of the root of the host.
623          *
624          * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
625          * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
626          * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
627          * prefixed accordingly.
628          *
629          * Algorithmically this operates on two path buffers: "done" are the components of the path we already
630          * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
631          * process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
632          * each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
633          * slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
634          * at a minimum.
635          *
636          * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
637          * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
638          * function what to do when encountering a symlink with an absolute path as directory: prefix it by the
639          * specified path.
640          *
641          * Note: there's also chase_symlinks_prefix() (see below), which as first step prefixes the passed path by the
642          * passed root. */
643
644         if (original_root) {
645                 r = path_make_absolute_cwd(original_root, &root);
646                 if (r < 0)
647                         return r;
648
649                 if (flags & CHASE_PREFIX_ROOT)
650                         path = prefix_roota(root, path);
651         }
652
653         r = path_make_absolute_cwd(path, &buffer);
654         if (r < 0)
655                 return r;
656
657         fd = open("/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
658         if (fd < 0)
659                 return -errno;
660
661         todo = buffer;
662         for (;;) {
663                 _cleanup_free_ char *first = NULL;
664                 _cleanup_close_ int child = -1;
665                 struct stat st;
666                 size_t n, m;
667
668                 /* Determine length of first component in the path */
669                 n = strspn(todo, "/");                  /* The slashes */
670                 m = n + strcspn(todo + n, "/");         /* The entire length of the component */
671
672                 /* Extract the first component. */
673                 first = strndup(todo, m);
674                 if (!first)
675                         return -ENOMEM;
676
677                 todo += m;
678
679                 /* Just a single slash? Then we reached the end. */
680                 if (isempty(first) || path_equal(first, "/"))
681                         break;
682
683                 /* Just a dot? Then let's eat this up. */
684                 if (path_equal(first, "/."))
685                         continue;
686
687                 /* Two dots? Then chop off the last bit of what we already found out. */
688                 if (path_equal(first, "/..")) {
689                         _cleanup_free_ char *parent = NULL;
690                         int fd_parent = -1;
691
692                         /* If we already are at the top, then going up will not change anything. This is in-line with
693                          * how the kernel handles this. */
694                         if (isempty(done) || path_equal(done, "/"))
695                                 continue;
696
697                         parent = dirname_malloc(done);
698                         if (!parent)
699                                 return -ENOMEM;
700
701                         /* Don't allow this to leave the root dir.  */
702                         if (root &&
703                             path_startswith(done, root) &&
704                             !path_startswith(parent, root))
705                                 continue;
706
707                         free_and_replace(done, parent);
708
709                         fd_parent = openat(fd, "..", O_CLOEXEC|O_NOFOLLOW|O_PATH);
710                         if (fd_parent < 0)
711                                 return -errno;
712
713                         safe_close(fd);
714                         fd = fd_parent;
715
716                         continue;
717                 }
718
719                 /* Otherwise let's see what this is. */
720                 child = openat(fd, first + n, O_CLOEXEC|O_NOFOLLOW|O_PATH);
721                 if (child < 0) {
722
723                         if (errno == ENOENT &&
724                             (flags & CHASE_NONEXISTENT) &&
725                             (isempty(todo) || path_is_safe(todo))) {
726
727                                 /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
728                                  * what we got so far. But don't allow this if the remaining path contains "../ or "./"
729                                  * or something else weird. */
730
731                                 if (!strextend(&done, first, todo, NULL))
732                                         return -ENOMEM;
733
734                                 exists = false;
735                                 break;
736                         }
737
738                         return -errno;
739                 }
740
741                 if (fstat(child, &st) < 0)
742                         return -errno;
743                 if ((flags & CHASE_NO_AUTOFS) &&
744                     fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
745                         return -EREMOTE;
746
747                 if (S_ISLNK(st.st_mode)) {
748                         char *joined;
749
750                         _cleanup_free_ char *destination = NULL;
751
752                         /* This is a symlink, in this case read the destination. But let's make sure we don't follow
753                          * symlinks without bounds. */
754                         if (--max_follow <= 0)
755                                 return -ELOOP;
756
757                         r = readlinkat_malloc(fd, first + n, &destination);
758                         if (r < 0)
759                                 return r;
760                         if (isempty(destination))
761                                 return -EINVAL;
762
763                         if (path_is_absolute(destination)) {
764
765                                 /* An absolute destination. Start the loop from the beginning, but use the root
766                                  * directory as base. */
767
768                                 safe_close(fd);
769                                 fd = open(root ?: "/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
770                                 if (fd < 0)
771                                         return -errno;
772
773                                 free(done);
774
775                                 /* Note that we do not revalidate the root, we take it as is. */
776                                 if (isempty(root))
777                                         done = NULL;
778                                 else {
779                                         done = strdup(root);
780                                         if (!done)
781                                                 return -ENOMEM;
782                                 }
783
784                         }
785
786                         /* Prefix what's left to do with what we just read, and start the loop again,
787                          * but remain in the current directory. */
788
789                         joined = strjoin("/", destination, todo);
790                         if (!joined)
791                                 return -ENOMEM;
792
793                         free(buffer);
794                         todo = buffer = joined;
795
796                         continue;
797                 }
798
799                 /* If this is not a symlink, then let's just add the name we read to what we already verified. */
800                 if (!done) {
801                         done = first;
802                         first = NULL;
803                 } else {
804                         if (!strextend(&done, first, NULL))
805                                 return -ENOMEM;
806                 }
807
808                 /* And iterate again, but go one directory further down. */
809                 safe_close(fd);
810                 fd = child;
811                 child = -1;
812         }
813
814         if (!done) {
815                 /* Special case, turn the empty string into "/", to indicate the root directory. */
816                 done = strdup("/");
817                 if (!done)
818                         return -ENOMEM;
819         }
820
821         if (ret) {
822                 *ret = done;
823                 done = NULL;
824         }
825
826         return exists;
827 }