/* Then, change the ownership of the whole tree, if necessary. When dynamic users are used we
* drop the suid/sgid bits, since we really don't want SUID/SGID files for dynamic UID/GID
* assignments to exist. */
- r = path_chown_recursive(pp ?: p, uid, gid, context->dynamic_user ? 01777 : 07777);
+ r = path_chown_recursive(pp ?: p, uid, gid, context->dynamic_user ? 01777 : 07777, AT_SYMLINK_FOLLOW);
if (r < 0)
goto fail;
}
const char *path,
uid_t uid,
gid_t gid,
- mode_t mask) {
+ mode_t mask,
+ int flags) {
_cleanup_close_ int fd = -EBADF;
struct stat st;
- fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+ assert((flags & ~AT_SYMLINK_FOLLOW) == 0);
+
+ fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOATIME|(FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? 0 : O_NOFOLLOW));
if (fd < 0)
return -errno;
#include <sys/types.h>
-int path_chown_recursive(const char *path, uid_t uid, gid_t gid, mode_t mask);
+int path_chown_recursive(const char *path, uid_t uid, gid_t gid, mode_t mask, int flags);
int fd_chown_recursive(int fd, uid_t uid, gid_t gid, mode_t mask);
assert_se(st.st_gid == gid);
assert_se(has_xattr(p));
- assert_se(path_chown_recursive(t, 1, 2, 07777) >= 0);
+ assert_se(path_chown_recursive(t, 1, 2, 07777, 0) >= 0);
p = strjoina(t, "/dir");
assert_se(lstat(p, &st) >= 0);