查明用户是不是有权在 PostgreSQL 中选择/更新/...一个表/函数/...
Posted
技术标签:
【中文标题】查明用户是不是有权在 PostgreSQL 中选择/更新/...一个表/函数/...【英文标题】:Find out if user got permission to select/update/... a table/function/... in PostgreSQL查明用户是否有权在 PostgreSQL 中选择/更新/...一个表/函数/... 【发布时间】:2009-06-03 19:49:48 【问题描述】:在 PostgreSQL 中确定用户是否对某个类(例如表或函数)具有某种权限(例如选择或执行)的推荐方法是什么?
目前我得到了类似的东西
aclcontains(
someColumnWithAclitemArray,
makeaclitem(userOid,grantorOid,someRight,false))
但这很糟糕,因为我必须检查每个可能的grantorOid
以及用户可以属于的每个userOid
。
在相关说明中:您可以测试哪些可能的权利? 我没有找到任何文档,但我猜是阅读源代码:
INSERT
SELECT
UPDATE
DELETE
TRUNCATE
REFERENCES
TRIGGER
EXECUTE
USAGE
CREATE
CONNECT
似乎也有一个CREATE TEMP
对,但我无法找出在makeaclitem
-函数中使用的正确文本。
【问题讨论】:
【参考方案1】:我发现一个更好的方法(我似乎记得这是从 psql 内置的一些查询中获取的,或者可能是 information_schema 视图)是使用 has_*_privilege
函数,并将它们简单地应用于一组用户和对象的所有可能组合。这也将考虑通过某些组角色访问对象。
例如,这将显示哪些用户对非目录表和视图具有哪些访问权限:
select usename, nspname || '.' || relname as relation,
case relkind when 'r' then 'TABLE' when 'v' then 'VIEW' end as relation_type,
priv
from pg_class join pg_namespace on pg_namespace.oid = pg_class.relnamespace,
pg_user,
(values('SELECT', 1),('INSERT', 2),('UPDATE', 3),('DELETE', 4)) privs(priv, privorder)
where relkind in ('r', 'v')
and has_table_privilege(pg_user.usesysid, pg_class.oid, priv)
and not (nspname ~ '^pg_' or nspname = 'information_schema')
order by 2, 1, 3, privorder;
可能的权限在http://www.postgresql.org/docs/current/static/functions-info.html#FUNCTIONS-INFO-ACCESS-TABLEhas_*_privilege
函数的描述中有详细说明。
'CREATE TEMP' 是数据库级权限:它允许用户使用pg_temp_*
模式。可以用has_database_privilege(useroid, datoid, 'TEMP')
进行测试。
【讨论】:
【参考方案2】:查看"Access Privilege Inquiry Functions" 和"GRANT" 参考页面。
【讨论】:
【参考方案3】:因为 Redshift 在 INSERT INTO
查询中支持 values()
only,所以下面的查询可以与明显不太好的 union all select
一起使用。
select usename, nspname || '.' || relname as relation,
case relkind when 'r' then 'table' when 'v' then 'view' end as relation_type,
priv
from pg_class join pg_namespace on pg_namespace.oid = pg_class.relnamespace,
pg_user,
(select 'select' as priv,1 as privorder union all select 'insert',2 union all select 'update',3 union all select 'delete',4)
where relkind in ('r', 'v')
and has_table_privilege(pg_user.usesysid, pg_class.oid, priv)
and not (nspname ~ '^pg_' or nspname = 'information_schema')
order by 2, 1, 3, privorder;
编辑:
另外,我意识到,在我们的 db Dataiku 中创建的表中可以包含大写字母,因此,如果发生table not exist
错误,您应该使用lower()
函数
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。以上是关于查明用户是不是有权在 PostgreSQL 中选择/更新/...一个表/函数/...的主要内容,如果未能解决你的问题,请参考以下文章