11

确定用户是否在 PostgreSQL 中的某个类(例如表或函数)上获得某种权限(例如选择或执行)的推荐方法是什么?

此刻我得到了类似的东西

aclcontains(
    someColumnWithAclitemArray,
    makeaclitem(userOid,grantorOid,someRight,false))

但这很糟糕,因为我必须检查所有grantorOid可能的情况以及userOid用户可以属于的每一个。

在相关说明中:您可以测试哪些可能的权利?我没有找到任何文档,但我猜想阅读源代码:

INSERT
SELECT
UPDATE
DELETE
TRUNCATE
REFERENCES
TRIGGER
EXECUTE
USAGE
CREATE
CONNECT

似乎也有一个CREATE TEMP权利,但我无法弄清楚在makeaclitem-function 中使用的正确文本。

4

3 回答 3

18

我发现一个更好的方法(我似乎记得这是从 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').

于 2009-06-03T20:59:57.743 回答
6

查看“访问权限查询功能”以及“GRANT”参考页面。

于 2009-06-03T21:00:14.527 回答
-1

因为 Redshiftvalues() INSERT INTO查询中支持,所以下面的查询可以与明显不那么好的一起使用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;

编辑:另外,我意识到,在我们的数据库 Dataiku 中创建的表中可以包含大写字母,因此,如果table not exist发生错误,您应该使用该lower()函数

于 2021-09-13T20:45:29.733 回答