Skip to content

Commit d3f5c62

Browse files
author
Wayne Davison
committed
Avoid directory permission issues with --fake-super.
Fixes bug 7070.
1 parent 8b6ebde commit d3f5c62

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

generator.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,8 +1285,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
12851285
fnamecmp = fname;
12861286

12871287
if (is_dir) {
1288+
mode_t added_perms;
12881289
if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
12891290
goto cleanup;
1291+
if (am_root < 0) {
1292+
/* For --fake-super, the dir must be useable by the copying
1293+
* user, just like it would be for root. */
1294+
added_perms = S_IRUSR|S_IWUSR|S_IXUSR;
1295+
} else
1296+
added_perms = 0;
12901297
if (is_dir < 0) {
12911298
/* In inc_recurse mode we want to make sure any missing
12921299
* directories get created while we're still processing
@@ -1297,7 +1304,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
12971304
&& (S_ISDIR(sx.st.st_mode)
12981305
|| delete_item(fname, sx.st.st_mode, del_opts | DEL_FOR_DIR) != 0))
12991306
goto cleanup; /* Any errors get reported later. */
1300-
if (do_mkdir(fname, file->mode & 0700) == 0)
1307+
if (do_mkdir(fname, (file->mode|added_perms) & 0700) == 0)
13011308
file->flags |= FLAG_DIR_CREATED;
13021309
goto cleanup;
13031310
}
@@ -1340,10 +1347,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
13401347
itemize(fnamecmp, file, ndx, statret, &sx,
13411348
statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL);
13421349
}
1343-
if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) {
1350+
if (real_ret != 0 && do_mkdir(fname,file->mode|added_perms) < 0 && errno != EEXIST) {
13441351
if (!relative_paths || errno != ENOENT
13451352
|| make_path(fname, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0
1346-
|| (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) {
1353+
|| (do_mkdir(fname, file->mode|added_perms) < 0 && errno != EEXIST)) {
13471354
rsyserr(FERROR_XFER, errno,
13481355
"recv_generator: mkdir %s failed",
13491356
full_fname(fname));

receiver.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
extern int dry_run;
2626
extern int do_xfers;
27+
extern int am_root;
2728
extern int am_server;
2829
extern int inc_recurse;
2930
extern int log_before_transfer;
@@ -173,15 +174,25 @@ int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique)
173174
int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file)
174175
{
175176
int fd;
177+
mode_t added_perms;
176178

177179
if (!get_tmpname(fnametmp, fname, False))
178180
return -1;
179181

182+
if (am_root < 0) {
183+
/* For --fake-super, the file must be useable by the copying
184+
* user, just like it would be for root. */
185+
added_perms = S_IRUSR|S_IWUSR;
186+
} else {
187+
/* For a normal copy, we need to be able to tweak things like xattrs. */
188+
added_perms = S_IWUSR;
189+
}
190+
180191
/* We initially set the perms without the setuid/setgid bits or group
181192
* access to ensure that there is no race condition. They will be
182193
* correctly updated after the right owner and group info is set.
183194
* (Thanks to [email protected] for pointing this out.) */
184-
fd = do_mkstemp(fnametmp, (file->mode & INITACCESSPERMS) | S_IWUSR);
195+
fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS);
185196

186197
#if 0
187198
/* 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)
191202
&& make_path(fnametmp, MKP_SKIP_SLASH | MKP_DROP_NAME) == 0) {
192203
/* Get back to name with XXXXXX in it. */
193204
get_tmpname(fnametmp, fname, False);
194-
fd = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
205+
fd = do_mkstemp(fnametmp, (file->mode|added_perms) & INITACCESSPERMS);
195206
}
196207
#endif
197208

testsuite/xattrs.test

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ makepath "$chkdir/foo"
4848
echo wow >"$chkdir/file1"
4949
cp_touch "$fromdir/foo/file3" "$chkdir/foo"
5050

51-
files='foo file0 file1 file2 foo/file3 file4 foo/bar/file5'
51+
files='foo file0 file1 file2 foo/file3 file4 foo/bar foo/bar/file5'
52+
uid_gid=`"$TOOLDIR/tls" "$fromdir/foo" | sed 's/^.* \([0-9][0-9]*\)\.\([0-9][0-9]*\) .*/\1:\2/'`
5253

5354
cd "$fromdir"
5455

@@ -106,12 +107,35 @@ checkit "$RSYNC -aiX --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir"
106107
cd "$todir"
107108
xls $files | diff $diffopt "$scratchdir/xattrs.txt" -
108109

109-
sed -n -e '/\.\/file1$/d' -e '/^[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *1 /p' "$scratchdir/ls-to" >"$scratchdir/ls-diff"
110+
sed -n -e '/^[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *1 /p' "$scratchdir/ls-to" >"$scratchdir/ls-diff-all"
111+
fgrep -v './file1' "$scratchdir/ls-diff-all" >"$scratchdir/ls-diff" || :
110112
if [ -s "$scratchdir/ls-diff" ]; then
111113
echo "Missing hard links on:"
112114
cat "$scratchdir/ls-diff"
113115
exit 1
114116
fi
117+
if [ ! -s "$scratchdir/ls-diff-all" ]; then
118+
echo "Too many hard links on file1!"
119+
exit 1
120+
fi
121+
122+
cd "$chkdir"
123+
chmod go-rwx . $files
124+
125+
xset user.nice 'this is nice, but different' file1
126+
xset user.rsync.%stat "100000 0,0 $uid_gid" $files
127+
xset user.rsync.%stat "40000 0,0 $uid_gid" foo foo/bar
128+
129+
xls $files >"$scratchdir/xattrs.txt"
130+
131+
cd "$fromdir"
132+
rm -rf "$todir"
133+
134+
# When run by a non-root tester, this checks if no-user-perm files/dirs can be copied.
135+
checkit "$RSYNC -aiX --fake-super --chmod=a= . ../to" "$chkdir" "$todir" # 2>"$scratchdir/errors.txt"
136+
137+
cd "$todir"
138+
xls $files | diff $diffopt "$scratchdir/xattrs.txt" -
115139

116140
cd "$fromdir"
117141
rm -rf "$todir" "$chkdir"

0 commit comments

Comments
 (0)