From a9519f6155c0f632d0520e5598bf8c6adc5a0f4b Mon Sep 17 00:00:00 2001 From: steve-chavez Date: Tue, 10 Dec 2024 19:00:29 -0500 Subject: [PATCH] feat: add supautils.superuser GUC Acts the same as the supautils.privileged_extensions_superuser GUC, this is still maintained for backwards compatibility. Also renames variables to clarify the codebase. --- README.md | 6 +-- src/privileged_extensions.c | 18 ++++---- src/privileged_extensions.h | 6 +-- src/supautils.c | 55 +++++++++++++++---------- src/utils.c | 6 +-- src/utils.h | 2 +- test/expected/privileged_extensions.out | 2 +- test/sql/privileged_extensions.sql | 2 +- 8 files changed, 54 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index cbfbbdf..0bd61a8 100644 --- a/README.md +++ b/README.md @@ -87,12 +87,12 @@ supautils allows you to let non-superusers manage extensions that would normally To handle this, you can put the extension in `supautils.privileged_extensions`: -``` +```psql supautils.privileged_extensions = 'hstore' -supautils.privileged_extensions_superuser = 'postgres' +supautils.superuser = 'postgres'; -- used to be called supautils.privileged_extensions_superuser, this is still provided for backwards compatibility ``` -Once you do, the extension creation will be delegated to the configured `supautils.privileged_extensions_superuser` (defaults to the bootstrap user, i.e. the role used to bootstrap the Postgres cluster). That means the `hstore` extension would be created as if by the superuser. +Once you do, the extension creation will be delegated to the configured `supautils.superuser` (defaults to the bootstrap user, i.e. the role used to bootstrap the Postgres cluster). That means the `hstore` extension would be created as if by the superuser. Note that extension creation would behave normally (i.e. no delegation) if the current role is already a superuser. diff --git a/src/privileged_extensions.c b/src/privileged_extensions.c index 0d7b331..bdc88db 100644 --- a/src/privileged_extensions.c +++ b/src/privileged_extensions.c @@ -92,7 +92,7 @@ static void run_custom_script(const char *filename, const char *extname, void handle_create_extension( void (*process_utility_hook)(PROCESS_UTILITY_PARAMS), PROCESS_UTILITY_PARAMS, const char *privileged_extensions, - const char *privileged_extensions_superuser, + const char *superuser, const char *privileged_extensions_custom_scripts_path, const extension_parameter_overrides *epos, const size_t total_epos) { CreateExtensionStmt *stmt = (CreateExtensionStmt *)pstmt->utilityStmt; @@ -124,7 +124,7 @@ void handle_create_extension( } } - switch_to_superuser(privileged_extensions_superuser, + switch_to_superuser(superuser, &already_switched_to_superuser); snprintf(filename, MAXPGPATH, "%s/before-create.sql", @@ -163,7 +163,7 @@ void handle_create_extension( } } - switch_to_superuser(privileged_extensions_superuser, + switch_to_superuser(superuser, &already_switched_to_superuser); snprintf(filename, MAXPGPATH, "%s/%s/before-create.sql", @@ -216,7 +216,7 @@ void handle_create_extension( if (is_string_in_comma_delimited_string(stmt->extname, privileged_extensions)) { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, + switch_to_superuser(superuser, &already_switched_to_superuser); run_process_utility_hook(process_utility_hook); @@ -254,7 +254,7 @@ void handle_create_extension( } } - switch_to_superuser(privileged_extensions_superuser, + switch_to_superuser(superuser, &already_switched_to_superuser); snprintf(filename, MAXPGPATH, "%s/%s/after-create.sql", @@ -274,12 +274,12 @@ void handle_alter_extension( void (*process_utility_hook)(PROCESS_UTILITY_PARAMS), PROCESS_UTILITY_PARAMS, const char *extname, const char *privileged_extensions, - const char *privileged_extensions_superuser) { + const char *superuser) { if (is_string_in_comma_delimited_string(extname, privileged_extensions)) { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, + switch_to_superuser(superuser, &already_switched_to_superuser); run_process_utility_hook(process_utility_hook); @@ -295,7 +295,7 @@ void handle_alter_extension( void handle_drop_extension(void (*process_utility_hook)(PROCESS_UTILITY_PARAMS), PROCESS_UTILITY_PARAMS, const char *privileged_extensions, - const char *privileged_extensions_superuser) { + const char *superuser) { DropStmt *stmt = (DropStmt *)pstmt->utilityStmt; bool all_extensions_are_privileged = true; ListCell *lc; @@ -311,7 +311,7 @@ void handle_drop_extension(void (*process_utility_hook)(PROCESS_UTILITY_PARAMS), if (all_extensions_are_privileged) { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, + switch_to_superuser(superuser, &already_switched_to_superuser); run_process_utility_hook(process_utility_hook); diff --git a/src/privileged_extensions.h b/src/privileged_extensions.h index 669a982..aca185a 100644 --- a/src/privileged_extensions.h +++ b/src/privileged_extensions.h @@ -7,7 +7,7 @@ extern void handle_create_extension( void (*process_utility_hook)(PROCESS_UTILITY_PARAMS), PROCESS_UTILITY_PARAMS, const char *privileged_extensions, - const char *privileged_extensions_superuser, + const char *superuser, const char *privileged_extensions_custom_scripts_path, const extension_parameter_overrides *epos, const size_t total_epos); @@ -16,11 +16,11 @@ handle_alter_extension(void (*process_utility_hook)(PROCESS_UTILITY_PARAMS), PROCESS_UTILITY_PARAMS, const char *extname, const char *privileged_extensions, - const char *privileged_extensions_superuser); + const char *superuser); extern void handle_drop_extension(void (*process_utility_hook)(PROCESS_UTILITY_PARAMS), PROCESS_UTILITY_PARAMS, const char *privileged_extensions, - const char *privileged_extensions_superuser); + const char *superuser); #endif diff --git a/src/supautils.c b/src/supautils.c index 8c14d26..362135d 100644 --- a/src/supautils.c +++ b/src/supautils.c @@ -60,9 +60,9 @@ static char *placeholders = NULL; static char *placeholders_disallowed_values = NULL; static char *empty_placeholder = NULL; static char *privileged_extensions = NULL; -static char *privileged_extensions_superuser = NULL; +static char *supautils_superuser = NULL; static char *privileged_extensions_custom_scripts_path = NULL; -static char *privileged_role = NULL; +static char *privileged_role = NULL; // the privileged_role is a proxy role for the `supautils.superuser` role static char *privileged_role_allowed_configs = NULL; static ProcessUtility_hook_type prev_hook = NULL; @@ -146,7 +146,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { } // Allow setting bypassrls & replication. - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -191,7 +191,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -283,7 +283,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { // Allow `privileged_role` (in addition to superusers) to // set bypassrls & replication attributes. - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -394,7 +394,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { handle_create_extension(prev_hook, PROCESS_UTILITY_ARGS, privileged_extensions, - privileged_extensions_superuser, + supautils_superuser, privileged_extensions_custom_scripts_path, epos, total_epos); return; @@ -417,7 +417,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { PROCESS_UTILITY_ARGS, stmt->extname, privileged_extensions, - privileged_extensions_superuser); + supautils_superuser); return; } @@ -439,7 +439,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { PROCESS_UTILITY_ARGS, strVal(stmt->object), privileged_extensions, - privileged_extensions_superuser); + supautils_superuser); } return; @@ -467,7 +467,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { break; } - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -531,7 +531,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { break; } - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -589,7 +589,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { break; } - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -613,7 +613,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { if (is_current_role_granted_table_policy(stmt->table, pgs, total_pgs)) { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -640,7 +640,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { if (is_current_role_granted_table_policy(stmt->table, pgs, total_pgs)) { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -674,7 +674,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { handle_drop_extension(prev_hook, PROCESS_UTILITY_ARGS, privileged_extensions, - privileged_extensions_superuser); + supautils_superuser); return; } @@ -696,7 +696,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { break; } - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -725,7 +725,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { break; } - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -759,7 +759,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -793,7 +793,7 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) { { bool already_switched_to_superuser = false; - switch_to_superuser(privileged_extensions_superuser, &already_switched_to_superuser); + switch_to_superuser(supautils_superuser, &already_switched_to_superuser); run_process_utility_hook(prev_hook); @@ -1169,7 +1169,7 @@ void _PG_init(void) { NULL); DefineCustomStringVariable("supautils.privileged_extensions", - "Comma-separated list of extensions which get installed using supautils.privileged_extensions_superuser", + "Comma-separated list of extensions which get installed using supautils.superuser", NULL, &privileged_extensions, NULL, @@ -1188,10 +1188,21 @@ void _PG_init(void) { NULL, NULL); - DefineCustomStringVariable("supautils.privileged_extensions_superuser", + DefineCustomStringVariable("supautils.superuser", "Superuser to install extensions in supautils.privileged_extensions as", NULL, - &privileged_extensions_superuser, + &supautils_superuser, + NULL, + PGC_SIGHUP, 0, + NULL, + NULL, + NULL); + + // TODO emit a warning when this deprecated GUC is used + DefineCustomStringVariable("supautils.privileged_extensions_superuser", + "Superuser to install extensions in supautils.privileged_extensions as. Deprecated: use supautils.superuser instead.", + NULL, + &supautils_superuser, NULL, PGC_SIGHUP, 0, NULL, @@ -1199,7 +1210,7 @@ void _PG_init(void) { NULL); DefineCustomStringVariable("supautils.privileged_role", - "Non-superuser role to be granted with additional privileges", + "Non-superuser role to be granted with some superuser privileges", NULL, &privileged_role, NULL, diff --git a/src/utils.c b/src/utils.c index 2c19e41..098844a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -14,7 +14,7 @@ static bool is_switched_to_superuser = false; static bool strstarts(const char *, const char *); -void switch_to_superuser(const char *privileged_extensions_superuser, +void switch_to_superuser(const char *supauser, bool *already_switched) { Oid superuser_oid = BOOTSTRAP_SUPERUSERID; *already_switched = is_switched_to_superuser; @@ -24,8 +24,8 @@ void switch_to_superuser(const char *privileged_extensions_superuser, } is_switched_to_superuser = true; - if (privileged_extensions_superuser != NULL) { - superuser_oid = get_role_oid(privileged_extensions_superuser, false); + if (supauser != NULL) { + superuser_oid = get_role_oid(supauser, false); } GetUserIdAndSecContext(&prev_role_oid, &prev_role_sec_context); diff --git a/src/utils.h b/src/utils.h index ef92579..2f08fc4 100644 --- a/src/utils.h +++ b/src/utils.h @@ -79,7 +79,7 @@ * Switch to a superuser and save the original role. Caller is responsible for * calling switch_to_original_role() afterwards. */ -extern void switch_to_superuser(const char *privileged_extensions_superuser, +extern void switch_to_superuser(const char *superuser, bool *already_switched); /** diff --git a/test/expected/privileged_extensions.out b/test/expected/privileged_extensions.out index 1241b87..f18397e 100644 --- a/test/expected/privileged_extensions.out +++ b/test/expected/privileged_extensions.out @@ -87,7 +87,7 @@ select extnamespace::regnamespace from pg_extension where extname = 'sslinfo'; drop extension sslinfo; \echo --- switch to privileged_extensions_superuser even if superuser +-- switch to supautils.superuser even if superuser reset role; create role another_superuser superuser; set role another_superuser; diff --git a/test/sql/privileged_extensions.sql b/test/sql/privileged_extensions.sql index 86033b2..3d77d8e 100644 --- a/test/sql/privileged_extensions.sql +++ b/test/sql/privileged_extensions.sql @@ -55,7 +55,7 @@ select extnamespace::regnamespace from pg_extension where extname = 'sslinfo'; drop extension sslinfo; \echo --- switch to privileged_extensions_superuser even if superuser +-- switch to supautils.superuser even if superuser reset role; create role another_superuser superuser; set role another_superuser;