如何查看角色的所有数据库和对象授予?

时间:2016-10-01 20:16:58

标签: postgresql postgresql-9.5

我试图在发布之前审核应用程序的所有权限,并且我希望确保没有角色拥有超出其需要的访问权限。我查看了不同的函数和系统表,但一切都非常零碎。

是否有一个好的查询或方法可以转出特定角色的每个授权?

我正在使用第9.5页。

2 个答案:

答案 0 :(得分:5)

系统目录relacl的列pg_class包含有关权限的所有信息。

public所拥有的架构postgres中的示例数据,其中包含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;

查询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)

评论:

  • coalesce(relacl::text[], format('{%s=arwdDxt/%s}', rolname, rolname)) - relacl中的空表示所有者拥有所有权限;
  • unnest(...) acl - relaclaclitem的数组,是用户的一个数组元素;
  • regexp_split_to_array(acl, '=|/') s - 将aclitem分成:s [1]用户名,s [2]权限;
  • coalesce(nullif(s[1], ''), 'public') as grantee - 空用户名是指public

修改查询以选择单个用户或特定种类的关系或其他模式等...

请阅读文档:

以类似的方式,您可以获取有关在模式(列nspacl in pg_namespace)和数据库(datacl in pg_database)上授予的权限的信息

答案 1 :(得分:1)

relacl列(以及其他类型为aclitem的列)不必解析为文本。 函数aclexplode取消嵌套数组,使其适用于横向连接。结果是使用命名字段进行记录,只需将oid转换为人类可读的名称即可:

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;