postgresql - view schema privileges

后端 未结 9 1984
再見小時候
再見小時候 2020-12-24 12:17

Is there a query I can run to show currently assigned privileges on a particular schema?

i.e. privileges that were assigned like so:

GRANT USAGE ON S         


        
相关标签:
9条回答
  • 2020-12-24 12:43

    in console util psql:

    \dn+
    

    will show you

         Name      |  Owner   |   Access privileges   |      Description   
    
    0 讨论(0)
  • 2020-12-24 12:48

    The privileges are stored in the nspacl field of pg_namespace. Since it's an array field, you have to do a little fancy coding to parse it. This query will give you the grant statements used for users and groups:

    select 
    'grant ' || substring(
              case when charindex('U',split_part(split_part(array_to_string(nspacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',usage ' else '' end 
              ||case when charindex('C',split_part(split_part(array_to_string(nspacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',create ' else '' end 
           , 2,10000)
    || ' on schema '||nspname||' to "'||pu.usename||'";' 
    from pg_namespace pn,pg_user pu
     where  array_to_string(nspacl,',') like '%'||pu.usename||'%' --and pu.usename='<username>' 
    and nspowner > 1 
    union
    select 
    'grant ' || substring(
              case when charindex('U',split_part(split_part(array_to_string(nspacl, '|'),pg.groname,2 ) ,'/',1)) > 0 then ',usage ' else '' end 
              ||case when charindex('C',split_part(split_part(array_to_string(nspacl, '|'),pg.groname,2 ) ,'/',1)) > 0 then ',create ' else '' end 
           , 2,10000)
    || ' on schema '||nspname||' to group "'||pg.groname||'";' 
    from pg_namespace pn,pg_group pg
     where array_to_string(nspacl,',') like '%'||pg.groname||'%' --and pg.groname='<username>' 
     and nspowner > 1 
    
    0 讨论(0)
  • 2020-12-24 12:48

    I know this post is old but I made another query based on the different answers to have one that is short and easy to use afterward :

    select
        nspname as schema_name
        , r.rolname as role_name
        , pg_catalog.has_schema_privilege(r.rolname, nspname, 'CREATE') as create_grant
        , pg_catalog.has_schema_privilege(r.rolname, nspname, 'USAGE') as usage_grant
    from pg_namespace pn,pg_catalog.pg_roles r
    where array_to_string(nspacl,',') like '%'||r.rolname||'%' 
        and nspowner > 1 
    

    I keep thinking one day I will make a query to have all rights in only one view... One day. ;)

    0 讨论(0)
  • 2020-12-24 12:57

    Try this one (works for PUBLIC role):

    SELECT nspname,
           coalesce(nullif(role.name,''), 'PUBLIC') AS name,
           substring(
              CASE WHEN position('U' in split_part(split_part((','||array_to_string(nspacl,',')), ','||role.name||'=',2 ) ,'/',1)) > 0 THEN ', USAGE' ELSE '' END 
              || CASE WHEN position('C' in split_part(split_part((','||array_to_string(nspacl,',')), ','||role.name||'=',2 ) ,'/',1)) > 0 THEN ', CREATE' ELSE '' END 
           , 3,10000) AS privileges
    FROM pg_namespace pn, (SELECT pg_roles.rolname AS name
       FROM pg_roles UNION ALL SELECT '' AS name) AS role
     WHERE (','||array_to_string(nspacl,',')) LIKE '%,'||role.name||'=%'
     AND nspowner > 1;
    
    0 讨论(0)
  • 2020-12-24 12:57

    Even more concisely, one can do:

      SELECT 
        n.nspname AS schema_name
       FROM pg_namespace n
      WHERE  has_schema_privilege('my_user',n.nspname, 'CREATE, USAGE');
    
    0 讨论(0)
  • 2020-12-24 13:02

    Combined version (groups, users, PUBLIC) that works for AWS Redshift:

        SELECT *
    FROM (SELECT CASE
                   WHEN charindex ('U',SPLIT_PART(SPLIT_PART(ARRAY_TO_STRING(nspacl,'|'),pu.usename,2),'/',1)) > 0 THEN ' USAGE'
                   ELSE ''
                 END ||case WHEN charindex('C',SPLIT_PART(SPLIT_PART(ARRAY_TO_STRING(nspacl,'|'),pu.usename,2),'/',1)) > 0 THEN ' CREATE' ELSE '' END AS rights,
                 nspname AS schema,
                 '' AS role,
                 pu.usename AS user
          FROM pg_namespace pn,
               pg_user pu
          WHERE ARRAY_TO_STRING(nspacl,',') LIKE '%' ||pu.usename|| '%'
          --and pu.usename='<username>' 
          AND   nspowner > 1
    
      UNION
    
          SELECT CASE
                   WHEN charindex ('U',SPLIT_PART(SPLIT_PART(ARRAY_TO_STRING(nspacl,'|'),pg.groname,2),'/',1)) > 0 THEN ' USAGE '
                   ELSE ''
                 END ||case WHEN charindex('C',SPLIT_PART(SPLIT_PART(ARRAY_TO_STRING(nspacl,'|'),pg.groname,2),'/',1)) > 0 THEN ' CREATE' ELSE '' END as rights,
                 nspname AS schema,
                 pg.groname AS role,
                 '' AS user
          FROM pg_namespace pn,
               pg_group pg
          WHERE ARRAY_TO_STRING(nspacl,',') LIKE '%' ||pg.groname|| '%'
          --and pg.groname='<username>' 
          AND   nspowner > 1
    
      UNION
    
          SELECT CASE
                   WHEN POSITION('U' IN SPLIT_PART(SPLIT_PART((',' ||array_to_string (nspacl,',')),',' ||roles.name|| '=',2),'/',1)) > 0 THEN ' USAGE'
                   ELSE ''
                 END 
          || CASE
                   WHEN POSITION('C' IN SPLIT_PART(SPLIT_PART((',' ||array_to_string (nspacl,',')),',' ||roles.name|| '=',2),'/',1)) > 0 THEN ' CREATE'
                   ELSE ''
                 END AS rights,
                 nspname AS schema,
                 COALESCE(NULLIF(roles.name,''),'PUBLIC') AS role,
                 '' AS user
          FROM pg_namespace pn,
               (SELECT pg_group.groname AS name
                FROM pg_group
                UNION ALL
                SELECT '' AS name) AS roles
          WHERE (',' ||array_to_string (nspacl,',')) LIKE '%,' ||roles.name|| '=%'
          AND   nspowner > 1) privs
    
    ORDER BY schema,rights
    
    0 讨论(0)
提交回复
热议问题