diff options
Diffstat (limited to 'src/backend/commands/variable.c')
-rw-r--r-- | src/backend/commands/variable.c | 121 |
1 files changed, 70 insertions, 51 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 9345131711e..61eae295fa8 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -811,63 +811,77 @@ check_session_authorization(char **newval, void **extra, GucSource source) if (*newval == NULL) return true; - if (!IsTransactionState()) + if (InitializingParallelWorker) { /* - * Can't do catalog lookups, so fail. The result of this is that - * session_authorization cannot be set in postgresql.conf, which seems - * like a good thing anyway, so we don't work hard to avoid it. + * In parallel worker initialization, we want to copy the leader's + * state even if it no longer matches the catalogs. ParallelWorkerMain + * already installed the correct role OID and superuser state. */ - return false; + roleid = GetSessionUserId(); + is_superuser = GetSessionUserIsSuperuser(); } + else + { + if (!IsTransactionState()) + { + /* + * Can't do catalog lookups, so fail. The result of this is that + * session_authorization cannot be set in postgresql.conf, which + * seems like a good thing anyway, so we don't work hard to avoid + * it. + */ + return false; + } - /* - * When source == PGC_S_TEST, we don't throw a hard error for a - * nonexistent user name or insufficient privileges, only a NOTICE. See - * comments in guc.h. - */ + /* + * When source == PGC_S_TEST, we don't throw a hard error for a + * nonexistent user name or insufficient privileges, only a NOTICE. + * See comments in guc.h. + */ - /* Look up the username */ - roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval)); - if (!HeapTupleIsValid(roleTup)) - { - if (source == PGC_S_TEST) + /* Look up the username */ + roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval)); + if (!HeapTupleIsValid(roleTup)) { - ereport(NOTICE, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("role \"%s\" does not exist", *newval))); - return true; + if (source == PGC_S_TEST) + { + ereport(NOTICE, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", *newval))); + return true; + } + GUC_check_errmsg("role \"%s\" does not exist", *newval); + return false; } - GUC_check_errmsg("role \"%s\" does not exist", *newval); - return false; - } - roleform = (Form_pg_authid) GETSTRUCT(roleTup); - roleid = roleform->oid; - is_superuser = roleform->rolsuper; + roleform = (Form_pg_authid) GETSTRUCT(roleTup); + roleid = roleform->oid; + is_superuser = roleform->rolsuper; - ReleaseSysCache(roleTup); + ReleaseSysCache(roleTup); - /* - * Only superusers may SET SESSION AUTHORIZATION a role other than itself. - * Note that in case of multiple SETs in a single session, the original - * authenticated user's superuserness is what matters. - */ - if (roleid != GetAuthenticatedUserId() && - !superuser_arg(GetAuthenticatedUserId())) - { - if (source == PGC_S_TEST) + /* + * Only superusers may SET SESSION AUTHORIZATION a role other than + * itself. Note that in case of multiple SETs in a single session, the + * original authenticated user's superuserness is what matters. + */ + if (roleid != GetAuthenticatedUserId() && + !superuser_arg(GetAuthenticatedUserId())) { - ereport(NOTICE, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission will be denied to set session authorization \"%s\"", - *newval))); - return true; + if (source == PGC_S_TEST) + { + ereport(NOTICE, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission will be denied to set session authorization \"%s\"", + *newval))); + return true; + } + GUC_check_errcode(ERRCODE_INSUFFICIENT_PRIVILEGE); + GUC_check_errmsg("permission denied to set session authorization \"%s\"", + *newval); + return false; } - GUC_check_errcode(ERRCODE_INSUFFICIENT_PRIVILEGE); - GUC_check_errmsg("permission denied to set session authorization \"%s\"", - *newval); - return false; } /* Set up "extra" struct for assign_session_authorization to use */ @@ -918,6 +932,16 @@ check_role(char **newval, void **extra, GucSource source) roleid = InvalidOid; is_superuser = false; } + else if (InitializingParallelWorker) + { + /* + * In parallel worker initialization, we want to copy the leader's + * state even if it no longer matches the catalogs. ParallelWorkerMain + * already installed the correct role OID and superuser state. + */ + roleid = GetCurrentRoleId(); + is_superuser = current_role_is_superuser; + } else { if (!IsTransactionState()) @@ -957,13 +981,8 @@ check_role(char **newval, void **extra, GucSource source) ReleaseSysCache(roleTup); - /* - * Verify that session user is allowed to become this role, but skip - * this in parallel mode, where we must blindly recreate the parallel - * leader's state. - */ - if (!InitializingParallelWorker && - !member_can_set_role(GetSessionUserId(), roleid)) + /* Verify that session user is allowed to become this role */ + if (!member_can_set_role(GetSessionUserId(), roleid)) { if (source == PGC_S_TEST) { |