mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-18 11:55:32 -04:00
Avoid directory permission issues with --fake-super.
Fixes bug 7070.
This commit is contained in:
15
generator.c
15
generator.c
@@ -1411,8 +1411,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
fnamecmp = fname;
|
||||
|
||||
if (is_dir) {
|
||||
mode_t added_perms;
|
||||
if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
|
||||
goto cleanup;
|
||||
if (am_root < 0) {
|
||||
/* For --fake-super, the dir must be useable by the copying
|
||||
* user, just like it would be for root. */
|
||||
added_perms = S_IRUSR|S_IWUSR|S_IXUSR;
|
||||
} else
|
||||
added_perms = 0;
|
||||
if (is_dir < 0) {
|
||||
/* In inc_recurse mode we want to make sure any missing
|
||||
* directories get created while we're still processing
|
||||
@@ -1423,7 +1430,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
&& (S_ISDIR(sx.st.st_mode)
|
||||
|| delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0))
|
||||
goto cleanup; /* Any errors get reported later. */
|
||||
if (do_mkdir(fname, file->mode & 0700) == 0)
|
||||
if (do_mkdir(fname, (file->mode|added_perms) & 0700) == 0)
|
||||
file->flags |= FLAG_DIR_CREATED;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1466,10 +1473,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
||||
itemize(fnamecmp, file, ndx, statret, &sx,
|
||||
statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
|
||||
}
|
||||
if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
|
||||
if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) {
|
||||
if (!relative_paths || errno != ENOENT
|
||||
|| create_directory_path(fname) < 0
|
||||
|| (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) {
|
||||
|| create_directory_path(fname) < 0
|
||||
|| (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) {
|
||||
rsyserr(FERROR_XFER, errno,
|
||||
"recv_generator: mkdir %s failed",
|
||||
full_fname(fname));
|
||||
|
||||
15
receiver.c
15
receiver.c
@@ -24,6 +24,7 @@
|
||||
extern int verbose;
|
||||
extern int dry_run;
|
||||
extern int do_xfers;
|
||||
extern int am_root;
|
||||
extern int am_server;
|
||||
extern int do_progress;
|
||||
extern int inc_recurse;
|
||||
@@ -131,15 +132,25 @@ int get_tmpname(char *fnametmp, const char *fname)
|
||||
int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
|
||||
{
|
||||
int fd;
|
||||
mode_t added_perms;
|
||||
|
||||
if (!get_tmpname(fnametmp, fname))
|
||||
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);
|
||||
fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS);
|
||||
|
||||
#if 0
|
||||
/* In most cases parent directories will already exist because their
|
||||
@@ -149,7 +160,7 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
|
||||
&& create_directory_path(fnametmp) == 0) {
|
||||
/* Get back to name with XXXXXX in it. */
|
||||
get_tmpname(fnametmp, fname);
|
||||
fd = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@ makepath "$chkdir/foo"
|
||||
echo wow >"$chkdir/file1"
|
||||
cp_touch "$fromdir/foo/file3" "$chkdir/foo"
|
||||
|
||||
files='foo file0 file1 file2 foo/file3 file4 foo/bar/file5'
|
||||
files='foo file0 file1 file2 foo/file3 file4 foo/bar foo/bar/file5'
|
||||
uid_gid=`"$TOOLDIR/tls" "$fromdir/foo" | sed 's/^.* \([0-9][0-9]*\)\.\([0-9][0-9]*\) .*/\1:\2/'`
|
||||
|
||||
cd "$fromdir"
|
||||
|
||||
@@ -117,6 +118,23 @@ if [ -s "$scratchdir/ls-diff" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$chkdir"
|
||||
chmod go-rwx . $files
|
||||
|
||||
xset user.rsync.%stat "100000 0,0 $uid_gid" $files
|
||||
xset user.rsync.%stat "40000 0,0 $uid_gid" foo foo/bar
|
||||
|
||||
xls $files >"$scratchdir/xattrs.txt"
|
||||
|
||||
cd "$fromdir"
|
||||
rm -rf "$todir"
|
||||
|
||||
# When run by a non-root tester, this checks if no-user-perm files/dirs can be copied.
|
||||
checkit "$RSYNC -aiX --fake-super --chmod=a= . ../to" "$chkdir" "$todir" # 2>"$scratchdir/errors.txt"
|
||||
|
||||
cd "$todir"
|
||||
xls $files | diff $diffopt "$scratchdir/xattrs.txt" -
|
||||
|
||||
cd "$fromdir"
|
||||
rm -rf "$todir" "$chkdir"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user