RGW ACL分析文档
1、描述
ACL(Access Control List)权限控制列表,用于控制用户的行为权限。RGW提供bucket和object级别的权限访问控制,RGW允许针对每个用户设置不同的权限,也可以一次性对所有用户设置权限,具体的权限值及含义如下表:
权限值 | 权限对访问者的限制 |
---|---|
READ | 可读。Bucket:列出bucket下的object;Object:读取object的数据; |
WRITE | 可写。Bucket:创建/删除/覆盖写该bucket下的object;Object:无 |
READ_CAP | 可读取acl规则。Bucket:读取bucket的acl规则;Object:读取object的acl规则; |
WRITE_CAP | 可修改acl规则。Bucket:修改bucket的acl规则;Object:修改object的acl规则; |
FULL_CONTROL | 同时具备上述权限 |
默认情况下,对其所属用户而言,bucket和object的acl均为FULL_CONTROL。
2、关键代码分析
2.1 数据结构
RGW的请求入口函数是process_request,然后调用rgw_process_authenticated函数进行各种鉴权、校验和请求执行操作,acl的读取和鉴权操作也在该函数中实现。
在rgw_process_authenticated函数内部,会从磁盘上读取bucket和object权限,并保保存到内存中,相关函数为:
读取bucket规则:rgw_build_bucket_policies
读取object规则:rgw_build_object_policies
用来保存bucket和object的数据结构如下:
/** Store all the state necessary to complete and respond to an HTTP request*/
struct req_state {
CephContext *cct;
rgw::io::BasicClient *cio;
RGWRequest *req{nullptr}; /// XXX: re-remove??
//…
std::unique_ptr<RGWAccessControlPolicy> user_acl; //保存user acl
std::unique_ptr<RGWAccessControlPolicy> bucket_acl; //保存bucket acl
std::unique_ptr<RGWAccessControlPolicy> object_acl; //object acl
};
class RGWAccessControlPolicy
{
protected:
CephContext *cct;
RGWAccessControlList acl;
ACLOwner owner;
//…
};
class RGWAccessControlList
{
protected:
CephContext *cct;
map<string, int> acl_user_map;
map<uint32_t, int> acl_group_map;
list<ACLReferer> referer_list;
multimap<string, ACLGrant> grant_map;
};
class ACLGrant
{
protected:
ACLGranteeType type;
rgw_user id;
string email;
ACLPermission permission;
string name;
ACLGroupTypeEnum group;
string url_spec;
//…
};
由上面的数据结构可以清晰看出,内存中保存acl规则列表的是multimap,即multimap<string, ACLGrant> grant_map;
其中:
(1)struct rgw_user的成员id用于标识用户id;
(2)string name 用于标识用户名;
(3)class ACLGranteeType的type成员用于标识用户类型,比如是针对所有用户,还是特定用户;取值如下:
ACL_TYPE_CANON_USER = 0,
ACL_TYPE_EMAIL_USER = 1,
ACL_TYPE_GROUP = 2,
ACL_TYPE_UNKNOWN = 3,
ACL_TYPE_REFERER = 4,
(4)class ACLPermission的flags成员用于标识权限,取值如下:
#define RGW_PERM_NONE 0x00
#define RGW_PERM_READ 0x01
#define RGW_PERM_WRITE 0x02
#define RGW_PERM_READ_ACP 0x04
#define RGW_PERM_WRITE_ACP 0x08
#define RGW_PERM_READ_OBJS 0x10
#define RGW_PERM_WRITE_OBJS 0x20
#define RGW_PERM_FULL_CONTROL ( RGW_PERM_READ | RGW_PERM_WRITE | \
RGW_PERM_READ_ACP | RGW_PERM_WRITE_ACP )
#define RGW_PERM_ALL_S3 RGW_PERM_FULL_CONTROL
#define RGW_PERM_INVALID 0xFF00
由上述信息可以唯一确定一条acl规则,可以直观地从下图看到:
2.2 基本操作
1、Acl鉴权过程:
操作之前,先从磁盘读取acl到内存中,再和用户码进行比较。比如创建object时,会先判断该bucket有WRITE权限;读取object时,判断该object有READ权限等;
2、acl设置
下面从主要看获取acl和设置acl的处理,类图如下:
(1) 修改/设置acl
入口函数:
RGWPutACLs::execute();
客户端发送请求数据到rgw,格式为为xml,如下图定义6条acl规则,分别针对用户级别(FULL_CONTROL、READ、WRITE、READ_CAP、WRITE_CAP)和group级别(READ)。
Rgw将xml解析成map<string, bufferlist> attrs;结构,并调用rgw_bucket_set_attrs函数写入到bucket的attr中。对于object来说,调用modify_obj_attr写入对象的attr中。
3、acl获取
获取的处理比较简单,在第一节acl鉴权过程中已将acl读取到内存中,直接从struct req_state结构体变量中提取,并转换成xml格式返回。