Thread: Fix for OWNER TO breaking ACLs

Fix for OWNER TO breaking ACLs

From
Christopher Kings-Lynne
Date:
Attached is a patch that fixes the owner change command on objects that
have privileges.

It probably needs a once over review since it involves a decent amount
of pointer arithmetic.

Note that languages don't have owners, and hence don't need fixing.

The owner change acl support is as follows:

1. If the acl is currently null, then don't do anything with the acl

2. If it is non null, then call aclnewowner() to get a new acl

3. aclnewowner() first looks for a grantee that is the new owner already
and remembers this item

4. A new acl is generated as a copy of the old acl, exlcuding the item
above if it exists.  During the copy, any grantors or grantees in the
new acl that refer to the old owner are changed to refer to the new owner.

5. The excluded acl item's rights (if it existed) are merged with those
of the old owner and become the new owner's rights.

Chris


Attachment

Re: Fix for OWNER TO breaking ACLs

From
Tom Lane
Date:
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:
> Attached is a patch that fixes the owner change command on objects that
> have privileges.

Applied with revisions.  Just FYI ---

* The aclnewowner code wasn't really right at all.  It was changing
ai_grantee without checking whether that value was a UID, GID, or WORLD;
and it was not adequately handling the problem of merging duplicate
entries afterwards.  (You have to think about entries with the new owner
as grantor as well as such entries with grantee; and even considering
only the grantee case, it's wrong to suppose there can be only one.)
I replaced the logic with a general-purpose search for duplicate
entries, which might be overkill but it will reliably get the right
answer.

* You had consistently changed the simple_heap_update calls to do the
wrong thing.  (I'm surprised it didn't blow up on you in your testing.)
In a sequence like

        newtuple = heap_modifytuple(tup, rel, repl_val, repl_null, repl_repl);

        simple_heap_update(rel, &newtuple->t_self, newtuple);
        CatalogUpdateIndexes(rel, newtuple);

the second parameter to simple_heap_update *must* be newtuple->t_self
not tup->t_self.  The reason is that simple_heap_update stores the new
physical location of the updated tuple back into that parameter, and
then the CatalogUpdateIndexes call relies on newtuple->t_self to
generate new index entries.  The way you had it coded, it was generating
new index entries pointing at the old version of the tuple ...

            regards, tom lane

Re: Fix for OWNER TO breaking ACLs

From
Christopher Kings-Lynne
Date:
> * You had consistently changed the simple_heap_update calls to do the
> wrong thing.  (I'm surprised it didn't blow up on you in your testing.)
> In a sequence like
>
>         newtuple = heap_modifytuple(tup, rel, repl_val, repl_null, repl_repl);
>
>         simple_heap_update(rel, &newtuple->t_self, newtuple);
>         CatalogUpdateIndexes(rel, newtuple);
>
> the second parameter to simple_heap_update *must* be newtuple->t_self
> not tup->t_self.  The reason is that simple_heap_update stores the new
> physical location of the updated tuple back into that parameter, and
> then the CatalogUpdateIndexes call relies on newtuple->t_self to
> generate new index entries.  The way you had it coded, it was generating
> new index entries pointing at the old version of the tuple ...

Strange.  I guess I must have been testing with a database that had
short enough system catalogs that the indexes were never used?

Chris


Re: Fix for OWNER TO breaking ACLs

From
Tom Lane
Date:
Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:
>> The way you had it coded, it was generating
>> new index entries pointing at the old version of the tuple ...

> Strange.  I guess I must have been testing with a database that had
> short enough system catalogs that the indexes were never used?

Could be, especially if you were using client-side queries to check the
result.  I think most of the system's internal catalog fetches are
hard-wired to use indexes except under the most dire circumstances
(mainly, a standalone backend with -P).  But a client-issued query
would do whatever the planner thought best.

            regards, tom lane