Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions src/supautils.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {
// Allow setting bypassrls & replication.
switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -278,7 +279,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {
bool already_switched_to_superuser = false;
switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -367,7 +369,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {
switch_to_superuser(supautils_superuser,
&already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -482,11 +485,11 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {
override_create_ext_statement(stmt, total_epos, epos);

if (is_extension_privileged(stmt->extname, privileged_extensions)) {
run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);
} else {
if (!already_switched_to_superuser) {
switch_to_original_role();
already_switched_to_superuser = false;
}

run_process_utility_hook(prev_hook);
Expand Down Expand Up @@ -519,7 +522,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand All @@ -545,7 +549,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -580,7 +585,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

CreateFdwStmt *stmt = (CreateFdwStmt *)utility_stmt;

Expand Down Expand Up @@ -610,7 +616,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

CreatePublicationStmt *stmt = (CreatePublicationStmt *)utility_stmt;

Expand Down Expand Up @@ -639,7 +646,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand All @@ -663,7 +671,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand All @@ -690,7 +699,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -719,7 +729,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {
switch_to_superuser(supautils_superuser,
&already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -752,7 +763,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -782,7 +794,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -815,7 +828,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {
bool already_switched_to_superuser = false;
switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -852,7 +866,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {
bool already_switched_to_superuser = false;
switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!already_switched_to_superuser) {
switch_to_original_role();
Expand Down Expand Up @@ -904,7 +919,8 @@ static void supautils_hook(PROCESS_UTILITY_PARAMS) {

switch_to_superuser(supautils_superuser, &already_switched_to_superuser);

run_process_utility_hook(prev_hook);
run_process_utility_hook_with_cleanup(
prev_hook, already_switched_to_superuser, switch_to_original_role);

if (!current_user_is_super)
// Change event trigger owner to the current role (which is a privileged
Expand Down
14 changes: 14 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@
standard_ProcessUtility(PROCESS_UTILITY_ARGS); \
}

#define run_process_utility_hook_with_cleanup(process_utility_hook, \
already_switched_to_superuser, \
switch_to_original_role) \
PG_TRY(); \
{ run_process_utility_hook(prev_hook); } \
PG_CATCH(); \
{ \
if (!already_switched_to_superuser) { \
switch_to_original_role(); \
} \
PG_RE_THROW(); \
} \
PG_END_TRY();

// helper for testing a guc config
#if TEST
# define SUPAUTILS_GUC_CONTEXT_SIGHUP PGC_USERSET
Expand Down
16 changes: 16 additions & 0 deletions test/expected/privileged_role.out
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,19 @@ drop cascades to function deny_drop_triggers.f()
set role privileged_role;
\echo

-- regression: is_switched_to_superuser is restored when an exception is thrown
create publication p;
do $$
begin
alter publication p add table missing_table;
exception
when undefined_table then
null;
end $$;
-- if is_switched_to_superuser is not restored, role switching won't happen here
-- and publication creation would fail
create publication pp for all tables;
drop publication p;
drop publication pp;
\echo

17 changes: 17 additions & 0 deletions test/sql/privileged_role.sql
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,20 @@ set role postgres;
drop schema deny_drop_triggers cascade;
set role privileged_role;
\echo

-- regression: is_switched_to_superuser is restored when an exception is thrown
create publication p;
do $$
begin
alter publication p add table missing_table;
exception
when undefined_table then
null;
end $$;
-- if is_switched_to_superuser is not restored, role switching won't happen here
-- and publication creation would fail
create publication pp for all tables;

drop publication p;
drop publication pp;
\echo
Loading