diff --git a/rsync.1.md b/rsync.1.md index 2b4b75087..f57fe3306 100644 --- a/rsync.1.md +++ b/rsync.1.md @@ -3016,6 +3016,10 @@ expand it. > --usermap=:nobody --groupmap=*:nobody + An empty **FROM** value matches only sender-side IDs that have no name. It + is not a wildcard for named users or groups; use "`*`" when you want to map + every sender-side name. + When the [`--numeric-ids`](#opt) option is used, the sender does not send any names, so all the IDs are treated as having an empty name. This means that you will need to specify numeric **FROM** values if you want to map these diff --git a/testsuite/ownership-depth_test.py b/testsuite/ownership-depth_test.py index 9a5d5ed80..f4df789af 100644 --- a/testsuite/ownership-depth_test.py +++ b/testsuite/ownership-depth_test.py @@ -11,6 +11,7 @@ # remap only runs as root, so a non-root run exercises the group-only path too. fleet_nonroot = True +import grp import os from rsyncfns import ( @@ -45,6 +46,13 @@ def assert_all(entries, *, gid=None, uid=None, label=''): test_fail(f"{label}: owner of {rel} is {st.st_uid}, expected {uid}") +try: + grp.getgrgid(prim) + prim_has_name = True +except KeyError: + prim_has_name = False + + if is_root: # Root may assign any numeric id (it need not exist); pick targets that # differ from the source's ids so the remap is observable. @@ -55,6 +63,20 @@ def assert_all(entries, *, gid=None, uid=None, label=''): run_rsync('-a', f'--groupmap={prim}:{target_gid}', f'{src}/', f'{TODIR}/') assert_all(entries, gid=target_gid, label='--groupmap (root)') + entries = seed() + run_rsync('-a', f'--groupmap=*:{target_gid}', f'{src}/', f'{TODIR}/') + assert_all(entries, gid=target_gid, label='--groupmap wildcard (root)') + + if prim_has_name: + entries = seed() + run_rsync('-a', f'--groupmap=:{target_gid}', f'{src}/', f'{TODIR}/') + assert_all(entries, gid=prim, label='--groupmap empty named group (root)') + + entries = seed() + run_rsync('-a', '--numeric-ids', f'--groupmap=:{target_gid}', + f'{src}/', f'{TODIR}/') + assert_all(entries, gid=target_gid, label='--groupmap empty nameless group (root)') + entries = seed() run_rsync('-a', f'--chown=:{target_gid}', f'{src}/', f'{TODIR}/') assert_all(entries, gid=target_gid, label='--chown group (root)') @@ -79,6 +101,19 @@ def assert_all(entries, *, gid=None, uid=None, label=''): run_rsync('-a', f'--groupmap={prim}:{sec}', f'{src}/', f'{TODIR}/') assert_all(entries, gid=sec, label='--groupmap') + entries = seed() + run_rsync('-a', f'--groupmap=*:{sec}', f'{src}/', f'{TODIR}/') + assert_all(entries, gid=sec, label='--groupmap wildcard') + + if prim_has_name: + entries = seed() + run_rsync('-a', f'--groupmap=:{sec}', f'{src}/', f'{TODIR}/') + assert_all(entries, gid=prim, label='--groupmap empty named group') + + entries = seed() + run_rsync('-a', '--numeric-ids', f'--groupmap=:{sec}', f'{src}/', f'{TODIR}/') + assert_all(entries, gid=sec, label='--groupmap empty nameless group') + entries = seed() run_rsync('-a', f'--chown=:{sec}', f'{src}/', f'{TODIR}/') assert_all(entries, gid=sec, label='--chown group')