Robert Haas:
Fairly obviously, my thinking here is biased by having written the
patch to allow restricting SET ROLE. If alice can neither inherit
bob's privileges nor SET ROLE bob, she had better not be able to
create objects owned by bob, because otherwise she can make a table,
add an expression index that calls a user-defined function, do stuff
until it needs to be autovacuumed, and then give it to bob, and boom,
exploit. But that doesn't mean that the is_member_of_role() tests here
have to be changed to has_privs_of_role(). They could be changed to
has_privs_of_role() || member_can_set_role(). And if the consensus is
to do it that way, I'm OK with that.
I'm just a little unconvinced that it's actually the best route. I
think that logic of the form "well Alice could just SET ROLE and do it
anyway" is weak -- and not only because of the patch to allow
restricting SET ROLE, but because AFAICT there is no point to the
INHERIT option in the first place unless it is to force you to issue
SET ROLE. That is literally the only thing it does. If we're going to
have weird exceptions where you don't have to SET ROLE after all, why
even have INHERIT in the first place?
I think to change the owner of an object from role A to role B, you just
need a different "privilege" on that role B to "use" the role that way,
which is distinct from INHERIT or SET ROLE "privileges".
When you are allowed to INHERIT a role, you are allowed to use the
GRANTs that have been given to this role. When you are allowed to SET
ROLE, then you are allowed to switch into this role. You could think of
another "privilege", USAGE on a role, which would allow you to "use"
this role as a target in a statement to change the owner of an object.
To change the owner for an object from role A to role B, you need:
- the privilege to ALTER the object, which is implied when you are A
- the privilege to "use" role B as a target
So basically the privilege to use role B as the new owner, is a
privilege you have **on** the role object B, while the privilege to
change the owner of an object is something you have **through** your
membership in role A.
Up to v15, there were no separate privileges for this. You were either a
member of a role or you were not. Now with INHERIT and maybe SET ROLE
privileges/grant options, we can do two things:
- Keep the ability to use a role as a target in those statements as the
most basic privilege on a role, that is implied by membership in that
role and can't be taken away (currently the case), or
- invent a new privilege or grant option to allow changing that.
But mixing this with either INHERIT or SET ROLE doesn't make sense, imho.
Best
Wolfgang