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:
@@ -848,6 +848,20 @@ int parse_args(Config* config, int argc, char* argv[], int* positional_args,
|
||||
config->no_motd = true;
|
||||
continue;
|
||||
}
|
||||
/* "--super" / "--no-super" are real rsync option names controlling the
|
||||
* receiver's super-user activity policy (ownership, device nodes), not a
|
||||
* Boolean pair for the generic --no-* negation branch: both map onto the
|
||||
* Config->super_mode tri-state. Handle them explicitly (exact match only,
|
||||
* so a malformed "--super=x" still falls through to the unknown-option
|
||||
* error) before the generic negation branch would mis-reject "--no-super". */
|
||||
if (strcmp(argv[i], "--super") == 0) {
|
||||
config->super_mode = SUPER_MODE_ON;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "--no-super") == 0) {
|
||||
config->super_mode = SUPER_MODE_OFF;
|
||||
continue;
|
||||
}
|
||||
if (strncmp(argv[i], "--no-", strlen("--no-")) == 0) {
|
||||
if (strcmp(argv[i], "--no-delta") == 0)
|
||||
no_delta = true;
|
||||
|
||||
@@ -168,6 +168,14 @@ void print_usage(void) {
|
||||
printf(" user.fastsync.stat xattr on each written file and\n");
|
||||
printf(" re-apply it (fd-relative) on a privileged run; the\n");
|
||||
printf(" recording format diverges from rsync's user.rsync.%%stat%%\n");
|
||||
printf(" --super Permit the receiver to attempt super-user activities\n");
|
||||
printf(" (ownership application, char/block device-node\n");
|
||||
printf(" creation) within the confined receive root. Never\n");
|
||||
printf(" elevates privileges and never bypasses confinement;\n");
|
||||
printf(" with no explicit identity policy, ownership follows\n");
|
||||
printf(" raw numeric ids (as if --numeric-ids)\n");
|
||||
printf(" --no-super Forbid those super-user activities even when the\n");
|
||||
printf(" receiver is running as root\n");
|
||||
printf(" --chmod <changes> Modify transferred permissions (rsync syntax)\n");
|
||||
printf(" --numeric-ids Do not map uid/gid by name: use the source numeric\n");
|
||||
printf(" ids directly when applying ownership\n");
|
||||
|
||||
Reference in New Issue
Block a user