feat(p7-super): implement --super/--no-super safe-subset privilege gate (protocol 2.18.0)

Add the receiver-side --super / --no-super tri-state (Config->super_mode)
under the safe-subset + clear-refusal privilege model: FastSync never
elevates privileges, it only permits super-user attempts that are already
confined fd-relative below the authorized receive root.

- identity: privilege_super_permitted() gate (OFF=false, ON=true, AUTO follows
  geteuid()==0); identity_apply_ownership/_link become no-ops when not
  permitted; --super with no explicit identity policy implies raw numeric-id
  preservation (explicit usermap/groupmap/chown/numeric-ids still win); warn
  exactly once when --super is requested by a non-root receiver.
- file_receive: gate char/block device-node creation on the gate; FIFO/socket
  handling is unchanged.
- wire: trailing super_mode int after the --iconv spec, validated 0..2 in
  receive_privilege_options and validate_received_config; PROTOCOL_VERSION
  2.17.0 -> 2.18.0; version-sensitive tests and docs updated.
- CLI: --super/--no-super parsed explicitly before the generic --no-* branch
  (malformed --super=x rejected); usage text added.
- tests: config wire round-trip + invalid-value rejection, privilege-gate mode
  unit test, CLI parse test, integration transfer + root-gated ownership
  suppression/appliance tests.
- docs: RSYNC_COMPAT --super row + Wave E note, protocol mentions, README.
This commit is contained in:
2026-09-12 12:01:19 +02:00
parent f64d252faf
commit a785ec13c4
13 changed files with 366 additions and 26 deletions
+10
View File
@@ -65,4 +65,14 @@ void identity_apply_ownership_link(int parent_fd, const char* leaf, int32_t sour
/* Receiver-side wire validation of the resolved identity fields. */
bool identity_wire_valid(const Config* config);
/* P7 Wave E receiver-side permission gate for super-user activities (ownership
* application and char/block device-node creation). Returns false when the
* active config is --no-super (SUPER_MODE_OFF); true when it is --super
* (SUPER_MODE_ON); and otherwise (SUPER_MODE_AUTO, the default, or before
* identity_set_active() has been called) only when the receiver is ALREADY root
* (geteuid() == 0). This NEVER elevates privileges: it only reports whether an
* attempt that is already confined below the authorized receive root may be
* made. */
bool privilege_super_permitted(void);
#endif