How can I review all database and object grants for a role?

笑着哭i 提交于 2019-12-07 18:51:53

问题


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 in relacl means that the owner has all privileges;
  • unnest(...) acl - relacl is an array of aclitem, one array element for a user;
  • regexp_split_to_array(acl, '=|/') s - split aclitem into: s[1] username, s[2] privileges;
  • coalesce(nullif(s[1], ''), 'public') as grantee - empty username means public.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!