mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-08-04 09:42:21 -04:00
The change a couple days ago to create files initially without group and
other access resulted in group and other access being left off when the '-p' option was not used. This fixes it by reintroducing the ACCESSPERMS mask and setting permissions to (file->mode & ACCESSPERMS) if preserve_perms is off. I decided to change the mask INITPERMMASK to INITACCESSPERMS at the same time. When preserve_perms is off, rsync is restored to the previous behavior of having the permissions of the original file with the umask and setuid/setgid bits shut off. Also, I decided that a check for "(updated && (file->mode & ~ACCESSPERMS))" is no longer needed since as far as I can tell that would have only affected permissions when not running as root and when a chgrp was done to a group the user was not a member of, using system V chgrp semantics. This is no longer allowed.
This commit is contained in:
@@ -412,14 +412,15 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
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 */
|
||||
this out. We also set it initially without group
|
||||
access because of a similar race condition. */
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
|
||||
file->mode & INITPERMMASK);
|
||||
file->mode & INITACCESSPERMS);
|
||||
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT &&
|
||||
create_directory_path(fnametmp) == 0) {
|
||||
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
|
||||
file->mode & INITPERMMASK);
|
||||
file->mode & INITACCESSPERMS);
|
||||
}
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));
|
||||
|
||||
23
rsync.c
23
rsync.c
@@ -200,14 +200,19 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
}
|
||||
|
||||
#ifdef HAVE_CHMOD
|
||||
if (preserve_perms && !S_ISLNK(st->st_mode) &&
|
||||
(st->st_mode != file->mode ||
|
||||
(updated && (file->mode & ~INITPERMMASK)))) {
|
||||
updated = 1;
|
||||
if (do_chmod(fname,file->mode) != 0) {
|
||||
rprintf(FERROR,"failed to set permissions on %s : %s\n",
|
||||
fname,strerror(errno));
|
||||
return 0;
|
||||
if (!S_ISLNK(st->st_mode)) {
|
||||
int file_mode;
|
||||
if (preserve_perms)
|
||||
file_mode = file->mode;
|
||||
else
|
||||
file_mode = file->mode & ACCESSPERMS;
|
||||
if (st->st_mode != file->mode) {
|
||||
updated = 1;
|
||||
if (do_chmod(fname,file_mode) != 0) {
|
||||
rprintf(FERROR,"failed to set permissions on %s : %s\n",
|
||||
fname,strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -260,7 +265,7 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
|
||||
if (errno == EXDEV) {
|
||||
/* rename failed on cross-filesystem link.
|
||||
Copy the file instead. */
|
||||
if (copy_file(fnametmp,fname, file->mode & INITPERMMASK)) {
|
||||
if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) {
|
||||
rprintf(FERROR,"copy %s -> %s : %s\n",
|
||||
fnametmp,fname,strerror(errno));
|
||||
} else {
|
||||
|
||||
5
rsync.h
5
rsync.h
@@ -462,10 +462,13 @@ extern int errno;
|
||||
|
||||
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
|
||||
|
||||
#ifndef ACCESSPERMS
|
||||
#define ACCESSPERMS 0777
|
||||
#endif
|
||||
/* Initial mask on permissions given to temporary files. Mask off setuid
|
||||
bits and group access because of potential race-condition security
|
||||
holes, and mask other access because mode 707 is bizarre */
|
||||
#define INITPERMMASK 0700
|
||||
#define INITACCESSPERMS 0700
|
||||
|
||||
/* handler for null strings in printf format */
|
||||
#define NS(s) ((s)?(s):"<NULL>")
|
||||
|
||||
Reference in New Issue
Block a user