X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/667e72a1956cea3c144036432eaa923a5a62bba9..bf9f01689f9cba70ed595ddcfabdf92d4b03cb80:/rsync.c diff --git a/rsync.c b/rsync.c index 00c6beb5..38321459 100644 --- a/rsync.c +++ b/rsync.c @@ -304,13 +304,15 @@ static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, fname,strerror(errno)); return 0; } + } else { + updated = 1; } - updated = 1; } #ifdef HAVE_CHMOD if (preserve_perms && !S_ISLNK(st->st_mode) && - st->st_mode != file->mode) { + (st->st_mode != file->mode || + (updated && (file->mode & ~ACCESSPERMS)))) { updated = 1; if (do_chmod(fname,file->mode) != 0) { rprintf(FERROR,"failed to set permissions on %s : %s\n", @@ -885,10 +887,18 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) continue; } - fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode); + /* we initially set the perms without the + setuid/setgid bits to ensure that there is no race + condition. They are then correctly updated after + the lchown. Thanks to snabb@epipe.fi for pointing + this out */ + fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL, + file->mode & ACCESSPERMS); + if (fd2 == -1 && relative_paths && errno == ENOENT && create_directory_path(fnametmp) == 0) { - fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode); + fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL, + file->mode & ACCESSPERMS); } if (fd2 == -1) { rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));