On 06/02/18 19:03, Dave Gordon via rsync wrote:
[:snip:]>
> The other part of this problem is that it doesn't at present seem
> possible to satisfy all of three individually reasonable requirements of
> a backup system at the same time:
>
> 1. The backup receiver (daemon) need not run as root.
> 2. The backup daemon should preserve all of the client's metadata.
> 3. The backup daemon should have control over modes, ownership, etc
> of the backup files.
>
> 1 & 2 can be satisfied today with the use of --fake-super, but even
> apart from the issue with 0777 symlinks, the modes of the backup files
> are based on those of the originals .. unless you use chmod.
>
> 1 & 3 can be satisfied together by using --fake-super with --chmod on
> the receiving side or incoming-chmod in the daemon config. But this
> actually loses information as it affects not only the modes of the
> backup files, but also the state saved in user.rsync.%stat.
>
> So my proposal would be for the receiving-side chmod to be applied (in
> fake mode) *after* user.rsync.%stat has been saved, and likewise after
> the conversion of symlinks (et al.) to plain files.
>
> This would allow a daemon configuration containing both fake-super and
> an absolute setting for incoming-chmod to fulfil all three of the above.
>
> The logical flow for a push-to-fake-super-daemon would then be:
> 1. client sends filespecs, applying any local --chmod on the way
> 2. daemon receives filespecs, does *not* tweak_mode at this stage
> 3. ... data transfer as needed ...
> 4. daemon sets backup file attributes
> 4a. in fake mode, daemon saves user.rsync.%stat, then applies
> tweak_mode() to the local file. Daemon modes take precedence
> as expected.
> 4b. in non-fake mode, the daemon just applies the deferred
> tweak_mode(). This may lose information, as at present
> (because that's *also* useful).
>
> The reverse flow (pull-from-fake-super-daemon) is:
> 1. daemon sends filespecs, getting modes from user.rsync.%stat
> (daemon would apply outgoing-chmod here, but I don't think it
> would be set in this configuration).
> 2. client receives filespecs, does *not* tweak_mode at this stage
> 3. ... date transfer as needed ...
> 4. client sets local file attributes
> 4b. (non-fake-mode) client applies any local --chmod
>
> Any client-local --chmod is applied later in this flow than at present,
> but that should make no difference. Note that the client didn't need to
> know (and shouldn't be able to tell?) whether the daemon was super or
> just faking it :)
>
> .Dave.
One more point for consideration: at present the set_stat_xattr()
creates the user.rsync.%stat xattr iff it would contain information
different from the state of the actual file. Thus, it's always created
for symlinks, devices, etc because they're stored as plain files; but
for plain files and directories, the xattr is created only if there's
some way in which the logical and actual objects differ (uid, gid,
permissions).
Presumably this is for reasons of economy, but it seems a little odd;
and there are (perhaps contrived) scenarios where this might lead to
confusion, information loss, and/or security breaches. For example:
Client A is backed up onto a non-root fake-super server B, which stores
all backups under its own uid/gid but leaves permissions unchanged. Then
every backup file will be tagged with a user.rsync.%stat xattr, *except*
for those owned by a user on A whose numerical uid/gid happen to match
those of the backup daemon on B. If the backups are now copied by an
administrator to server C, where the uid/gid of the backup daemon are
different from those on B, naturally the admin will adjust ownership
accordingly (c.f. rsync copy-ownership-by-username). Finally, if client
A is restored from the backups on C rather than B, one specific user's
files will be recreated with the wrong uid. This would be quite
baffling, especially as the local administrator on A might not know
anything about what the (remote) administrator of servers B & C has been
doing!
To avoid this and similar inconsistencies, I would like to completely
decouple the representation of the logical uid/gid/mode of the stored
object from the real uid/gid/mode of the filesystem object representing
it. This would simply mean removing the tests in set_stat_xattr() so
that the xattr is *always* created for every object stored in fake-super
mode. Since the purpose of fake-super mode is to preserve origin
filesystem metadata unchanged whether or not the target filesystem can
represent it, it seems odd to have the extra code that creates this
corner case. Without it, the code would be both simpler and easier to
explain :)
.Dave.