From 7ac2aef2fd35ed0cffe2b558b69643f12662a03e Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Sat, 28 Oct 2006 06:26:40 +0000 Subject: [PATCH] - I decided that we should leave as much of the real mode attached to the real file as we can. - Added the --fake-super option to the rsync.yo manpage. - Added the "fake super" setting to the rsyncd.conf.yo manpage. --- fake-super.diff | 95 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 16 deletions(-) diff --git a/fake-super.diff b/fake-super.diff index faa3ea8..ef69f25 100644 --- a/fake-super.diff +++ b/fake-super.diff @@ -6,27 +6,34 @@ fake super-user mode that stores various file attributes in an extended- attribute value instead of as real file-system attributes. The items affected are: - mode the real mode of a file is always (666 & umask) while - the real mode of a directory is always (777 & umask). + mode the real mode of the file always has the special-permission bits + cleared (u-s,g-s,o-t) and full owner access is always enabled + (u+rw for files and u+rwx for directories). The former makes + the files safe if the user and/or group info was not really + preserved, and the latter ensures that our fake-super process + can always read & write & scan the files and directories. - rdev devices and special files are created as zero-length - normal files. + rdev devices and special files are created as zero-length normal + files (with all the attributes preserved in the xattr-stat). - uid the real owner is always left unchanged. + uid the real owner will be the executor of the receiving rsync. - gid the real group is always left unchanged. - -A daemon can set "fake super = yes" in the rsync.conf file for any module -that you'd like to run without root perms while pretending it has them (the -client cannot affect this). + gid the real group will be the default group of the executor. The --fake-super option only affects the side where the option is used. To affect the remote side of a remote-shell connection, specify an rsync path: rsync -av --rsync-path='rsync --fake-super' /src/ host:/dest/ -For a local copy where you want to affect only one side or the other, -you'll need to turn the copy into a remote copy to localhost. +The --fake-super option affects both sides of a local copy, so if you want +to affect only one side or the other, you'll need to turn the copy into a +remote copy to/from localhost. However, it's always safe to copy from some +non-fake-super files into some fake-super files using a normal local copy +since the non-fake source files will just have their normal attributes. + +A daemon can set "fake super = yes" in the rsync.conf file for any module +that you'd like to be able to preserve all attributes without having it +run as root (the client cannot affect this setting on the daemon). After applying this patch, run these commands for a successful build: @@ -203,7 +210,7 @@ or, if you want ACL support too: rprintf(F," -t, --times preserve times\n"); rprintf(F," -O, --omit-dir-times omit directories when preserving times\n"); rprintf(F," --super receiver attempts super-user activities\n"); -+ rprintf(F," --fake-super fake root by storing/reading ownership/etc in EAs\n"); ++ rprintf(F," --fake-super store/recover privileged attrs using xattrs\n"); rprintf(F," -S, --sparse handle sparse files efficiently\n"); rprintf(F," -n, --dry-run show what would have been transferred\n"); rprintf(F," -W, --whole-file copy files whole (without rsync algorithm)\n"); @@ -290,6 +297,62 @@ or, if you want ACL support too: if (ret < 0) { rsyserr(FERROR, errno, "failed to set permissions on %s", +--- old/rsync.yo ++++ new/rsync.yo +@@ -333,6 +333,7 @@ to the detailed description below for a + -t, --times preserve times + -O, --omit-dir-times omit directories when preserving times + --super receiver attempts super-user activities ++ --fake-super store/recover privileged attrs using xattrs + -S, --sparse handle sparse files efficiently + -n, --dry-run show what would have been transferred + -W, --whole-file copy files whole (without rsync algorithm) +@@ -899,6 +900,31 @@ also for ensuring that you will get erro + being running as the super-user. To turn off super-user activities, the + super-user can use bf(--no-super). + ++dit(bf(--fake-super)) When this option is enabled, privileged attributes ++are stored and recovered via a special extended attribute that is attached ++to each file (as needed). This includes the file's owner and group (if it ++is not the default), the file's device info (device & special files are ++created as empty text files), and any permission bits that we won't allow ++to be set on the real file (e.g. the real file gets u-s,g-s,o-t for safety) ++or that would limit the owner's access (since the real super user can ++always access a file or directory, the files we create can always be ++accessed by the creating user too). ++ ++The bf(--fake-super) option only affects the side where the option is used. ++To affect the remote side of a remote-shell connection, specify an rsync ++path: ++ ++quote(tt( rsync -av --rsync-path="rsync --fake-super" /src/ host:/dest/)) ++ ++The bf(--fake-super) option affects both sides of a em(local) copy, so if ++you want to affect only one side or the other, you'll need to turn the copy ++into a remote copy to/from localhost. However, it's always safe to copy ++from some non-fake-super files into some fake-super files using a normal ++local copy since the non-fake source files will just have their normal ++attributes. ++ ++See also the "fake super" setting in the daemon's rsyncd.conf file. ++ + dit(bf(-S, --sparse)) Try to handle sparse files efficiently so they take + up less space on the destination. Conflicts with bf(--inplace) because it's + not possible to overwrite data in a sparse fashion. +--- old/rsyncd.conf.yo ++++ new/rsyncd.conf.yo +@@ -226,6 +226,11 @@ file transfers to and from that module s + was run as root. This complements the "uid" option. The default is gid -2, + which is normally the group "nobody". + ++dit(bf(fake super)) Setting "fake super = yes" for a module causes the ++daemon side to behave as if the bf(--fake-user) command-line option had ++been specified. This allows the full attributes of a file to be stored ++without having to have the daemon actually running as root. ++ + dit(bf(filter)) The "filter" option allows you to specify a space-separated + list of filter rules that the daemon will not allow to be read or written. + This is only superficially equivalent to the client specifying these --- old/syscall.c +++ new/syscall.c @@ -28,6 +28,7 @@ @@ -457,9 +520,9 @@ or, if you want ACL support too: + else + rdev = 0; + -+ /* Force the real file's mode to our liking. */ -+ mode = (fst.st_mode & ~CHMOD_BITS) -+ | ((S_ISDIR(fst.st_mode) ? 0777 : 0666) & (~orig_umask | S_IRWXU)); ++ /* Dump the special permissions and enable full owner access. */ ++ mode = (fst.st_mode & ~CHMOD_BITS) | (file->mode & ACCESSPERMS) ++ | (S_ISDIR(fst.st_mode) ? 0700 : 0600); + if (fst.st_mode != mode) + do_chmod(fname, mode); + if (!IS_DEVICE(fst.st_mode) && !IS_SPECIAL(fst.st_mode)) -- 2.34.1