2.3.2 ACL在VFS中的实现
在Linux中,ACL是根据POSIX标准实现的,其数据结构和POSIX标准规定的数据结构相同,并且定义了若干与ACL相关的操作,下面分别进行介绍。
2.3.2.1 POSIX标准中的ACL
在POSIX标准中,用posix_acl结构体来表示一个文件的ACL属性,其定义在include/linux/posix_acl.h中,具体定义如下所示:
对于该结构体,各重要字段含义如表2-3所示:
表2-3 posix_acl中重要字段的含义
类型
字段
含义
atomic_t
a_refcount
表示该ACL的引用计数
unsigned int
a_count
访问控制列表中的访问控制列表项的数量
struct posix_acl_entry
a_entries
指向具体访问控制列表项的数组
如上表所示,a_entries变量存放了ACL中的表项,在POSIX标准中,访问控制列表表项用posix_acl_entry结构体表示,具体定义如下所示:
对于该结构体,其各字段如下表2-4所示:
表2-4 posix_acl_entry中重要字段的含义
类型
字段
含义
short
e_tag
要限制的实体的类型
unsigned short
e_perm
授予该实体的访问权限,在posix中定义了三个宏:ACL_READ、ACL_WRITE、ACL_EXECUTE分别表示读、写、执行
unsigned int
e_id
相应的实体的id,如果e_tag为user,则该id表示uid,如果e_tag为group,则其表示gid
对于e_tag字段,POSIX标准预定义了六种实体类型:
表2-5 posix标准中实体类型
实体类型
含义
ACL_USER_OBJ
代表文件属主的ACL 表项
ACL_USER
代表文件属主之外的其他单个用户的ACL表项
ACL_GROUP_OBJ
代表文件所属用户组的ACL表项
ACL_GROUP
代表其他用户组的ACL表项
ACL_OTHER
代表除了上述各项之外的其他用户的ACL表项
ACL_MASK
代表除了ACL_USER_OBJ和ACL_OTHER之外的ACL表项所允许的最大权限
2.3.2.2ACL在VFS中的相关操作
对于Linux,其实现的POSIX标准中定义的ACL相关的操作如表2-6所示:
表2-6 POSIX标准规定的ACL相关的操作
函数所属文件
函数名称
函数功能
posix_acl.h
posix_acl_dup()
将访问控制列表的引用计数加1
posix_acl_release()
释放ACL所占有的空间
acl_by_type()
根据ACL的类型获得文件相应的ACL属性。POSIX标准定义了两种类型:ACL_TYPE_ACCESS表示用于访问控制的ACL;ACL_TYPE_DEFAULT只能由于目录,表示目录的默认ACL
get_cached_acl()
根据指定的类型获得文件的ACL属性,并将ACL的引用计数加1
get_cached_acl_rcu()
通过调用rcu_dereference()获取受RCU保护的指向ACL的指针
set_cached_acl()
通过调用rcu_assign_pointer()函数来设置文件的ACL属性,并释放原来的ACL所占有的空间
forget_cached_acl()
如果指定文件的指定类型的ACL属性位于高速缓存,则释放它
forget_all_cached_acl()
释放文件所有的ACL属性
cache_no_acl()
用于将文件对应的inode中的ACL属性字段清空
posix_acl.c
posix_acl_init()
根据指定的参数初始化ACL
posix_acl_alloc()
根据参数为ACL分配相应的存储空间,并进行初始化
posix_acl_clone()
复制一个ACL,并返回指向该ACL的指针
posix_acl_valid()
检查一个访问控制列表是否有效
posix_acl_equiv_mode()
判断ACL是否可以被传统的文件模式权限位所替代
posix_acl_from_mode()
创建一个代表文件权限模式位的ACL
posix_acl_permission()
根据ACL判断当前进程是否具有对指定节点的指定权限
posix_acl_create_masq()
根据创建文件时指定的文件权限去修改相应的ACL表项
posix_acl_chmod_masq()
该函数用于在调用chmod()时修改ACL
posix_acl_create()
该函数用于根据指定文件的权限和ACL属性来创建一个新的ACL,并释放原来的ACL
posix_acl_chmod()
在调用chmod()时,为文件创建一个新的ACL
如表2-6所示,其中最重要的函数为posix_acl_permission()函数,该函数用来检查当前进程是否具有对指定文件的访问权限,若有则返回0,反之返回错误码。下面主要针对该函数从源码上进行分析,其函数头如下所示:
该函数包含三个参数:inode参数指定了该函数要检查的目标文件;acl参数指定了该目标文件的访问控制列表;want参数指定了要检查的权限。
图2-15 posix_acl_permission()函数调用流程图
如图2-15所示,posix_acl_permission()函数实际上是通过FOREACH_ACL_ENTRY()宏来遍历ACL的列表项,并根据列表项中指定的ACL的实体类型进行不同的处理。在对进程组进行操作时,调用了in_group_p()函数,该函数用于判断组id是否等于当前进程的fsgid,如果不等,接着判断该gid是否位于进程的附加组中。
图2-16 in_group_p()函数调用流程图
如图2-16所示,in_group_p()函数依次调用了三个函数:current_cred()宏用于获取当前进程的cred;gid_eq()函数用于判断两个gid是否相等,这里用于判断当前进程的fsgid和指定ACL表项中的gid是否相等,如果相等,则直接返回,反之调用groups_search()函数,该函数采用折半查找法在当前进程的fsgid附加组中查找指定的组。in_group_p()函数在成功执行时返回1,反之返回0。为什么当指定ACL表项中gid和进程的fsuid相等时,就返回真呢?事实上,在Linux中,每个进程都有四种类型的ID:真实的用户/组id,该ID标识了进程的真正所有者;有效的用户/组ID,该ID用于判断进程执行各种操作的权限;文件系统用户/组ID,该ID用于标识对文件系统进行访问检查的用户或组,从而将对文件系统的权限限制在指定的ID上;保存的设置用户/组ID,该ID用于还原有效用户。所以在in_group_p()函数中,当gid与当前进程的fsuid相等时,就表示该进程可以访问该文件,从而直接返回。
赞赏
人赞赏
标签:
本文链接:https://www.hello-linux.com/linux/42230.html
版权声明:本网站内容均来源于网络,如涉及侵权,请联系作者!
还没有评论,快来说点什么吧~