diff --git a/src/server/server.c b/src/server/server.c index dce8fee..066b817 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -458,7 +458,7 @@ void handler(int file_descriptor) { * device-node creation) sees SUPER_MODE_OFF. The gate never mutated the * received config. */ if (gate_ctx.super_mode_override != -1) - config->super_mode = gate_ctx.super_mode_override; + config->super_mode = (SuperMode)gate_ctx.super_mode_override; protocol_set_8_bit_output(config->eight_bit_output); if (!authorized_root) { log_message(LOG_LEVEL_ERROR, "No server-side destination root configured"); diff --git a/src/shared/config.c b/src/shared/config.c index 61ea67c..4bd72c9 100644 --- a/src/shared/config.c +++ b/src/shared/config.c @@ -1293,14 +1293,14 @@ static bool receive_iconv_spec(int fd, Config* c) { * validated to the SUPER_MODE_AUTO..SUPER_MODE_OFF range (also re-checked by * validate_received_config). */ static bool send_privilege_options(int fd, const Config* c) { - return send_int(fd, c->super_mode); + return send_int(fd, (int)c->super_mode); } static bool receive_privilege_options(int fd, Config* c) { int mode; if (!receive_int(fd, &mode) || mode < SUPER_MODE_AUTO || mode > SUPER_MODE_OFF) return false; - c->super_mode = mode; + c->super_mode = (SuperMode)mode; return true; } diff --git a/src/shared/config.h b/src/shared/config.h index da3770e..66fd5eb 100644 --- a/src/shared/config.h +++ b/src/shared/config.h @@ -68,6 +68,13 @@ typedef struct { int value; /* 0/1 for booleans, byte count for SO_RCVBUF/SO_SNDBUF */ } SockOptEntry; +/* --super / --no-super tri-state (Config->super_mode). AUTO (default) and ON + * both permit a confined super-user attempt (AUTO preserves FastSync's + * historical best-effort behavior; an unprivileged attempt is refused by the + * kernel and skipped per entry); OFF forbids the attempt even for root. See + * privilege_super_mode_permitted() in identity.h. */ +typedef enum SuperMode { SUPER_MODE_AUTO = 0, SUPER_MODE_ON = 1, SUPER_MODE_OFF = 2 } SuperMode; + typedef struct Config { char* version; char* send_directory; @@ -416,7 +423,7 @@ typedef struct Config { * as a trailing int so the receiver can enforce the policy. See * privilege_super_permitted() and identity_ownership_requested() in * identity.h. */ - int super_mode; + SuperMode super_mode; // Receiver-side runtime staging registry for --delay-updates. Never sent // over the wire and never set on the sender side. @@ -644,15 +651,6 @@ typedef struct Config { #define IDENTITY_CURRENT (-1) #define MAX_IDENTITY_MAP 128 -/* --super / --no-super tri-state (Config->super_mode). AUTO (default) and ON - * both permit a confined super-user attempt (AUTO preserves FastSync's - * historical best-effort behavior; an unprivileged attempt is refused by the - * kernel and skipped per entry); OFF forbids the attempt even for root. See - * privilege_super_mode_permitted() in identity.h. */ -#define SUPER_MODE_AUTO 0 -#define SUPER_MODE_ON 1 -#define SUPER_MODE_OFF 2 - Config* config_create(void); void config_delete(Config* config); diff --git a/src/shared/identity.c b/src/shared/identity.c index 5a39f0e..a43c84b 100644 --- a/src/shared/identity.c +++ b/src/shared/identity.c @@ -30,7 +30,7 @@ typedef struct { /* --super / --no-super tri-state (SUPER_MODE_AUTO when unset). Snapshotted * per connection so privilege_super_permitted() can gate super-user * activities without a Config argument. */ - int super_mode; + SuperMode super_mode; /* --copy-as=USER[:GROUP]: snapshotted so the ownership resolver can force the * target ids without a Config argument. */ bool copy_as_set; @@ -128,7 +128,7 @@ bool privilege_super_permitted(void) { return privilege_super_mode_permitted(g_identity.super_mode); } -bool privilege_super_mode_permitted(int mode) { +bool privilege_super_mode_permitted(SuperMode mode) { /* AUTO and ON both attempt the confined operation; OFF forbids it even for a * root receiver. AUTO is the historical FastSync behavior (always attempt * and let the kernel refuse an unprivileged call, which the caller skips), so diff --git a/src/shared/identity.h b/src/shared/identity.h index 592c5e7..e01c674 100644 --- a/src/shared/identity.h +++ b/src/shared/identity.h @@ -128,6 +128,6 @@ bool identity_wire_valid(const Config* config); * best-effort behavior where an unprivileged attempt is refused by the kernel * and skipped. Neither EVER elevates privileges. */ bool privilege_super_permitted(void); -bool privilege_super_mode_permitted(int mode); +bool privilege_super_mode_permitted(SuperMode mode); #endif \ No newline at end of file diff --git a/tests/test_config.c b/tests/test_config.c index f70d99d..4ffc49f 100644 --- a/tests/test_config.c +++ b/tests/test_config.c @@ -1672,7 +1672,7 @@ static void test_config_receive_rejects_invalid_iconv_spec() { static void test_config_super_mode_wire_roundtrip() { if (is_running_under_valgrind()) return; - int modes[] = {SUPER_MODE_AUTO, SUPER_MODE_ON, SUPER_MODE_OFF}; + SuperMode modes[] = {SUPER_MODE_AUTO, SUPER_MODE_ON, SUPER_MODE_OFF}; for (size_t i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) { int p[2]; EXPECT_EQ_INT(socketpair(AF_UNIX, SOCK_STREAM, 0, p), 0);