Re: GRANT/roles problem: grant is shown as from login role - Mailing list pgsql-hackers

From Tom Lane
Subject Re: GRANT/roles problem: grant is shown as from login role
Date
Msg-id 6208.1128709370@sss.pgh.pa.us
Whole thread Raw
In response to Re: GRANT/roles problem: grant is shown as from login role  (Stephen Frost <sfrost@snowman.net>)
Responses Re: GRANT/roles problem: grant is shown as from login role
List pgsql-hackers
[ finally got back to considering this issue ]

Stephen Frost <sfrost@snowman.net> writes:
> Tom Lane (tgl@sss.pgh.pa.us) wrote:
>> This is looking a bit messy.  Maybe for GRANT/REVOKE, we have to insist
>> that privileges do not inherit, you have to actually be SET ROLE'd to
>> whatever role has the authority to do the grant.  I haven't figured out
>> how the SQL spec avoids this problem, considering that they do have the
>> concept of rights inheriting for roles.

> There is 'revoke update on t1 from u3 granted by u2;' syntax in the 
> SQL 2003 specification. It doesn't look like we support that syntax 
> (looking at 8.0.3 anyway)- would that solve the problem if we did?

> From your example, u1 couldn't revoke it because u1 couldn't become u2,
> and we don't support syntax for saying "revoke this priviledge which was
> granted by someone else", but the SQL spec has that syntax and if we did
> then I think we'd allow the owner to use it.  

> Does that help?

Not a lot.  After further consideration, there's a related problem,
which is brought on by the fact that we store privilege information
per-database rather than globally: what happens when a user's membership
in a role is revoked?  Take the same scenario I gave before:

regression=# create user u1;
CREATE ROLE
regression=# create user u2;
CREATE ROLE
regression=# create user u3;
CREATE ROLE
regression=# grant u1 to u2;
GRANT ROLE
regression=# \c - u1
You are now connected as new user "u1".
regression=> create table t1(f1 int);
CREATE TABLE
regression=> \c - u2
You are now connected as new user "u2".
regression=> grant update on t1 to u3;
GRANT
regression=> \z t1  Access privileges for database "regression"Schema | Name | Type  |    Access privileges
--------+------+-------+-------------------------public | t1   | table | {u1=arwdRxt/u1,u3=w/u2}
(1 row)

Suppose now that we REVOKE u2's membership in u1 --- what should happen
to the privilege granted to u3?  There are two plausible theories,
I think:

1. The privilege granted to u3 is dependent on u2's membership in u1  and so it should be revoked too.

2. u2 should have been considered to act in her capacity as member of  u1, therefore the privilege should remain; it is
upto some other  member of u1 to revoke u3's privilege if wanted.
 

The SQL99 spec is exceedingly convoluted but I think it probably wants
interpretation #1 (not totally sure about it though).

However, we can't implement #1 with the present data structure --- if
the REVOKE u1 FROM u2 is done while connected to a different database
than t1 is in, we can't even see that there's an issue, much less clean
it up.  The only way to support interpretation #1 would be, every time
we *use* an ACL entry, to go and check that the grantor of the privilege
still has it.  Given that the same rule would apply to whatever ACL says
the grantor has it, this would be a double recursion with unbelievably
bad performance (did you study Ackermann's function in school?).  And it
still doesn't really do the right thing: consider what happens if u2's
membership is re-granted.  The subsidiary privileges would come back to
life, which they should not under theory #1.

AFAICS, to implement #1 we'd have to switch over to a global data
structure, ie, all privilege descriptors of all databases carried in a
single shared catalog.  This strikes me as a pretty bad idea from both
performance and security viewpoints.

So I think we don't have much choice but to implement theory #2; which
is essentially the same thing I said earlier, ie, ACLs have to record
the grantor of a privilege as being the role actually holding the grant
option, not the role-member issuing the GRANT.

I think it's probably OK to still allow role-members to issue GRANTs,
with the understanding that if you've inherited a grant option via more
than one path, it's indeterminate which source role will get logged as
the grantor.  This seems like it would be a seldom-seen corner case, so
I'm not too concerned about it.  (We'll tell people that if they care,
they should SET ROLE to the specific role they want recorded as the
grantor.  The code's search can be set up to guarantee that the current
role is recorded as the grantor if suitable.)

Comments?
        regards, tom lane


pgsql-hackers by date:

Previous
From: "Magnus Hagander"
Date:
Subject: Re: Vote needed: revert beta2 changes or not?
Next
From: Tom Lane
Date:
Subject: Re: Vote needed: revert beta2 changes or not?