Re: Bogus permissions display in 7.4 - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Bogus permissions display in 7.4
Date
Msg-id 22615.1084545322@sss.pgh.pa.us
Whole thread Raw
In response to Re: Bogus permissions display in 7.4  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Bogus permissions display in 7.4
Re: Bogus permissions display in 7.4
Re: Bogus permissions display in 7.4
List pgsql-hackers
I wrote:
> I've been thinking more about this, and realizing that there are more
> implications than I first thought.  Specifically, we have to consider
> how any hacking we do here will affect recursive_revoke().

After further consideration I think that at least part of the problem
here is that recursive_revoke is wrong.  Or you could say that our ACL
datastructure is inadequate.  Consider the following situation:

1. A, the owner of some object, grants rights with grant option to  both B and C.

2. B and C independently re-grant those rights with grant option to D.

3. D grants the rights to E.

4. A revokes the rights from B.

recursive_revoke will revoke B's grant to D, while not touching C's
grant to D, which is correct.  However it will then recurse to revoke
D's grant to E.  I claim this is wrong because D still has the rights
via C.

You could imagine extending the ACL datastructure to keep track of where
a grantor's rights came from, but this would be horribly messy, and
I'm not sure it's what we want anyway.  (For instance, we'd really need
to extend GRANT to allow D to say whether he was granting to E on the
basis of B's grant or C's grant.  Yech.)

I think the correct solution involves having recursive_revoke look to
see if D still has the rights from somewhere else before it goes off to
recursively revoke D's grants.  This makes it correctly implement the
notion that one always has the union of the rights granted by anyone.

Now having said that, does it improve the situations I was worried about
last night?  It does, but we really need to fix things so that the ACL
representation explicitly shows the owner.  Here's what I suggest:

1. The first entry of an ACL list should always be a grant of all
relevant grant options for the object type from "the system" (AclId 0,
let's say) to the object owner.  This entry represents the semantics
we've agreed to that an owner has nonrevocable grant options.

2. In a default ACL list there will also be an entry that grants all
regular privileges (not grant options) to the owner, from the owner.
This can be considered to be authorized by the system-granted grant
options.  Because it's set up this way, the owner can revoke his own
regular privileges --- make a table read-only, for instance.

3. It will not matter whether the owner grants himself grant options
(or revokes them later).  They'll be redundant with the system grant
and therefore have no effect on behavior.  Note we need the aforesaid
fix to recursive_revoke to make that true.  Also note that the system
grant *must not* grant regular privileges, or the owner couldn't make
his table read-only to himself.

4. I think that the system ACL entry should be "hidden" and not
displayed by ACL-list printing.  I'm not quite sure yet how to make
that happen.  It would be nicer if the owner ID could be passed to
recursive_revoke out-of-band, instead of being represented inside the
ACL list, but I don't see how to do that for all its callers.

Thoughts?
        regards, tom lane


pgsql-hackers by date:

Previous
From: Gaetano Mendola
Date:
Subject: invalid type internal size -1
Next
From: Tom Lane
Date:
Subject: Re: invalid type internal size -1