问题
I am trying to audit all of the permissions for an application before release and I want to ensure no role has more access than it needs. I have looked at the different functions and system tables, but everything is very piecemeal.
Is there a good query or method to be able to dump out every grant a particular role has?
I am using pg 9.5.
回答1:
The column relacl of the system catalog pg_class contains all informations on privileges.
Example data in schema public owned by postgres with grants to newuser:
create table test(id int);
create view test_view as select * from test;
grant select, insert, update on test to newuser;
grant select on test_view to newuser;
Querying the pg_class:
select
relname,
relkind,
coalesce(nullif(s[1], ''), 'public') as grantee,
s[2] as privileges
from
pg_class c
join pg_namespace n on n.oid = relnamespace
join pg_roles r on r.oid = relowner,
unnest(coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)::text[])) acl,
regexp_split_to_array(acl, '=|/') s
where nspname = 'public'
and relname like 'test%';
relname | relkind | grantee | privileges
-----------+---------+----------+------------
test | r | postgres | arwdDxt <- owner postgres has all privileges on the table
test | r | newuser | arw <- newuser has append/read/write privileges
test_view | v | postgres | arwdDxt <- owner postgres has all privileges on the view
test_view | v | newuser | r <- newuser has read privilege
(4 rows)
Comments:
coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname))- Null inrelaclmeans that the owner has all privileges;unnest(...) acl-relaclis an array ofaclitem, one array element for a user;regexp_split_to_array(acl, '=|/') s- splitacliteminto: s[1] username, s[2] privileges;coalesce(nullif(s[1], ''), 'public') as grantee- empty username meanspublic.
Modify the query to select individual user or specific kind of relation or another schemas, etc...
Read in the documentation:
- The catalog pg_class,
- GRANT with the description of acl system.
In a similar way you can get information about privileges granted on schemas (the column nspacl in pg_namespace) and databases (datacl in pg_database)
回答2:
The relacl column (and others of type aclitem) doesn't have to be parsed as text.
The function aclexplode unnests array, which makes it suitable for lateral join. Result is record with well named fields, just convert oid to human-readable name:
select c.*, n.nspname,
acl.grantor, acl.grantee,
pg_catalog.pg_get_userbyid(acl.grantor), pg_catalog.pg_get_userbyid(acl.grantee),
acl.privilege_type, acl.is_grantable
from pg_catalog.pg_class c
join pg_catalog.pg_namespace n on n.oid = c.relnamespace,
lateral aclexplode(c.relacl) acl;
来源:https://stackoverflow.com/questions/39811058/how-can-i-review-all-database-and-object-grants-for-a-role