一个策略中一定要包含被SELinux内核和其他客体管理器支持的所有客体类和权限的声明.通常来说,我们作为策略编写者,不用担心创建新的客体类.然而,我们需要理解被定义的客体类来编写出更有效率的SELinux策略.理解客体类和权限声明语法是非常有用的,因为特允许我们理解我们正在使用的策略版本支持的客体类和权限.
添加一个新的客体类和权限
添加一个新的客体类和在一个存在的客体类上修改权限非常复杂的工作,这项工作通常只能在修改系统代码本身的时候进行.不像SELinux策略语言的其他方面,客体类和权限在Linux细节实现上是紧紧绑定在一起的,特别是内核.事实上,客体类和权限被设计来尽可能精确的代表被系统实现的资源.对于这个原因,当系统发生改变的时候,改变客体类和权限来匹配对应的系统是非常有意义的.
一个类型改变的例子就是在客体类中授权一个改变,并且权限是IPC对内核新的形式的附加.在这个实例中,一个完全新的资源类别被添加,就像新的或者是扩展的系统调用,一个新的客体类可能会被需要代表这个资源的语义.
添加或者是改变客体类或语义不仅仅需要对策略修改,还需要对系统代码修改,那将会基于新的客体类或权限强制进行访问控制.仅仅是向策略中添加客体类或权限而不修改代码除了浪费内核内存没有别的作用.
基本上来说,对于这本书的目标读者(SELinux的策略编写者和管理员),你应该永远不要改变客体类和权限定义.
4.2.1 声明客体类
客体类使用类声明语句进行声明.类声明语句仅仅声明了一个客体类的名称,别的就没有什么了.例如,我们用下面的描述为类别定义一个客体类.
class dir
类声明是由关键字”class”以及后面的类名称组成.注意;类声明不用分号结尾.
客体类名称有一个分离的命名空间.客体类,权限,类型(标识符)等有相同的名称的情况是可能的,但是那是一种不好的策略书写方法.
类定义语法
类定义允许你声明客体类名称.下面是类声明的全语法:
class class_name
class_name 客体类的标识符.这个标识符可以任意长度,并且可以包含ASCII字符或数字
类定义仅仅在整体策略和基本可加载模块中是有效的.在条件语句和非基本可加载模块中他不是有效的.
4.2.2 声明和关联客体类权限
有两种方法声明权限.第一种叫做公共权限,并且允许我们创造一个和客体类关联成一个组的权限.当客体类分享一系列访问权限的时候,公共权限是有用的.第二种方法叫做类特定权限,该方法允许我们单独声明某个类的特定权限.正如我们看到的,有一些客体类仅仅有特定权限,有些仅仅有公共权限,有些这两种权限都有.
4.2.2.1 公共权限
公共权限语句允许我们声明一些列的权限与两个或多个客体类联系起来组成组.公共权限语句的完全语法在后面会有展示.例如,unix”一切皆文件”的信条意味着很多文件相关的客体类拥有公共权限.下面是一个文件相关的权限的声明方式:
common file
{
ioctl
read
write
create
getattr
setattr
lock
relabelfrom
relabelto
append
unlike
link
rename
execute
swapom
quotaon
mounton
}
这个语句声明了一个公共权限集称为文件,并且里面定义了一些相关权限.一个公共权限语句本身是没有效果的.当我们将这些权限和客体类联系在一起的时候他才会有用.
就像对象类(客体类),公共权限名称被声明在他们自己的命名空间中.当我们不仔细的话,可能会使我们迷惑.例如,就像我们在前面例子中阐述的一样,我们有一个客体类和一个公用权限名字为文件.虽然名字是一样的,他们事实上是策略的两个不同的组件.
公共权限语句语法
公共权限语句允许你声明一个公共权限名称,该公共权限有一系列的权限能够和客体类关联成一个组.公共权限可以和多个客体类相关联.下面是公共权限语句的完全语法.
commom commom_name {perm_set}
common_name 公共权限的标识符.客体类可以是任意长度并且可以包含ASCII字符,数字和横线(-),还有点(.)
perm_set 在一个空间分离列表中的一个或多个权限标识符.标识符可以是任何长度,并且可以包含ASCII字符,数字,横线和点
一个公共权限集使用访问向量语句于客体类向关联.
公共权限语句仅仅在整体策略和基本可加载模块中是有效的.他们在条件语句和非基本可加载模块中是无效的.
4.2.2.2 权限和客体类相关联
我们使用访问向量语句将权限和客体类关联在一起.我们使用访问向量语句去关联公共和类特定权限.例如,下面语句是将客体类dir和单个类特定权限关联在一起.
class dir{search}
正如这个例子显示的,访问向量语句看上去很像类定义语句.类定义语句和访问向量语句虽然是使用同一个关键字开始的,但是他们是不同的.访问向量语句必须要提供一个之前定义的类名称和提供一个或多个权限.在这个例子中,我们定义了一个单一的,类特定权限,注意,这条语句是不用分好结尾的.
之前的访问向量语句会导致dir客体类拥有一个类特定权限:search.通常来说,在一个客体类中你会看到有很多权限,就像下面的语句.
class dir{search add_name remove_name}
这个例子将三个类特定权限和客体类dir关联在一起.我们也可以通过在访问向量语句中使用可选的关键子”inherits”将公共权限和客体类关联在一起.例如,dir客体类是很多文件相似的客体类中的一个,并且和其他文件相似客体类共享公共权限.下面的访问向量语句是一个完整的将die和公共权限文件关联在一起的语句,就像之前展示的,和一些类特定权限一块就会使其与别的目录不同.
class dir
inherits file
{
add_name
remove_name
reparent
search
rmdir
}
正如这个例子阐述的,我们通过关键字”inherits”加上后面之前声明的公共权限集(file)来将所有的公共权限和dir关联在一起.这条语句的结果就是客体类dir有效的权限都是那些之前定义的公共权限file,并且还有dir的五个特定权限.
对于一个客体类仅仅拥有公共权限是可能的.例如,对于客体类链接文件(lnk_file)的访问向量语句:
class lnk_file inherits file
这条语句会使得类lnk_file仅仅拥有在公共权限file中定义的权限,而没有别的.
同样的,客体类仅仅拥有类特定权限也是可能的(也就是说没有公共权限).例如,代表文件描述符的客体类(fd)的访问向量语句有一个单一的类特定权限,允许使用文件描述符.
class fd {use}
访问向量语句语法
访问向量语句将权限和之前声明的客体类关联起来.下面是访问向量语句的完全语法:
class class_name [inherits common] [{perm_set}]
//class_name 之前声明的客体类名称
//commom 之前声明的公共权限集合名称
//perm_set 在一个分离空间列表中的一个或多个权限标识符. 标识符可以是任意长度,可以包含ASCII字符,数字还有点
在最小情况下,common和perm_set至少要提供一个,或者是两个都提供.访问向量语句的最后结果就是这两个方面的权限的集合.
访问向量语句仅仅在整体策略或者是基本可加载模块中是有效的,但是在条件语句和非基本可加载模块中是无效的.