summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2019-03-30 07:28:55 +0000
committerderaadt <deraadt@openbsd.org>2019-03-30 07:28:55 +0000
commitafb54730ad1175de20ce3552ce337317a1619931 (patch)
treef267ae6bd2b0d9d2b53b5037c5012d281b34669f
parentAdd --del as alias for --delete. (diff)
downloadwireguard-openbsd-afb54730ad1175de20ce3552ce337317a1619931.tar.xz
wireguard-openbsd-afb54730ad1175de20ce3552ce337317a1619931.zip
For now perform utimes, chown, chmod in the same order as cp(1), until
we know later how rsync wants to behave and how it interacts with future option development. This sequence is safest, since it drops setugid bits in case of failure to chown.. ok florian
-rw-r--r--usr.bin/rsync/receiver.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/usr.bin/rsync/receiver.c b/usr.bin/rsync/receiver.c
index 873c5d2df69..c6d26cb0917 100644
--- a/usr.bin/rsync/receiver.c
+++ b/usr.bin/rsync/receiver.c
@@ -1,4 +1,4 @@
-/* $Id: receiver.c,v 1.21 2019/03/23 16:04:28 deraadt Exp $ */
+/* $Id: receiver.c,v 1.22 2019/03/30 07:28:55 deraadt Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -47,49 +47,52 @@ rsync_set_metadata(struct sess *sess, int newfile,
{
uid_t uid = (uid_t)-1;
gid_t gid = (gid_t)-1;
+ mode_t mode;
struct timespec ts[2];
+ /* Conditionally adjust file modification time. */
+
+ if (sess->opts->preserve_times) {
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_sec = f->st.mtime;
+ ts[1].tv_nsec = 0;
+ if (futimens(fd, ts) == -1) {
+ ERR(sess, "%s: futimens", path);
+ return 0;
+ }
+ LOG4(sess, "%s: updated date", f->path);
+ }
+
/*
* Conditionally adjust identifiers.
* If we have an EPERM, report it but continue on: this just
* means that we're mapping into an unknown (or disallowed)
* group identifier.
*/
-
if (getuid() == 0 && sess->opts->preserve_uids)
uid = f->st.uid;
if (sess->opts->preserve_gids)
gid = f->st.gid;
+ mode = f->st.mode;
if (uid != (uid_t)-1 || gid != (gid_t)-1) {
if (fchown(fd, uid, gid) == -1) {
if (errno != EPERM) {
ERR(sess, "%s: fchown", path);
return 0;
}
- WARNX(sess, "%s: identity unknown or not available "
- "to user.group: %u.%u", f->path, uid, gid);
+ if (getuid() == 0)
+ WARNX(sess, "%s: identity unknown or not available "
+ "to user.group: %u.%u", f->path, uid, gid);
} else
LOG4(sess, "%s: updated uid and/or gid", f->path);
- }
-
- /* Conditionally adjust file modification time. */
-
- if (sess->opts->preserve_times) {
- ts[0].tv_nsec = UTIME_NOW;
- ts[1].tv_sec = f->st.mtime;
- ts[1].tv_nsec = 0;
- if (futimens(fd, ts) == -1) {
- ERR(sess, "%s: futimens", path);
- return 0;
- }
- LOG4(sess, "%s: updated date", f->path);
+ mode &= ~(S_ISTXT | S_ISUID | S_ISGID);
}
/* Conditionally adjust file permissions. */
if (newfile || sess->opts->preserve_perms) {
- if (fchmod(fd, f->st.mode) == -1) {
+ if (fchmod(fd, mode) == -1) {
ERR(sess, "%s: fchmod", path);
return 0;
}
@@ -105,51 +108,52 @@ rsync_set_metadata_at(struct sess *sess, int newfile, int rootfd,
{
uid_t uid = (uid_t)-1;
gid_t gid = (gid_t)-1;
+ mode_t mode;
struct timespec ts[2];
+ /* Conditionally adjust file modification time. */
+
+ if (sess->opts->preserve_times) {
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_sec = f->st.mtime;
+ ts[1].tv_nsec = 0;
+ if (utimensat(rootfd, path, ts, AT_SYMLINK_NOFOLLOW) == -1) {
+ ERR(sess, "%s: utimensat", path);
+ return 0;
+ }
+ LOG4(sess, "%s: updated date", f->path);
+ }
+
/*
* Conditionally adjust identifiers.
* If we have an EPERM, report it but continue on: this just
* means that we're mapping into an unknown (or disallowed)
* group identifier.
*/
-
if (getuid() == 0 && sess->opts->preserve_uids)
uid = f->st.uid;
if (sess->opts->preserve_gids)
gid = f->st.gid;
+ mode = f->st.mode;
if (uid != (uid_t)-1 || gid != (gid_t)-1) {
- if (fchownat(rootfd, path, uid, gid, AT_SYMLINK_NOFOLLOW) ==
- -1) {
+ if (fchownat(rootfd, path, uid, gid, AT_SYMLINK_NOFOLLOW) == -1) {
if (errno != EPERM) {
ERR(sess, "%s: fchownat", path);
return 0;
}
- WARNX(sess, "%s: identity unknown or not available "
- "to user.group: %u.%u", f->path, uid, gid);
+ if (getuid() == 0)
+ WARNX(sess, "%s: identity unknown or not available "
+ "to user.group: %u.%u", f->path, uid, gid);
} else
LOG4(sess, "%s: updated uid and/or gid", f->path);
- }
-
- /* Conditionally adjust file modification time. */
-
- if (sess->opts->preserve_times) {
- ts[0].tv_nsec = UTIME_NOW;
- ts[1].tv_sec = f->st.mtime;
- ts[1].tv_nsec = 0;
- if (utimensat(rootfd, path, ts, AT_SYMLINK_NOFOLLOW) == -1) {
- ERR(sess, "%s: utimensat", path);
- return 0;
- }
- LOG4(sess, "%s: updated date", f->path);
+ mode &= ~(S_ISTXT | S_ISUID | S_ISGID);
}
/* Conditionally adjust file permissions. */
if (newfile || sess->opts->preserve_perms) {
- if (fchmodat(rootfd, path, f->st.mode, AT_SYMLINK_NOFOLLOW) ==
- -1) {
+ if (fchmodat(rootfd, path, mode, AT_SYMLINK_NOFOLLOW) == -1) {
ERR(sess, "%s: fchmodat", path);
return 0;
}