I noticed that rsync sometimes miscalculates the permissions of the
top-level destination directory when --perms is off.  For example, run
these commands in an area free of default ACLs:

umask 0000
mkdir -p src/foo
chmod 700 src src/foo
rsync -r src/ dest/
find . -ls

763054    0 drwx------   4 matt     matt           96 Feb 16 17:57 .
763158    0 drwx------   3 matt     matt           72 Feb 16 17:57 ./src
1424849    0 drwx------   2 matt     matt           48 Feb 16 17:57 ./src/foo
1075094    0 drwxrwxrwx   3 matt     matt           72 Feb 16 17:57 ./dest
1511362    0 drwx------   2 matt     matt           48 Feb 16 17:57 ./dest/foo

Notice that the permissions of dest/foo were correctly restricted by
the 700 permissions of src/foo, but the permissions of dest were not
restricted by the permissions of src.

The trouble is that the generator creates the top-level destination
directory in get_local_name with default permissions and then treats
it as already existing, so it doesn't change the permissions.  The
generator then checks new_root_dir and begins pretending the directory
doesn't exist so that it can itemize the creation correctly.  Moving
the pretending above the permission calculation (as in the attached
patch) seems to fix the problem.

Matt
### Eclipse Workspace Patch 1.0
#P rsync
Index: generator.c
===================================================================
RCS file: /cvsroot/rsync/generator.c,v
retrieving revision 1.330
diff -u -r1.330 generator.c
--- generator.c	16 Feb 2007 02:35:31 -0000	1.330
+++ generator.c	16 Feb 2007 23:03:02 -0000
@@ -1143,6 +1143,12 @@
 		return;
 	}
 
+	if (S_ISDIR(file->mode) && new_root_dir) {
+		if (*fname == '.' && fname[1] == '\0')
+			statret = -1;
+		new_root_dir = 0;
+	}
+
 	/* If we're not preserving permissions, change the file-list's
 	 * mode based on the local permissions and some heuristics. */
 	if (!preserve_perms) {
@@ -1168,11 +1174,6 @@
 		}
 		real_ret = statret;
 		real_st = st;
-		if (new_root_dir) {
-			if (*fname == '.' && fname[1] == '\0')
-				statret = -1;
-			new_root_dir = 0;
-		}
 		if (statret != 0 && basis_dir[0] != NULL) {
 			int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &st,
 					      itemizing, code);
-- 
To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html

Reply via email to