mirror of
https://github.com/ceph/ceph
synced 2025-02-23 19:17:37 +00:00
rgw: user info structure supports multiple subusers and keys
This commit is contained in:
parent
6f8708baec
commit
2cf5048f6b
@ -326,17 +326,22 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int err;
|
||||
map<string, RGWAccessKey>::iterator kiter;
|
||||
switch (opt_cmd) {
|
||||
case OPT_USER_CREATE:
|
||||
case OPT_USER_MODIFY:
|
||||
if (user_id)
|
||||
info.user_id = user_id;
|
||||
if (access_key)
|
||||
info.access_key = access_key;
|
||||
if (secret_key)
|
||||
info.secret_key = secret_key;
|
||||
if (access_key && secret_key) {
|
||||
RGWAccessKey k;
|
||||
k.id = access_key;
|
||||
k.key = secret_key;
|
||||
info.access_keys[access_key] = k;
|
||||
} else if (access_key || secret_key) {
|
||||
cerr << "access key modification requires both access key and secret key" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if (display_name)
|
||||
info.display_name = display_name;
|
||||
if (user_email)
|
||||
@ -357,8 +362,12 @@ int main(int argc, char **argv)
|
||||
|
||||
case OPT_USER_INFO:
|
||||
cout << "User ID: " << info.user_id << std::endl;
|
||||
cout << "Access Key: " << info.access_key << std::endl;
|
||||
cout << "Secret Key: " << info.secret_key << std::endl;
|
||||
for (kiter = info.access_keys.begin(); kiter != info.access_keys.end(); ++kiter) {
|
||||
RGWAccessKey& k = kiter->second;
|
||||
cout << "User: " << info.user_id << (k.subuser.empty() ? "" : ":") << k.subuser << std::endl;
|
||||
cout << " Access Key: " << k.id << std::endl;
|
||||
cout << " Secret Key: " << k.key << std::endl;
|
||||
}
|
||||
cout << "Display Name: " << info.display_name << std::endl;
|
||||
cout << "Email: " << info.user_email << std::endl;
|
||||
cout << "OpenStack User: " << (info.openstack_name.size() ? info.openstack_name : "<undefined>")<< std::endl;
|
||||
|
@ -43,7 +43,7 @@ extern string rgw_root_bucket;
|
||||
|
||||
#define RGW_BUCKETS_OBJ_PREFIX ".buckets"
|
||||
|
||||
#define USER_INFO_VER 5
|
||||
#define USER_INFO_VER 6
|
||||
|
||||
#define RGW_MAX_CHUNK_SIZE (4*1024*1024)
|
||||
|
||||
@ -155,17 +155,62 @@ struct fcgx_state {
|
||||
|
||||
class RGWAccessControlPolicy;
|
||||
|
||||
struct RGWAccessKey {
|
||||
string id;
|
||||
string key;
|
||||
string subuser;
|
||||
|
||||
RGWAccessKey() {}
|
||||
void encode(bufferlist& bl) const {
|
||||
__u32 ver = 1;
|
||||
::encode(ver, bl);
|
||||
::encode(id, bl);
|
||||
::encode(key, bl);
|
||||
::encode(subuser, bl);
|
||||
}
|
||||
|
||||
void decode(bufferlist::iterator& bl) {
|
||||
__u32 ver;
|
||||
::decode(ver, bl);
|
||||
::decode(id, bl);
|
||||
::decode(key, bl);
|
||||
::decode(subuser, bl);
|
||||
}
|
||||
};
|
||||
WRITE_CLASS_ENCODER(RGWAccessKey);
|
||||
|
||||
struct RGWSubUser {
|
||||
string name;
|
||||
uint32_t flags;
|
||||
|
||||
RGWSubUser() {}
|
||||
void encode(bufferlist& bl) const {
|
||||
__u32 ver = 1;
|
||||
::encode(ver, bl);
|
||||
::encode(name, bl);
|
||||
::encode(flags, bl);
|
||||
}
|
||||
|
||||
void decode(bufferlist::iterator& bl) {
|
||||
__u32 ver;
|
||||
::decode(ver, bl);
|
||||
::decode(name, bl);
|
||||
::decode(flags, bl);
|
||||
}
|
||||
};
|
||||
WRITE_CLASS_ENCODER(RGWSubUser);
|
||||
|
||||
|
||||
struct RGWUserInfo
|
||||
{
|
||||
uint64_t auid;
|
||||
string user_id;
|
||||
string access_key;
|
||||
string secret_key;
|
||||
string display_name;
|
||||
string user_email;
|
||||
string openstack_name;
|
||||
string openstack_key;
|
||||
map<string, RGWAccessKey> access_keys;
|
||||
map<string, RGWSubUser> subusers;
|
||||
|
||||
RGWUserInfo() : auid(0) {}
|
||||
|
||||
@ -173,6 +218,14 @@ struct RGWUserInfo
|
||||
__u32 ver = USER_INFO_VER;
|
||||
::encode(ver, bl);
|
||||
::encode(auid, bl);
|
||||
string access_key;
|
||||
string secret_key;
|
||||
if (!access_keys.empty()) {
|
||||
map<string, RGWAccessKey>::const_iterator iter = access_keys.begin();
|
||||
const RGWAccessKey& k = iter->second;
|
||||
access_key = k.id;
|
||||
secret_key = k.key;
|
||||
}
|
||||
::encode(access_key, bl);
|
||||
::encode(secret_key, bl);
|
||||
::encode(display_name, bl);
|
||||
@ -180,14 +233,24 @@ struct RGWUserInfo
|
||||
::encode(openstack_name, bl);
|
||||
::encode(openstack_key, bl);
|
||||
::encode(user_id, bl);
|
||||
::encode(access_keys, bl);
|
||||
::encode(subusers, bl);
|
||||
}
|
||||
void decode(bufferlist::iterator& bl) {
|
||||
__u32 ver;
|
||||
::decode(ver, bl);
|
||||
if (ver >= 2) ::decode(auid, bl);
|
||||
else auid = CEPH_AUTH_UID_DEFAULT;
|
||||
string access_key;
|
||||
string secret_key;
|
||||
::decode(access_key, bl);
|
||||
::decode(secret_key, bl);
|
||||
if (ver < 6) {
|
||||
RGWAccessKey k;
|
||||
k.id = access_key;
|
||||
k.key = secret_key;
|
||||
access_keys[access_key] = k;
|
||||
}
|
||||
::decode(display_name, bl);
|
||||
::decode(user_email, bl);
|
||||
if (ver >= 3) ::decode(openstack_name, bl);
|
||||
@ -196,15 +259,18 @@ struct RGWUserInfo
|
||||
::decode(user_id, bl);
|
||||
else
|
||||
user_id = access_key;
|
||||
if (ver >= 6) {
|
||||
::decode(access_keys, bl);
|
||||
::decode(subusers, bl);
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
user_id.clear();
|
||||
access_key.clear();
|
||||
secret_key.clear();
|
||||
display_name.clear();
|
||||
user_email.clear();
|
||||
auid = CEPH_AUTH_UID_DEFAULT;
|
||||
access_keys.clear();
|
||||
}
|
||||
};
|
||||
WRITE_CLASS_ENCODER(RGWUserInfo)
|
||||
|
@ -118,7 +118,7 @@ bool rgw_verify_os_token(req_state *s)
|
||||
return false;
|
||||
}
|
||||
|
||||
RGW_LOG(0) << "user_id=" << s->user.user_id << " access_key=" << s->user.access_key << dendl;
|
||||
RGW_LOG(0) << "user_id=" << s->user.user_id << dendl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -427,8 +427,14 @@ bool RGWHandler_REST_S3::authorize(struct req_state *s)
|
||||
get_auth_header(s, auth_hdr, qsr);
|
||||
RGW_LOG(10) << "auth_hdr:\n" << auth_hdr << dendl;
|
||||
|
||||
const char *key = s->user.secret_key.c_str();
|
||||
int key_len = strlen(key);
|
||||
map<string, RGWAccessKey>::iterator iter = s->user.access_keys.find(auth_id);
|
||||
if (iter == s->user.access_keys.end()) {
|
||||
RGW_LOG(0) << "ERROR: access key not encoded in user info" << dendl;
|
||||
return false;
|
||||
}
|
||||
RGWAccessKey& k = iter->second;
|
||||
const char *key = k.key.c_str();
|
||||
int key_len = k.key.size();
|
||||
|
||||
char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
|
||||
calc_hmac_sha1(key, key_len, auth_hdr.c_str(), auth_hdr.size(), hmac_sha1);
|
||||
|
@ -28,7 +28,7 @@ void rgw_get_anon_user(RGWUserInfo& info)
|
||||
{
|
||||
info.user_id = RGW_USER_ANON_ID;
|
||||
info.display_name.clear();
|
||||
info.secret_key.clear();
|
||||
info.access_keys.clear();
|
||||
}
|
||||
|
||||
static int put_obj(string& uid, string& bucket, string& oid, const char *data, size_t size)
|
||||
@ -68,13 +68,17 @@ int rgw_store_user_info(RGWUserInfo& info)
|
||||
}
|
||||
}
|
||||
|
||||
if (info.access_key.size()) {
|
||||
/* check if openstack mapping exists */
|
||||
if (info.access_keys.size()) {
|
||||
/* check if access keys already exist */
|
||||
RGWUserInfo inf;
|
||||
int r = rgw_get_user_info_by_access_key(info.access_key, inf);
|
||||
if (r >= 0 && inf.user_id.compare(info.user_id) != 0) {
|
||||
RGW_LOG(0) << "can't store user info, access key already mapped to another user" << dendl;
|
||||
return -EEXIST;
|
||||
map<string, RGWAccessKey>::iterator iter = info.access_keys.begin();
|
||||
for (; iter != info.access_keys.end(); ++iter) {
|
||||
RGWAccessKey& k = iter->second;
|
||||
int r = rgw_get_user_info_by_access_key(k.id, inf);
|
||||
if (r >= 0 && inf.user_id.compare(info.user_id) != 0) {
|
||||
RGW_LOG(0) << "can't store user info, access key already mapped to another user" << dendl;
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,10 +98,14 @@ int rgw_store_user_info(RGWUserInfo& info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (info.access_key.size()) {
|
||||
ret = put_obj(info.access_key, ui_key_bucket, info.access_key, uid_bl.c_str(), uid_bl.length());
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (info.access_keys.size()) {
|
||||
map<string, RGWAccessKey>::iterator iter = info.access_keys.begin();
|
||||
for (; iter != info.access_keys.end(); ++iter) {
|
||||
RGWAccessKey& k = iter->second;
|
||||
ret = put_obj(k.id, ui_key_bucket, k.id, uid_bl.c_str(), uid_bl.length());
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.openstack_name.size())
|
||||
|
Loading…
Reference in New Issue
Block a user