我试图在发布之前审核应用程序的所有权限,并且我希望确保没有角色具有超出其需要的访问权限。我查看了不同的函数和系统表,但一切都非常零碎。
是否有一个好的查询或方法能够转出特定角色的每个授权?
我正在使用第9.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
中的Null意味着拥有者拥有所有特权;unnest(...) acl
- relacl
是一个aclitem
数组,一个用户的数组元素;regexp_split_to_array(acl, '=|/') s
- 将aclitem
分成:s [1]用户名,s [2]特权;coalesce(nullif(s[1], ''), 'public') as grantee
- 空用户名是指public
。修改查询以选择单个用户或特定种类的关系或其他模式等...
阅读文档:
pg_class
,GRANT
与acl系统的描述。以类似的方式,您可以获取有关在模式(列nspacl
in pg_namespace
)和数据库(datacl
in pg_database
)上授予的权限的信息
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;