查明用户是不是有权在 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 中选择/更新/...一个表/函数/...的主要内容,如果未能解决你的问题,请参考以下文章

查明输入文本是不是用于冠状病毒

PostgreSQL 错误的所有权

Snowflake 中是不是有办法允许用户在程序上获取 ddl 但没有使用或所有权权限?

查明是不是使用了资源

postgresql 权限详解

(LINX-IPC 协议)如何查明具有 PID 的进程是不是在 C++ 中运行?