Skip to content

feat(daemon,transfer): consume fake super = yes module directive (#1904)#3559

Merged
oferchen merged 1 commit into
masterfrom
feature/issue-1904-fake-super-module-wireup
May 2, 2026
Merged

feat(daemon,transfer): consume fake super = yes module directive (#1904)#3559
oferchen merged 1 commit into
masterfrom
feature/issue-1904-fake-super-module-wireup

Conversation

@oferchen
Copy link
Copy Markdown
Owner

@oferchen oferchen commented May 2, 2026

Summary

  • Threads the daemon module directive fake super = yes from ModuleConfig.fake_super through ServerConfig.fake_super and into MetadataOptions.fake_super, so daemon-side receivers honour the directive end-to-end.
  • Previously, fake super = yes was parsed but never consumed: receivers issued real chown() calls regardless of the directive, which silently dropped ownership for non-root daemons and contradicted upstream's clientserver.c:1106-1107 semantics.
  • Adds an end-to-end daemon push test that pushes with -og to a module configured with fake super = yes and asserts the destination carries the user.rsync.%stat xattr.

Wire-up path

ModuleConfig.fake_super (already parsed)
  -> ServerConfig.fake_super              [transfer/config]
    -> MetadataOptions.fake_super         [transfer/receiver/transfer.rs]
      -> apply_ownership_via_fake_super   [metadata/apply/ownership.rs] (already in place)
        -> store user.rsync.%stat xattr   [metadata/fake_super.rs] (already in place)

Files changed

  • crates/transfer/src/config/mod.rs (+23): add pub fake_super: bool field with upstream-cited rustdoc.
  • crates/transfer/src/config/builder.rs (+23): add .fake_super(bool) builder method.
  • crates/transfer/src/config/builder_tests.rs (+21): default-false assertion and round-trip test.
  • crates/daemon/src/daemon/sections/module_access/client_args.rs (+7): set cfg.fake_super = module.fake_super in build_server_config.
  • crates/transfer/src/receiver/transfer.rs (+6/-1): chain .fake_super(self.config.fake_super) on the receiver's MetadataOptions::new() builder.
  • crates/daemon/src/tests/chunks/daemon_fake_super_module_push.rs (+158, new): end-to-end daemon test.
  • crates/daemon/src/tests.rs (+2): wire the new chunk into the test harness.

Upstream references

  • clientserver.c:1106-1107 — daemon fake super = yes demotes the receiver's am_root and forces fake-super semantics regardless of client args.
  • loadparm.cfake super module parameter parsing.
  • rsync.c:set_file_attrs() — fake-super stores ownership in xattrs.
  • xattrs.c:set_stat_xattr()user.rsync.%stat encoding format.

Per upstream, client --fake-super is demoted to --super on the wire before reaching the daemon, so the directive is purely daemon-config-driven; we do not parse --fake-super server-side.

Test plan

  • crates/daemon/src/tests/chunks/daemon_fake_super_module_push.rs covers the end-to-end daemon push case (skips gracefully on filesystems without user.* xattr support).
  • crates/transfer/src/config/builder_tests.rs::fake_super_round_trips_through_builder covers the builder.
  • crates/transfer/src/config/builder_tests.rs::default_optional_fields adds the default-false assertion.
  • Existing crates/daemon/src/rsyncd_config/tests.rs::module_fake_super_yes_parses_to_true_for_am_root_demotion covers the parser side (unchanged).
  • CI: fmt+clippy, nextest stable, Windows stable, macOS stable, Linux musl stable.

Closes #1904.

The daemon parsed `fake super = yes` from `rsyncd.conf(5)` into
`ModuleConfig.fake_super` but never threaded it into the transfer
pipeline. Receivers therefore tried real chown() regardless of the
module directive, which silently dropped ownership for non-root
daemons and contradicted upstream's `clientserver.c:1106-1107`
behaviour where `fake super = yes` demotes the receiver's am_root
and forces fake-super semantics on the wire.

Wire-up path:
  ModuleConfig.fake_super
    -> ServerConfig.fake_super (transfer/config)
       -> MetadataOptions.fake_super (receiver/transfer.rs)
          -> apply_ownership_via_fake_super (writes user.rsync.%stat)
             -> create_*_with_fake_super placeholders for special files

Changes:
- transfer/config/mod.rs: add `pub fake_super: bool` to ServerConfig
  with upstream citation and default false.
- transfer/config/builder.rs: add `.fake_super(bool)` builder method
  matching the existing `&mut self -> &mut Self` style.
- transfer/config/builder_tests.rs: assert default false and
  round-trip through the builder.
- daemon/sections/module_access/client_args.rs: in
  `build_server_config`, set `cfg.fake_super = module.fake_super`
  after the iconv wire-up. Per upstream, the directive is purely
  daemon-config-driven; client `--fake-super` is demoted to
  `--super` on the wire and never reaches the server-side parser.
- transfer/receiver/transfer.rs: call `.fake_super(self.config.fake_super)`
  on the MetadataOptions builder so the receiver routes ownership
  writes into the user.rsync.%stat xattr instead of chown().
- daemon/tests/chunks/daemon_fake_super_module_push.rs: end-to-end
  test that pushes a file with `-og` to a daemon module configured
  with `fake super = yes` and asserts the destination carries the
  user.rsync.%stat xattr.

Upstream references:
- clientserver.c:1106-1107: `fake super = yes` demotes am_root and
  rewrites client `--fake-super` to honour the daemon directive.
- loadparm.c: `fake super` module parameter parsing.
- rsync.c:set_file_attrs(): fake-super stores ownership in xattrs.
- xattrs.c:set_stat_xattr(): user.rsync.%stat encoding.

Closes #1904.
@github-actions github-actions Bot added the enhancement New feature or request label May 2, 2026
@oferchen oferchen merged commit bebfd0a into master May 2, 2026
38 checks passed
@oferchen oferchen deleted the feature/issue-1904-fake-super-module-wireup branch May 2, 2026 13:01
oferchen added a commit that referenced this pull request May 5, 2026
…) (#3559)

The daemon parsed `fake super = yes` from `rsyncd.conf(5)` into
`ModuleConfig.fake_super` but never threaded it into the transfer
pipeline. Receivers therefore tried real chown() regardless of the
module directive, which silently dropped ownership for non-root
daemons and contradicted upstream's `clientserver.c:1106-1107`
behaviour where `fake super = yes` demotes the receiver's am_root
and forces fake-super semantics on the wire.

Wire-up path:
  ModuleConfig.fake_super
    -> ServerConfig.fake_super (transfer/config)
       -> MetadataOptions.fake_super (receiver/transfer.rs)
          -> apply_ownership_via_fake_super (writes user.rsync.%stat)
             -> create_*_with_fake_super placeholders for special files

Changes:
- transfer/config/mod.rs: add `pub fake_super: bool` to ServerConfig
  with upstream citation and default false.
- transfer/config/builder.rs: add `.fake_super(bool)` builder method
  matching the existing `&mut self -> &mut Self` style.
- transfer/config/builder_tests.rs: assert default false and
  round-trip through the builder.
- daemon/sections/module_access/client_args.rs: in
  `build_server_config`, set `cfg.fake_super = module.fake_super`
  after the iconv wire-up. Per upstream, the directive is purely
  daemon-config-driven; client `--fake-super` is demoted to
  `--super` on the wire and never reaches the server-side parser.
- transfer/receiver/transfer.rs: call `.fake_super(self.config.fake_super)`
  on the MetadataOptions builder so the receiver routes ownership
  writes into the user.rsync.%stat xattr instead of chown().
- daemon/tests/chunks/daemon_fake_super_module_push.rs: end-to-end
  test that pushes a file with `-og` to a daemon module configured
  with `fake super = yes` and asserts the destination carries the
  user.rsync.%stat xattr.

Upstream references:
- clientserver.c:1106-1107: `fake super = yes` demotes am_root and
  rewrites client `--fake-super` to honour the daemon directive.
- loadparm.c: `fake super` module parameter parsing.
- rsync.c:set_file_attrs(): fake-super stores ownership in xattrs.
- xattrs.c:set_stat_xattr(): user.rsync.%stat encoding.

Closes #1904.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant