Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit79de984

Browse files
committed
Remove the ability of a role to administer itself.
Commitf9fd176 effectively gaveevery role ADMIN OPTION on itself. However, this appears to besomething that happened accidentally as a result of refactoringwork rather than an intentional decision. Almost a decade later,it was discovered that this was a security vulnerability. As aresult, commitfea164a restrictedthis implicit ADMIN OPTION privilege to be exercisable only whenthe role being administered is the same as the session user andwhen no security-restricted operation is in progress. Thatcommit also documented the existence of this implicit privilegefor what seems to be the first time.The effect of the privilege is to allow a login role to grantthe privileges of that role, and optionally ADMIN OPTION on it,to some other role. That's an unusual thing to do, because generallymembership is granted in roles used as groups, rather than rolesused as users. Therefore, it does not seem likely that removingthe privilege will break things for many PostgreSQL users.However, it will make it easier to reason about the permissionssystem. This is the only case where a user who has not been given anyspecial permission (superuser, or ADMIN OPTION on some role) canmodify role membership, so removing it makes things more consistent.For example, if a superuser sets up role A and B and grants A to Bbut no other privileges to anyone, she can now be sure that no oneelse will be able to revoke that grant. Without this change, thatwould have been true only if A was a non-login role.Patch by me. Reviewed by Tom Lane and Stephen Frost.Discussion:http://postgr.es/m/CA+Tgmoawdt03kbA+dNyBcNWJpRxu0f4X=69Y3+DkXXZqmwMDLg@mail.gmail.com
1 parent6176242 commit79de984

File tree

5 files changed

+8
-58
lines changed

5 files changed

+8
-58
lines changed

‎doc/src/sgml/ref/grant.sgml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,10 @@ GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replace
251251
in turn grant membership in the role to others, and revoke membership
252252
in the role as well. Without the admin option, ordinary users cannot
253253
do that. A role is not considered to hold <literal>WITH ADMIN
254-
OPTION</literal> on itself, but it may grant or revoke membership in
255-
itself from a database session where the session user matches the
256-
role. Database superusers can grant or revoke membership in any role
257-
to anyone. Roles having <literal>CREATEROLE</literal> privilege can grant
258-
or revoke membership in any role that is not a superuser.
254+
OPTION</literal> on itself. Database superusers can grant or revoke
255+
membership in any role to anyone. Roles having
256+
<literal>CREATEROLE</literal> privilege can grant or revoke membership
257+
in any role that is not a superuser.
259258
</para>
260259

261260
<para>

‎src/backend/commands/user.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,11 +1425,6 @@ AddRoleMems(const char *rolename, Oid roleid,
14251425
* The role membership grantor of record has little significance at
14261426
* present. Nonetheless, inasmuch as users might look to it for a crude
14271427
* audit trail, let only superusers impute the grant to a third party.
1428-
*
1429-
* Before lifting this restriction, give the member == role case of
1430-
* is_admin_of_role() a fresh look. Ensure that the current role cannot
1431-
* use an explicit grantor specification to take advantage of the session
1432-
* user's self-admin right.
14331428
*/
14341429
if (grantorId!=GetUserId()&& !superuser())
14351430
ereport(ERROR,

‎src/backend/utils/adt/acl.c

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4619,11 +4619,6 @@ pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode)
46194619
{
46204620
if (mode&ACL_GRANT_OPTION_FOR(ACL_CREATE))
46214621
{
4622-
/*
4623-
* XXX For roleid == role_oid, is_admin_of_role() also examines the
4624-
* session and call stack. That suits two-argument pg_has_role(), but
4625-
* it gives the three-argument version a lamentable whimsy.
4626-
*/
46274622
if (is_admin_of_role(roleid,role_oid))
46284623
returnACLCHECK_OK;
46294624
}
@@ -4935,38 +4930,9 @@ is_admin_of_role(Oid member, Oid role)
49354930
if (superuser_arg(member))
49364931
return true;
49374932

4933+
/* By policy, a role cannot have WITH ADMIN OPTION on itself. */
49384934
if (member==role)
4939-
4940-
/*
4941-
* A role can admin itself when it matches the session user and we're
4942-
* outside any security-restricted operation, SECURITY DEFINER or
4943-
* similar context. SQL-standard roles cannot self-admin. However,
4944-
* SQL-standard users are distinct from roles, and they are not
4945-
* grantable like roles: PostgreSQL's role-user duality extends the
4946-
* standard. Checking for a session user match has the effect of
4947-
* letting a role self-admin only when it's conspicuously behaving
4948-
* like a user. Note that allowing self-admin under a mere SET ROLE
4949-
* would make WITH ADMIN OPTION largely irrelevant; any member could
4950-
* SET ROLE to issue the otherwise-forbidden command.
4951-
*
4952-
* Withholding self-admin in a security-restricted operation prevents
4953-
* object owners from harnessing the session user identity during
4954-
* administrative maintenance. Suppose Alice owns a database, has
4955-
* issued "GRANT alice TO bob", and runs a daily ANALYZE. Bob creates
4956-
* an alice-owned SECURITY DEFINER function that issues "REVOKE alice
4957-
* FROM carol". If he creates an expression index calling that
4958-
* function, Alice will attempt the REVOKE during each ANALYZE.
4959-
* Checking InSecurityRestrictedOperation() thwarts that attack.
4960-
*
4961-
* Withholding self-admin in SECURITY DEFINER functions makes their
4962-
* behavior independent of the calling user. There's no security or
4963-
* SQL-standard-conformance need for that restriction, though.
4964-
*
4965-
* A role cannot have actual WITH ADMIN OPTION on itself, because that
4966-
* would imply a membership loop. Therefore, we're done either way.
4967-
*/
4968-
returnmember==GetSessionUserId()&&
4969-
!InLocalUserIdChange()&& !InSecurityRestrictedOperation();
4935+
return false;
49704936

49714937
(void)roles_is_member_of(member,ROLERECURSE_MEMBERS,role,&result);
49724938
returnresult;

‎src/test/regress/expected/privileges.out

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,14 +1653,8 @@ SET ROLE regress_priv_group2;
16531653
GRANT regress_priv_group2 TO regress_priv_user5; -- fails: SET ROLE did not help
16541654
ERROR: must have admin option on role "regress_priv_group2"
16551655
SET SESSION AUTHORIZATION regress_priv_group2;
1656-
GRANT regress_priv_group2 TO regress_priv_user5; -- ok: a role can self-admin
1657-
NOTICE: role "regress_priv_user5" is already a member of role "regress_priv_group2"
1658-
CREATE FUNCTION dogrant_fails() RETURNS void LANGUAGE sql SECURITY DEFINER AS
1659-
'GRANT regress_priv_group2 TO regress_priv_user5';
1660-
SELECT dogrant_fails();-- fails: no self-admin in SECURITY DEFINER
1656+
GRANT regress_priv_group2 TO regress_priv_user5; -- fails: no self-admin
16611657
ERROR: must have admin option on role "regress_priv_group2"
1662-
CONTEXT: SQL function "dogrant_fails" statement 1
1663-
DROP FUNCTION dogrant_fails();
16641658
SET SESSION AUTHORIZATION regress_priv_user4;
16651659
DROP FUNCTION dogrant_ok();
16661660
REVOKE regress_priv_group2 FROM regress_priv_user5;

‎src/test/regress/sql/privileges.sql

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,11 +1089,7 @@ SET ROLE regress_priv_group2;
10891089
GRANT regress_priv_group2 TO regress_priv_user5;-- fails: SET ROLE did not help
10901090

10911091
SET SESSION AUTHORIZATION regress_priv_group2;
1092-
GRANT regress_priv_group2 TO regress_priv_user5;-- ok: a role can self-admin
1093-
CREATEFUNCTIONdogrant_fails() RETURNS void LANGUAGE sql SECURITY DEFINERAS
1094-
'GRANT regress_priv_group2 TO regress_priv_user5';
1095-
SELECT dogrant_fails();-- fails: no self-admin in SECURITY DEFINER
1096-
DROPFUNCTION dogrant_fails();
1092+
GRANT regress_priv_group2 TO regress_priv_user5;-- fails: no self-admin
10971093

10981094
SET SESSION AUTHORIZATION regress_priv_user4;
10991095
DROPFUNCTION dogrant_ok();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp