在MogDB中权限分两种,分别是系统权限和对象权限,系统权限更多的是针对用户设计,而对象权限更多的是针对数据库对象。
系统权限
系统权限又称为用户属性,一般通过CREATE/ALTER ROLE/USER语法来指定修改,SYSADMIN权限可以通过GRANT/REVOKE ALL PRIVILEGE授予或撤销;
系统权限无法通过ROLE和USER的权限被继承,也无法授予PUBLIC,包括SYSADMIN、CREATEDB、CREATEROLE、AUDITADMIN、MONADMIN、OPRADMIN、POLADMIN和LOGIN
对象权限
MogDB支持的权限有:SELECT、INSERT、UPDATE、DELETE、TRUNCATE、REFERENCES、CREATE、CONNECT、EXECUTE、ALTER、DROP、COMMENT、INDEX、VACUUM和USAGE
select | insert | update | delete | truncate | references | create | connect | execute | usage | alter | drop | comment | index | vacuum | temp | temporary | write | read | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
tablespace | Y | Y | Y | Y | |||||||||||||||
database | Y | Y | Y | Y | Y | Y | Y | ||||||||||||
schema | Y | Y | Y | Y | Y | ||||||||||||||
table | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | ||||||||
column | Y | Y | Y | Y | |||||||||||||||
sequence | Y | Y | Y | Y | Y | Y | |||||||||||||
type | Y | Y | Y | Y | |||||||||||||||
domain | Y | ||||||||||||||||||
function | Y | Y | Y | Y | |||||||||||||||
procedure | Y | Y | Y | Y | |||||||||||||||
package | Y | Y | Y | Y | |||||||||||||||
language | Y | ||||||||||||||||||
large object | Y | Y | |||||||||||||||||
data source | Y | ||||||||||||||||||
directory | Y | Y | Y | Y | |||||||||||||||
foreign server | Y | Y | Y | Y | |||||||||||||||
FDW | Y | ||||||||||||||||||
CMK | Y | Y | |||||||||||||||||
CEK | Y | Y |
ACL权限缩写
权限 | 缩写 | 适用对象类型 |
---|---|---|
SELECT | r | table 、column 、sequence 、large object |
INSERT | a | table 、column |
UPDATE | w | table 、column 、sequence 、large object |
DELETE | d | table |
TRUNCATE | D | table |
REFERENCES | x | table |
EXECUTE | X | function 、procedure 、package |
USAGE | U | schema、sequence、type、domain、language、data source、foreign server、FDW 、CMK 、CEK |
CREATE | C | tablespace 、database 、schema |
CONNECT | c | database |
TEMPORARY | T | database |
ALTER | A | tablespace、database、schema、table、sequence、type、function 、procedure 、package 、directory、foreign server |
DROP | P | tablespace、database、schema、table、column 、sequence、type、function 、procedure 、package 、directory、foreign server、CMK 、CEK |
COMMENT | m | tablespace、database、schema、table、sequence、type、function 、procedure 、package 、foreign server |
INDEX | i | table |
VACUUM | v | table |
对象所有者
对象所有者权限(隐藏,不可授予或撤销)有:
ALTER、 DROP、COMMENT、INDEX、VACUUM、GRANT和REVOKE
PUBLIC组
关键字PUBLIC表示该权限要赋予所有角色,包括以后创建的用户。
PUBLIC可以看做是一个隐含定义好的组,它总是包括所有角色。
任何角色或用户都将拥有通过GRANT直接赋予的权限和所属的权限,再加上PUBLIC的权限。
默认会授予PUBLIC的权限:数据库的CONNECT权限和CREATE TEMP TABLE权限、函数的EXECUTE特权、语言和数据类型(包括域)的USAGE特权
可以通过系统表PG_DEFAULT_ACL来查看添加到PUBLIC的权限。
ALTER DEFAULT PRIVILEGES
允许你设置将被应用于未来要创建的对象的特权(它不会影响分配给已经存在的对象的特权)。
目前只支持表(包括视图)、 序列、函数、类型、密态数据库客户端主密钥和列加密密钥的权限更改,语法如下:
ANY权限
- 不允许将ANY权限授予PUBLIC,也不允许从PUBLIC回收ANY权限。
- ANY权限属于数据库内的权限,只对授予该权限的数据库内的对象有效,例如SELECT ANY TABLE只允许用户查看当前数据库内的所有用户表数据,对其他数据库内的用户表无查看权限。
即使用户被授予ANY权限,也不能对私有用户下的对象进行访问操作(INSERT、DELETE、UPDATE、SELECT)。 - ANY权限与原有的权限相互无影响。
- 如果用户被授予CREATE ANY TABLE权限,在同名schema下创建表的属主是该schema的创建者,用户对表进行其他操作时,需要授予相应的操作权限。
系统视图GS_DB_PRIVILEGES记录ANY权限的授予情况
ALL权限
all 权限指的是将这个对象类型的所有权限都给目标用户,而不需要单独去赋权。
权限管理
不受权限限制的特权用户有:初始化用户、系统管理员用户(未开启三权分立)
数据库系统管理员可以给任何角色或用户授予/撤销任何权限。拥有CREATEROLE权限的角色可以赋予或者撤销任何非系统管理员角色的权限。
授予权限
GRANT命令由两种基本的变体:一种授予在一个数据库对象上的特权,另一个授予一个角色中的成员关系。
数据库对象权限:如果声明了 WITH GRANT OPTION,则被授权的用户也可以将此权限赋予他人,否则就不能授权给他人。这个选项不能赋予PUBLIC,这是MogDB特有的属性。
角色/用户权限:声明了WITH ADMIN OPTION,被授权的用户可以将该权限再次授予其他角色或用户,以及撤销所有由该角色或用户继承到的权限。当授权的角色或用户发生变更或被撤销时
,所有继承该角色或用户权限的用户拥有的权限都会随之发生变更。
撤销权限
REVOKE命令收回之前从一个或者更多角色 授予的特权。关键词PUBLIC隐式定义的全部角色的组。
示例
普通用户
- 创建一个普通用户,默认会在当前数据库下创建一个与用户同名的schema
- 当你在不指定schema的情况下直接创建数据库对象,默认会放在同名schema下,这是因为search_path参数的默认值是""$user",public"
- 普通用户具有public schema的usage权限,但是没有create权限,如果要在public模式下创建对象,需要单独赋权
- 普通用户没有public模式下对象的访问权限,如果需要请单独申请
- grant all on schema s1 to u1 语句只代表schema本身的权限,如果要访问 s1 下的其他对象,依然需要执行类似grant xxx on table in schema s1 to u1 这样的赋权语句
--创建用户
MogDB=# create user yunlong password 'Yunlong@0902';
--以yunlong登录数据库
MogDB=# \c postgres yunlong
--默认模式下创建表t1
--普通用户默认是有public模式的usage权限的,但如果需要查看public模式下的表,依然需要单独授予select权限
MogDB=> create table t1(id int);
MogDB=> \dt t1
Schema | Name | Type | Owner | Storage
---------+------+-------+---------+----------------------------------
yunlong | t1 | table | yunlong | {orientation=row,compression=no}
--在其他schema下创建表,以public为例
MogDB=> create table public.tp(id int);
ERROR: permission denied for schema public
--给public模式的create权限
--如果public模式下的表的owner是普通用户,那么即使将该普通用户public模式的create权限收回,此普通用户依然可以对该表进行增删改差,甚至是drop操作
MogDB=# grant create on schema public to yunlong;
MogDB=> create table public.tp(id int);
MogDB=> insert into public.tp values(1);
--收回connect权限,此权限默认存在PUBLIC组,所以从普通用户收回此权限没有效果
MogDB=# revoke connect on database postgres from public;
REVOKE
[om1@node1 mogdb1]$ gsql -p 26000 postgres -r -Uyunlong -WYunlong@0902
gsql: FATAL: permission denied for database "ssp"
DETAIL: User does not have CONNECT privilege.
权限继承
上面的示例中,使用yunlong用户创建了表t1,现在我们创建用户yun1
MogDB=# create user yun1 password 'Yunlong@0902';
--查询yunlong.t1
[om1@node1 mogdb1]$ gsql -p 26000 postgres -r -Uyun1 -WYunlong@0902
MogDB=> select * from yunlong.t1;
ERROR: permission denied for schema yunlong
--让其继承yunlong的权限,即yun1成为yunlong的角色成员
MogDB=# grant yunlong to yun1;
[om1@node1 mogdb1]$ gsql -p 26000 postgres -r -Uyun1 -WYunlong@0902
MogDB=> insert into yunlong.t1 values(1);
--取消成员角色
MogDB=# revoke yunlong from yun1;
MogDB=> select * from yunlong.t1;
ERROR: permission denied for schema yunlong
普通用户可以将其他用户添加为自己的成员,但不能将自己添加为其他用户的成员
--以用户yunlong为例
grant yunlong to om1;
grant yunlong to yun1;
revoke yunlong from yun1;
都可以成功,但是如下操作执行失败
grant yun1 to yunlong;
提示 ERROR: must have admin option on role "yun1"
--如果给yun1 admin权限,且我们还有一个用户yun2
MogDB=> grant yunlong to yun1 with admin option;
GRANT ROLE
MogDB=> grant yun1 to yun2;
ERROR: must have admin option on role "yun1"
我们发现依然需要yun1的admin权限,原因是yunlong用户本身是没有admin权限
由此可以推断出只有admin权限的用户,才可以级联的添加角色成员,而普通用户只允许将自己的权限给其他用户
只有admin权限的用户才可以执行grant all privileges to yunlong;命令
权限传递
此部分与权限继承的区别在于,权限继承是将用户的所有权限都给其他用户,但从安全性考虑,我们可能只将部分对象权限给某个用户,可使用with grant option
--yonlong用户登录
MogDB=> \c postgres yunlong
MogDB=> grant usage on schema yunlong to yun1;
MogDB=> grant select,insert,update,delete on table t1 to yun1 ;
--yun1用户登录
MogDB=> \c postgres yun1
MogDB=> select * from yunlong.t1;
MogDB=> grant usage on schema yunlong to yun2;
WARNING: no privileges were granted for "yunlong"
MogDB=> grant select on table yunlong.t1 to yun2;
WARNING: no privileges were granted for "t1"
--yun2用户登录
MogDB=> \c postgres yun2
MogDB=> select * from yunlong.t1;
ERROR: permission denied for schema yunlong
--重新执行一次,这次使用 with grant option
--yonlong用户登录
MogDB=> \c postgres yunlong
MogDB=> grant usage on schema yunlong to yun1 with grant option;
MogDB=> grant select,insert,update,delete on table t1 to yun1 with grant option;
--yun1用户登录
MogDB=> \c postgres yun1
MogDB=> select * from yunlong.t1;
MogDB=> insert into yunlong.t1 values(1);
MogDB=> grant usage on schema yunlong to yun2;
MogDB=> grant select on table yunlong.t1 to yun2;
--yun2用户登录
MogDB=> \c postgres yun2
MogDB=> select * from yunlong.t1;
id
----
1
(1 row)