Skip to content

Commit a0363ab

Browse files
Fix privilege check for SET SESSION AUTHORIZATION.
Presently, the privilege check for SET SESSION AUTHORIZATION checks whether the original authenticated role was a superuser at connection start time. Even if the role loses the superuser attribute, its existing sessions are permitted to change session authorization to any role. This commit modifies this privilege check to verify the original authenticated role currently has superuser. In the event that the authenticated role loses superuser within a session authorization change, the authorization change will remain in effect, which means the user can still take advantage of the target role's privileges. However, [RE]SET SESSION AUTHORIZATION will only permit switching to the original authenticated role. Author: Joseph Koshakow Discussion: https://postgr.es/m/CAAvxfHc-HHzONQ2oXdvhFF9ayRnidPwK%2BfVBhRzaBWYYLVQL-g%40mail.gmail.com
1 parent 9987a7b commit a0363ab

File tree

4 files changed

+10
-23
lines changed

4 files changed

+10
-23
lines changed

doc/src/sgml/ref/set_session_auth.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ RESET SESSION AUTHORIZATION
5151

5252
<para>
5353
The session user identifier can be changed only if the initial session
54-
user (the <firstterm>authenticated user</firstterm>) had the
54+
user (the <firstterm>authenticated user</firstterm>) has the
5555
superuser privilege. Otherwise, the command is accepted only if it
5656
specifies the authenticated user name.
5757
</para>

src/backend/commands/variable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ check_session_authorization(char **newval, void **extra, GucSource source)
854854
* authenticated user's superuserness is what matters.
855855
*/
856856
if (roleid != GetAuthenticatedUserId() &&
857-
!GetAuthenticatedUserIsSuperuser())
857+
!superuser_arg(GetAuthenticatedUserId()))
858858
{
859859
if (source == PGC_S_TEST)
860860
{

src/backend/utils/init/miscinit.c

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,8 @@ ChangeToDataDir(void)
467467
* AuthenticatedUserId is determined at connection start and never changes.
468468
*
469469
* SessionUserId is initially the same as AuthenticatedUserId, but can be
470-
* changed by SET SESSION AUTHORIZATION (if AuthenticatedUserIsSuperuser).
471-
* This is the ID reported by the SESSION_USER SQL function.
470+
* changed by SET SESSION AUTHORIZATION (if AuthenticatedUserId is a
471+
* superuser). This is the ID reported by the SESSION_USER SQL function.
472472
*
473473
* OuterUserId is the current user ID in effect at the "outer level" (outside
474474
* any transaction or function). This is initially the same as SessionUserId,
@@ -492,8 +492,7 @@ static Oid OuterUserId = InvalidOid;
492492
static Oid CurrentUserId = InvalidOid;
493493
static const char *SystemUser = NULL;
494494

495-
/* We also have to remember the superuser state of some of these levels */
496-
static bool AuthenticatedUserIsSuperuser = false;
495+
/* We also have to remember the superuser state of the session user */
497496
static bool SessionUserIsSuperuser = false;
498497

499498
static int SecurityRestrictionContext = 0;
@@ -582,16 +581,6 @@ GetAuthenticatedUserId(void)
582581
return AuthenticatedUserId;
583582
}
584583

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-
595584

596585
/*
597586
* GetUserIdAndSecContext/SetUserIdAndSecContext - get/set the current user ID
@@ -741,6 +730,7 @@ InitializeSessionUserId(const char *rolename, Oid roleid)
741730
HeapTuple roleTup;
742731
Form_pg_authid rform;
743732
char *rname;
733+
bool is_superuser;
744734

745735
/*
746736
* Don't do scans if we're bootstrapping, none of the system catalogs
@@ -780,10 +770,10 @@ InitializeSessionUserId(const char *rolename, Oid roleid)
780770
rname = NameStr(rform->rolname);
781771

782772
AuthenticatedUserId = roleid;
783-
AuthenticatedUserIsSuperuser = rform->rolsuper;
773+
is_superuser = rform->rolsuper;
784774

785775
/* This sets OuterUserId/CurrentUserId too */
786-
SetSessionUserId(roleid, AuthenticatedUserIsSuperuser);
776+
SetSessionUserId(roleid, is_superuser);
787777

788778
/* Also mark our PGPROC entry with the authenticated user id */
789779
/* (We assume this is an atomic store so no lock is needed) */
@@ -816,7 +806,7 @@ InitializeSessionUserId(const char *rolename, Oid roleid)
816806
* just document that the connection limit is approximate.
817807
*/
818808
if (rform->rolconnlimit >= 0 &&
819-
!AuthenticatedUserIsSuperuser &&
809+
!is_superuser &&
820810
CountUserBackends(roleid) > rform->rolconnlimit)
821811
ereport(FATAL,
822812
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
@@ -828,7 +818,7 @@ InitializeSessionUserId(const char *rolename, Oid roleid)
828818
SetConfigOption("session_authorization", rname,
829819
PGC_BACKEND, PGC_S_OVERRIDE);
830820
SetConfigOption("is_superuser",
831-
AuthenticatedUserIsSuperuser ? "on" : "off",
821+
is_superuser ? "on" : "off",
832822
PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
833823

834824
ReleaseSysCache(roleTup);
@@ -851,8 +841,6 @@ InitializeSessionUserIdStandalone(void)
851841
Assert(!OidIsValid(AuthenticatedUserId));
852842

853843
AuthenticatedUserId = BOOTSTRAP_SUPERUSERID;
854-
AuthenticatedUserIsSuperuser = true;
855-
856844
SetSessionUserId(BOOTSTRAP_SUPERUSERID, true);
857845
}
858846

src/include/miscadmin.h

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

0 commit comments

Comments
 (0)