--ignore-existing protects the live transfer destination, but three
peer-selectable options reach other existing objects inside the
restricted directory: --log-file appends to one, --partial-dir consumes
and then renames or unlinks one, and --delay-updates does the same
through its implicit .~tmp~ directory. Refuse all three under
-no-overwrite.
Refusal rather than confinement, because confining these paths does not
help: keeping the --log-file append inside the tree still appends to an
existing file, and for the partial directories the peer controls both
the directory and the transferred basename, so a collision is always
reachable. A pre-exec emptiness check would be raceable. The cost is
that a push naming --partial-dir on the remote receiver, or using
--delay-updates, is now refused for a -no-overwrite account.
Each regression drives the option through a wrapper WITHOUT
-no-overwrite as well, and requires that to be accepted. Without that
control the tests cannot tell "refused under -no-overwrite" from
"refused always", and would still pass if the options were disabled for
every rrsync deployment -- verified by making the refusal unconditional,
which the controls then catch.
The wrapper is handed a shim rather than RSYNC directly: RSYNC is a
multi-word command whenever the runner forces --protocol=N, and rrsync
execlp()s its RSYNC as a single executable name, so every one of these
tests died before reaching the policy under test. A fleet run caught it
on the protocol columns of three targets.
Backup mode belongs in the same set. Publishing a backup onto a name
that already exists deletes what is there (backup.c make_backup()), and
deleting a file backs it up first (delete.c), so a --delete of an
unrelated file can land on a protected name -- overwriting a file that
--ignore-existing was holding, with rc=0 and no diagnostic. Disable -b
and --backup-dir. --suffix is left enabled: with both of those refused
nothing can turn backups on, so it is inert.
The short option must be disabled before short_no_arg_re is built, since
a stock client sends b inside the remote short-option bundle and the
regex is snapshotted there; the whole -no-overwrite block therefore
moves up beside the other policy gates rather than sitting after the
chdir. Its regression drives the collision through a wrapper without
-no-overwrite, passing --ignore-existing by hand, which both proves the
refusal is conditional and shows the primitive defeating the very
protection -no-overwrite forces.
rrsync.1.md now states what -no-overwrite costs: no explicit
--partial-dir, no --delay-updates, no server-side --log-file, no backups.
(cherry picked from commit c3abc6c095)
- Add link targets for all option choices, not just the first one.
- Tweak cross-link arg format.
- Add more links, including some in the latest NEWS.
- Split out a few numbered lists.
- Convert rrsync to python.
- Enhance security of arg & option checking.
- Reject `-L` (`--copy-links`) by default.
- Add `-munge` and `-no-del` options.
- Tweak the logfile line format.
- Created an rrsync man page.
- Use `configure --with-rrsync` if you want `make install` to install
rrsync and its man page.
- Give lsh more rrsync testing support.