openGauss源码解析(201)
openGauss源码解析:安全管理源码解析(12)
9.4.2 权限检查
用户在对数据库对象进行访问操作时,数据库会检查用户是否拥有该对象的操作权限。通常数据库对象的所有者和初始用户(superuser)拥有该对象的全部操作权限,其他普通用户需要被授予权限才可以执行相应操作。数据库通过查询数据库对象的访问控制列表检查用户对数据库对象的访问权限,数据库对象的ACL保存在对应的系统表中,当被授予或回收对象权限时,系统表中保存的ACL权限位会被更新。常用的数据库对象权限检查函数、ACL检查函数、ACL所在系统表以及对象所有者检查函数对应关系如表9-5所示。
表9-5 数据库对象函数对应关系表。
对象 | 权限检查 | ACL检查 | 所有者检查 | 系统表 |
---|---|---|---|---|
table | pg_class_aclcheck | pg_class_aclmask | pg_class_ownercheck | pg_class |
column | pg_attribute_aclcheck | pg_attribute_aclmask | NA | pg_attribute |
database | pg_database_aclcheck | pg_database_aclmask | pg_database_ownercheck | pg_database |
function | pg_proc_aclcheck | pg_proc_aclmask | pg_proc_ownercheck | pg_proc |
language | pg_language_aclcheck | pg_language_aclmask | pg_language_ownercheck | pg_language |
largeobject | pg_largeobject_aclcheck_snapshot | pg_largeobject_aclmask_snapshot | pg_largeobject_ownercheck | pg_largeobject_metadata |
namespace | pg_namespace_aclcheck | pg_namespace_aclmask | pg_namespace_ownercheck | pg_namespace |
tablespace | pg_tablespace_aclcheck | pg_tablespace_aclmask | pg_tablespace_ownercheck | pg_tablespace |
foreign data wrapper | pg_foreign_data_wrapper_aclcheck | pg_foreign_data_wrapper_aclmask | pg_foreign_data_wrapper_ownercheck | pg_foreign_data_wrapper |
foreign server | pg_foreign_server_aclcheck | pg_foreign_server_aclmask | pg_foreign_server_ownercheck | pg_foreign_server |
type | pg_type_aclcheck | pg_type_aclmask | pg_type_ownercheck | pg_type |
下面以表的权限检查为例进行权限检查过程说明。表权限检查函数pg_class_aclcheck的定义代码如下:
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode, bool check_nodegroup)
{
if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY, check_nodegroup) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
}
pg_class_aclcheck函数有4个入参,其中table_oid用于表示待检查的表,roleid用于表示待检查的用户或角色,mode表示待检查的权限,此权限可以是一种权限也可以是多种权限的组合。第4个参数check_nodegroup用于表示是否检查nodegroup逻辑集群权限,如果调用时不给此参数赋值则默认为true。函数返回值为枚举类型AclResult,如果检查结果有权限返回ACLCHECK_OK,无权限则返回ACLCHECK_NO_PRIV。
pg_class_aclcheck函数通过调用pg_class_aclmask函数实现对象权限检查。pg_class_aclmask函数有5个参数,其中第4个参数how为AclMaskHow枚举类型,包括ACLMASK_ALL和ACLMASK_ANY两种取值;ACLMASK_ALL表示需要满足待检查权限mode中的所有权限,ACLMASK_ANY表示只需满足待检查权限mode中的一种权限即可。pg_class_aclmask函数的其余4个参数table_oid、roleid、mode和check_nodegroup,直接由pg_class_aclcheck函数传入。pg_class_aclmask函数从pg_class系统表中获取ACL权限信息并调用aclmask函数完成权限位校验,通过AclMode数据类型返回权限检查结果。