如何枚举PostgreSQL中所有用户的所有已启用角色?

时间:2014-03-11 08:00:39

标签: postgresql

如果要检查用户有权访问的角色,PostgreSQL中没有简单的方法。在information_schema中有关系enabled_rolesapplicable roles,但这些只提供current_user的权限。那么如何为任何用户访问相同的信息?

2 个答案:

答案 0 :(得分:3)

诀窍是对系统目录关系pg_rolespg_auth_members进行递归查询:

WITH RECURSIVE membership_tree(grpid, userid) AS (
    -- Get all roles and list them as their own group as well
    SELECT pg_roles.oid, pg_roles.oid
    FROM pg_roles
  UNION ALL
    -- Now add all group membership
    SELECT m_1.roleid, t_1.userid
    FROM pg_auth_members m_1, membership_tree t_1
    WHERE m_1.member = t_1.grpid
)
SELECT DISTINCT t.userid, r.rolname AS usrname, t.grpid, m.rolname AS grpname
FROM membership_tree t, pg_roles r, pg_roles m
WHERE t.grpid = m.oid AND t.userid = r.oid
ORDER BY r.rolname, m.rolname;

这给出了系统中具有所有继承角色成员资格的所有用户的视图。将此包装在视图中以使此实用程序始终方便。

干杯, 帕特里克

答案 1 :(得分:0)

这对我非常有用,因为我一直在寻找此类信息。修改上面的工作以包含一个跟踪继承的级别

WITH RECURSIVE membership_tree(grpid, userid, lvl) AS (
-- Get all roles and list them as their own group as well
SELECT 
    pg_roles.oid
    , pg_roles.oid
    , 0
FROM
    pg_roles

UNION ALL

-- Now add all group membership
SELECT 
    m_1.roleid
    , t_1.userid
    , lvl + 1
FROM
    pg_auth_members m_1
INNER JOIN
    membership_tree t_1 
ON
    m_1.member = t_1.grpid
)
SELECT DISTINCT
    t.userid
    , r.rolname AS usrname
    , t.grpid
    , m.rolname AS grpname
    , t.lvl
FROM
    membership_tree t
INNER JOIN
    pg_roles r
ON
    t.userid = r.oid
INNER JOIN
    pg_roles m
ON
    t.grpid = m.oid
ORDER BY
    r.rolname
    , t.lvl
    , m.rolname;