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)