强制访问控制

4.1 如何创建策略

4.1.1 策略的组成

策略是一组预定义的标记组件,包括等级、范围和组这三种组件,三种组件分别从不同的维度对数据进行了描述。一个策略最多只能包含这三种组件,其中必须包含等级,范围和组可以缺省。

等级(Level)

等级是线性有序的名称序列,用L=(l1,l2,…,lp)表示。其中li(1≤i≤p)表示第i个名称,任意两个名称li、lj之间,若i≤j,则li≤lj,于是有l1≤l2≤…≤lp,其中l1,l2,…,lp称为等级分类(以下简称等级)。

在DM中,一个策略最大可定义10000个等级。用户在定义策略中的等级时,需要为其指定编号,其编号在0-9999之间(编号小的意味着级别较低)。

范围(Compartment)

范围是集合类型,设集合C={c1,c2,…,cm}中每一元素都是一名称,c1,c2,…,cm间彼此独立,无序,则集合C及其任意子集称为非等级类别集合,其中c1,c2,…,cm称为非等级类别(以下简称为范围)。

在DM中,最大可定义10000个范围,需要用户设置编号,且编号在一个策略里面须是唯一的,编号之间没有级别高低之分。

组(Group)

组为树形结构,有父子之分,可以用来描述组织结构。

设树G={g1,g2,…,gm},其中每一元素都是一名称,g1,g2,…,gm间有父子之分,则g1,g2,…,gm称为组。

在DM中,最多能定义10000个组,也就是说组织结构的层次最多为10000。组中只能有一个根组,除根组外,每个组有且仅有一个父组。

4.1.2 创建、修改与删除策略

4.1.2.1 创建策略

使用如下系统过程创建一个策略。

VOID
MAC_CREATE_POLICY(
	POLICY_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 新创建的策略名称

使用说明:

只有具有LABEL_DATABASE数据库权限的用户才能执行此操作。

例如,创建策略P_01

MAC_CREATE_POLICY('P_01');

4.1.2.2 修改策略

可以使用下面的系统过程修改一个策略的策略名。

VOID
MAC_ALTER_POLICY(
    POLICY_NAME VARCHAR(128),
    NEW_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 待修改的策略名称

NEW_NAME 将修改成的策略名称

使用说明:

只有具有LABEL_DATABASE数据库权限的用户才能执行此操作。

例如,将策略P_01改名为P_02。

MAC_ALTER_POLICY('P_01', 'P_02');

4.1.2.3 删除策略

可以使用下面的系统过程删除一个已存在的策略。

VOID
MAC_DROP_POLICY(
    POLICY_NAME VARCHAR(128),
    DROP_COLUMN INT
);

参数说明:

POLICY_NAME 待删除的策略名称

DROP_COLUMN 对应用此策略的表的标记列的处理方式,取值为0或1

0:不删除应用此策略的所有表对应的标记列

1:删除应用此策略的所有表对应的标记列

若DROP_COLUMN为NULL,则按默认为0进行处理

使用说明:

  1. 只有具有LABEL_DATABASE数据库权限的用户才能执行此操作;
  2. 指定待删除策略必须存在。

例如,删除策略P_02。

MAC_DROP_POLICY('P_02');

4.1.3 为策略添加组件

创建一个策略后,需要对策略添加组件,这样策略才可以被应用到表和用户上。

4.1.3.1 为策略添加等级

使用下面的系统过程为指定的策略添加等级。

VOID
MAC_CREATE_LEVEL(
    POLICY_NAME VARCHAR(128),
    LEVEL_NUM INT,
    LEVEL_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 要添加等级的策略名

LEVEL_NUM 创建的等级编号,在0-9999之间的整数

LEVEL_NAME 创建的等级名称

使用说明:

  1. LEVEL_NAME不能包含“:”和“,”;
  2. 该过程只能由具有LABEL_DATABASE的用户调用;
  3. 指定策略必须存在;
  4. 同一个策略中,等级ID和等级名称唯一;
  5. 一个策略最多可以定义10000个等级;
  6. 每个等级都要有一个等级ID,ID越小表示安全等级越低。

例如,创建策略P_03,并给策略P_03添加等级L_01,等级编号为10。

MAC_CREATE_POLICY('P_03');
MAC_CREATE_LEVEL('P_03', 10, 'L_01');

在为策略添加等级后,还可以通过系统过程修改等级名称和删除等级。

修改等级

修改等级名称的系统过程如下:

VOID
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. 该过程只能由具有LABEL_DATABASE的用户调用;
  3. 待修改等级名必须存在。

例如,将策略P_03中的等级L_01,更名为L_02。

MAC_ALTER_LEVEL('P_03', 'L_01', 'L_02');

删除等级

删除等级的系统过程如下:

VOID
MAC_DROP_LEVEL(
    POLICY_NAME VARCHAR(128),
    LEVEL_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 待删除等级所在策略名

LEVEL_NAME 待删除的等级名称

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定等级必须存在;
  3. 如果待删除等级被某个标记使用,则拒绝删除。

例如,删除策略P_03中的等级L_02。

MAC_DROP_LEVEL('P_03', 'L_02');

4.1.3.2 为策略添加范围

使用下面的系统过程为指定的策略添加范围。

VOID
MAC_CREATE_COMPARTMENT(
    POLICY_NAME VARCHAR(128),
    COMPART_NUM INT,
    COMPART_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 要添加范围的策略名

COMPART_NUM 创建的范围编号,在0-9999之间的整数

COMPART_NAME 创建的范围名称

使用说明:

  1. COMPART_NAME不能包含“:”和“,”;
  2. 该过程只能由具有LABEL_DATABASE的用户调用;
  3. 指定策略必须存在;
  4. 同一个策略中,范围ID和范围名称唯一;
  5. 一个策略中最多可以定义10000个范围;
  6. 范围独立无序,范围之间是平等关系,没有等级高低之分,范围之间的比较运算采用集合间的包含关系。

例如,给策略P_03添加范围C_01。

MAC_CREATE_COMPARTMENT('P_03',10, 'C_01');

在为策略添加范围后,还可以通过系统过程修改范围名称和删除范围。

修改范围

修改范围名称的系统过程如下:

VOID
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. 该过程只能由具有LABEL_DATABASE的用户调用;
  3. 待修改范围名必须存在。

例如,将策略P_03中的范围C_01,更名为C_02。

MAC_ALTER_COMPARTMENT('P_03', 'C_01', 'C_02');

删除范围

删除范围的系统过程如下:

VOID
MAC_DROP_COMPARTMENT(
    POLICY_NAME VARCHAR(128),
    COMPART_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 待删除范围所在策略名

COMPART_NAME 待删除的范围名称

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定范围必须存在;
  3. 如果待删除范围被某个标记使用,则拒绝删除。

例如,删除策略P_03中的范围C_02。

MAC_DROP_COMPARTMENT('P_03', 'C_02');

4.1.3.3 为策略添加组

使用下面的系统过程为指定的策略添加组。

VOID
MAC_CREATE_GROUP(
    POLICY_NAME VARCHAR(128),
    GROUP_NUM INT,
    GROUP_NAME VARCHAR(128),
    PARENT_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 要添加组的策略名

GROUP_NUM 创建的组编号,在0-9999之间的整数

GROUP_NAME 创建的组名称

PARENT_NAME 新创建组的父组的名称

使用说明:

  1. GROUP_NAME不能包含“:”和“,”;
  2. 该过程只能由具有LABEL_DATABASE的用户调用;
  3. 指定策略必须存在;
  4. 同一个策略中,组ID和组名称唯一;
  5. 一个策略最多可以定义10000个组;
  6. 同一个策略中,只能有一个根组,如果PARENT_NAME为NULL,则创建根组;
  7. 组之间的比较运算采用树形结构间的从属关系。

例如,给策略P_03创建根组G_01;再以G_01为父组,创建组G_02;以G_02为父组,创建组G_03。

MAC_CREATE_GROUP ('P_03',10, 'G_01',NULL);
MAC_CREATE_GROUP ('P_03',20, 'G_02', 'G_01');
MAC_CREATE_GROUP ('P_03',30, 'G_03', 'G_02');

在为策略添加组后,还可以通过系统过程修改组名称、更新父组和删除组。

修改组

修改组名称的系统过程如下:

VOID
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. 该过程只能由具有LABEL_DATABASE的用户调用;
  3. 待修改组名必须存在。

例如,将策略P_03中的组G_03,更名为G_04。

MAC_ALTER_GROUP('P_03', 'G_03', 'G_04');

更新父组

更新父组的系统过程如下:

VOID
MAC_ALTER_GROUP_PARENT(
    POLICY_NAME VARCHAR(128),
    GROUP_NAME VARCHAR(128),
    PARENT_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 要更新父组的组所在的策略名

GROUP_NAME 待更新父组的组名称

PARENT_NAME 待修改成的父组名称

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 待修改组和待修改成的父组必须存在;
  3. 父组不能是自身,同时不能是自己的子节点。

例如,将策略P_03中的组G_04,更换父组为G_01。

MAC_ALTER_GROUP_PARENT ('P_03', 'G_04', 'G_01');

删除组

删除组的系统过程如下:

VOID
MAC_DROP_GROUP (
    POLICY_NAME VARCHAR(128),
    GROUP_NAME VARCHAR(128),
);

参数说明:

POLICY_NAME 待删除组所在策略名

GROUP_NAME 待删除的组名称

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定组必须存在;
  3. 待删除的组不能有子节点存在,否则删除失败。

例如,删除策略P_03中的组G_04。

MAC_DROP_GROUP('P_03', 'G_04');

4.2 如何创建标记

当把策略应用于用户或表时,那么该用户或表就获得了一个安全标记。一个安全标记由多个组件组成,其组件包括等级、范围和组。每个标记必须包含一个等级,范围和组则是可选的。

在DM中,标记用字符串表示,其最大长度为4000。格式如下:

<等级>:[<范围>{,<范围>}]:[<组>{,<组>}];

假定系统中存在策略P1,其包含等级L1,L2,L3,范围C1,C2,C3,C4,组G1,G2,G3。则下列标记为合法标记:

L1::
L1:C1:
L1:C1,C2:
L1::G1
L1:C1:G1,G2

而下列标记为不合法标记:

:
:C1,C2
C1,C2
:C1:G1
::G1,G2
G1,G2

标记以二进制位的形式存储于数据库中。当一个策略被应用到表上时,需要指定标记的存储列名,此列的类型为INT,此时表上每条元组的标记均存在于该列中。

在应用策略时,还可设置标记列是否被隐藏。当标记列被隐藏时,若用户在插入数据时不指定列清单,则在值列表中可以不设置该列的值,另外,在查询时也不显示该列数据。

标记列上可以建索引,设置列约束、改列名等,但不能修改列类型、设置缺省值等。标记列不能被用户显式删除,除非在表上取消该策略。

4.2.1 创建标记

可使用下面的系统过程创建一个标记。

VOID
MAC_CREATE_LABEL(
    POLICY_NAME VARCHAR(128),
    LABEL_TAG INT,
    LABEL_VALUE VARCHAR(4000)
);

参数说明:

POLICY_NAME 要创建的标记所在的策略名

LABEL_TAG 标记值,有效范围为0~999999999

LABEL_VALUE 标记串

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;

  2. 指定策略必须存在;

  3. 根据标记值和标记串,生成一个标记,若此标记已经存在,则返回错误。标记值由用户自己指定,且标记值在系统中应是唯一的,不同的策略中也不能使用相同的标记值。

    例如,创建标记L_01:C_01:G_02。

MAC_CREATE_POLICY('P_04');
MAC_CREATE_LEVEL ('P_04',100, 'L_01');
MAC_CREATE_COMPARTMENT ('P_04',100, 'C_01');
MAC_CREATE_GROUP ('P_04',100, 'G_01',NULL);
MAC_CREATE_GROUP ('P_04',200, 'G_02', 'G_01');
MAC_CREATE_LABEL('P_04',11, 'L_01:C_01:G_02');

上述例子执行后,将在SYSMACLABELS系统表中记录TAG值以及标记字符串'L1:C1:G1'的内部格式,这个格式是对字符串'L1:C1:G1'进行处理后的格式。

如果要查看系统中某个标记对应的具体的值,例如,要查看刚刚创建的ID为11的标记的具体值,可以使用如下系统函数:

SF_MAC_LABEL_TO_CHAR(11);

此系统函数的参数为标记的标记值,返回该标记对应的标记串。

4.2.2 修改标记

可根据标记的标记值或标记串对标记修改其标记串,使用如下的系统过程:

VOID
MAC_ALTER_LABEL(
    POLICY_NAME VARCHAR(128),
    LABEL_TAG INT,
    NEW_LABEL_VALUE VARCHAR(4000)
);
VOID
MAC_ALTER_LABEL(
    POLICY_NAME VARCHAR(128),
    LABEL_VALUE VARCHAR(4000),
    NEW_LABEL_VALUE VARCHAR(4000)
);

参数说明:

POLICY_NAME 待修改标记所在策略名

LABEL_TAG 待修改标记的标记值

LABEL_VALUE 待修改标记的标记串

NEW_LABEL_VALUE 要修改为的标记串

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在;
  3. 新的标记串必须是不存在的标记串,如果存在则报错;
  4. 修改标记的用处主要在于可以不用更新表中的标记列,而直接修改标记串,来改变原始数据的安全级别;
  5. 修改标记的标记串,如果新的标记串为NULL,则保持原始值;
  6. 如果修改的标记同时应用在用户上,那么用户的标记合法性可能会遭到破坏。

例如,更改标记L_01:C_01:G_02。

MAC_ALTER_LABEL('P_04',11, 'L_01:C_01:G_01,G_02');
MAC_ALTER_LABEL('P_04', 'L_01:C_01:G_01,G_02', 'L_01:C_01:');

4.2.3 删除标记

可根据标记的标记值或标记串删除标记,使用如下的系统过程:

VOID
MAC_DROP_LABEL(
    POLICY_NAME VARCHAR(128),
    LABEL_TAG INT
);
VOID
MAC_DROP_LABEL(
    POLICY_NAME VARCHAR(128),
    LABEL_VALUE VARCHAR(4000)
);

参数说明:

POLICY_NAME 待删除标记所在策略名

LABEL_TAG 待删除标记的标记值

LABEL_VALUE 待删除标记的标记串

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在;
  3. 待删除的标记必须是已存在的标记,否则报错;
  4. 标记可以进行删除,即使标记被应用在表或用户上,这样会导致表或用户的标记失效,使用时需注意。

例如,创建标记之后删除。

MAC_CREATE_LABEL('P_04',12, 'L_01::');
MAC_DROP_LABEL('P_04',12);
MAC_CREATE_LABEL('P_04',13, 'L_01::G_01');
MAC_DROP_LABEL('P_04', 'L_01::G_01');

4.2.4 隐式创建标记

可以使用下面的系统过程隐式创建标记。

VOID
SP_MAC_LABEL_FROM_CHAR(
    POLICY_NAME VARCHAR(128),
    LABEL_VALUE VARCHAR(4000),
    TAG INT
);

参数说明:

POLICY_NAME 标记所在的策略名

LABEL_VALUE 标记串

标记值 输出参数,标记串对应的标记值

使用说明:

  1. 指定策略必须存在;

这个系统过程首先会去系统表SYSMACLABELS查找是否具有指定标记串的标记,如果存在,则返回相应的标记值,如果不存在,系统会自动创建一个对应的标记,并返回给用户相应的标记值,标记值由系统自动生成。

DM的INI参数MAC_LABEL_OPTION用于控制SP_MAC_LABEL_FROM_CHAR过程的使用范围,有三种取值:

  • 0:只有SSO可以调用
  • 1:所有用户都可以调用
  • 2:所有用户可以调用,但是非SSO用户不会主动创建新的LABEL

例1隐式创建标记,标记串不存在的情况。

DECLARE
TAG INT;
BEGIN
    SP_MAC_LABEL_FROM_CHAR ('P_04', 'L_01::G_02', TAG);
    PRINT TAG ;
END;
/

由于之前系统中没有指定标记串的标记,此时会为这个标记串创建一个标记,返回系统自动生成的TAG值。

例2隐式创建标记,标记值已存在的情况。

MAC_CREATE_LABEL('P_04',21, 'L_01:C_01:G_02');
DECLARE
TAG INT;
BEGIN
    SP_MAC_LABEL_FROM_CHAR ('P_04', 'L_01:C_01:G_02', TAG);
    PRINT TAG ;
END;
/

由于先创建了标记串为L_01:C_01:G_02的标记,指定标记值为21,因此后面的SP_MAC_LABEL_FROM_CHAR过程调用不会创建新的标记,直接返回标记值21。

4.3 如何对表应用策略

4.3.1 对表应用策略

将策略应用在一个表上时,就使该表处于一定的等级、范围和组内。一个表上可以应用多个策略,但一个策略对表只能应用一次。

对表应用策略时,会在表上新建一个标记列,用于记录标记,新建的标记列名必须和表中已有列名不同,同时还可以指定初始的标记值,以及是否将标记列设置为隐藏列。

使用下述系统过程对表应用策略:

VOID
MAC_APPLY_TABLE_POLICY(
    POLICY_NAME VARCHAR(128),
    SCHEMANAME VARCHAR(128),
    TABLENAME VARCHAR(128),
    COLNAME VARCHAR(128),
    LABELVALUE VARCHAR(4000),
    OPTION INT
);

参数说明:

POLICY_NAME 应用于指定表的策略名

SCHEMANAME 表所属模式名称

TABLENAME 策略所应用的表名称

COLNAME 用于记录标记的列名称

LABELVALUE 用于说明被应用了策略的表中,已有元组的等级、范围和组

OPTION 1代表隐藏标记列,0代表不隐藏标记列,默认为0

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在;
  3. 策略不能应用在系统表、临时表、HUGE表、水平分区表、物化视图、含有聚集主键的表、含有位图连接索引的表、含有位图索引的表上;

例如,将策略P_04应用于PRODUCTION模式中PRODUCT表,指定标记列为LABEL_COL,不隐藏标记列。

MAC_APPLY_TABLE_POLICY ('P_04', 'PRODUCTION', 'PRODUCT', 'LABEL_COL', 'L_01::',0);

过程中的OPTION参数用来指定该标记列是否隐藏。若对表应用策略时指定新增的这一列隐藏,那么对表进行INSERT数据时,如果未指定标记列的列名,就不能对这一列插入数据,如果对其插入数据,则会出错;如果指明具体的列来插入数据,这一列是允许插入数据的。当执行SELECT * 来查询该表数据时,标记列被隐藏不予显示;但也允许通过指明列名来查询该列。若对表应用策略时指定新增的这一列为0,那么该列就可以被视为一个普通列。

当一个新的策略被应用于表上时,过程的LABELVALUE参数用于初始化表中已有的数据关于该策略的标记。当某个策略已被应用于表时,则其已有的等级、范围和组均不能被删除,除非从所有的用户和表上取消对该策略的应用。

4.3.2 取消表策略

使用下述系统过程取消表上的指定策略:

VOID
MAC_REMOVE_TABLE_POLICY(
    POLICY_NAME VARCHAR(128),
    SCHEMANAME VARCHAR(128),
    TABLENAME VARCHAR(128),
    DROP_COLUMN INT
);

参数说明:

POLICY_NAME 表上待取消应用的策略

SCHEMANAME 表所属模式名称

TABLENAME 表名称

DROP_COLUMN 1代表删除标记列,0代表不删除标记列,默认为0

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在;

例如,取消应用在PRODUCTION模式中PRODUCT表上的策略,删除标记列。

MAC_REMOVE_TABLE_POLICY ('P_04', 'PRODUCTION', 'PRODUCT' ,1);

4.4 如何对用户应用策略

用户的标记来源于策略。对用户应用一个策略,要指定一个最高等级、最低等级、默认等级和行等级,其中默认等级介于最高等级和最低等级之间,最高等级限制了用户最高的读写权限,最低等级限制了用户的写权限,默认等级表示用户登录时会话标记的等级,行等级表示插入一行数据的标记使用的等级;指定范围和组,对范围需要指定读的范围、写的范围、默认范围和行级范围,其中写范围必须是读范围的子集,默认范围是读范围的子集,行级范围是写范围和默认范围的交集的子集。组的规则与范围相同。用户标记属性如下表所示:

表4.1 用户标记属性表
组成 备注
max_level 最大读写级别
min_level 最小写级别
def_level 默认级别,登录时级别
row_level 列级别,用于默认插入
categories 包含的范围,可设置属性
groups 包含的组,可设置属性

4.4.1 设置用户等级

对用户应用策略,应先设置用户的等级,使用如下系统过程:

VOID
MAC_USER_SET_LEVELS(
    POLICY_NAME VARCHAR(128),
    USER_NAME VARCHAR(128),
    MAX_LEVEL VARCHAR(128),
    MIN_LEVEL VARCHAR(128),
    DEF_LEVEL VARCHAR(128),
    ROW_LEVEL VARCHAR(128)
);

参数说明:

POLICY_NAME 应用于用户的策略名称

USER_NAME 策略所应用的用户名称

MAX_LEVEL 应用于用户的最大等级

MIN_LEVEL 应用于用户的最小等级

DEF_LEVEL 应用于用户的默认等级

ROW_LEVEL 应用于用户的行等级

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在;
  3. MAX_LEVEL不能为空;
  4. MIN_LEVEL不指定时,设置为策略的最小级别;
  5. DEF_LEVEL不指定时,设置为MAX_LEVEL;
  6. ROW_LEVEL不指定时,设置为DEF_LEVEL;
  7. 合法的LEVEL规则如下:

MAX_LEVEL >= MIN_LEVEL

MAX_LEVEL >= DEF_LEVEL >= MIN_LEVEL

DEF_LEVEL >= ROW_LEVEL >= MIN_LEVEL

例如,设置BOOKSHOP_USER用户的等级。等级L_01,L_02,L_03,L_04已存在,且等级级别相等,或依次增加。

MAC_USER_SET_LEVELS('P_04', 'BOOKSHOP_USER', 'L_04', 'L_01', 'L_03', 'L_02');

4.4.2 设置用户范围

对用户设置了等级后,可以对用户设置相应的范围和组。

使用下面的系统过程为用户设置范围:

VOID
MAC_USER_SET_COMPARTMENTS(
    POLICY_NAME VARCHAR(128),
    USER_NAME VARCHAR(128),
    READ_COMP VARCHAR(128),
    WRITE_COMP VARCHAR(128),
    DEF_COMP VARCHAR(128),
    ROW_COMP VARCHAR(128)
);

参数说明:

POLICY_NAME 应用于用户的策略名称

USER_NAME 策略所应用的用户名称

READ_COMP 应用于用户的可读范围

WRITE_COMP 应用于用户的可写范围

DEF_COMP 应用于用户的默认范围

ROW_COMP 应用于用户的行范围

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;

  2. 用户范围具有READ、WRITE、DEFAULT和ROW四个属性,说明如下:

    1. READ:用户的可读范围,READ不能为空;
    2. WRITE:用户的可写范围,进行UPDATE,DELETE时需要使用,进行判断权限。WRITE属于READ,为空时使用READ;
    3. DEFAULT:会话默认使用的范围。DEFAULT属于READ,为空时使用READ;
    4. ROW:插入时不指定标记时使用。ROW属于DEFAULT和WRITE的交集,为空时使用DEFAULT和WRITE的交集。

例如,假设范围C_01,C_02,C_03已存在,设置BOOKSHOP_USER用户的范围。

MAC_USER_SET_COMPARTMENTS('P_04','BOOKSHOP_USER','C_01,C_02,C_03','C_01,C_02','C_01,C_03','C_01');

4.4.3 设置用户组

使用下面的系统过程为用户设置组:

VOID
MAC_USER_SET_GROUPS (
    POLICY_NAME VARCHAR(128),
    USER_NAME VARCHAR(128),
    READ_GROUP VARCHAR(128),
    WRITE_GROUP VARCHAR(128),
    DEF_GROUP VARCHAR(128),
    ROW_GROUP VARCHAR(128)
);

参数说明:

POLICY_NAME 应用于用户的策略名称

USER_NAME 策略所应用的用户名称

READ_GROUP 应用于用户的可读组

WRITE_GROUP 应用于用户的可写组

DEF_GROUP 应用于用户的默认组

ROW_GROUP 应用于用户的行组

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 用户的组具有READ、WRITE、DEFAULT和ROW四个属性,说明如下:
  3. READ:用户的可读组;
  4. DEFAULT:会话默认使用的组;
  5. WRITE:进行UPDATE,DELETE时需要使用,进行判断权限;
  6. ROW:插入时不指定标记时使用;
  7. 合法的用户组规则如下:
  • WRITE属于READ
  • DEFAULT属于READ
  • ROW属于DEFAULT和WRITE的交集

例如,假设组G_01,G_02,G_03已存在,设置BOOKSHOP_USER用户的组。

MAC_USER_SET_GROUPS ('P_04', 'BOOKSHOP_USER', 'G_01,G_02,G_03', 'G_02,G_03', 'G_01,G_03', 'G_03');

4.4.4 清除用户策略

使用下面的系统过程清除应用于某用户的指定策略。

VOID
MAC_USER_REMOVE_POLICY(
POLICY_NAME VARCHAR(128),
USER_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 要清除的策略名

USER_NAME 用户名

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在。

例如,清除用户BOOKSHOP_USER的策略P_04。

MAC_USER_REMOVE_POLICY ('P_04', 'BOOKSHOP_USER');

4.5 如何对会话应用策略

为了方便用户在执行时进行MAC权限的设置,系统提供了针对会话的标记设置,这些设置会挂载在会话上,一旦会话结束,这些信息就完全被抛弃,而不会影响系统表。

用户可以设置自身当前会话的默认标记,但其必须在合法的范围内,等级必须在用户的MIN_LEVEL和MAX_LEVEL之间,范围必须是用户READ_COMP的子集,组必须是用户READ_GROUP的子集。用户还可以设置会话的行级标记,同样必须在合法的范围内。

4.5.1 设置会话默认标记

使用如下的系统过程设置会话的默认标记:

VOID
MAC_SET_SESSION_LABEL(
    POLICY_NAME VARCHAR(128),
    LABELVALUE VARCHAR(4000)
);

参数说明:

POLICY_NAME 策略名

LABELVALUE 为会话设置的默认标记

使用说明:

  1. 设置的等级必须在用户的MIN_LEVEL和MAX_LEVEL之间,范围必须是用户READ_COMP的子集,组必须是用户READ_GROUP的子集;
  2. 由于行标记的范围来源于会话标记,故重置会话标记后,需对行标记进行调整。

例如,接4.4.1、4.4.2、4.4.3节的例子,BOOKSHOP_USER用户设置会话默认标记。

MAC_SET_SESSION_LABEL('P_04', 'L_03:C_01,C_02:G_01,G_03');

4.5.2 设置会话行标记

使用如下的系统过程设置会话的行标记:

VOID
MAC_SET_SESSION_ROW_LABEL(
    POLICY_NAME VARCHAR(128),
    LABELVALUE VARCHAR(4000)
);

参数说明:

POLICY_NAME 策略名

LABELVALUE 为会话设置的行标记

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 设置的行标记必须是合法值。

例如,设置当前会话行标记。

MAC_SET_SESSION_ROW_LABEL('P_04', 'L_01:C_02:G_01');

4.5.3 清除会话标记

POLICY_NAME 要保存的会话标记所在的策略名

例如,将当前会话上策略P_04的标记刷入相应的数据字典。

使用如下的系统过程清除会话上对应某策略的标记:

VOID
    MAC_RESTORE_DEFAULT_LABELS(
		POLICY_NAME VARCHAR(128)
	);

参数说明:

POLICY_NAME 指定策略名

使用说明:

清除当前会话对应指定策略的所有的标记,仅用户的标记可用。

例如,清除当前会话对应策略P_04的所有标记。

MAC_RESTORE_DEFAULT_LABELS('P_04');

4.5.4 保存会话标记

会话上的标记只在会话生存期间存在,并没有保存到数据库的数据字典中,一旦会话结束,会话标记就被丢弃。DM提供以下的系统过程允许用户将会话上指定策略刷入相应的数据字典,这时,用户标记会被会话标记覆盖,会话标记与用户标记一致。

VOID
MAC_SAVE_DEFAULT_LABELS (
	POLICY_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 要保存的会话标记所在的策略名

例如,将当前会话上策略P_04的标记刷入相应的数据字典。

使用如下的系统过程清除会话上对应某策略的标记:

MAC_SAVE_DEFAULT_LABELS('P_04');

4.6 读写控制规则

DM支持同时使用自主访问控制与强制访问控制策略。自主访问控制策略优先于强制访问控制策略。为了能访问一条元组,用户不仅首先要满足自主访问控制条件,还必须满足强制访问控制的条件。

用户访问表时,必须保证应用于表上的所有策略均适用于该用户,否则访问被拒绝。若表上未应用任何策略,则用户只需满足自主访问控制条件即可。

4.6.1 读访问规则

强制访问控制的读访问规则为:

  1. 用户的等级必须大于等于数据的等级;
  2. 用户的标记必须包含至少一个数据的组(或者是其某一个的父亲组);
  3. 用户的标记必须包含数据的所有的范围。

如果用户满足以上三个规则,即可以对数据进行读取。比较的先后顺序是等级,组,范围。DM中实现读访问规则的流程如图4.1所示。

强制访问控制读访问规则

图4.1 强制访问控制读访问规则

4.6.2 写访问规则

强制访问控制的写访问规则为:

  1. 数据标记的等级必须大于等于用户标记的最小等级,小于或等于用户的会话标记的等级;
  2. 用户的标记必须包含至少一个数据的组(或者是其某一个的父亲组)的写权限;
  3. 用户的标记必须包含数据的所有的范围上的写权限。

如果用户满足以上三个规则,即可以对数据进行写操作。比较的先后顺序是等级,组,范围。DM中实现写访问规则的流程如图4.2所示。

强制访问控制写访问规则

图4.2强制访问控制写访问规则

4.6.3 特权

在给用户应用策略时,可以同时授予策略特权。策略特权分为访问特权和行标记特权。

访问特权分为两种:

  • READ:读数据时不受策略影响,但写数据访问控制仍然受到强制访问控制
  • FULL:可以读写任何数据,不受策略影响。

一旦一个行的标记设定后,就需要行标记特权才能UPDATE其标记列。行标记特权有如下三种:

  • WRITE UP:用户可以利用该特权提升一个行的等级,同时不改变范围和组。这个等级可以提高到用户的最高等级,而该行的原始等级可能比用户的最低等级还低
  • WRITE DOWN:用户可以利用该特权降低一个行的等级,同时不改变范围和组。这个等级可以降低到用户的最低等级,而该行的原始等级可能比用户的最低等级还低
  • WRITE ACROSS:用户可以利用该特权修改一个行的范围和组,同时不改变等级。新的范围和组只要满足在策略中是合理的就可以了,不必限于用户拥有访问权的范围和组

使用下面的系统过程为用户设置特权:

VOID
MAC_USER_SET_USER_PRIVS(
    POLICY_NAME VARCHAR(128),
    USER_NAME VARCHAR(128),
    PRIVS VARCHAR(128)
);

参数说明:

POLICY_NAME 特权对应的策略名

USER_NAME 为其设置特权的用户名

PRIVS 特权类型

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. PRIVS取值可以是READ、FULL、WRITEUP、WRITEDOWN、WRITEACCROSS中的一种或几种的组合。

例如,设置BOOKSHOP_USER用户的特权。

MAC_USER_SET_USER_PRIVS('P1', 'BOOKSHOP_USER', 'READ,WRITEUP');

4.7 扩展客体标记

除了行标记,DM的扩展客体标记支持对数据库除约束和目录外的所有的客体进行标记,如模式、表、索引等对象。一旦一个对象被应用了扩展客体标记,则用户只有在支配相应标记的情况下,才能访问客体。

创建的新对象不会含有默认的标记,需要安全员进行手工设置。

4.7.1 对客体应用标记

使用下面的系统过程可以对客体应用标记:

VOID
MAC_APPLY_OBJ_POLICY(
    POLICY_NAME VARCHAR(128),
    OBJ_TYPE VARCHAR(128),
    SCH_NAME VARCHAR(128),
    OBJ_NAME VARCHAR(128),
    COL_NAME VARCHAR(128),
    LABEL VARCHAR(4000)
);

参数说明:

POLICY_NAME 策略名称

OBJ_TYPE 客体对象类型,必须是下面几个选项之一: “SCHEMA”、“TABLE”、“VIEW”、“INDEX”、“PROCEDURE”、“FUNCTION”、“PACKAGE”、“SEQUENCE”、“TRIGGER”、“COLUMN”、“SYNONYM”、“DOMAIN”、“CONTEXT INDEX”、“CONTEXT”

SCH_NAME 客体所在的模式名,为NULL时代表对库级的对象应用策略,如公用同义词

OBJ_NAME 应用标记的客体名称,如果对模式应用策略,则此值和SCH_NAME值一致

COL_NAME 应用标记的列名,只有在OBJ_TYPE='COLUMN'时,此列才有效

LABEL 应用的标记值

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在。

例如,对模式PRODUCTION应用策略P1的标记(L1:C1:G1)。

MAC_APPLY_OBJ_POLICY('P1', 'SCHEMA', 'PRODUCTION', 'PRODUCTION', NULL'L1:C1:G1');

4.7.2 修改客体标记

使用下面的系统过程修改客体的标记:

VOID
MAC_ALTER_OBJ_POLICY(
    POLICY_NAME VARCHAR(128),
    OBJ_TYPE VARCHAR(128),
    SCH_NAME VARCHAR(128),
    OBJ_NAME VARCHAR(128),
    COL_NAME VARCHAR(128),
    LABEL VARCHAR(4000)
);

参数说明:

POLICY_NAME 策略名称

OBJ_TYPE 客体对象类型,必须是下面几个选项之一, “SCHEMA”、“TABLE”、“VIEW”、“INDEX”、“PROCEDURE”、“FUNCTION”、“PACKAGE”、“SEQUENCE”、“TRIGGER”、“COLUMN”、“SYNONYM”、“DOMAIN”、“CONTEXT INDEX”、“CONTEXT”

SCH_NAME 客体所在的模式名,为NULL时代表对库级的对象应用策略,如公用同义词

OBJ_NAME 修改标记的客体名称,如果对模式应用策略,则此值和SCH_NAME值一致

COL_NAME 修改标记的列名,只有在OBJ_TYPE='COLUMN'时,此列才有效

LABEL 修改的标记值

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在。

例如,将模式PRODUCTION的标记修改为策略P1的标记(L1:C1,C2:G1)。

MAC_ALTER_OBJ_POLICY ('P1', 'SCHEMA', 'PRODUCTION', 'PRODUCTION', NULL, 'L1:C1,C2:G1');

4.7.3 删除客体标记

使用下面的系统过程删除指定客体上对应指定策略的标记:

VOID
MAC_DROP_OBJ_POLICY(
    POLICY_NAME VARCHAR(128),
    OBJ_TYPE VARCHAR(128),
    SCH_NAME VARCHAR(128),
    OBJ_NAME VARCHAR(128),
    COL_NAME VARCHAR(128)
);

参数说明:

POLICY_NAME 策略名称

OBJ_TYPE 客体对象类型,必须是下面几个选项之一, “SCHEMA”、“TABLE”、“VIEW”、“INDEX”、“PROCEDURE”、“FUNCTION”、“PACKAGE”、“SEQUENCE”、“TRIGGER”、“COLUMN”、“SYNONYM”、“DOMAIN”、“CONTEXT INDEX”、“CONTEXT”

SCH_NAME 客体所在的模式名,为NULL时代表对库级的对象应用策略,如公用同义词

OBJ_NAME 删除标记的客体名称,如果对模式应用策略,则此值和SCH_NAME值一致

COL_NAME 删除标记的列名,只有在OBJ_TYPE='COLUMN'时,此列才有效

使用说明:

  1. 该过程只能由具有LABEL_DATABASE的用户调用;
  2. 指定策略必须存在。

例如,删除模式PRODUCTION与策略P1相关的标记。

MAC_DROP_OBJ_POLICY('P1', 'SCHEMA', 'PRODUCTION', 'PRODUCTION',NULL);

4.8 一个强制访问控制的例子

下面给出一个强制访问控制的例子,综合运用了本章介绍的一些主要概念和方法。强制访问控制在真实应用中的使用会复杂得多,需要安全管理员事先进行全面的策略设计。

  1. SYSSSO登录,创建一个策略P_TEST
/*--- SYSSSO/SYSSSO,创建策略 ---*/
MAC_CREATE_POLICY('P_TEST');
MAC_CREATE_LEVEL('P_TEST', 11, 'L_01');
MAC_CREATE_LEVEL('P_TEST', 12, 'L_02');
MAC_CREATE_LEVEL('P_TEST', 13, 'L_03');
MAC_CREATE_LEVEL('P_TEST', 14, 'L_04');
MAC_CREATE_COMPARTMENT('P_TEST',11, 'C_01');
MAC_CREATE_COMPARTMENT('P_TEST',12, 'C_02');
MAC_CREATE_COMPARTMENT('P_TEST',13, 'C_03');
MAC_CREATE_COMPARTMENT('P_TEST',14, 'C_04');
MAC_CREATE_GROUP ('P_TEST',11, 'G_01',NULL);
MAC_CREATE_GROUP ('P_TEST',12, 'G_02','G_01');
MAC_CREATE_GROUP ('P_TEST',13, 'G_03','G_02');
  1. SYSDBA登录,创建一个用户USER_TEST,并授予其RESOURCE角色
/*--- SYSDBA/SYSDBA,创建用户USER_TEST,并授予其RESOURCE角色 ---*/
CREATE USER USER_TEST IDENTIFIED BY TEST12345;
GRANT RESOURCE TO USER_TEST;
  1. USER_TEST登录,创建一个表TEST,插入两行数据,并查询,此时由于没有对表应用策略,表中没有标记列
/*--- USER_TEST/TEST12345,创建表TEST,插入数据 ---*/
CREATE TABLE TEST(C1 INT, C2 INT);
INSERT INTO TEST VALUES(1,1);
INSERT INTO TEST VALUES(2,2);
COMMIT;
SELECT * FROM TEST;

行号 			C1 			C2
---------- ----------- -----------
1 			1 			1
2 			2 			2
  1. SYSSSO登录,为用户USER_TEST和表USER_TEST.TEST应用策略
/*--- SYSSSO/SYSSSO,为用户USER_TEST应用策略,为表USER_TEST.TEST应用策略 ---*/
MAC_USER_SET_LEVELS('P_TEST', 'USER_TEST', 'L_04', 'L_01', 'L_03', 'L_02');
MAC_USER_SET_COMPARTMENTS('P_TEST', 'USER_TEST', 'C_01,C_02,C_03', 'C_01,C_02', 'C_01,C_03', 'C_01');
MAC_USER_SET_GROUPS ('P_TEST', 'USER_TEST', 'G_01,G_02,G_03', 'G_02,G_03', 'G_01,G_03', 'G_03');
MAC_APPLY_TABLE_POLICY ('P_TEST', 'USER_TEST', 'TEST', 'LABEL_COL', 'L_01::',0);
  1. USER_TEST登录,此时查询表TEST,可看到表中已有行的LABEL_COL值为应用表策略时指定的值
/*--- USER_TEST/TEST12345 ---*/
SELECT * FROM TEST;
行号 			C1 			C2 			LABEL_COL
---------- ----------- ----------- -----------
1 			1 			1 			11
2 			2 			2 			11
  1. USER_TEST继续操作,向表TEST插入一行新的记录,可以看到这行记录的标记为USER_TEST的行标记
INSERT INTO TEST(C1,C2) VALUES(3,3);
COMMIT;
SELECT * FROM TEST;
行号 			C1 			C2 			LABEL_COL
---------- ----------- ----------- -----------
1 			1 			1 			11
2 			2 			2 			11
3 			3 			3 			21

SELECT SF_MAC_LABEL_TO_CHAR(21);
行号 		  SF_MAC_LABEL_TO_CHAR(21)
---------- ------------------------
1 			L_02:C_01:G_03
  1. USER_TEST继续操作,设置会话默认标记和会话行标记,再向表TEST中插入一行数据,可看到这一行的标记为会话的行标记
MAC_SET_SESSION_LABEL('P_TEST', 'L_03:C_01,C_02:G_01,G_03');
MAC_SET_SESSION_ROW_LABEL('P_TEST', 'L_01:C_01:G_03');
INSERT INTO TEST(C1, C2) VALUES(4,4);
COMMIT;
SELECT * FROM TEST;
行号 			C1 			C2 			LABEL_COL
---------- ----------- ----------- -----------
1 			1 			1 			11
2 			2 			2 			11
3 			3 			3 			21
4 			4 			4 			24

SELECT SF_MAC_LABEL_TO_CHAR(24);
行号 			SF_MAC_LABEL_TO_CHAR(24)
---------- ------------------------
1 			L_01:C_01:G_03
  1. SYSDBA登录,查询表USER_TEST.TEST,由于此时SYSDBA没有被应用策略P_TEST,因此一行数据也不能访问
/*--- SYSDBA/SYSDBA ---*/
SELECT * FROM USER_TEST.TEST;

未选定行

  1. SYSSSO登录,为SYSDBA应用策略,设置SYSDBA的标记
/*--- SYSSSO/SYSSSO,为SYSDBA应用策略 ---*/
MAC_USER_SET_LEVELS('P_TEST', 'SYSDBA', 'L_01', 'L_01', 'L_01', 'L_01');
MAC_USER_SET_COMPARTMENTS('P_TEST', 'SYSDBA', 'C_01,C_02,C_03', 'C_01,C_02', 'C_01,C_03', 'C_01');
MAC_USER_SET_GROUPS ('P_TEST', 'SYSDBA', 'G_01,G_02,G_03', 'G_02,G_03', 'G_01,G_03', 'G_03');
  1. SYSDBA登录,再次查询表USER_TEST.TEST,根据读访问规则,可以查询到三条记录
/*--- SYSDBA/SYSDBA ---*/
SELECT * FROM USER_TEST.TEST;
行号 			C1 			C2 			LABEL_COL
---------- ----------- ----------- -----------
1 			1 			1 			11
2 			2 			2 			11
3 			4 			4 			24
  1. SYSSSO登录,为SYSDBA设置READ特权
/*--- SYSSSO/SYSSSO,为SYSDBA设置特权 ---*/
MAC_USER_SET_USER_PRIVS('P_TEST', 'SYSDBA', 'READ');
  1. SYSDBA登录,再次查询表USER_TEST.TEST,由于拥有READ特权,可以查询到全部记录
/*--- SYSDBA/SYSDBA ---*/
SELECT * FROM USER_TEST.TEST;
行号 			C1 			C2 			LABEL_COL
---------- ----------- ----------- -----------
1 			1 			1 			11
2 			2 			2 			11
3 			3 			3 			21
4 			4 			4 			24

4.9 相关数据字典表

DM中与强制访问控制相关的数据字典表有以下这些,这些字典表属于模式“SYSSSO”,只有具有SSO类型的用户才能查询。

  1. SYSMACPLYS

记录策略定义。

序号 数据类型 说明
1 ID INTEGER 策略ID
2 NAME VARCHAR(128) 策略名
  1. SYSMACLVLS

记录策略的等级。

序号 数据类型 说明
1 PID INTEGER 策略ID
2 ID SMALLINT 等级ID
3 NAME VARCHAR(128) 等级名
  1. SYSMACCOMPS

记录策略的范围。

序号 数据类型 说明
1 PID INTEGER 策略ID
2 ID SMALLINT 范围ID
3 NAME VARCHAR(128) 范围名
  1. SYSMACGRPS

记录策略所在组的信息。

序号 数据类型 说明
1 PID INTEGER 策略ID
2 ID SMALLINT 组ID
3 PARENTID SMALLINT 父节点ID
4 NAME VARCHAR(128) 组名
  1. SYSMACLABELS

记录策略的标记信息。

序号 数据类型 说明
1 PID INTEGER 策略ID
2 ID INTEGER 标记ID
3 LABEL VARCHAR(4000) 标记信息
  1. SYSMACTABPLY

记录表策略信息。

序号 数据类型 说明
1 TID INTEGER 表ID
2 PID INTEGER 策略ID
3 COLID SMALLINT 列ID
4 OPTIONS BYTE 可见性
  1. SYSMACUSRPLY

记录用户的策略信息。

序号 数据类型 说明
1 UID INTEGER 用户ID
2 PID INTEGER 策略ID
3 MAXREAD INTEGER 最大读标记ID
4 MINWRITE INTEGER 最小写标记ID
5 DEFTAG INTEGER 默认标记ID
6 ROWTAG INTEGER 行级标记ID
7 PRIVS BYTE 特权
  1. SYSMACOBJ

记录扩展客体标记信息。

序号 数据类型 说明
1 OBJID INTEGER 对象ID
2 COLID SMALLINT 列ID
3 PID INTEGER 策略ID
4 TAG INTEGER 标记ID
微信扫码
分享文档
扫一扫
联系客服