The Samba-Bugzilla – Attachment 5950 Details for
Bug 7070
Permission denied message with --fake-super and permissionless directory
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to fix fake-super permissions
0001-fake-super-give-owner-full-permissions-on-created-fi.patch (text/plain), 9.78 KB, created by
Chris Dunlop
on 2010-09-06 23:28:55 UTC
(
hide
)
Description:
Patch to fix fake-super permissions
Filename:
MIME Type:
Creator:
Chris Dunlop
Created:
2010-09-06 23:28:55 UTC
Size:
9.78 KB
patch
obsolete
>From 8d921300191568f32c37697dc19bc398443d876b Mon Sep 17 00:00:00 2001 >From: Chris Dunlop <chris@onthe.net.au> >Date: Tue, 7 Sep 2010 14:10:05 +1000 >Subject: [PATCH] fake-super: give owner full permissions on created files and directories > > >Signed-off-by: Chris Dunlop <chris@onthe.net.au> >--- > generator.c | 27 +++++- > receiver.c | 17 +++- > testsuite/fake-super.test | 222 +++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 262 insertions(+), 4 deletions(-) > create mode 100644 testsuite/fake-super.test > >diff --git a/generator.c b/generator.c >index be36e63..81e2b0b 100644 >--- a/generator.c >+++ b/generator.c >@@ -1094,6 +1094,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, > int is_dir = !S_ISDIR(file->mode) ? 0 > : inc_recurse && ndx != cur_flist->ndx_start - 1 ? -1 > : 1; >+ uint16 initial_mode; > > if (DEBUG_GTE(GENR, 1)) > rprintf(FINFO, "recv_generator(%s,%d)\n", fname, ndx); >@@ -1237,7 +1238,21 @@ 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 (am_root == -1) { >+ /* The rsync manual says of fake-super, "any >+ * permission bits ... that would limit the >+ * owner's access" should be stored in the >+ * xattr rather than on the real file. So we >+ * need to make sure the owner has full >+ * permissions on the created directory. (This >+ * also avoids a permissions error when trying >+ * to read the xattrs on a mode 000 directory >+ * just after we create it.) */ >+ initial_mode = S_IRUSR|S_IWUSR|S_IXUSR; >+ } >+ else >+ initial_mode = file->mode & 0700; >+ if (do_mkdir(fname, initial_mode) == 0) > file->flags |= FLAG_DIR_CREATED; > goto cleanup; > } >@@ -1278,10 +1293,16 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, > itemize(fname, file, ndx, statret, &sx, > statret ? ITEM_LOCAL_CHANGE : 0, 0, NULL); > } >- if (real_ret != 0 && do_mkdir(fname,file->mode) < 0 && errno != EEXIST) { >+ >+ /* see comment above regarding fake-super */ >+ if (am_root == -1) >+ initial_mode = S_IRUSR|S_IWUSR|S_IXUSR; >+ else >+ initial_mode = file->mode; >+ if (real_ret != 0 && do_mkdir(fname,initial_mode) < 0 && errno != EEXIST) { > if (!relative_paths || errno != ENOENT > || make_path(fname, MKP_DROP_NAME | MKP_SKIP_SLASH) < 0 >- || (do_mkdir(fname, file->mode) < 0 && errno != EEXIST)) { >+ || (do_mkdir(fname, initial_mode) < 0 && errno != EEXIST)) { > rsyserr(FERROR_XFER, errno, > "recv_generator: mkdir %s failed", > full_fname(fname)); >diff --git a/receiver.c b/receiver.c >index d5a338c..efd88d8 100644 >--- a/receiver.c >+++ b/receiver.c >@@ -25,6 +25,7 @@ > extern int dry_run; > extern int do_xfers; > extern int am_server; >+extern int am_root; > extern int inc_recurse; > extern int log_before_transfer; > extern int stdout_format_has_i; >@@ -165,6 +166,7 @@ int get_tmpname(char *fnametmp, const char *fname, BOOL make_unique) > int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file) > { > int fd; >+ uint16 initial_mode; > > if (!get_tmpname(fnametmp, fname, False)) > return -1; >@@ -173,7 +175,20 @@ int open_tmpfile(char *fnametmp, const char *fname, struct file_struct *file) > * 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) | S_IWUSR); >+ initial_mode = (file->mode & INITACCESSPERMS) | S_IWUSR; >+ >+ if (am_root == -1) { >+ /* The rsync manual says of fake-super, "any permission bits >+ * ... that would limit the owner's access" should be stored >+ * in the xattr rather than on the real file. So we need to >+ * make sure the owner has read permission on the created files >+ * (write permission was granted above). (This also avoids a >+ * permissions error when trying to read the xattrs on a mode >+ * 000 file just after we create it.) */ >+ initial_mode |= S_IRUSR; >+ } >+ >+ fd = do_mkstemp(fnametmp, initial_mode); > > #if 0 > /* In most cases parent directories will already exist because their >diff --git a/testsuite/fake-super.test b/testsuite/fake-super.test >new file mode 100644 >index 0000000..cffb239 >--- /dev/null >+++ b/testsuite/fake-super.test >@@ -0,0 +1,222 @@ >+#! /bin/sh >+ >+# This program is distributable under the terms of the GNU GPL (see >+# COPYING). >+ >+# Test various aspects of --fake-super >+ >+. "$suitedir/rsync.fns" >+ >+# >+# We want a local rsyncd running as root (so it can read mode 000 >+# files), talking to a non-root "--fake-root" daemon. This is the >+# non-root user we use to run the daemon... >+# >+nonrootuser=nobody >+ >+id $nonrootuser \ >+ || test_skipped "Sorry, can't find '$nonrootuser' as a non-root user on your system" >+ >+# >+# Make sure our rsync supports xattrs >+# >+$RSYNC --version | grep ", xattrs" > /dev/null \ >+ || test_skipped "Rsync needs xattrs for fake-super tests" >+ >+# >+# Build a daemon config file >+# >+local_build_rsyncd_conf() { >+ # Build an appropriate configuration file >+ conf="$scratchdir/test-rsyncd.conf" >+ pidfile="$scratchdir/daemon.pid" >+ logfile="$scratchdir/daemon.log" >+ address=127.0.0.1 >+ port=2612 >+ hostname=`uname -n` >+ >+ cat > "$conf" <<EOF >+pid file = $pidfile >+log file = $logfile >+port = $port >+address = $address >+use chroot = no >+munge symlinks = no >+hosts allow = localhost 127.0.0.0/24 192.168.0.0/16 10.0.0.0/8 $hostname >+log format = %i %h [%a] %m (%u) %l %f%L >+transfer logging = yes >+#max verbosity = 4 >+ >+[test-fake-super] >+ comment = fake-super >+ fake super = yes >+ log file = $logfile >+ log format = %i %h [%a] %m (%u) %l %f%L >+ path = $todir >+ read only = no >+ # incoming chmod u+rw >+EOF >+ >+ # >+ # Ensure our nonrootuser has permissions on these >+ # >+ chmod 644 $conf >+ chown $nonrootuser $scratchdir >+} >+ >+local_start_daemon() { >+ # >+ # Start non-root daemon >+ # >+ if [ ! -f "$conf" ] >+ then >+ test_skipped "Can't start daemon, config missing: $conf" >+ fi >+ >+ su $nonrootuser -c "$RSYNC --config=$conf --daemon" \ >+ || test_skipped "Can't start rsync daemon" >+ >+ daemonpid=`cat $pidfile` >+ if [ x"$daemonpid" = x ] >+ then >+ test_skipped "$pidfile hasn't recorded our rsync daemon pid" >+ fi >+ >+ # Make our daemon go away when we do >+ trap "kill -TERM $daemonpid" EXIT >+} >+ >+# >+# Build a directory structure for testing >+# >+local_create_test_source() { >+ hands_setup >+ >+ # >+ # Our nonrootuser daemon needs to to write here... >+ # >+ chown -R $nonrootuser "$todir" >+ >+ # >+ # Make sure the destination supports xattrs >+ # >+ touch "$todir/test" >+ setfattr -n 'user.rsync.%stat' -v "foo" "$todir/test" \ >+ || test_skipped "Your file system doesn't support xattrs, required for fake-super tests" >+ rm "$todir/test" >+ >+ # >+ # Mode 000 file >+ # >+ ls > "$fromdir/test.txt" >+ chmod 000 "$fromdir/test.txt" >+ cat "$fromdir/test.txt" > /dev/null \ >+ || test_skipped "Can't read 'chmod 000' file (probably need root)" >+ >+ ls > "$fromdir/test2.txt" >+ chmod 000 "$fromdir/test2.txt" >+ chown $nonrootuser "$fromdir/test2.txt" >+ >+ # >+ # Mode 000 nested directories >+ # >+ mkdir "$fromdir/test.dir" >+ ls > "$fromdir/test.dir/test.txt" >+ chmod 000 "$fromdir/test.dir" >+ cat "$fromdir/test.dir/test.txt" > /dev/null \ >+ || test_skipped "Can't read file in 'chmod 000' dir (probably need root)" >+ >+ mkdir "$fromdir/test.dir/level2" >+ ls > "$fromdir/test.dir/level2/test.txt" >+ chmod 000 "$fromdir/test.dir/level2" >+ >+ # >+ # Mode 000 owned by non-root >+ # >+ mkdir "$fromdir/test2.dir" >+ ls > "$fromdir/test2.dir/test.txt" >+ chown $nonrootuser "$fromdir/test2.dir" >+ chown $nonrootuser "$fromdir/test2.dir/test.txt" >+ chmod 000 "$fromdir/test2.dir" >+ chmod 000 "$fromdir/test2.dir/test.txt" >+} >+ >+############################## >+ >+ >+# >+# Create source directory and keep a directory listing for later >+# comparison as we're going to overwrite the source by bringing back the >+# destination >+# >+local_create_test_source >+( cd "$fromdir" && rsync_ls_lR . ) > "$tmpdir/ls-orig" >+ >+# >+# Our fake-root daemon >+# >+local_build_rsyncd_conf >+local_start_daemon >+ >+# >+# Sync to dest... >+# >+$RSYNC -v -a --port $port "$fromdir/" "${address}::test-fake-super" \ >+ || test_fail "Error $? syncing to rsync daemon" >+ >+# >+# The rsync manual says of fake-super, "any permission bits ... that >+# would limit the owner's access" should be stored in the xattr rather >+# than on the real file. >+# >+# We test for that here (knowing that the original file/directory >+# permissions were 000). >+# >+if [ `ls -l "$todir/test.txt" | sed 's/ .*//'` != "-rw-------" ] >+then >+ test_fail "file: insufficient permissions set" >+fi >+if [ `ls -l "$todir/test2.txt" | sed 's/ .*//'` != "-rw-------" ] >+then >+ test_fail "file: insufficient permissions set" >+fi >+ >+if [ `ls -ld "$todir/test.dir" | sed 's/ .*//'` != "drwx------" ] >+then >+ test_fail "directory: insufficient permissions" >+fi >+if [ `ls -ld "$todir/test2.dir" | sed 's/ .*//'` != "drwx------" ] >+then >+ test_fail "directory: insufficient permissions" >+fi >+ >+# >+# Sync back to populated source... >+# >+$RSYNC -va --port $port "${address}::test-fake-super" "$fromdir/" \ >+ || test_fail "Error $? syncing to rsync daemon" >+ >+( cd "$fromdir" && rsync_ls_lR . ) > "$tmpdir/ls-return" >+ >+diff $diffopt "$tmpdir/ls-orig" "$tmpdir/ls-return" \ >+ || test_fail "Returned permissions don't match originals!" >+ >+# >+# Sync back to empty source... >+# >+rm -rf "$fromdir" >+mkdir "$fromdir" >+ >+$RSYNC -va --port $port "${address}::test-fake-super" "$fromdir/" \ >+ || test_fail "Error $? syncing to rsync daemon" >+ >+( cd "$fromdir" && rsync_ls_lR . ) > "$tmpdir/ls-empty-return" >+ >+diff $diffopt "$tmpdir/ls-orig" "$tmpdir/ls-empty-return" \ >+ || test_fail "Returned permissions to empty dir don't match originals!" >+ >+ >+# >+# Success! >+# >+exit 0 >-- >1.6.3.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 7070
:
5226
|
5897
| 5950