【问题标题】:Query grants for a table in postgres在 postgres 中查询表的授权
【发布时间】:2011-11-12 06:41:54
【问题描述】:

如何在 postgres 中查询授予对象的所有 GRANTS?

例如我有表“mytable”:

GRANT SELECT, INSERT ON mytable TO user1
GRANT UPDATE ON mytable TO user2 

我需要一些能给我的东西:

user1: SELECT, INSERT
user2: UPDATE

【问题讨论】:

    标签: sql postgresql grant


    【解决方案1】:

    下面的查询将为您提供所有用户的列表以及他们对架构中表的权限。

    select a.schemaname, a.tablename, b.usename,
      HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'select') as has_select,
      HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'insert') as has_insert,
      HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'update') as has_update,
      HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'delete') as has_delete, 
      HAS_TABLE_PRIVILEGE(usename, quote_ident(schemaname) || '.' || quote_ident(tablename), 'references') as has_references 
    from pg_tables a, pg_user b 
    where a.schemaname = 'your_schema_name' and a.tablename='your_table_name';
    

    更多关于has_table_privilages的信息请见here

    【讨论】:

    • 这是这里唯一计算从其他角色的成员资格获得的权限的答案,所以它得到了我的投票。另一方面,我会说has_table_privilege(usename, contact(schemaname, '.', tablename), ...) 以避免歧义。
    • 加一 - 这是纯金!
    【解决方案2】:

    添加到@shruti 的答案

    为给定用户查询架构中所有表的授权

    select a.tablename, 
           b.usename, 
           HAS_TABLE_PRIVILEGE(usename,tablename, 'select') as select,
           HAS_TABLE_PRIVILEGE(usename,tablename, 'insert') as insert, 
           HAS_TABLE_PRIVILEGE(usename,tablename, 'update') as update, 
           HAS_TABLE_PRIVILEGE(usename,tablename, 'delete') as delete, 
           HAS_TABLE_PRIVILEGE(usename,tablename, 'references') as references 
    from pg_tables a, 
         pg_user b 
    where schemaname='your_schema_name' 
          and b.usename='your_user_name' 
    order by tablename;
    

    【讨论】:

    • 这很好用,假设您以具有适当权限的用户身份登录。 Nitpick:我建议应该明确编写交叉连接,例如FROM pg_tables AS a CROSS JOIN pg_user AS b 而不是 SQL 92 使用逗号 from pg_tables a, pg_user b 的方式
    【解决方案3】:

    此查询将列出所有数据库和架构中的所有表(取消注释 WHERE 子句中的行以过滤特定数据库、架构或表),并按顺序显示权限很容易看出是否授予了特定特权:

    SELECT grantee
          ,table_catalog
          ,table_schema
          ,table_name
          ,string_agg(privilege_type, ', ' ORDER BY privilege_type) AS privileges
    FROM information_schema.role_table_grants 
    WHERE grantee != 'postgres' 
    --  and table_catalog = 'somedatabase' /* uncomment line to filter database */
    --  and table_schema  = 'someschema'   /* uncomment line to filter schema  */
    --  and table_name    = 'sometable'    /* uncomment line to filter table  */
    GROUP BY 1, 2, 3, 4;
    

    样本输出:

    grantee |table_catalog   |table_schema  |table_name     |privileges     |
    --------|----------------|--------------|---------------|---------------|
    PUBLIC  |adventure_works |pg_catalog    |pg_sequence    |SELECT         |
    PUBLIC  |adventure_works |pg_catalog    |pg_sequences   |SELECT         |
    PUBLIC  |adventure_works |pg_catalog    |pg_settings    |SELECT, UPDATE |
    ...
    

    【讨论】:

    • 这只会给出与执行它的用户匹配的行......不是所有的授权
    【解决方案4】:

    这是一个为特定表生成授权查询的脚本。它省略了所有者的权限。

    SELECT 
        format (
          'GRANT %s ON TABLE %I.%I TO %I%s;',
          string_agg(tg.privilege_type, ', '),
          tg.table_schema,
          tg.table_name,
          tg.grantee,
          CASE
            WHEN tg.is_grantable = 'YES' 
            THEN ' WITH GRANT OPTION' 
            ELSE '' 
          END
        )
      FROM information_schema.role_table_grants tg
      JOIN pg_tables t ON t.schemaname = tg.table_schema AND t.tablename = tg.table_name
      WHERE
        tg.table_schema = 'myschema' AND
        tg.table_name='mytable' AND
        t.tableowner <> tg.grantee
      GROUP BY tg.table_schema, tg.table_name, tg.grantee, tg.is_grantable;
    

    【讨论】:

      【解决方案5】:

      如果你真的想要每个用户一行,你可以按被授权者分组(string_agg 需要 PG9+)

      SELECT grantee, string_agg(privilege_type, ', ') AS privileges
      FROM information_schema.role_table_grants 
      WHERE table_name='mytable'   
      GROUP BY grantee;
      

      这应该输出类似:

       grantee |   privileges   
      ---------+----------------
       user1   | INSERT, SELECT
       user2   | UPDATE
      (2 rows)
      

      【讨论】:

      • 几乎是我想要的,我可以得到准确的GRANTs 像 pg_dump 输出吗?
      【解决方案6】:

      我已经找到了:

      SELECT grantee, privilege_type 
      FROM information_schema.role_table_grants 
      WHERE table_name='mytable'
      

      【讨论】:

        【解决方案7】:

        来自 psql 的\z mytable 为您提供表中的所有授权,但您必须按单个用户将其拆分。

        【讨论】:

        • 你会直接从 sql 窗格或 pg 命令行运行它吗?
        • @DanielL.VanDenBosch:所有元命令,如\z,都用于 psql。 psql 是 PostgreSQL 的命令行界面。
        猜你喜欢
        • 1970-01-01
        • 2018-12-10
        • 1970-01-01
        • 2011-11-12
        • 2015-02-14
        • 1970-01-01
        • 1970-01-01
        • 2019-02-20
        • 2015-12-07
        相关资源
        最近更新 更多