Обсуждение: FOR SHARE permissions

Поиск
Список
Период
Сортировка

FOR SHARE permissions

От
David Underhill
Дата:
I have two tables.  One has a foreign key referencing a serial field in the other table.  I've given INSERT privilege to a role other than the owner, but I still can't insert into the table containing the foreign key unless I grant the owner of the table UPDATE privilege on the table containing the referenced field.
I don't quite understand why the owner needs to have UPDATE permission in order for another distinct role (with INSERT privilege) to be able to insert a row in this case.

This is a little confusing, so I've provided a boiled down example of my issue.

createuser -U postgres testowner -DIRS --pwprompt
createdb -U postgres -O testowner testdb
createuser -U postgres testupdater -DIRS --pwprompt

psql -d testdb -U testowner
CREATE TABLE a ( id serial PRIMARY KEY );
CREATE TABLE b ( a_id integer REFERENCES a(id) );
GRANT SELECT,INSERT ON ALL TABLES IN SCHEMA public TO testupdater;
GRANT USAGE,UPDATE ON SEQUENCE a_id_seq TO testupdater;
REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA public FROM testowner;
INSERT INTO a VALUES (DEFAULT);  -- as expected: ERROR:  permission denied for relation a
\q

psql -d testdb -U testupdater
INSERT INTO a VALUES (DEFAULT);
SELECT id FROM a LIMIT 1;  -- selects the first id (1)
INSERT INTO b VALUES (1); -- unexpected error: 
\q

ERROR:  permission denied for relation a
CONTEXT:  SQL statement "SELECT 1 FROM ONLY "public"."a" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x"

However, the above insert works if I give testowner back the UPDATE privilege (GRANT UPDATE ON a TO testowner;).  Why does testowner need UPDATE in this case?

Thanks,

~ David

Re: FOR SHARE permissions

От
Tom Lane
Дата:
David Underhill <dound07@gmail.com> writes:
> I have two tables.  One has a foreign key referencing a serial field in the
> other table.  I've given INSERT privilege to a role other than the owner,
> but I still can't insert into the table containing the foreign key unless I
> grant the *owner* of the table UPDATE privilege on the table containing the
> referenced field.
> I don't quite understand why the *owner* needs to have UPDATE permission in
> order for another distinct role (with INSERT privilege) to be able to insert
> a row in this case.

The owner is the one who established the foreign key reference.  That
reference is no concern of the third-party user who's been given insert
permission on the referencing table.  The design you seem to have in
mind would make management of permissions a lot more complicated, since
instead of just granting insert permission to the third party, you'd
have to think about all the subsidiary permissions that might be needed
to deal with the table's FK linkages.

            regards, tom lane

Re: FOR SHARE permissions

От
David Underhill
Дата:
On Sun, Dec 12, 2010 at 08:11, Tom Lane <tgl@sss.pgh.pa.us> wrote:
David Underhill <dound07@gmail.com> writes:
> I have two tables.  One has a foreign key referencing a serial field in the
> other table.  I've given INSERT privilege to a role other than the owner,
> but I still can't insert into the table containing the foreign key unless I
> grant the *owner* of the table UPDATE privilege on the table containing the
> referenced field.
> I don't quite understand why the *owner* needs to have UPDATE permission in
> order for another distinct role (with INSERT privilege) to be able to insert
> a row in this case.

The owner is the one who established the foreign key reference.  That
reference is no concern of the third-party user who's been given insert
permission on the referencing table.  The design you seem to have in
mind would make management of permissions a lot more complicated, since
instead of just granting insert permission to the third party, you'd
have to think about all the subsidiary permissions that might be needed
to deal with the table's FK linkages.

Thanks Tom.  It still seems strange that the role given insert is only able to insert (in the test case I mentioned) iff the owner role has update privileges.

Anyway, I wanted a role which could just copy info from an external source into the db.  I could have done this with the owner role, but I was trying to do it with the least permissions possible (just in case I dorked up this might help limit the maximum damage the role could do).  Maybe this is a bit overly complicated, as you suggest, and not worth much in the end (i.e., I should just be cautious and use the role as intended ... probably not too hard to verify since it is a script doing the inserting).

This was also nice though as it allowed the owner to revoke its own privileges so that the db was read-only for it.  Perhaps an easier solution is to still revoke the owner's privileges by default, but temporarily re-grant them when it needs to do inserts.

Thanks again for your thoughts.

~ David

Re: FOR SHARE permissions

От
Craig James
Дата:
On 12/11/10 7:47 PM, David Underhill wrote:
> I have two tables.  One has a foreign key referencing a serial
>  field in the other table.  I've given INSERT privilege to a role
>  other than the owner, but I still can't insert into the table
>  containing the foreign key unless I grant the /owner/ of the table
>  UPDATE privilege on the table containing the referenced field.
>
> I don't quite understand why the /owner/ needs to have UPDATE
>  permission in order for another distinct role (with INSERT
>  privilege) to be able to insert a row in this case.

I don't know about the specifics of the Postgres implementation, but this makes sense from a security point of view.

When you insert into second table, you're effectively "locking" the referenced row in the referenced (first) table,
makingit so that the owner of that table can no long delete that row.  You ARE updating that table.  You're not
insertingor deleting data from it, but you are changing what the owner can do to it.  In other words, you're updating
theowner's ability to delete from and update the referenced table. 

Craig