Skip to content

Commit 9987a7b

Browse files
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
1 parent edca342 commit 9987a7b

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

src/backend/commands/variable.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -821,14 +821,16 @@ check_session_authorization(char **newval, void **extra, GucSource source)
821821
return false;
822822
}
823823

824+
/*
825+
* When source == PGC_S_TEST, we don't throw a hard error for a
826+
* nonexistent user name or insufficient privileges, only a NOTICE. See
827+
* comments in guc.h.
828+
*/
829+
824830
/* Look up the username */
825831
roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval));
826832
if (!HeapTupleIsValid(roleTup))
827833
{
828-
/*
829-
* When source == PGC_S_TEST, we don't throw a hard error for a
830-
* nonexistent user name, only a NOTICE. See comments in guc.h.
831-
*/
832834
if (source == PGC_S_TEST)
833835
{
834836
ereport(NOTICE,
@@ -846,6 +848,28 @@ check_session_authorization(char **newval, void **extra, GucSource source)
846848

847849
ReleaseSysCache(roleTup);
848850

851+
/*
852+
* Only superusers may SET SESSION AUTHORIZATION a role other than itself.
853+
* Note that in case of multiple SETs in a single session, the original
854+
* authenticated user's superuserness is what matters.
855+
*/
856+
if (roleid != GetAuthenticatedUserId() &&
857+
!GetAuthenticatedUserIsSuperuser())
858+
{
859+
if (source == PGC_S_TEST)
860+
{
861+
ereport(NOTICE,
862+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
863+
errmsg("permission will be denied to set session authorization \"%s\"",
864+
*newval)));
865+
return true;
866+
}
867+
GUC_check_errcode(ERRCODE_INSUFFICIENT_PRIVILEGE);
868+
GUC_check_errmsg("permission denied to set session authorization \"%s\"",
869+
*newval);
870+
return false;
871+
}
872+
849873
/* Set up "extra" struct for assign_session_authorization to use */
850874
myextra = (role_auth_extra *) guc_malloc(LOG, sizeof(role_auth_extra));
851875
if (!myextra)

src/backend/utils/init/miscinit.c

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,16 @@ GetAuthenticatedUserId(void)
582582
return AuthenticatedUserId;
583583
}
584584

585+
/*
586+
* Return whether the authenticated user was superuser at connection start.
587+
*/
588+
bool
589+
GetAuthenticatedUserIsSuperuser(void)
590+
{
591+
Assert(OidIsValid(AuthenticatedUserId));
592+
return AuthenticatedUserIsSuperuser;
593+
}
594+
585595

586596
/*
587597
* GetUserIdAndSecContext/SetUserIdAndSecContext - get/set the current user ID
@@ -889,28 +899,12 @@ system_user(PG_FUNCTION_ARGS)
889899
/*
890900
* Change session auth ID while running
891901
*
892-
* Only a superuser may set auth ID to something other than himself. Note
893-
* that in case of multiple SETs in a single session, the original userid's
894-
* superuserness is what matters. But we set the GUC variable is_superuser
895-
* to indicate whether the *current* session userid is a superuser.
896-
*
897-
* Note: this is not an especially clean place to do the permission check.
898-
* It's OK because the check does not require catalog access and can't
899-
* fail during an end-of-transaction GUC reversion, but we may someday
900-
* have to push it up into assign_session_authorization.
902+
* Note that we set the GUC variable is_superuser to indicate whether the
903+
* current role is a superuser.
901904
*/
902905
void
903906
SetSessionAuthorization(Oid userid, bool is_superuser)
904907
{
905-
/* Must have authenticated already, else can't make permission check */
906-
Assert(OidIsValid(AuthenticatedUserId));
907-
908-
if (userid != AuthenticatedUserId &&
909-
!AuthenticatedUserIsSuperuser)
910-
ereport(ERROR,
911-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
912-
errmsg("permission denied to set session authorization")));
913-
914908
SetSessionUserId(userid, is_superuser);
915909

916910
SetConfigOption("is_superuser",

src/include/miscadmin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ extern Oid GetUserId(void);
357357
extern Oid GetOuterUserId(void);
358358
extern Oid GetSessionUserId(void);
359359
extern Oid GetAuthenticatedUserId(void);
360+
extern bool GetAuthenticatedUserIsSuperuser(void);
360361
extern void GetUserIdAndSecContext(Oid *userid, int *sec_context);
361362
extern void SetUserIdAndSecContext(Oid userid, int sec_context);
362363
extern bool InLocalUserIdChange(void);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy