diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/transam/parallel.c | 11 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 25 |
2 files changed, 20 insertions, 16 deletions
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index d6830507330..1f542ed8d86 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -75,9 +75,11 @@ typedef struct FixedParallelState Oid database_id; Oid authenticated_user_id; Oid current_user_id; + Oid outer_user_id; Oid temp_namespace_id; Oid temp_toast_namespace_id; int sec_context; + bool is_superuser; PGPROC *parallel_master_pgproc; pid_t parallel_master_pid; BackendId parallel_master_backend_id; @@ -296,6 +298,8 @@ InitializeParallelDSM(ParallelContext *pcxt) shm_toc_allocate(pcxt->toc, sizeof(FixedParallelState)); fps->database_id = MyDatabaseId; fps->authenticated_user_id = GetAuthenticatedUserId(); + fps->outer_user_id = GetCurrentRoleId(); + fps->is_superuser = session_auth_is_superuser; GetUserIdAndSecContext(&fps->current_user_id, &fps->sec_context); GetTempNamespaceState(&fps->temp_namespace_id, &fps->temp_toast_namespace_id); @@ -1115,6 +1119,13 @@ ParallelWorkerMain(Datum main_arg) */ InvalidateSystemCaches(); + /* + * Restore current role id. Skip verifying whether session user is + * allowed to become this role and blindly restore the leader's state for + * current role. + */ + SetCurrentRoleId(fps->outer_user_id, fps->is_superuser); + /* Restore user ID and security context. */ SetUserIdAndSecContext(fps->current_user_id, fps->sec_context); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ae22185fbdb..65372d7cc55 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -446,6 +446,7 @@ char *event_source; bool row_security; bool check_function_bodies = true; bool default_with_oids = false; +bool session_auth_is_superuser; int log_min_error_statement = ERROR; int log_min_messages = WARNING; @@ -492,7 +493,6 @@ int huge_pages; * and is kept in sync by assign_hooks. */ static char *syslog_ident_str; -static bool session_auth_is_superuser; static double phony_random_seed; static char *client_encoding_string; static char *datestyle_string; @@ -8986,12 +8986,18 @@ read_nondefault_variables(void) * constants; a few, like server_encoding and lc_ctype, are handled specially * outside the serialize/restore procedure. Therefore, SerializeGUCState() * never sends these, and RestoreGUCState() never changes them. + * + * Role is a special variable in the sense that its current value can be an + * invalid value and there are multiple ways by which that can happen (like + * after setting the role, someone drops it). So we handle it outside of + * serialize/restore machinery. */ static bool can_skip_gucvar(struct config_generic *gconf) { return gconf->context == PGC_POSTMASTER || - gconf->context == PGC_INTERNAL || gconf->source == PGC_S_DEFAULT; + gconf->context == PGC_INTERNAL || gconf->source == PGC_S_DEFAULT || + strcmp(gconf->name, "role") == 0; } /* @@ -9252,7 +9258,6 @@ SerializeGUCState(Size maxsize, char *start_address) Size actual_size; Size bytes_left; int i; - int i_role = -1; /* Reserve space for saving the actual size of the guc state */ Assert(maxsize > sizeof(actual_size)); @@ -9260,19 +9265,7 @@ SerializeGUCState(Size maxsize, char *start_address) bytes_left = maxsize - sizeof(actual_size); for (i = 0; i < num_guc_variables; i++) - { - /* - * It's pretty ugly, but we've got to force "role" to be initialized - * after "session_authorization"; otherwise, the latter will override - * the former. - */ - if (strcmp(guc_variables[i]->name, "role") == 0) - i_role = i; - else - serialize_variable(&curptr, &bytes_left, guc_variables[i]); - } - if (i_role >= 0) - serialize_variable(&curptr, &bytes_left, guc_variables[i_role]); + serialize_variable(&curptr, &bytes_left, guc_variables[i]); /* Store actual size without assuming alignment of start_address. */ actual_size = maxsize - bytes_left - sizeof(actual_size); |