postgresql - view schema privileges

后端 未结 9 1985
再見小時候
再見小時候 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 13:03

    List all schemas with their priveleges for current user:

    WITH "names"("name") AS (
      SELECT n.nspname AS "name"
        FROM pg_catalog.pg_namespace n
          WHERE n.nspname !~ '^pg_'
            AND n.nspname <> 'information_schema'
    ) SELECT "name",
      pg_catalog.has_schema_privilege(current_user, "name", 'CREATE') AS "create",
      pg_catalog.has_schema_privilege(current_user, "name", 'USAGE') AS "usage"
        FROM "names";
    

    The response will be for example:

      name   | create | usage 
    ---------+--------+-------
     public  | t      | t
     test    | t      | t
     awesome | f      | f
    (3 rows)
    

    In this example current user is not owner of the awesome schema.

    As you could guess, similar request for particular schema:

    SELECT
      pg_catalog.has_schema_privilege(
        current_user, 'awesome', 'CREATE') AS "create",
      pg_catalog.has_schema_privilege(
        current_user, 'awesome', 'USAGE') AS "usage";
    

    and response:

     create | usage 
    --------+-------
     f      | f
    

    As you know, it's possible to use pg_catalog.current_schema() for current schema.

    Of all the possible privileges

    -- SELECT
    -- INSERT
    -- UPDATE
    -- DELETE
    -- TRUNCATE
    -- REFERENCES
    -- TRIGGER
    -- CREATE
    -- CONNECT
    -- TEMP
    -- EXECUTE
    -- USAGE
    

    the only CREATE and USAGE allowed for schemas.

    Like the current_schema() the current_user can be replaced with particular role.


    BONUS with current column

    WITH "names"("name") AS (
      SELECT n.nspname AS "name"
        FROM pg_catalog.pg_namespace n
          WHERE n.nspname !~ '^pg_'
            AND n.nspname <> 'information_schema'
    ) SELECT "name",
      pg_catalog.has_schema_privilege(current_user, "name", 'CREATE') AS "create",
      pg_catalog.has_schema_privilege(current_user, "name", 'USAGE')  AS "usage",
      "name" = pg_catalog.current_schema() AS "current"
        FROM "names";
    
    --   name   | create | usage | current
    -- ---------+--------+-------+---------
    --  public  | t      | t     | t
    --  test    | t      | t     | f
    --  awesome | f      | f     | f
    -- (3 rows)
    

    WITH | System Information Functions | GRANT (privileges)

    0 讨论(0)
  • 2020-12-24 13:05

    For current question can try this one:

    SELECT r.rolname AS role_name,
           n.nspname AS schema_name,
           p.perm AS privilege
    FROM pg_catalog.pg_namespace AS n
        CROSS JOIN pg_catalog.pg_roles AS r
        CROSS JOIN (VALUES ('USAGE'), ('CREATE')) AS p(perm)
    WHERE has_schema_privilege(r.oid, n.oid, p.perm)
    --      AND n.nspname <> 'information_schema'
    --      AND n.nspname !~~ 'pg\_%'
    --      AND NOT r.rolsuper
    

    Could be pretty low in performance at database with a lot of objects and users with which I have come across. So i've got possible workaround using aclexplode() default function like this:

    SELECT  oid_to_rolname(a.grantee) AS role_name,
            n.nspname AS schema_name,
            a.privilege_type AS privilege_type
    FROM pg_catalog.pg_namespace AS n,
            aclexplode(nspacl) a
    WHERE n.nspacl IS NOT NULL 
            AND oid_to_rolname(a.grantee) IS NOT NULL 
    --      AND n.nspname <> 'information_schema'
    --      AND n.nspname !~~ 'pg\_%'
    

    But, be careful, last one doesn't include privileges which users have obtained from PUBLIC role. Where oid_to_rolname() is simple custom function SELECT rolname FROM pg_roles WHERE oid = $1.

    And, like @Jaisus, my task required to have all privileges which all users have. So i have similar to schema privileges queries for table, views, columns, sequences, functions, database and even default privileges.

    Also, there is helpful extension pg_permission where I get logic for provided queries and just upgraded it for my purposes.

    0 讨论(0)
  • 2020-12-24 13:08

    This is what psql uses internally :)

    SELECT n.nspname AS "Name",
      pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner",
      pg_catalog.array_to_string(n.nspacl, E'\n') AS "Access privileges",
      pg_catalog.obj_description(n.oid, 'pg_namespace') AS "Description"
    FROM pg_catalog.pg_namespace n
    WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
    ORDER BY 1;
    
    0 讨论(0)
提交回复
热议问题