security_mac
规则介绍
在访问数据时,需要验证主体(用户)是否有权访问,而且非法用户即使拿到了数据,也无法读取数据的内容,数据(客体)还要验证拿到数据的用户是否能够读写。实现方法: 给主体一个标记,给客体一个标记,只有主客体相匹配才能执行操作。主体指数据库操作人员,客体指数据。
强制访问控制是安全产品必须实现的一个基本安全属性。Greatdb security 版本的强制访问控制实现是基于BLP模型的“下读,上写”(低安全级的信息向高安全级流动),同时参考了oralce的强制访问控制。下面将从安全标记、策略应用、规则比较、特权管理这四个方面描述强制访问控制的实现。
安全标记(LABEL)
安全标记组件
label是一组预定义的标记组件,包括等级、范围和组这三种组件,三种组件分别从不同的维度对数据进行了描述。一个label最多只能 包含这三种组件,其中必须包含等级,范围和组可以缺省。
等级(LEVEL)
等级是线性有序的名称序列,用 L=(l1,l2,...,lp)表示。其中 li(1≤i≤p)表示第 i 个名称,任意两个名称 li、lj 之间,若 i≤j,则 li≤lj,于是有 l1≤l2≤...≤lp,其中 l1,l2,...,lp 称为等级分类(以下简称等级)。 用户在定义策略中的等级时,需要为 其指定编号,其编号在 0-9999 之间(编号小的意味着级别较低)。
范围(Compartment)
范围是集合类型,设集合 C={c1,c2,...,cm}中每一元素都是一名称,c1,c2,..., cm 间彼此独立,无序,则集合 C 及其任意子集称为非等级类别集合,其中 c1,c2,..., cm 称为非等级类别(以下简称为范围)。
组(Group)
组为树形结构,有父子之分,可以用来描述组织结构。 设树 G={g1,g2,...,gm},其中每一元素都是一名称,g1,g2,...,gm 间有父子之 分,则 g1,g2,...,gm 称为组。一个组最多拥有一个父组。
安全标记语法
Level:[Compartment{,Compartment}]:[Group{,Group}] 在元数据中保存时Level使用num表示,其余用对应的id表示,Level必须必须存在,Compartment和Group没有必须要求。
安全策略
为了更好的管理和应用LABEL,每个等级,范围,组,LABEL都有自己的所属的策略组(policy)。
安全标记的工作原理
标记又被分为用户标记和客体标记,当用户访问客体时,将用户标记和客体标记进行比较,就能轻松的限制用户对敏感信息的访问。
怎么理解安全标记
我们先重新通过举例介绍level, compartment, group,policy。将policy看成一个公司;level为公司内员工的等级比如(P1, P2,P3,P4);compatment为公司内部的部门(行政部,开发部,测试部);group为公司的特殊组(预研组(1,2),专家组(1,2),管理组)这样公司成员可以从三个维度去给划分开。
如一个普通员工的工资数据的标记为P1:行政部:管理组,那么这个可以查看这个数据的只能是含有在等级上大于等于P1,属于财政部,且属于管理组的可以查看,当然用户的label不是这么简单。详见读写规则。
但其中Level才是最重要的,compartment 和 group都是在这之上再做一个细分。那compartment 和 group的差别又是什么呢?group是树形结构,compartment是集合,树形关系本身存在包含关系,父包含子,集合是严格区分开,没有一点交集。
策略
- 创建策略
- 函数定义
MAC_CREATE_POLICY( POLICY_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 策略名称
复制
- 使用说明
1.POLICY_NAME 不能为空,且必须唯一
复制
- 调用例子
CALL sys_mac.MAC_CREATE_POLICY('P01');
复制
- 函数定义
- 修改策略
- 函数定义
MAC_ALTER_POLICY( POLICY_NAME VARCHAR(128), NEW_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 要更改的策略名称 NEW_NAME 更改后的策略名称
复制
- 使用说明
1.POLICY_NAME 必须存在 2.NEW_NAME 不能为空,且必须唯一
复制
- 调用例子
CALL sys_mac.MAC_ALTER_POLICY('P01', 'P02');
复制
- 函数定义
- 删除策略
- 函数定义
MAC_DROP_POLICY( POLICY_NAME VARCHAR(128) );
复制
- 参数说明
1.POLICY_NAME 必须存在
复制
- 使用说明
1.没有label使用才可以删除。
复制
- 调用例子
CALL sys_mac.MAC_DROP_POLICY('P01');
复制
- 函数定义
- 开启策略
- 函数定义
MAC_ENABLE_POLICY( V_POLICY_NAME VARCHAR(128) );
复制
- 参数说明
V_POLICY_NAME 策略名称
复制
- 使用说明
1.创建策略后默认是开启,即应用到数据后,数据就受该策略保护。
复制
- 调用例子
CALL sys_mac.MAC_ENABLE_POLICY('P01');
复制
- 函数定义
- 关闭策略
- 函数定义
MAC_DISABLE_POLICY( V_POLICY_NAME VARCHAR(128) );
复制
- 参数说明
V_POLICY_NAME 策略名称
复制
- 使用说明
1.关闭策略后,该策略就失效,及其对应的读写规则就没有发生作用,如正常数据操作流程。
复制
- 调用例子
CALL sys_mac.MAC_DISABLE_POLICY('P01');
复制
- 函数定义
等级
- 添加等级
- 函数定义
MAC_CREATE_LEVEL( POLICY_NAME VARCHAR(128), LEVEL_NAME VARCHAR(128), LEVEL_NUM INT );
复制
- 参数说明
POLICY_NAME 要创建等级的策略名称 LEVEL_NAME 创建的等级名称 LEVEL_NUM 创建的等级编号,在 0-9999 之间的整数
复制
- 使用说明
1.LEVEL_NAME 不能包含“:”和“,”; 2.指定策略必须存在; 3.同一个策略中,等级LEVEL_NUM 和等级名称唯一; 4.每个等级都要有一个等级LEVEL_NUM,LEVEL_NUM越小表示安全等级越低。
复制
- 调用例子
CALL sys_mac.MAC_CREATE_LEVEL('P01', 'L01', 1);
复制
- 函数定义
- 修改等级
- 函数定义
MAC_ALTER_LEVEL( POLICY_NAME VARCHAR(128), LEVEL_NAME VARCHAR(128), NEW_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 要修改等级的策略名称 LEVEL_NAME 修改的等级名称 NEW_NAME 修改后的等级名称
复制
- 使用说明
1.NEW_LEVEL 不能包含“:”和“,”; 2.待修改等级名必须存在。
复制
- 调用例子
CALL sys_mac.ALTER_LEVEL('P01', 'L01', 'L02');
复制
- 函数定义
- 删除等级
- 函数定义
MAC_DROP_LEVEL( POLICY_NAME VARCHAR(128), LEVEL_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 待删除等级的策略名 LEVEL_NAME 待删除等级的名称
复制
- 使用说明
1.指定等级必须存在; 2.如果待删除等级被某个标记使用,则拒绝删除。
复制
- 调用例子
CALL sys_mac.MAC_DROP_LEVEL('P01', 'L01');
复制
- 函数定义
范围
- 添加范围
- 函数定义
MAC_CREATE_COMPARTMENT( POLICY_NAME VARCHAR(128), COMPART_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 要添加范围的策略名 COMPART_NAME 创建的范围名称
复制
- 使用说明
1.COMPART_NAME 不能包含“:”和“,”; 2.指定策略必须存在; 3.同一个策略中,范围名称唯一; 4.范围独立无序,范围之间是平等关系,没有等级高低之分,范围之间的比较运算采用集合间的包含关系。
复制
- 调用例子
CALL sys_mac.MAC_CREATE_COMPARTMENT('P01', 'C01');
复制
- 函数定义
修改范围
函数定义
MAC_ALTER_COMPARTMENT( POLICY_NAME VARCHAR(128), COMPART_NAME VARCHAR(128), NEW_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 要修改范围名的策略名 COMPART_NAME 待修改的范围名称 NEW_NAME 要修改成的范围名称
复制
- 使用说明
1. NEW_LEVEL 不能包含“:”和“,”; 2. 待修改范围名必须存在。
复制
- 调用例子
CALL sys_mac.MAC_ALTER_COMPARTMENT('P01', 'C01', 'C02');
复制
- 删除范围
- 函数定义
MAC_DROP_COMPARTMENT( POLICY_NAME VARCHAR(128), COMPART_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 待删除范围所在策略名 COMPART_NAME 待删除的范围名称
复制
- 使用说明
1. 指定范围必须存在; 2. 如果待删除范围被某个标记使用,则拒绝删除。
复制
- 调用例子
CALL sys_mac.MAC_DROP_COMPARTMENT('P01', 'C01');
复制
- 函数定义
分组
- 添加分组
- 函数定义
MAC_CREATE_GROUP( POLICY_NAME VARCHAR(128), GROUP_NAME VARCHAR(128), PARENT_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 要添加组的策略名 GROUP_NUM 创建的组编号,在 0-9999 之间的整数 GROUP_NAME 创建的组名称 PARENT_NAME 新创建组的父组的名称
复制
- 使用说明
1. GROUP_NAME 不能包含“:”和“,”; 2. 指定策略必须存在; 3. 同一个策略中,组名称唯一; 4. 同一个策略中,只能有一个根组,如果 PARENT_NAME 为 NULL,则创建根组; 5. 组之间的比较运算采用树形结构间的从属关系。
复制
- 调用例子
CALL sys_mac.MAC_CREATE_GROUP('P01', 'G01', NULL); CALL sys_mac.MAC_CREATE_GROUP('P01', 'G02', 'G01');
复制
- 函数定义
- 修改分组
- 函数定义
MAC_ALTER_GROUP( POLICY_NAME VARCHAR(128), GROUP_NAME VARCHAR(128), NEW_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 要修改组名的策略名 GROUP_NAME 待修改的组名称 NEW_NAME 要修改成的组名称
复制
- 使用说明
1. NEW_NAME 不能包含“:”和“,”; 2. 待修改组名必须存在。
复制
- 调用例子
CALL sys_mac.MAC_ALTER_GROUP('P01', 'G01', 'G02');
复制
- 函数定义
- 修改父组
- 函数定义
MAC_ALTER_GROUP_PARENT( POLICY_NAME VARCHAR(128), GROUP_NAME VARCHAR(128), PARENT_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 要更新父组的组所在的策略名 GROUP_NAME 待更新父组的组名称 PARENT_NAME 待修改成的父组名称
复制
- 使用说明
1. 待修改组和待修改成的父组必须存在; 2. 父组不能是自身,同时不能是自己的子节点; 3. 组不能构成闭环。
复制
- 调用例子
CALL sys_mac.MAC_ALTER_GROUP_PARENT('P01', 'G02', 'G01');
复制
- 函数定义
- 删除分组
- 函数定义
MAC_DROP_GROUP( POLICY_NAME VARCHAR(128), GROUP_NAME VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 待删除组所在策略名 GROUP_NAME 待删除的组名称
复制
- 使用说明
1. 指定组必须存在; 2. 待删除的组不能有子节点存在,否则删除失败。
复制
- 调用例子
CALL sys_mac.MAC_DROP_GROUP('P01', 'G02');
复制
- 函数定义
标记
- 创建标记
- 函数定义
MAC_CREATE_LABEL( POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) );
复制
- 参数说明
POLICY_NAME 要创建的标记所在的策略名 LABEL_VALUE 标记串
复制
- 使用说明
1. 策略必须存在; 2. LABEL 中使用的POLICY组件的元素必须已经创建。
复制
- 调用例子
CALL sys_mac.MAC_CREATE_LABEL('P01', 'L01:C01,C02:G01');
复制
- 函数定义
- 指定ID创建标记
- 函数定义
MAC_CREATE_LABEL_USE_ID( LABEL_ID INT, POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) );
复制
- 参数说明
LABEL_ID 标记值,大于0 POLICY_NAME 要创建的标记所在的策略名 LABEL_VALUE 标记串
复制
- 使用说明
1. 策略必须存在; 2. LABEL 中使用的POLICY组件的元素必须已经创建。
复制
- 调用例子
CALL sys_mac.MAC_CREATE_LABEL(1, 'P01', 'L01:C01,C02:G01');
复制
- 函数定义
- 修改标记
- 函数定义
MAC_ALTER_LABEL( POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600), NEW_VALUE VARCHAR(600) );
复制
- 参数说明
POLICY_NAME 待修改标记所在策略名 LABEL_VALUE 待修改标记的标记串 NEW_VALUE 要修改为的标记串
复制
- 使用说明
1. 指定策略必须存在; 2. 新的标记串必须是不存在的标记串,如果存在则报错; 3. 修改标记的用处主要在于可以不用更新表中的标记列,而直接修改标记串,来改变 原始数据的安全级别; 4. 如果修改的标记同时应用在用户上,那么用户的标记合法性可能会遭到破坏。
复制
- 调用例子
CALL sys_mac.MAC_ALTER_LABEL('P01', 'L01:C01,C02:G01', 'L01::');
复制
- 函数定义
- 删除标记
- 函数定义
MAC_DORP_LABEL( POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(128) );
复制
- 参数说明
POLICY_NAME 待删除标记所在策略名 LABEL_VALUE 待删除标记的标记串
复制
- 使用说明
1. 指定策略必须存在; 2. 待删除的标记必须是已存在的标记,否则报错; 3. 标记可以进行删除,即使标记被应用在表或用户上,这样会导致表或用户的标记失 效,使用时需注意。
复制
- 调用例子
CALL sys_mac.MAC_DROP_LABEL('P01', 'L01::');
复制
- 函数定义
- 查看标记
- 将标记转标记id
- 函数定义
mac_char_to_label(string policy_name, string label_value);
复制
- 参数说明
policy_name 待转换标记的策略名 label_value 待转换的标记值
复制
- 使用说明
1. 策略必须存在; 2. 标记值必须存在;
复制
- 调用例子
select mac_char_to_label('P01', 'L01::');
复制
- 函数
- 函数定义
- 标记id转标记
- 函数定义
mac_label_to_char(int label_id);
复制
- 参数说明
label_id 待转换标记id
复制
- 使用说明
1. 标记值必须存在。
复制
- 调用例子
select mac_label_to_char(1);
复制
- 函数定义
- 将标记转标记id
策略应用
用户策略
用户的策略下包括read_label, write_label,default_read_label, default_write_label, row_label 这个5个标记,限制了用户的读写范围。用户可以被应用多个策略,但每个策略对用户只能应用一次。那为什么用户要有这么多个label呢?而不是一个客体一个label用户一个label,当时第一个版本就是这么做的,我们之所以改是因为当时读写满足必须是level相等,其它能改的数据因不能见又被划为不能改,能读的数据改不了,能操作的范围太少。后面才去参考oracle的强制访问控制,将一个label改成5个。从理论上来说,一个label就是满足BLP模型的(下读,上写)数据只能从低安全级的信息向高安全级流动,缺少灵活性,而且可能破坏高安全客体中数据完整性,不太适用大多数的场景。oracle的强制访问可以说是一个对BLP模型的改进。先简单从level的角度对6种level做一个说明:
read_label: 小于等于该level的数据对用户都是可见的。 write_label: 大于等于该level的数据 并且小于等于read_label的数据是可改的。 既然有这两个label可以确定用户的读写范围了,那为什么还需要下面3个label呢? 为了满足用户自己在安全区间内做灵活的调整,筛选数据,用户可以自己设置session的读写范围。下面三个label是安全管理员给用户默认设置的,用户登录后可以根据自己的需求,在合理区间内调整。 default_read_label: 用户登录默认的读范围。 default_write_label: 用户默认的写范围。 row_label:用户插入数据时的默认label值,最终转换为id。
复制
- read_label
- 设置用户最大读的level, compartment, gorup,表示为max_level:read_comps:read_groups。
wirte_label
设置用户写范围,表示为min_level:write_comps:write_groups。有如下规则限制
min_level <= max_level write_comps ⊆ read_comps write_groups ⊆ read_groups
复制
其中level为用户的min_level限制用户最小写等级。
default_read_label
用户登录后默认用于读的label,即session read label。表示为def_read_level:def_read_comps:def_read_groups。 有如下规则
min_level <= def_read_level <= max_level def_read_comps ⊆ read_comps def_read_groups ⊆ read_groups
复制
default_write_label
用户登录后默认用于写的label,即session wirte label,是通过计算得到的。表示为min_level:def_write_comps:def_write_groups。 有如下规则
min_level def_write_comps = (wirte_comps ∩ def_read_comps) def_wirte_groups = (wirte_groups ∩ def_read_groups)
复制
row_label
用户登录后的session row label的初始值, 用户insert 时没有指定插入值时的表前列的插入默认值。表示为row_level:row_comps:row_groups。有如下规则
min_level <= row_level <= def_level row_comps ⊆ (wirte_comps ∩ def_read_comps) row_groups ⊆ (wirte_groups ∩ def_read_groups)
复制
上述group都是不扩展的group,没有扩展出子集来比较。原因是group的父组可以调整。
用户规则设置要求
level: max_level >= min_level max_level >= def_level >= min_level def_level >= row_level >= min_level ==> max_level >= def_level >= row_level >= min_level compartments: write_comps ⊆ read_comps def_comps ⊆ read_comps row_comps ⊆ (wirte_comps ∩ def_comps) groups: write_groups ⊆ read_groups def_groups ⊆ read_groups row_groups ⊆ (wirte_groups ∩ def_groups)
复制
应用用户策略
- 函数定义
MAC_APPLY_USER_POLICY( V_USER VARCHAR(32), V_HOST VARCHAR(255), POLICY_NAME VARCHAR(128), READ_LABEL VARCHAR(600), WRITE_LABEL VARCHAR(600), DEF_LABEL VARCHAR(600), ROW_LABEL VARCHAR(600));
复制
- 参数说明
V_USER 用户名 V_HOST 用户的HOST POLICY_NAME 待设置策略名 READ_LABEL 待设置的用户的读LABLE WRITE_LABEL 待设置的用户的写LABLE DEF_LABEL 待设置的用户的默认LABLE ROW_LABEL 待设置的用户的行LABLE
复制
- 使用说明
1. 策略必须存在; 2. 使用的标记不用提前创建,但其中元素必须存在,且符合标记语法; 3. READ_LABEL 对应用户的read_label; 4. WRITE_LABEL对应write_label; 5. DEF_LABEL对应default_read_label; 6. ROW_LABEL对应row_label 所以传入的参数必须满足对应label的要求; 7. 用户的default_write_label会根据WRITE_LABEL,和DEF_LABEL推导出的; 8. 所有LABEL的设置必须满足用户规则设置要求。
复制
- 调用例子
call sys_mac.mac_apply_user_policy('root', 'localhost', 'P1', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01');
复制
- 函数定义
更改用户策略
- 函数定义
MAC_ALTER_USER_POLICY( V_USER VARCHAR(32), V_HOST VARCHAR(255), POLICY_NAME VARCHAR(128), READ_LABEL VARCHAR(600), WRITE_LABEL VARCHAR(600), DEF_LABEL VARCHAR(600), ROW_LABEL VARCHAR(600));
复制
- 参数说明
V_USER 用户名 V_HOST 用户的HOST POLICY_NAME 待更改的策略名 READ_LABEL 更新后的用户的读标记值 WRITE_LABEL 更新后的用户的写标记值 DEF_LABEL 更新后的用户的默认LABLE ROW_LABEL 更新后的用户的行LABLE
复制
- 使用说明
1. 指定策略必须存在; 2. 如果想更改用户的标记,需要调用该接口; 3. 更改标记必须满足用户规则设置要求。
复制
- 调用例子
call sys_mac.mac_alter_user_policy('root', 'localhost', 'P1', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01', 'L01:C01,C02:G01');
复制
- 函数定义
删除用户策略
- 函数定义
MAC_DROP_USER_POLICY( V_USER VARCHAR(32), V_HOST VARCHAR(255), POLICY_NAME VARCHAR(128));
复制
- 参数说明
V_USER 用户名 V_HOST 用户的HOST POLICY_NAME 待删除的用户策略
复制
- 使用说明
1. 指定策略必须存在。
复制
- 调用例子
call sys_mac.mac_drop_user_policy('root', 'localhost', 'P1');
复制
- 函数定义
session labels
在用户应用策略生效后,重新登录后session中就包含了READ_LABEL,WRITE_LABEL ,DEF_READ_LABEL,DEF_WRITE_LABEL ,DEF_ROW_LABEL。默认是用户元数据中对应的label,但 READ_LABEL,WRITE_LABEL,DEF_READ_LABEL, DEF_WRITE_LABEL 中的group是扩展开了的,为了便于进行规则的比较。可以通过mac_get_seesion_labels查看。
函数定义
mac_get_session_labels(string policy_name);
复制
- 参数说明
policy_name 策略名
复制
- 使用说明
1. 指定策略必须存在
复制
- 调用例子
select mac_get_session_labels('P1');
复制
DEF_READ_LABEL的调整
用户登录后,使用用户的default_label赋值,并且可以通过mac_set_def_label 函数设置,但必须满足default_label设定规则,且在当前session结束后就失效,更改session label 后可能会影响DEF_ROW_LABEL和DEF_WRITE_LABEL。在读请求时,以DEF_READ_LABEL为准;写请求可能只有部分组件使用,详见读写规则。再调整完def_write_label和 def_row_label后扩展开group。
- def_write_label对应的调整
1. level依然为min_level; 2. compartment为 write_comps ∩ DEF_READ_LABEL.write_comps; 3. group 等于 write_groups ∩ DEF_READ_LABEL.def_read_groups 使用DEF_READ_LABEL.def_read_groups作为驱动,按元素依次遍历write_label.group.得到交集,并全部扩展;
复制
- def_row_label对应的调整
1. level = def_read_label.level; 2. compartment = def_write_label.compartment; 3. group 等于 write_groups ∩ DEF_READ_LABEL.def_read_groups使用DEF_READ_LABEL.def_read_groups作为驱动,按元素依次遍历write_label.group.得到交集,但不扩展;
复制
- 函数定义
mac_set_def_label(string policy_name, string label_value);
复制
- 参数说明
policy_name 待更改的def_label所属的策略名 label_value 更新的def_label值
复制
- 使用说明
1. 当前用户已经应用了该策略; 2. 更改后的def_label必须满足用户规则设置要求。
复制
- 调用例子
select mac_set_def_label('P1', 'L1:C1:G1');
复制
- def_write_label对应的调整
DEF_ROW_LABEL的调整
用户登录后,使用用户row_label赋值,并可以通过mac_set_row_label设置,但必须满足row_label的设定规则,且当前session结束后失效。用户insert 时没有指定插入值时的表前列的插入默认值。
函数定义
mac_set_row_label(string policy_name, string label_value);
复制
- 参数说明
policy_name 待更改的row_label所属的策略名 label_value 更新的row_label值
复制
- 使用说明
1. 当前用户已经应用了该策略; 2. 更改后的row_label必须满足用户规则设置要求。
复制
- 调用例子
select mac_set_row_label('P1', 'L1:C1:G1');
复制
重置session labels
调用mac_reset_session_labels,重新从元数据表加载指定策略的用户的session label信息。
- 函数定义
mac_reset_session_labels(string policy_name);
复制
- 参数说明
policy_name 待重置的策略名
复制
- 使用说明
1. 当前用户已经应用了该策略。
复制
- 调用例子
select mac_reset_session_labels('p1');
复制
- 函数定义
行策略
应用行策略
为表添加一列,列名为_gdb_mac_policy${pid}的标记列,类型为INT。并指定初始值LABEL_VALUE,再创建后根据用户的row_label指定。一个行上可以应用多个策略,但一个策略对表只能应用一次。
函数定义
sys_mac.MAC_APPLY_ROW_POLICY( V_DB_NAME VARCHAR(64), V_TABLE_NAME VARCHAR(64), V_POLICY_NAME VARCHAR(128), V_LABEL VARCHAR(600), V_OPTION_VISIBLE INT);
复制
- 参数说明
V_DB_NAME 库名,不能为系统库 V_TABLE_NAME 表名 V_POLICY_NAME 策略名 V_LABEL 已经创建好的label,其id做为已有数据的策略列的默认值 V_OPTION_VISBLE 是否为隐藏列 0为隐藏,1为非隐藏。
复制
- 使用说明
1. 指定策略必须存在; 2. 策略不能应用在系统表、临时表、视图上。
复制
- 调用例子
call sys_mac.MAC_APPLY_ROW_POLICY('test', 't1', 'P1', 1, 1);
复制
删除行策略
删除策略后,删除该标记列。
- 函数定义
sys_mac.MAC_DROP_ROW_POLICY( V_DB_NAME VARCHAR(64), V_TABLE_NAME VARCHAR(64), V_POLICY_NAME VARCHAR(128));
复制
- 参数说明
V_DB_NAME 待删除行策略的库名 V_TABLE_NAME 待删除行策略的表名 V_POLICY_NAME 待删除行策略名
复制
- 使用说明
1. 指定的策略必须存在; 2. 删除策略后drop掉表对应的标记列。
复制
- 调用例子
call sys_mac.MAC_DROP_ROW_POLICY('test', 't1', 'p1');
复制
- 函数定义
开启行策略
在对行应用策略后,开关默认是开启的,每次访问数据需要检查是否符合读写权限。
- 函数定义
sys_mac.MAC_ENABLE_ROW_POLICY( V_DB_NAME VARCHAR(64), V_TABLE_NAME VARCHAR(64), V_POLICY_NAME VARCHAR(128) );
复制
- 参数说明
V_DB_NAME 待开启行策略的库名 V_TABLE_NAME 待开启行策略的表名 V_POLICY_NAME 待开启行策略名
复制
- 使用说明
1. 指定的策略必须存在。
复制
- 调用例子
call sys_mac.MAC_ENABLE_ROW_POLICY('test', 't1', 'p1');
复制
- 函数定义
关闭行策略
关闭已应用的某个策略后,该策略在该表上不生效。
- 函数定义
sys_mac.MAC_ENABLE_ROW_POLICY( V_DB_NAME VARCHAR(64), V_TABLE_NAME VARCHAR(64), V_POLICY_NAME VARCHAR(128) );
复制
- 参数说明
V_DB_NAME 待关闭行策略的库名 V_TABLE_NAME 待关闭行策略的表名 V_POLICY_NAME 待关闭行策略名
复制
- 使用说明
1. 指定的策略必须存在。
复制
- 调用例子
call sys_mac.MAC_ENABLE_ROW_POLICY('test', 't1', 'p1');
复制
- 函数定义
行策略生效后的行为
- select
- 根据读规则,确定用户对数据的可见性,只返回对用户可见数据。标记列为隐藏时,使用SELECT *查询 ,隐藏的标记列不显示,如需查询标记列的值,需要指定对应列名。
- insert
- 标记列的值如果显示指定,那么必须满足当前用户写的权限,如果没有指定,就为当前用户row_label的id值。当存在隐藏标记列时,Insert没有指定列名时,隐藏标记列没有计算在插入列中。
- update
- 更改的数据必须满足用户有写权限,且不能更改标记列的值。如果更新的行可见但不可写,报错。
- delete
- 删除的数据必须满足用户有写权限。如果删除的行可见但不可写,报错。
- select
扩展客体策略
库策略
- 对库应用的策略
- 函数定义
MAC_APPLY_DATABASE_POLICY( DB_NAME VARCHAR(64), POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) );
复制
- 参数说明
DB_NAME 库名,不能为系统数据库名 POLICY_NAME 应用的策略名 LABEL_VALUE 应用的标记值
复制
- 使用说明
1. LABEL_VALUE 和 POLICY_NAME必须存在; 2. DB必须存在,且不能是系统库。
复制
- 调用例子
call sys_mac.MAC_APPLY_DATABASE_POLICY('test', 'P1', 'L1:C1:G1');
复制
- 函数定义
- 更改库应用的策略
- 函数定义
MAC_ALTER_DATABASE_POLICY( DB_NAME VARCHAR(64), POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) );
复制
- 参数说明
DB_NAME 待修改的数据库名 POLICY_NAME 待修改的数据库已经应用的策略名 LABEL_VALUE 更新的标记值
复制
- 使用说明
1. 在DATABASE下面的策略必须存在; 2. LABLE_VALUE必须存在,不存在必须提前创建; 3. 只能更改对应策略的标记值,改变可见范围。
复制
- 调用例子
call sys_mac.MAC_ALTER_DATABASE_POLICY('test', 'P1', 'L2:C2:G2');
复制
- 函数定义
- 删除库应用的策略
- 函数定义
MAC_DROP_DATABASE_POLICY( DB_NAME VARCHAR(64), POLICY_NAME VARCHAR(128) );
复制
- 参数说明
DB_NAME 待删除的数据库名 POLICY_NAME 待删除的数据库已经应用的策略名
复制
- 使用说明
1. 指定的策略必须存在。
复制
- 调用例子
call sys_mac.MAC_DROP_DATABASE_POLICY('test', 'P1');
复制
- 函数定义
表策略
- 对表应用策略
- 函数定义
MAC_APPLY_TABLE_POLICY( DB_NAME VARCHAR(64), TABLE_NAME VARCHAR(64), POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) )
复制
- 参数说明
DB_NAME 库名,不能为系统数据库名 TABLE_NAME 表名 POLICY_NAME 应用的策略名 LABEL_VALUE 应用的标记值
复制
- 使用说明
1. LABEL_VALUE 和 POLICY_NAME必须存在; 2. DB必须存在,且不能是系统库。
复制
- 调用例子
call sys_mac.MAC_APPLY_TABLE_POLICY('test', 't1', 'P1', 'L1:C1:G1');
复制
- 函数定义
- 修改对表应用的策略
- 函数定义
MAC_ALTER_TABLE_POLICY( DB_NAME VARCHAR(64), TABLE_NAME VARCHAR(64), POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) );
复制
- 参数说明
DB_NAME 待修改的数据库名 TABLE_NAME 待修改的表名 POLICY_NAME 待修改的数据库已经应用的策略名 LABEL_VALUE 更新的标记值
复制
- 使用说明
1. 在表上的策略必须存在; 2. LABLE_VALUE必须存在,不存在必须提前创建; 3. 只能更改对应策略的标记值,改变可见范围。
复制
- 调用例子
call sys_mac.MAC_ALTER_TABLE_POLICY('test', 't1', 'P1', 'L2:C2:G2');
复制
- 函数定义
- 删除对表应用的策略
- 函数定义
MAC_DROP_TABLE_POLICY( DB_NAME VARCHAR(64), TABLE_NAME VARCHAR(64), POLICY_NAME VARCHAR(128) );
复制
- 参数说明
DB_NAME 待删除的数据库名 TABLE_NAME 待删除的表名 POLICY_NAME 待删除的数据库已经应用的策略名
复制
- 使用说明
1. 在表上的策略必须存在;
复制
- 调用例子
call sys_mac.MAC_DROP_TABLE_POLICY('test', 't1', 'P1');
复制
- 函数定义
列策略
- 对列应用策略
- 函数定义
MAC_APPLY_COLUMN_POLICY( DB_NAME VARCHAR(64), TABLE_NAME VARCHAR(64), COLUMN_NAME VARCHAR(64), POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) );
复制
- 参数说明
DB_NAME 库名,不能为系统数据库名 TABLE_NAME 表名 COLUMN_NAME 列名 POLICY_NAME 应用的策略名 LABEL_VALUE 应用的标记值
复制
- 使用说明
1. LABEL_VALUE 和 POLICY_NAME必须存在; 2. DB必须存在,且不能是系统库。
复制
- 调用例子
call sys_mac.MAC_APPLY_COLUMN_POLICY('test', 't1', 'c1', 'P1', 'L1:C1:G1');
复制
- 函数定义
- 修改对表应用的策略
- 函数定义
MAC_ALTER_COLUMN_POLICY( DB_NAME VARCHAR(64), TABLE_NAME VARCHAR(64), COLUMN_NAME VARCHAR(64), POLICY_NAME VARCHAR(128), LABEL_VALUE VARCHAR(600) );
复制
- 参数说明
DB_NAME 待修改的数据库名 TABLE_NAME 待修改的表名 COLUMN_NAME 待修改的列名 POLICY_NAME 待修改的数据库已经应用的策略名 LABEL_VALUE 更新的标记值
复制
- 使用说明
1. 在列上的策略必须存在; 2. LABLE_VALUE必须存在,不存在必须提前创建; 3. 只能更改对应策略的标记值,改变可见范围。
复制
- 调用例子
call sys_mac.MAC_ALTER_COLUMN_POLICY('test', 't1', 'c1', 'P1', 'L2:C2:G2');
复制
- 函数定义
- 删除对表应用的策略
- 函数定义
MAC_DROP_COLUMN_POLICY( DB_NAME VARCHAR(64), TABLE_NAME VARCHAR(64), COLUMN_NAME VARCHAR(64), POLICY_NAME VARCHAR(128) );
复制
- 参数说明
DB_NAME 待删除的数据库名 TABLE_NAME 待删除的表名 COLUMN_NAME 待删除的列名 POLICY_NAME 待删除的数据库已经应用的策略名
复制
- 使用说明
1. 在列上的策略必须存在;
复制
- 调用例子
call sys_mac.MAC_DROP_COLUMN_POLICY('test', 't1', 'c1', 'P1');
复制
- 函数定义
扩展客体生效后的行为
DML没有读写权限直接报错。在database、table、column之间存在层级关系,如果上一层有权限,下层的都有权限,如果上一层没有权限,下次有权限也不能访问,这个和acl的控制有点区别。
读写规则
读规则
读是使用DEF_READ_LABEL,读规则详见下图,其中的没有特别说明都是指DEF_READ_LABEL中的元素。
写规则
写必须要满足读,使用的是DEF_READ_LABEL,DEF_WRITE_LABEL共同判断。写规则详见下图,其中的没有特别说明都是指DEF_READ_LABEL中的元素。
特权管理
读写特权
如果一个用户在策略上拥有对应的特权,就不需要检查对应的读写权限。
- 策略读特权(READ)
- 当一个用户有在某个policy上有读特权时,对受该策略保护的数据可见。
- 策略写特权(FULL)
- 当一个用户有在某个policy上有FULL特权时,对受该策略保护的数据可见可写。
- 设置读写特权
- 函数定义
sys_mac.MAC_SET_USER_PRIV( V_USER VARCHAR(32), V_HOST VARCHAR(255), POLICY_NAME VARCHAR(128), V_PRIVS enum('read', 'full'));
复制
- 参数说明
V_USER 用户名 V_HOST 用户host POLICY_NAME 设置特权的策略名 V_PRIVS 特权类型,read 为读特权,full为写特权
复制
- 使用说明
1. 策略必须存在。
复制
- 调用例子
call sys_mac.MAC_SET_USER_PRIV('root', 'localhost', 'P1', 'read');
复制
- 函数定义
- 清理用户特权
使用MAC_DROP_USER_POLICY清理
特权用户
特权用户具有不受任何policy限制的权限。
- 添加特权用户
- 函数定义
MAC_GRANT_USER_ALL_PRIVS( V_USER VARCHAR(32), V_HOST VARCHAR(255));
复制
- 参数说明
V_USER 用户名 V_HOST 用户HOST
复制
- 调用例子
call sys_mac.MAC_GRANT_USER_ALL_PRIVS('root', 'localhost');
复制
- 函数定义
- 删除特权用户
- 函数定义
sys_mac.MAC_REVOKE_USER_ALL_PRIVS( V_USER VARCHAR(32), V_HOST VARCHAR(255));
复制
- 参数说明
V_USER 待清理的用户名 V_HOST 待清理的用户HOST
复制
- 调用例子
call sys_mac.MAC_REVOKE_USER_ALL_PRIVS('root', 'localhost');
复制
- 函数定义
强制访问开关控制
强制访问开关
start_with_mandatory_access_control默认为false,为readonly参数。
set persist_only start_with_mandatory_access_control = ON; restart;
复制
控制session是否使用强制访问开关
enable_mandatory_access_control默认为false,为global参数。
set global enable_mandatory_access_control = ON;
复制