mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
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 4b2dafcc0b
, 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.
This commit is contained in:
parent
d17cf76bed
commit
bf3b85c6be
@ -1163,11 +1163,11 @@ recursive_revoke(Acl *acl,
|
||||
if (grantee == ownerId)
|
||||
return acl;
|
||||
|
||||
/* The grantee might still have the privileges via another grantor */
|
||||
/* The grantee might still have some grant options via another grantor */
|
||||
still_has = aclmask(acl, grantee, ownerId,
|
||||
ACL_GRANT_OPTION_FOR(revoke_privs),
|
||||
ACLMASK_ALL);
|
||||
revoke_privs &= ~still_has;
|
||||
revoke_privs &= ~ACL_OPTION_TO_PRIVS(still_has);
|
||||
if (revoke_privs == ACL_NO_RIGHTS)
|
||||
return acl;
|
||||
|
||||
|
@ -1216,6 +1216,56 @@ SELECT has_function_privilege('regressuser1', 'testns.testfunc(int)', 'EXECUTE')
|
||||
SET client_min_messages TO 'warning';
|
||||
DROP SCHEMA testns CASCADE;
|
||||
RESET client_min_messages;
|
||||
-- test that dependent privileges are revoked (or not) properly
|
||||
\c -
|
||||
set session role regressuser1;
|
||||
create table dep_priv_test (a int);
|
||||
grant select on dep_priv_test to regressuser2 with grant option;
|
||||
grant select on dep_priv_test to regressuser3 with grant option;
|
||||
set session role regressuser2;
|
||||
grant select on dep_priv_test to regressuser4 with grant option;
|
||||
set session role regressuser3;
|
||||
grant select on dep_priv_test to regressuser4 with grant option;
|
||||
set session role regressuser4;
|
||||
grant select on dep_priv_test to regressuser5;
|
||||
\dp dep_priv_test
|
||||
Access privileges
|
||||
Schema | Name | Type | Access privileges | Column access privileges
|
||||
--------+---------------+-------+-----------------------------------+--------------------------
|
||||
public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+|
|
||||
| | | regressuser2=r*/regressuser1 +|
|
||||
| | | regressuser3=r*/regressuser1 +|
|
||||
| | | regressuser4=r*/regressuser2 +|
|
||||
| | | regressuser4=r*/regressuser3 +|
|
||||
| | | regressuser5=r/regressuser4 |
|
||||
(1 row)
|
||||
|
||||
set session role regressuser2;
|
||||
revoke select on dep_priv_test from regressuser4 cascade;
|
||||
\dp dep_priv_test
|
||||
Access privileges
|
||||
Schema | Name | Type | Access privileges | Column access privileges
|
||||
--------+---------------+-------+-----------------------------------+--------------------------
|
||||
public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+|
|
||||
| | | regressuser2=r*/regressuser1 +|
|
||||
| | | regressuser3=r*/regressuser1 +|
|
||||
| | | regressuser4=r*/regressuser3 +|
|
||||
| | | regressuser5=r/regressuser4 |
|
||||
(1 row)
|
||||
|
||||
set session role regressuser3;
|
||||
revoke select on dep_priv_test from regressuser4 cascade;
|
||||
\dp dep_priv_test
|
||||
Access privileges
|
||||
Schema | Name | Type | Access privileges | Column access privileges
|
||||
--------+---------------+-------+-----------------------------------+--------------------------
|
||||
public | dep_priv_test | table | regressuser1=arwdDxt/regressuser1+|
|
||||
| | | regressuser2=r*/regressuser1 +|
|
||||
| | | regressuser3=r*/regressuser1 |
|
||||
(1 row)
|
||||
|
||||
set session role regressuser1;
|
||||
drop table dep_priv_test;
|
||||
-- clean up
|
||||
\c
|
||||
drop sequence x_seq;
|
||||
|
@ -671,6 +671,30 @@ DROP SCHEMA testns CASCADE;
|
||||
RESET client_min_messages;
|
||||
|
||||
|
||||
-- test that dependent privileges are revoked (or not) properly
|
||||
\c -
|
||||
|
||||
set session role regressuser1;
|
||||
create table dep_priv_test (a int);
|
||||
grant select on dep_priv_test to regressuser2 with grant option;
|
||||
grant select on dep_priv_test to regressuser3 with grant option;
|
||||
set session role regressuser2;
|
||||
grant select on dep_priv_test to regressuser4 with grant option;
|
||||
set session role regressuser3;
|
||||
grant select on dep_priv_test to regressuser4 with grant option;
|
||||
set session role regressuser4;
|
||||
grant select on dep_priv_test to regressuser5;
|
||||
\dp dep_priv_test
|
||||
set session role regressuser2;
|
||||
revoke select on dep_priv_test from regressuser4 cascade;
|
||||
\dp dep_priv_test
|
||||
set session role regressuser3;
|
||||
revoke select on dep_priv_test from regressuser4 cascade;
|
||||
\dp dep_priv_test
|
||||
set session role regressuser1;
|
||||
drop table dep_priv_test;
|
||||
|
||||
|
||||
-- clean up
|
||||
|
||||
\c
|
||||
|
Loading…
Reference in New Issue
Block a user