Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PostgreSQL 8.4 grant DML privileges on all tables to a role

How do I go about granting DML (SELECT,INSERT,UPDATE,DELETE) on all tables in a schema in PostgreSQL 8.4? I'd also like this grant to persist for new table creation in the future as well.

I've seen solutions for 9.0 but I'm stuck with 8.4 as it ships with Debian stable.

I have tried the following as a baseline but it doesn't work, resulting in the inevitable "access to relation X denied":

GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;

I've dredged through the documentation and I can't seem to find a suitable solution.

like image 207
pointyhat Avatar asked Jul 22 '12 10:07

pointyhat


People also ask

How do I grant access to all tables in a schema Postgres?

The PRIVILEGES key word is optional in PostgreSQL, though it is required by strict SQL. So you can basically use all for a particular schema that all the tables belong to. should do it for you but you need yo specify the schema name. Show activity on this post.

What is grant all privileges in PostgreSQL?

GRANT ALL PRIVILEGES ON DATABASE grants the CREATE , CONNECT , and TEMPORARY privileges on a database to a role (users are properly referred to as roles). None of those privileges actually permits a role to read data from a table; SELECT privilege on the table is required for that.


1 Answers

I'd also like this grant to persist for new table creation in the future as well. [...] I've dredged through the documentation and I can't seem to find a suitable solution.

Because before 9.0 there is none. All you can get is to set the permissions for existing tables. You have to do one GRANT for each table, because before 9.0 there was no "bulk" mode. See the SQL grammer for 8.4 and 9.0:

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [,...] | ALL [ PRIVILEGES ] }
    ON [ TABLE ] tablename [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

and 9.0 here:

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [,...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...]
         | ALL TABLES IN SCHEMA schema_name [, ...] }
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

The new ALL TABLES IN SCHEMA part is the one you are missing.

Also: Setting permissions on the database level as in you question won't help you: You will "only" set the permissions on he database, but not on any "contained" stuff like tables. The relevant section:

GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
    ON DATABASE dbname [, ...]
    TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]

Which means you can only set CREATE, CONNECT and TEMP permissions on the database itself but no SELECT, INSERT etc.


So far for the bad stuff. What you can do are the following things:

  • Reduce the number of permission management by granting rights not to users but to roles. Then add roles to individual users. When a new table is created you only need to adjust one or two roles, but not hundreds of users.

  • Query the system catalogues and create appropriate GRANT commands. Save them into a file and execute that file. This should give you an easier startup.

Such a query might look like this:

select 'GRANT ALL ON ' || table_schema || '.' || table_name ||' to my_group;' 
from information_schema.tables 
where 
    table_type = 'BASE TABLE' and 
    table_schema not in ('pg_catalog', 'information_schema');
like image 72
A.H. Avatar answered Nov 02 '22 23:11

A.H.