aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/variable.c
diff options
context:
space:
mode:
authorNathan Bossart <nathan@postgresql.org>2023-07-13 21:10:36 -0700
committerNathan Bossart <nathan@postgresql.org>2023-07-13 21:10:36 -0700
commit9987a7bf34061ed5cffc4e5113da056358976e94 (patch)
tree07fc348fd3ef1c4ddf2e99fdf0319c9b49fd6ba8 /src/backend/commands/variable.c
parentedca3424342da323499a1998d18a888283e52ac7 (diff)
downloadpostgresql-9987a7bf34061ed5cffc4e5113da056358976e94.tar.gz
postgresql-9987a7bf34061ed5cffc4e5113da056358976e94.zip
Move privilege check for SET SESSION AUTHORIZATION.
Presently, the privilege check for SET SESSION AUTHORIZATION is performed in session_authorization's assign_hook. A relevant comment states, "It's OK because the check does not require catalog access and can't fail during an end-of-transaction GUC reversion..." However, we plan to add a catalog lookup to this privilege check in a follow-up commit. This commit moves this privilege check to the check_hook for session_authorization. Like check_role(), we do not throw a hard error for insufficient privileges when the source is PGC_S_TEST. Author: Joseph Koshakow Discussion: https://postgr.es/m/CAAvxfHc-HHzONQ2oXdvhFF9ayRnidPwK%2BfVBhRzaBWYYLVQL-g%40mail.gmail.com
Diffstat (limited to 'src/backend/commands/variable.c')
-rw-r--r--src/backend/commands/variable.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index f0f2e076552..071bef63754 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -821,14 +821,16 @@ check_session_authorization(char **newval, void **extra, GucSource source)
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.
+ */
+
/* Look up the username */
roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval));
if (!HeapTupleIsValid(roleTup))
{
- /*
- * When source == PGC_S_TEST, we don't throw a hard error for a
- * nonexistent user name, only a NOTICE. See comments in guc.h.
- */
if (source == PGC_S_TEST)
{
ereport(NOTICE,
@@ -846,6 +848,28 @@ check_session_authorization(char **newval, void **extra, GucSource source)
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() &&
+ !GetAuthenticatedUserIsSuperuser())
+ {
+ 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;
+ }
+
/* Set up "extra" struct for assign_session_authorization to use */
myextra = (role_auth_extra *) guc_malloc(LOG, sizeof(role_auth_extra));
if (!myextra)