Skip to content

Commit ec8a013

Browse files
committed
Fix cascading privilege revoke to notice when privileges are still held.
If we revoke a grant option from some role X, but X still holds the option via another grant, we should not recursively revoke the privilege from role(s) Y that X had granted it to. This was supposedly fixed as one aspect of commit 4b2dafc, but I must not have tested it, because in fact that code never worked: it forgot to shift the grant-option bits back over when masking the bits being revoked. Per bug #6728 from Daniel German. Back-patch to all active branches, since this has been wrong since 8.0.
1 parent 8b6b50a commit ec8a013

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

src/backend/utils/adt/acl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,11 +1230,11 @@ recursive_revoke(Acl *acl,
12301230
if (grantee == ownerId)
12311231
return acl;
12321232

1233-
/* The grantee might still have the privileges via another grantor */
1233+
/* The grantee might still have some grant options via another grantor */
12341234
still_has = aclmask(acl, grantee, ownerId,
12351235
ACL_GRANT_OPTION_FOR(revoke_privs),
12361236
ACLMASK_ALL);
1237-
revoke_privs &= ~still_has;
1237+
revoke_privs &= ~ACL_OPTION_TO_PRIVS(still_has);
12381238
if (revoke_privs == ACL_NO_RIGHTS)
12391239
return acl;
12401240

src/test/regress/expected/privileges.out

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,56 @@ SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE')
13311331
SET client_min_messages TO 'warning';
13321332
DROP SCHEMA testns CASCADE;
13331333
RESET client_min_messages;
1334+
-- test that dependent privileges are revoked (or not) properly
1335+
\c -
1336+
set session role regressuser1;
1337+
create table dep_priv_test (a int);
1338+
grant select on dep_priv_test to regressuser2 with grant option;
1339+
grant select on dep_priv_test to regressuser3 with grant option;
1340+
set session role regressuser2;
1341+
grant select on dep_priv_test to regressuser4 with grant option;
1342+
set session role regressuser3;
1343+
grant select on dep_priv_test to regressuser4 with grant option;
1344+
set session role regressuser4;
1345+
grant select on dep_priv_test to regressuser5;
1346+
\dp dep_priv_test
1347+
Access privileges
1348+
Schema | Name | Type | Access privileges | Column access privileges
1349+
--------+---------------+-------+-----------------------------------+--------------------------
1350+
public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+|
1351+
| | | regressuser2=r*/regressuser1 +|
1352+
| | | regressuser3=r*/regressuser1 +|
1353+
| | | regressuser4=r*/regressuser2 +|
1354+
| | | regressuser4=r*/regressuser3 +|
1355+
| | | regressuser5=r/regressuser4 |
1356+
(1 row)
1357+
1358+
set session role regressuser2;
1359+
revoke select on dep_priv_test from regressuser4 cascade;
1360+
\dp dep_priv_test
1361+
Access privileges
1362+
Schema | Name | Type | Access privileges | Column access privileges
1363+
--------+---------------+-------+-----------------------------------+--------------------------
1364+
public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+|
1365+
| | | regressuser2=r*/regressuser1 +|
1366+
| | | regressuser3=r*/regressuser1 +|
1367+
| | | regressuser4=r*/regressuser3 +|
1368+
| | | regressuser5=r/regressuser4 |
1369+
(1 row)
1370+
1371+
set session role regressuser3;
1372+
revoke select on dep_priv_test from regressuser4 cascade;
1373+
\dp dep_priv_test
1374+
Access privileges
1375+
Schema | Name | Type | Access privileges | Column access privileges
1376+
--------+---------------+-------+-----------------------------------+--------------------------
1377+
public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+|
1378+
| | | regressuser2=r*/regressuser1 +|
1379+
| | | regressuser3=r*/regressuser1 |
1380+
(1 row)
1381+
1382+
set session role regressuser1;
1383+
drop table dep_priv_test;
13341384
-- clean up
13351385
\c
13361386
drop sequence x_seq;

src/test/regress/sql/privileges.sql

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,30 @@ DROP SCHEMA testns CASCADE;
795795
RESET client_min_messages;
796796

797797

798+
-- test that dependent privileges are revoked (or not) properly
799+
\c -
800+
801+
set session role regressuser1;
802+
create table dep_priv_test (a int);
803+
grant select on dep_priv_test to regressuser2 with grant option;
804+
grant select on dep_priv_test to regressuser3 with grant option;
805+
set session role regressuser2;
806+
grant select on dep_priv_test to regressuser4 with grant option;
807+
set session role regressuser3;
808+
grant select on dep_priv_test to regressuser4 with grant option;
809+
set session role regressuser4;
810+
grant select on dep_priv_test to regressuser5;
811+
\dp dep_priv_test
812+
set session role regressuser2;
813+
revoke select on dep_priv_test from regressuser4 cascade;
814+
\dp dep_priv_test
815+
set session role regressuser3;
816+
revoke select on dep_priv_test from regressuser4 cascade;
817+
\dp dep_priv_test
818+
set session role regressuser1;
819+
drop table dep_priv_test;
820+
821+
798822
-- clean up
799823

800824
\c

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