feat(identity): implement --copy-as USER[:GROUP] safe subset (P7 Wave E)
Force the receiver to apply the requested owner/group to every written entry through the confined fd-relative identity path instead of switching the process credentials (unsafe for the multithreaded receiver). An unprivileged receiver refuses the transfer up front in server_module_gate, before STATUS_OK, so no data is written with the wrong ownership. - new Config fields copy_as_set/copy_as_uid/copy_as_gid + defaults - identity_parse_copy_as (name/@N/* resolution, primary-gid default, gid==uid fallback for numeric ids with no passwd entry); implies -M - identity snapshot + highest-priority forcing in identity_resolve_targets - identity_copy_as_refused() helper - trailing config-frame block (presence int + two int32 ids, >=0 checked) - PROTOCOL_VERSION 2.17.0 -> 2.18.0; version-sensitive tests updated - unit tests for parse + wire round-trip/negative-id rejection - integration TestCopyAs: unprivileged refusal + root chown assertion - RSYNC_COMPAT.md --copy-as row updated (safe subset + divergence); README protocol version refreshed
This commit is contained in:
@@ -94,14 +94,14 @@ def _seed_protocol_source(source):
|
||||
class TestProtocol:
|
||||
@pytest.mark.ci
|
||||
def test_protocol_current_version_accepted(self, shared_server):
|
||||
"""--protocol=2.17.0 (the current PROTOCOL_VERSION) is accepted and the
|
||||
"""--protocol=2.18.0 (the current PROTOCOL_VERSION) is accepted and the
|
||||
transfer completes normally."""
|
||||
source = os.path.join(TEST_DATA_DIR, "proto_ok_src")
|
||||
dest = os.path.join(TEST_DATA_DIR, "proto_ok_dst")
|
||||
shutil.rmtree(dest, ignore_errors=True)
|
||||
os.makedirs(dest)
|
||||
_seed_protocol_source(source)
|
||||
result, _ = run_client(source, dest, flags=["--protocol=2.17.0"],
|
||||
result, _ = run_client(source, dest, flags=["--protocol=2.18.0"],
|
||||
port=shared_server.port)
|
||||
assert result.returncode == 0, \
|
||||
f"--protocol current run failed: {(result.stderr or result.stdout)[:400]}"
|
||||
@@ -118,7 +118,7 @@ class TestProtocol:
|
||||
shutil.rmtree(dest, ignore_errors=True)
|
||||
os.makedirs(dest)
|
||||
_seed_protocol_source(source)
|
||||
for bad in ("2.15.0", "2.16.0", "216", "31"):
|
||||
for bad in ("2.15.0", "2.16.0", "2.17.0", "216", "31"):
|
||||
result, _ = run_client(source, dest, flags=[f"--protocol={bad}"],
|
||||
port=shared_server.port)
|
||||
assert result.returncode != 0, f"--protocol={bad} should be rejected"
|
||||
|
||||
Reference in New Issue
Block a user