]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
home: Make sure we resolve /etc/skel symlink
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Sun, 22 Jun 2025 12:17:08 +0000 (14:17 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 25 Jun 2025 17:17:42 +0000 (18:17 +0100)
Otherwise copy_tree_at() will try to copy the symlink which we obviously
don't want.

(cherry picked from commit 1e0e7c7411ecb7dc1c6f4d7d6e6a2aa14f6f2395)
(cherry picked from commit 2a918e2a9741ccd28733e230f6e095cfdb5c6ff2)

src/home/homework.c

index 482db23dbcf56039daf0b47d586f8e68b0d9a24f..6ac9ada8045b851d63b2b7c2089134a5612e82eb 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "blockdev-util.h"
 #include "bus-unit-util.h"
+#include "chase.h"
 #include "chown-recursive.h"
 #include "copy.h"
 #include "env-util.h"
@@ -1063,16 +1064,25 @@ static int home_deactivate(UserRecord *h, bool force) {
 }
 
 static int copy_skel(UserRecord *h, int root_fd, const char *skel) {
+        _cleanup_close_ int skel_fd = -EBADF;
         int r;
 
         assert(h);
         assert(root_fd >= 0);
 
-        r = copy_tree_at(AT_FDCWD, skel, root_fd, ".", h->uid, h->gid, COPY_MERGE|COPY_REPLACE, NULL, NULL);
+        r = chase(skel, /* root= */ NULL, /* flags= */ 0, /* ret_path= */ NULL, &skel_fd);
         if (r == -ENOENT) {
                 log_info("Skeleton directory %s missing, ignoring.", skel);
                 return 0;
         }
+
+        r = copy_tree_at(
+                        skel_fd, /* from= */ NULL,
+                        root_fd, ".",
+                        h->uid, h->gid,
+                        COPY_MERGE|COPY_REPLACE,
+                        /* denylist= */ NULL,
+                        /* subvolumes= */ NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to copy in %s: %m", skel);