X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fbasic%2Fcopy.c;h=37212be228de1e2e9c7e0d6bc2abf89091b4e9ca;hp=b0a093f489cd7b40c0b235de78ec68a26be227fa;hb=9b00a533195b7fec54a791ca02090e0799214770;hpb=44e66a80e25b25d596596f97a595221969f533d8 diff --git a/src/basic/copy.c b/src/basic/copy.c index b0a093f48..37212be22 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -178,7 +178,16 @@ int copy_bytes(int fdf, int fdt, uint64_t max_bytes, CopyFlags copy_flags) { } #if 0 /// UNNEEDED by elogind -static int fd_copy_symlink(int df, const char *from, const struct stat *st, int dt, const char *to) { +static int fd_copy_symlink( + int df, + const char *from, + const struct stat *st, + int dt, + const char *to, + uid_t override_uid, + gid_t override_gid, + CopyFlags copy_flags) { + _cleanup_free_ char *target = NULL; int r; @@ -193,13 +202,25 @@ static int fd_copy_symlink(int df, const char *from, const struct stat *st, int if (symlinkat(target, dt, to) < 0) return -errno; - if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0) + if (fchownat(dt, to, + uid_is_valid(override_uid) ? override_uid : st->st_uid, + gid_is_valid(override_gid) ? override_gid : st->st_gid, + AT_SYMLINK_NOFOLLOW) < 0) return -errno; return 0; } -static int fd_copy_regular(int df, const char *from, const struct stat *st, int dt, const char *to, CopyFlags copy_flags) { +static int fd_copy_regular( + int df, + const char *from, + const struct stat *st, + int dt, + const char *to, + uid_t override_uid, + gid_t override_gid, + CopyFlags copy_flags) { + _cleanup_close_ int fdf = -1, fdt = -1; struct timespec ts[2]; int r, q; @@ -222,7 +243,9 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int return r; } - if (fchown(fdt, st->st_uid, st->st_gid) < 0) + if (fchown(fdt, + uid_is_valid(override_uid) ? override_uid : st->st_uid, + gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0) r = -errno; if (fchmod(fdt, st->st_mode & 07777) < 0) @@ -231,7 +254,6 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int ts[0] = st->st_atim; ts[1] = st->st_mtim; (void) futimens(fdt, ts); - (void) copy_xattr(fdf, fdt); q = close(fdt); @@ -245,7 +267,15 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int return r; } -static int fd_copy_fifo(int df, const char *from, const struct stat *st, int dt, const char *to) { +static int fd_copy_fifo( + int df, + const char *from, + const struct stat *st, + int dt, + const char *to, + uid_t override_uid, + gid_t override_gid, + CopyFlags copy_flags) { int r; assert(from); @@ -256,7 +286,10 @@ static int fd_copy_fifo(int df, const char *from, const struct stat *st, int dt, if (r < 0) return -errno; - if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0) + if (fchownat(dt, to, + uid_is_valid(override_uid) ? override_uid : st->st_uid, + gid_is_valid(override_gid) ? override_gid : st->st_gid, + AT_SYMLINK_NOFOLLOW) < 0) r = -errno; if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0) @@ -265,7 +298,15 @@ static int fd_copy_fifo(int df, const char *from, const struct stat *st, int dt, return r; } -static int fd_copy_node(int df, const char *from, const struct stat *st, int dt, const char *to) { +static int fd_copy_node( + int df, + const char *from, + const struct stat *st, + int dt, + const char *to, + uid_t override_uid, + gid_t override_gid, + CopyFlags copy_flags) { int r; assert(from); @@ -276,7 +317,10 @@ static int fd_copy_node(int df, const char *from, const struct stat *st, int dt, if (r < 0) return -errno; - if (fchownat(dt, to, st->st_uid, st->st_gid, AT_SYMLINK_NOFOLLOW) < 0) + if (fchownat(dt, to, + uid_is_valid(override_uid) ? override_uid : st->st_uid, + gid_is_valid(override_gid) ? override_gid : st->st_gid, + AT_SYMLINK_NOFOLLOW) < 0) r = -errno; if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0) @@ -292,6 +336,8 @@ static int fd_copy_directory( int dt, const char *to, dev_t original_device, + uid_t override_uid, + gid_t override_gid, CopyFlags copy_flags) { _cleanup_close_ int fdf = -1, fdt = -1; @@ -345,15 +391,15 @@ static int fd_copy_directory( continue; if (S_ISREG(buf.st_mode)) - q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, copy_flags); + q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags); else if (S_ISDIR(buf.st_mode)) - q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, copy_flags); + q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, override_uid, override_gid, copy_flags); else if (S_ISLNK(buf.st_mode)) - q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name); + q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags); else if (S_ISFIFO(buf.st_mode)) - q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name); + q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags); else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode) || S_ISSOCK(buf.st_mode)) - q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name); + q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags); else q = -EOPNOTSUPP; @@ -370,7 +416,9 @@ static int fd_copy_directory( st->st_mtim }; - if (fchown(fdt, st->st_uid, st->st_gid) < 0) + if (fchown(fdt, + uid_is_valid(override_uid) ? override_uid : st->st_uid, + gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0) r = -errno; if (fchmod(fdt, st->st_mode & 07777) < 0) @@ -383,7 +431,7 @@ static int fd_copy_directory( return r; } -int copy_tree_at(int fdf, const char *from, int fdt, const char *to, CopyFlags copy_flags) { +int copy_tree_at(int fdf, const char *from, int fdt, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags) { struct stat st; assert(from); @@ -393,21 +441,21 @@ int copy_tree_at(int fdf, const char *from, int fdt, const char *to, CopyFlags c return -errno; if (S_ISREG(st.st_mode)) - return fd_copy_regular(fdf, from, &st, fdt, to, copy_flags); + return fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags); else if (S_ISDIR(st.st_mode)) - return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, copy_flags); + return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, override_uid, override_gid, copy_flags); else if (S_ISLNK(st.st_mode)) - return fd_copy_symlink(fdf, from, &st, fdt, to); + return fd_copy_symlink(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags); else if (S_ISFIFO(st.st_mode)) - return fd_copy_fifo(fdf, from, &st, fdt, to); + return fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags); else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode)) - return fd_copy_node(fdf, from, &st, fdt, to); + return fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags); else return -EOPNOTSUPP; } -int copy_tree(const char *from, const char *to, CopyFlags copy_flags) { - return copy_tree_at(AT_FDCWD, from, AT_FDCWD, to, copy_flags); +int copy_tree(const char *from, const char *to, uid_t override_uid, gid_t override_gid, CopyFlags copy_flags) { + return copy_tree_at(AT_FDCWD, from, AT_FDCWD, to, override_uid, override_gid, copy_flags); } int copy_directory_fd(int dirfd, const char *to, CopyFlags copy_flags) { @@ -422,7 +470,7 @@ int copy_directory_fd(int dirfd, const char *to, CopyFlags copy_flags) { if (!S_ISDIR(st.st_mode)) return -ENOTDIR; - return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, copy_flags); + return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, UID_INVALID, GID_INVALID, copy_flags); } int copy_directory(const char *from, const char *to, CopyFlags copy_flags) { @@ -437,7 +485,7 @@ int copy_directory(const char *from, const char *to, CopyFlags copy_flags) { if (!S_ISDIR(st.st_mode)) return -ENOTDIR; - return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, copy_flags); + return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, UID_INVALID, GID_INVALID, copy_flags); } int copy_file_fd(const char *from, int fdt, CopyFlags copy_flags) { @@ -511,7 +559,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned cha } else r = rename_noreplace(AT_FDCWD, t, AT_FDCWD, to); if (r < 0) { - (void) unlink_noerrno(t); + (void) unlink(t); return r; }