rgw: user info structure supports multiple subusers and keys

This commit is contained in:
Yehuda Sadeh 2011-05-20 15:15:48 -07:00
parent 6f8708baec
commit 2cf5048f6b
5 changed files with 115 additions and 26 deletions

View File

@ -326,17 +326,22 @@ int main(int argc, char **argv)
} }
} }
int err; int err;
map<string, RGWAccessKey>::iterator kiter;
switch (opt_cmd) { switch (opt_cmd) {
case OPT_USER_CREATE: case OPT_USER_CREATE:
case OPT_USER_MODIFY: case OPT_USER_MODIFY:
if (user_id) if (user_id)
info.user_id = user_id; info.user_id = user_id;
if (access_key) if (access_key && secret_key) {
info.access_key = access_key; RGWAccessKey k;
if (secret_key) k.id = access_key;
info.secret_key = secret_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) if (display_name)
info.display_name = display_name; info.display_name = display_name;
if (user_email) if (user_email)
@ -357,8 +362,12 @@ int main(int argc, char **argv)
case OPT_USER_INFO: case OPT_USER_INFO:
cout << "User ID: " << info.user_id << std::endl; cout << "User ID: " << info.user_id << std::endl;
cout << "Access Key: " << info.access_key << std::endl; for (kiter = info.access_keys.begin(); kiter != info.access_keys.end(); ++kiter) {
cout << "Secret Key: " << info.secret_key << std::endl; 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 << "Display Name: " << info.display_name << std::endl;
cout << "Email: " << info.user_email << std::endl; cout << "Email: " << info.user_email << std::endl;
cout << "OpenStack User: " << (info.openstack_name.size() ? info.openstack_name : "<undefined>")<< std::endl; cout << "OpenStack User: " << (info.openstack_name.size() ? info.openstack_name : "<undefined>")<< std::endl;

View File

@ -43,7 +43,7 @@ extern string rgw_root_bucket;
#define RGW_BUCKETS_OBJ_PREFIX ".buckets" #define RGW_BUCKETS_OBJ_PREFIX ".buckets"
#define USER_INFO_VER 5 #define USER_INFO_VER 6
#define RGW_MAX_CHUNK_SIZE (4*1024*1024) #define RGW_MAX_CHUNK_SIZE (4*1024*1024)
@ -155,17 +155,62 @@ struct fcgx_state {
class RGWAccessControlPolicy; 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 struct RGWUserInfo
{ {
uint64_t auid; uint64_t auid;
string user_id; string user_id;
string access_key;
string secret_key;
string display_name; string display_name;
string user_email; string user_email;
string openstack_name; string openstack_name;
string openstack_key; string openstack_key;
map<string, RGWAccessKey> access_keys;
map<string, RGWSubUser> subusers;
RGWUserInfo() : auid(0) {} RGWUserInfo() : auid(0) {}
@ -173,6 +218,14 @@ struct RGWUserInfo
__u32 ver = USER_INFO_VER; __u32 ver = USER_INFO_VER;
::encode(ver, bl); ::encode(ver, bl);
::encode(auid, 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(access_key, bl);
::encode(secret_key, bl); ::encode(secret_key, bl);
::encode(display_name, bl); ::encode(display_name, bl);
@ -180,14 +233,24 @@ struct RGWUserInfo
::encode(openstack_name, bl); ::encode(openstack_name, bl);
::encode(openstack_key, bl); ::encode(openstack_key, bl);
::encode(user_id, bl); ::encode(user_id, bl);
::encode(access_keys, bl);
::encode(subusers, bl);
} }
void decode(bufferlist::iterator& bl) { void decode(bufferlist::iterator& bl) {
__u32 ver; __u32 ver;
::decode(ver, bl); ::decode(ver, bl);
if (ver >= 2) ::decode(auid, bl); if (ver >= 2) ::decode(auid, bl);
else auid = CEPH_AUTH_UID_DEFAULT; else auid = CEPH_AUTH_UID_DEFAULT;
string access_key;
string secret_key;
::decode(access_key, bl); ::decode(access_key, bl);
::decode(secret_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(display_name, bl);
::decode(user_email, bl); ::decode(user_email, bl);
if (ver >= 3) ::decode(openstack_name, bl); if (ver >= 3) ::decode(openstack_name, bl);
@ -196,15 +259,18 @@ struct RGWUserInfo
::decode(user_id, bl); ::decode(user_id, bl);
else else
user_id = access_key; user_id = access_key;
if (ver >= 6) {
::decode(access_keys, bl);
::decode(subusers, bl);
}
} }
void clear() { void clear() {
user_id.clear(); user_id.clear();
access_key.clear();
secret_key.clear();
display_name.clear(); display_name.clear();
user_email.clear(); user_email.clear();
auid = CEPH_AUTH_UID_DEFAULT; auid = CEPH_AUTH_UID_DEFAULT;
access_keys.clear();
} }
}; };
WRITE_CLASS_ENCODER(RGWUserInfo) WRITE_CLASS_ENCODER(RGWUserInfo)

View File

@ -118,7 +118,7 @@ bool rgw_verify_os_token(req_state *s)
return false; 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; return true;
} }

View File

@ -427,8 +427,14 @@ bool RGWHandler_REST_S3::authorize(struct req_state *s)
get_auth_header(s, auth_hdr, qsr); get_auth_header(s, auth_hdr, qsr);
RGW_LOG(10) << "auth_hdr:\n" << auth_hdr << dendl; RGW_LOG(10) << "auth_hdr:\n" << auth_hdr << dendl;
const char *key = s->user.secret_key.c_str(); map<string, RGWAccessKey>::iterator iter = s->user.access_keys.find(auth_id);
int key_len = strlen(key); 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]; char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
calc_hmac_sha1(key, key_len, auth_hdr.c_str(), auth_hdr.size(), hmac_sha1); calc_hmac_sha1(key, key_len, auth_hdr.c_str(), auth_hdr.size(), hmac_sha1);

View File

@ -28,7 +28,7 @@ void rgw_get_anon_user(RGWUserInfo& info)
{ {
info.user_id = RGW_USER_ANON_ID; info.user_id = RGW_USER_ANON_ID;
info.display_name.clear(); 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) 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()) { if (info.access_keys.size()) {
/* check if openstack mapping exists */ /* check if access keys already exist */
RGWUserInfo inf; RGWUserInfo inf;
int r = rgw_get_user_info_by_access_key(info.access_key, inf); map<string, RGWAccessKey>::iterator iter = info.access_keys.begin();
if (r >= 0 && inf.user_id.compare(info.user_id) != 0) { for (; iter != info.access_keys.end(); ++iter) {
RGW_LOG(0) << "can't store user info, access key already mapped to another user" << dendl; RGWAccessKey& k = iter->second;
return -EEXIST; 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; return ret;
} }
if (info.access_key.size()) { if (info.access_keys.size()) {
ret = put_obj(info.access_key, ui_key_bucket, info.access_key, uid_bl.c_str(), uid_bl.length()); map<string, RGWAccessKey>::iterator iter = info.access_keys.begin();
if (ret < 0) for (; iter != info.access_keys.end(); ++iter) {
return ret; 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()) if (info.openstack_name.size())