天天看點

PostgreSQL 權限 list 插件 pg_permissionspg_permission

标簽

PostgreSQL , pg_permissions , \dp , 權限

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E8%83%8C%E6%99%AF 背景

通常列出權限可以使用psql的一些簡寫:

\dp+  
  
\dp+ *.*  
           

列出使用者,schema的預設權限。列出表、視圖、序列的權限。

這幾個簡寫的介紹如下

\ddp [ pattern ]  
    Lists default access privilege settings.   
    An entry is shown for each role (and schema, if applicable)   
    for which the default privilege settings have been changed   
    from the built-in defaults. If pattern is specified, only  
    entries whose role name or schema name matches the pattern are listed.  
  
    The ALTER DEFAULT PRIVILEGES (ALTER_DEFAULT_PRIVILEGES(7))   
    command is used to set default access privileges.   
    The meaning of the privilege display is explained under GRANT(7).  
  
\dp [ pattern ]  
    Lists tables, views and sequences with their associated   
    access privileges. If pattern is specified, only tables,   
    views and sequences whose names match the pattern are listed.  
  
    The GRANT(7) and REVOKE(7) commands are used to set access privileges.   
    The meaning of the privilege display is explained under GRANT(7).  
  
\z [ pattern ]  
    Lists tables, views and sequences with their associated access privileges.   
    If a pattern is specified, only tables, views and sequences   
    whose names match the pattern are listed.   
  
    This is an alias for \dp (“display privileges”).   
           

脫離了psql用戶端,怎麼看權限呢?

一個小技巧psql -E可以列印psql執行的SQL。

psql -E  
psql (11.1)  
Type "help" for help.  
  
postgres=# \dp  
********* QUERY **********  
SELECT n.nspname as "Schema",  
  c.relname as "Name",  
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'S' THEN 'sequence' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'table' END as "Type",  
  pg_catalog.array_to_string(c.relacl, E'\n') AS "Access privileges",  
  pg_catalog.array_to_string(ARRAY(  
    SELECT attname || E':\n  ' || pg_catalog.array_to_string(attacl, E'\n  ')  
    FROM pg_catalog.pg_attribute a  
    WHERE attrelid = c.oid AND NOT attisdropped AND attacl IS NOT NULL  
  ), E'\n') AS "Column privileges",  
  pg_catalog.array_to_string(ARRAY(  
    SELECT polname  
    || CASE WHEN NOT polpermissive THEN  
       E' (RESTRICTIVE)'  
       ELSE '' END  
    || CASE WHEN polcmd != '*' THEN  
           E' (' || polcmd || E'):'  
       ELSE E':'  
       END  
    || CASE WHEN polqual IS NOT NULL THEN  
           E'\n  (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)  
       ELSE E''  
       END  
    || CASE WHEN polwithcheck IS NOT NULL THEN  
           E'\n  (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)  
       ELSE E''  
       END    || CASE WHEN polroles <> '{0}' THEN  
           E'\n  to: ' || pg_catalog.array_to_string(  
               ARRAY(  
                   SELECT rolname  
                   FROM pg_catalog.pg_roles  
                   WHERE oid = ANY (polroles)  
                   ORDER BY 1  
               ), E', ')  
       ELSE E''  
       END  
    FROM pg_catalog.pg_policy pol  
    WHERE polrelid = c.oid), E'\n')  
    AS "Policies"  
FROM pg_catalog.pg_class c  
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace  
WHERE c.relkind IN ('r','v','m','S','f','p')  
  AND n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid)  
ORDER BY 1, 2;  
**************************  
  
                                        Access privileges  
 Schema |         Name         | Type  |     Access privileges     | Column privileges | Policies   
--------+----------------------+-------+---------------------------+-------------------+----------  
 public | abc                  | table |                           |                   |   
 public | all_permissions      | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
 public | bb                   | table |                           |                   |   
 public | column_permissions   | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
 public | database_permissions | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
 public | function_permissions | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
 public | mytab                | table |                           |                   |   
 public | permission_target    | table | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =arwd/postgres            |                   |   
 public | pgbench_accounts     | table |                           |                   |   
 public | pgbench_branches     | table |                           |                   |   
 public | pgbench_history      | table |                           |                   |   
 public | pgbench_tellers      | table |                           |                   |   
 public | schema_permissions   | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
 public | sequence_permissions | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
 public | ssi                  | table |                           |                   |   
 public | table_permissions    | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
 public | tbl                  | table |                           |                   |   
 public | view_permissions     | view  | postgres=arwdDxt/postgres+|                   |   
        |                      |       | =r/postgres               |                   |   
(18 rows)  
           

是以,實際上你已經得到了dp背後查詢的SQL,你同樣可以使用這個查詢去獲得權限。

但是好像還是很麻煩,并且有幾個功能沒法實作(函數、列、資料庫、SCHEMA的權限沒有辦法列出。如果你想DIFF一下目前配置設定的權限是否是你所想要的權限,沒有很便捷的辦法。)。

為了解決這兩個問題,可以使用pg_permissions插件。

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#pg_permission pg_permission

安裝很簡單

git clone https://github.com/cybertec-postgresql/pg_permission  
  
cd pg_permission  
  
USE_PGXS=1 make  
USE_PGXS=1 make install  
  
create extension pg_permissions;  
           

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E8%A7%86%E5%9B%BE 視圖

The extension provides a number of views:

  • database_permissions: permissions granted on the current database
  • schema_permissions: permissions granted on schemas
  • table_permissions: permissions granted on tables
  • view_permissions: permissions granted on views
  • column_permissions: permissions granted on table and view columns
  • function_permissions: permissions granted on functions
  • sequence_permissions: permissions granted on sequences
  • all_permissions: permissions on all objects (UNION of the above)

All views have the same columns; a column is NULL if it has no meaning for the current view.

These views can be used to examine the currently granted permissions on database objects.

The granted column of these views can be updated, which causes the appropriate GRANT or REVOKE command to be executed.

Note: Superusers are not shown in the views, as they automatically have all permissions.

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E8%A1%A8

  • permission_target

The extension provides a table permission_target with which you can describe the permissions that should be granted on database objects.

If you set a relevant column in permission_target to NULL (e.g., the object_name and column_name columns in a TABLE entry), the meaning is that the entry refers to all possible objects (in the example above, all tables in the schema).

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E5%87%BD%E6%95%B0 函數

  • permission_diffs()

Functions

The table function permission_diffs() checks the desired permissions in permission_target against the actually granted permissions in the views of the extension and returns a table of differences.

If the first column missing is TRUE, the result is a permission that should be there but isn't; if missing is FALSE, the result row is a permission that is there even though it is not defined in permission_target (an extra permission).

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E5%8A%9F%E8%83%BD1 功能1

檢查(review)目前對象權限是否為你想要控制的權限。

1、往review表裡面輸入你想要控制的權限。

2、調用permission_diffs(),對比目前對象權限是否為你想要控制的權限。并列出差異。

Then you need to add entries to permission_target that correspond to your desired permissions.

Let's assume we have a schema appschema, and appuser should have SELECT, UPDATE, DELETE and INSERT permissions on all tables and views in that schema:

INSERT INTO public.permission_target  
   (id, role_name, permissions,  
    object_type, schema_name)  
VALUES  
   (1, 'appuser', '{SELECT,INSERT,UPDATE,DELETE}',  
    'TABLE', 'appschema');  
  
INSERT INTO public.permission_target  
   (id, role_name, permissions,  
    object_type, schema_name)  
VALUES  
   (2, 'appuser', '{SELECT,INSERT,UPDATE,DELETE}',  
    'VIEW', 'appschema');  
           

Of course, the user will need the USAGE privilege on the schema:

INSERT INTO public.permission_target  
   (id, role_name, permissions,i  
    object_type, schema_name)  
VALUES  
   (3, 'appuser', '{USAGE}',  
    'SCHEMA', 'appschema');  
           

The user also needs USAGE privileges on the appseq sequence in that schema:

INSERT INTO public.permission_target  
   (id, role_name, permissions,  
    object_type, schema_name, object_name)  
VALUES  
   (4, 'appuser', '{USAGE}',  
    'SEQUENCE', 'appschema', 'appseq');  
           

Now we can review which permissions are missing and which additional permissions are granted:

SELECT * FROM public.permission_diffs();  
  
 missing | role_name | object_type | schema_name | object_name | column_name | permission  
---------+-----------+-------------+-------------+-------------+-------------+------------  
 f       | laurenz   | VIEW        | appschema   | appview     |             | SELECT  
 t       | appuser   | TABLE       | appschema   | apptable    |             | DELETE  
(2 rows)  
           

That means that appuser is missing the DELETE privilege on appschema.apptable which should be granted, while user laurenz has the additional SELECT privilege on appschema.appview (missing is FALSE).

To review the actual permissions on an object, we can use the *_permissions views:

SELECT * FROM schema_permissions  
   WHERE role_name = 'appuser' AND schema_name = 'appschema';  
  
 object_type | role_name | schema_name | object_name | column_name | permissions | granted  
-------------+-----------+-------------+-------------+-------------+-------------+---------  
 SCHEMA      | appuser   | appschema   |             |             | USAGE       | t  
 SCHEMA      | appuser   | appschema   |             |             | CREATE      | f  
(2 rows)  
           

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E5%8A%9F%E8%83%BD2 功能2

檢視權限

1、列出單項對象權限

postgres=> \dv  
                List of relations  
 Schema |         Name         | Type |  Owner     
--------+----------------------+------+----------  
 public | column_permissions   | view | postgres  
 public | database_permissions | view | postgres  
 public | function_permissions | view | postgres  
 public | schema_permissions   | view | postgres  
 public | sequence_permissions | view | postgres  
 public | table_permissions    | view | postgres  
 public | view_permissions     | view | postgres  
           

2、列出所有對象權限

postgres=> \dv  
                List of relations  
 Schema |         Name         | Type |  Owner     
--------+----------------------+------+----------  
 public | all_permissions      | view | postgres  
           

注意:超級使用者的權限不列出,因為超級使用者預設擁有所有權限。

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E4%BE%8B%E5%AD%90 例子

create role digoal login;  
  
\c postgres digoal  
  
create table bb (id int);  
  
postgres=# select * from table_permissions where object_name='bb';  
 object_type |         role_name         | schema_name | object_name | column_name | permission | granted   
-------------+---------------------------+-------------+-------------+-------------+------------+---------  
 TABLE       | pg_monitor                | public      | bb          |             | SELECT     | f  
 TABLE       | pg_monitor                | public      | bb          |             | INSERT     | f  
 TABLE       | pg_monitor                | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_monitor                | public      | bb          |             | DELETE     | f  
 TABLE       | pg_monitor                | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_monitor                | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_monitor                | public      | bb          |             | TRIGGER    | f  
 TABLE       | pg_read_all_settings      | public      | bb          |             | SELECT     | f  
 TABLE       | pg_read_all_settings      | public      | bb          |             | INSERT     | f  
 TABLE       | pg_read_all_settings      | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_read_all_settings      | public      | bb          |             | DELETE     | f  
 TABLE       | pg_read_all_settings      | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_read_all_settings      | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_read_all_settings      | public      | bb          |             | TRIGGER    | f  
 TABLE       | pg_read_all_stats         | public      | bb          |             | SELECT     | f  
 TABLE       | pg_read_all_stats         | public      | bb          |             | INSERT     | f  
 TABLE       | pg_read_all_stats         | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_read_all_stats         | public      | bb          |             | DELETE     | f  
 TABLE       | pg_read_all_stats         | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_read_all_stats         | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_read_all_stats         | public      | bb          |             | TRIGGER    | f  
 TABLE       | pg_stat_scan_tables       | public      | bb          |             | SELECT     | f  
 TABLE       | pg_stat_scan_tables       | public      | bb          |             | INSERT     | f  
 TABLE       | pg_stat_scan_tables       | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_stat_scan_tables       | public      | bb          |             | DELETE     | f  
 TABLE       | pg_stat_scan_tables       | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_stat_scan_tables       | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_stat_scan_tables       | public      | bb          |             | TRIGGER    | f  
 TABLE       | pg_read_server_files      | public      | bb          |             | SELECT     | f  
 TABLE       | pg_read_server_files      | public      | bb          |             | INSERT     | f  
 TABLE       | pg_read_server_files      | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_read_server_files      | public      | bb          |             | DELETE     | f  
 TABLE       | pg_read_server_files      | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_read_server_files      | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_read_server_files      | public      | bb          |             | TRIGGER    | f  
 TABLE       | pg_write_server_files     | public      | bb          |             | SELECT     | f  
 TABLE       | pg_write_server_files     | public      | bb          |             | INSERT     | f  
 TABLE       | pg_write_server_files     | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_write_server_files     | public      | bb          |             | DELETE     | f  
 TABLE       | pg_write_server_files     | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_write_server_files     | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_write_server_files     | public      | bb          |             | TRIGGER    | f  
 TABLE       | pg_execute_server_program | public      | bb          |             | SELECT     | f  
 TABLE       | pg_execute_server_program | public      | bb          |             | INSERT     | f  
 TABLE       | pg_execute_server_program | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_execute_server_program | public      | bb          |             | DELETE     | f  
 TABLE       | pg_execute_server_program | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_execute_server_program | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_execute_server_program | public      | bb          |             | TRIGGER    | f  
 TABLE       | pg_signal_backend         | public      | bb          |             | SELECT     | f  
 TABLE       | pg_signal_backend         | public      | bb          |             | INSERT     | f  
 TABLE       | pg_signal_backend         | public      | bb          |             | UPDATE     | f  
 TABLE       | pg_signal_backend         | public      | bb          |             | DELETE     | f  
 TABLE       | pg_signal_backend         | public      | bb          |             | TRUNCATE   | f  
 TABLE       | pg_signal_backend         | public      | bb          |             | REFERENCES | f  
 TABLE       | pg_signal_backend         | public      | bb          |             | TRIGGER    | f  
 TABLE       | digoal                    | public      | bb          |             | SELECT     | t  
 TABLE       | digoal                    | public      | bb          |             | INSERT     | t  
 TABLE       | digoal                    | public      | bb          |             | UPDATE     | t  
 TABLE       | digoal                    | public      | bb          |             | DELETE     | t  
 TABLE       | digoal                    | public      | bb          |             | TRUNCATE   | t  
 TABLE       | digoal                    | public      | bb          |             | REFERENCES | t  
 TABLE       | digoal                    | public      | bb          |             | TRIGGER    | t  
(63 rows)  
           

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E5%8F%82%E8%80%83 參考

https://github.com/cybertec-postgresql/pg_permission https://www.postgresql.org/docs/current/ddl-priv.html

https://github.com/digoal/blog/blob/master/201901/20190123_01.md#%E5%85%8D%E8%B4%B9%E9%A2%86%E5%8F%96%E9%98%BF%E9%87%8C%E4%BA%91rds-postgresql%E5%AE%9E%E4%BE%8Becs%E8%99%9A%E6%8B%9F%E6%9C%BA 免費領取阿裡雲RDS PostgreSQL執行個體、ECS虛拟機

PostgreSQL 權限 list 插件 pg_permissionspg_permission