如何在postgresql中查询用户组权限?

时间:2014-06-22 17:57:49

标签: sql postgresql amazon-redshift

所以在postgresql中我可以做类似的事情:

SELECT has_table_privilege('myuser', 'mytable', 'select')

查看myuser是否对mytable具有选择权限。用户组是否有类似的东西?基本上,我希望能够提交查询以查看某个组是否在指定的表上具有某些特权。

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以创建一个简单的函数来查询角色权限;

CREATE FUNCTION role_has_table_privilege(g NAME, tn NAME, pt NAME) 
RETURNS boolean AS 
 'SELECT EXISTS (SELECT 1 FROM information_schema.role_table_grants WHERE (grantee, table_name, privilege_type) IN (($1, $2, $3)));' 
LANGUAGE sql;

它基本上只从information_schema.role_table_grants中选择角色表授权并与参数匹配。角色包括用户和组。

An SQLfiddle to test with

请注意,在这个非常简单的示例中有一些限制。例如,值区分大小写。这意味着权限类型称为INSERT,而不是insert。此外,如果您想包含PUBLIC权限,则必须稍微扩展该功能。

答案 1 :(得分:1)

Joe的观点看起来像是How do I view grants on Redshift。请注意这个用于查找丢失权限的其他有用查询,在此示例中,我想将select_group的读取权限授予没有权限的对象:

select 'grant select on '||namespace||'.'||item||' to group select_group;' from 
(
SELECT 
 use.usename as subject, 
 nsp.nspname as namespace, 
 c.relname as item, 
 c.relkind as type, 
 use2.usename as owner, 
 c.relacl 
FROM 
pg_user use 
cross join pg_class c 
left join pg_namespace nsp on (c.relnamespace = nsp.oid) 
left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE 
c.relowner = use.usesysid  
and  nsp.nspname  NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
and ((array_to_string(relacl, '|') not like '%select_group%' or relacl is null)
    or 
   (array_to_string(relacl, '|') like '%select_group%' and CHARINDEX('r', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), 'select_group', 2 ) , '/', 1 ) ) = 0 )
        )
and c.relkind   <> 'i'
ORDER BY  subject,   namespace,   item 
)

答案 2 :(得分:0)

这是关于Redshift还是Postgres的问题?如果它是Redshift,那么Joachim Isaksson的答案将无效,因为Redshift不支持函数。

我使用以下视图查看表权限。它基于Redshift论坛的内容,但不幸的是我没有记录来源。

/* List of all Grants currently in place. */
CREATE VIEW admin.vw_table_grants
AS
SELECT   relacl
        ,'GRANT ' 
        || SUBSTRING(
           CASE WHEN CHARINDEX('r', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', SELECT'     ELSE '' END
        || CASE WHEN CHARINDEX('w', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', UPDATE'     ELSE '' END
        || CASE WHEN CHARINDEX('a', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', INSERT'     ELSE '' END
        || CASE WHEN CHARINDEX('d', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', DELETE'     ELSE '' END
        || CASE WHEN CHARINDEX('R', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', RULE'       ELSE '' END
        || CASE WHEN CHARINDEX('x', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', REFERENCES' ELSE '' END
        || CASE WHEN CHARINDEX('t', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', TRIGGER'    ELSE '' END
        || CASE WHEN CHARINDEX('X', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', EXECUTE'    ELSE '' END
        || CASE WHEN CHARINDEX('U', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', USAGE'      ELSE '' END
        || CASE WHEN CHARINDEX('C', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', CREATE'     ELSE '' END
        || CASE WHEN CHARINDEX('T', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', TEMPORARY'  ELSE '' END
           , 3,10000)
        || ' ON '|| namespace ||'.'|| item ||' TO '|| pu.groname ||' ;' AS grantsql
FROM    (SELECT      use.usename AS subject
                    ,nsp.nspname AS namespace
                    ,cls.relname AS item
                    ,cls.relkind AS type
                    ,use2.usename AS owner
                    ,cls.relacl
        FROM        pg_user     use 
        CROSS JOIN  pg_class    cls
        LEFT JOIN   pg_namespace nsp 
        ON          cls.relnamespace = nsp.oid 
        LEFT JOIN   pg_user      use2 
        ON          cls.relowner = use2.usesysid
        WHERE       cls.relowner = use.usesysid
        AND         nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
        ORDER BY     subject
                    ,namespace
                    ,item ) 
JOIN    pg_group pu ON array_to_string(relacl, '|') LIKE '%'|| pu.groname ||'%' 
WHERE   relacl IS NOT NULL
ORDER BY 2