X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/9f5c16e51d274ad9c11b58396c0f9627d95611fb..8686d3abba4c5b4baf443871cd19c673056a3392:/receiver.c diff --git a/receiver.c b/receiver.c index 0bc65177..7641b9b5 100644 --- a/receiver.c +++ b/receiver.c @@ -24,6 +24,7 @@ extern int dry_run; extern int do_xfers; +extern int am_root; extern int am_server; extern int inc_recurse; extern int log_before_transfer; @@ -173,15 +174,25 @@ int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique) int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file) { int fd; + mode_t added_perms; if (!get_tmpname(fnametmp, fname, False)) return -1; + if (am_root < 0) { + /* For --fake-super, the file must be useable by the copying + * user, just like it would be for root. */ + added_perms = S_IRUSR|S_IWUSR; + } else { + /* For a normal copy, we need to be able to tweak things like xattrs. */ + added_perms = S_IWUSR; + } + /* We initially set the perms without the setuid/setgid bits or group * access to ensure that there is no race condition. They will be * correctly updated after the right owner and group info is set. * (Thanks to snabb@epipe.fi for pointing this out.) */ - fd = do_mkstemp(fnametmp, (file->mode & INITACCESSPERMS) | S_IWUSR); + fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS); #if 0 /* In most cases parent directories will already exist because their @@ -191,7 +202,7 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file) && make_path(fnametmp, MKP_SKIP_SLASH | MKP_DROP_NAME) == 0) { /* Get back to name with XXXXXX in it. */ get_tmpname(fnametmp, fname, False); - fd = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); + fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS); } #endif @@ -537,14 +548,16 @@ int recv_files(int f_in, int f_out, char *local_name) rprintf(FINFO, "recv_files(%s)\n", fname); #ifdef SUPPORT_XATTRS - if (iflags & ITEM_REPORT_XATTR && do_xfers) + if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers + && (protocol_version < 31 || !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE))) recv_xattr_request(file, f_in); #endif if (!(iflags & ITEM_TRANSFER)) { maybe_log_item(file, iflags, itemizing, xname); #ifdef SUPPORT_XATTRS - if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers) + if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers + && !BITS_SET(iflags, ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)) set_file_attrs(fname, file, NULL, fname, 0); #endif if (iflags & ITEM_IS_NEW) {