From ec8a0135c3228087761ad3cdba18aebb01c7e17a Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 23 Aug 2012 17:25:10 -0400 Subject: 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 4b2dafcc0b1a579ef5daaa2728223006d1ff98e9, 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. --- src/backend/utils/adt/acl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/backend/utils/adt/acl.c') diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 77322a115f1..1d6ae8b4f3e 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -1230,11 +1230,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; -- cgit v1.2.3