PG_PERMISSIONS插件为PG数据库提供以下功能
1.查询用户的所有对象权限,包括:数据库权限,模式权限,表权限,视图权限,列权限,函数权限以及序列权限。
2.检查用户权限是否符合要求。

一、安装pg_permissions

插件下载地址:https://github.com/cybertec-postgresql/pg_permissions
解压并安装:

tar -zxvf pg_permissions-REL_1_1.tar.gz
make install USE_PGXS=1 pg_config=/u01/pg13/pg13.4/bin/pg_config

登录PG数据库

/u01/pg13/pg13.4/bin/psql -p 6000

创建扩展

postgres=# create extension pg_permissions;

二、pg_permissions扩展会在数据库中创建8个视图,1张表,一个函数

postgres=# \dv *permissions
                List of relations
 Schema |         Name         | Type |  Owner
--------+----------------------+------+----------
 public | all_permissions      | view | postgres
 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
(8 rows)
database_permissions: 当前数据库权限的授予记录

schema_permissions: 架构权限的授予记录

table_permissions: 表权限的授予记录

view_permissions: 视图权限的授予记录

column_permissions: 表和视图列权限的授予记录

function_permissions: 函数权限的授予记录

sequence_permissions: 序列权限的授予记录

all_permissions:所有对象权限的授予记录(UNION以上)

所有视图都具有相同的列;如果某列对当前视图没有意义,则该列为 NULL。

这些视图可用于检查当前授予的对象的权限。

可以更新这些视图的granted列,这会导致执行与修改相对应的 GRANT 或 REVOKE 命令。

注意:超级用户不会显示在视图中,因为他们自动拥有所有权限。

postgres=# \dt *permission*
               List of relations
 Schema |       Name        | Type  |  Owner
--------+-------------------+-------+----------
 public | permission_target | table | postgres
(1 row)

permission_target表,用于记录应该授予数据库用户的对象权限。
如果将相关列设置permission_target为 NULL,则意味着该条目引用所有可能的对象。

postgres=# \df *permission_*
                                                                                         List of functions
 Schema |       Name       |                                                             Result data type                                                             | Argument data types | Type

--------+------------------+------------------------------------------------------------------------------------------------------------------------------------------+---------------------+-----
-
 public | permission_diffs | TABLE(missing boolean, role_name name, object_type obj_type, schema_name name, object_name text, column_name name, permission perm_type) |                     | func
(1 row)

permission_diffs()函数根据扩展视图中实际授予的权限检查permission_target表中记录的用户权限,并返回一个差异结果。
如果第一列missing是TRUE,则结果是应该存在但不存在的权限,即在permission_target表中有记录但用户实际不具有的权限;如果missing是FALSE,结果行是一个实际已分配但是没有记录在permission_target表中的权限。

三、功能测试
1.查询test1用户所有权限

db1=# \c - test1
You are now connected to database "db1" as user "test1".
db1=> create table t1 (id int);
CREATE TABLE
db1=> select * from all_permissions where role_name='test1' and object_name not like '%permission%';
 object_type | role_name | schema_name | object_name | column_name | permission | granted
-------------+-----------+-------------+-------------+-------------+------------+---------
 TABLE       | test1     | public      | t1          |             | SELECT     | t
 TABLE       | test1     | public      | t1          |             | INSERT     | t
 TABLE       | test1     | public      | t1          |             | UPDATE     | t
 TABLE       | test1     | public      | t1          |             | DELETE     | t
 TABLE       | test1     | public      | t1          |             | TRUNCATE   | t
 TABLE       | test1     | public      | t1          |             | REFERENCES | t
 TABLE       | test1     | public      | t1          |             | TRIGGER    | t
 COLUMN      | test1     | public      | t1          | id          | SELECT     | f
 COLUMN      | test1     | public      | t1          | id          | INSERT     | f
 COLUMN      | test1     | public      | t1          | id          | UPDATE     | f
 COLUMN      | test1     | public      | t1          | id          | REFERENCES | f
(11 rows)

2.查看user1用户权限是否符合要求
向表中插入要求user1所具有的权限:

db1=> \c - postgres
You are now connected to database "db1" as user "postgres".
db1=# create schema test1;
CREATE SCHEMA
db1=# INSERT INTO public.permission_target (id,role_name, permissions,object_type, schema_name) VALUES (1,'test1', '{USAGE}','SCHEMA', 'public');
INSERT 0 1
db1=# INSERT INTO public.permission_target (id,role_name, permissions,object_type, schema_name) VALUES (2,'test1', '{USAGE}','SCHEMA', 'test1');
INSERT 0 1
db1=# \dn+
                          List of schemas
  Name  |  Owner   |  Access privileges   |      Description
--------+----------+----------------------+------------------------
 public | postgres | postgres=UC/postgres+| standard public schema
        |          | =UC/postgres         |
 test1  | postgres |                      |
(2 rows)
比对user1用户实际所具有权限是否符合要求:

db1=# SELECT * FROM public.permission_diffs() where role_name='test1';
 missing | role_name | object_type | schema_name | object_name | column_name | permission
---------+-----------+-------------+-------------+-------------+-------------+------------
 f       | test1     | SCHEMA      | public      |             |             | CREATE
 t       | test1     | SCHEMA      | test1       |             |             | USAGE
(2 rows)

结果:用户test1实际多了在public角色上的create权限,缺少在test1角色上的usage权限。

四、PG_PERMISSIONS插件的不足
目前G_PERMISSION插件只提供查询用户在数据库,模式,表,视图,列,函数以及序列对象上的权限,其他对象上的权限还未支持。

db1=# create tablespace tbs_01 location '/u01/pg13/pgsource/pgdata/tbs_01';
WARNING:  tablespace location should not be inside the data directory
CREATE TABLESPACE
db1=# grant create on tablespace tbs_01 to test1;
GRANT
db1=# select * from all_permissions where role_name='test1' and object_name not like '%permission%';
 object_type | role_name | schema_name | object_name | column_name | permission | granted
-------------+-----------+-------------+-------------+-------------+------------+---------
(0 rows)