summaryrefslogtreecommitdiff
path: root/rsync.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2011-02-22 09:31:54 -0800
committerWayne Davison <wayned@samba.org>2011-02-22 10:27:35 -0800
commiteee2c77a93d466c11b6162054987114b9a342d8c (patch)
treec20655e7bd35192a31701c9ae77ee893725d1864 /rsync.c
parent7766e673215542dadc066193a5a166274d00e9ab (diff)
downloadrsync-eee2c77a93d466c11b6162054987114b9a342d8c.tar.gz
Some uid/gid fixes for (id_t)-1 and other large ID values.
The code now avoids any special internal meaning for uid/gid -1, which allows it to be mapped to a better value (use 4294967295 instead of -1 as the ID to map). Replaced atol() with something than can return a value > 0x7FFFFFFF and that will error-out if the value overflows. If chown() is called with a uid or gid of -1, complain that the ID is not settable and signal a transfer error. Fixes bug 6936.
Diffstat (limited to 'rsync.c')
-rw-r--r--rsync.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/rsync.c b/rsync.c
index 24b9c752..c42d5535 100644
--- a/rsync.c
+++ b/rsync.c
@@ -527,9 +527,9 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
}
}
if (am_root >= 0) {
- if (do_lchown(fname,
- change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid,
- change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid) != 0) {
+ uid_t uid = change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid;
+ gid_t gid = change_gid ? (gid_t)F_GROUP(file) : sxp->st.st_gid;
+ if (do_lchown(fname, uid, gid) != 0) {
/* We shouldn't have attempted to change uid
* or gid unless have the privilege. */
rsyserr(FERROR_XFER, errno, "%s %s failed",
@@ -537,6 +537,10 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
full_fname(fname));
goto cleanup;
}
+ if (uid == (uid_t)-1 && sxp->st.st_uid != (uid_t)-1)
+ rprintf(FERROR_XFER, "uid 4294967295 (-1) is impossible to set on %s\n", full_fname(fname));
+ if (gid == (gid_t)-1 && sxp->st.st_gid != (gid_t)-1)
+ rprintf(FERROR_XFER, "gid 4294967295 (-1) is impossible to set on %s\n", full_fname(fname));
/* A lchown had been done, so we need to re-stat if
* the destination had the setuid or setgid bits set
* (due to the side effect of the chown call). */