mirror of
https://github.com/ceph/ceph
synced 2025-03-11 02:39:05 +00:00
rgw: multiple swift keys per user
This commit is contained in:
parent
9b18e55e86
commit
f883e6382f
@ -56,15 +56,14 @@ void _usage()
|
||||
cerr << " specified date (and optional time)\n";
|
||||
cerr << "options:\n";
|
||||
cerr << " --uid=<id> user id\n";
|
||||
cerr << " --auth-uid=<auid> librados uid\n";
|
||||
cerr << " --subuser=<name> subuser name\n";
|
||||
cerr << " --access-key=<key> S3 access key\n";
|
||||
cerr << " --swift-user=<group:name> Swift user\n";
|
||||
cerr << " --email=<email>\n";
|
||||
cerr << " --auth_uid=<auid> librados uid\n";
|
||||
cerr << " --secret=<key> S3 key\n";
|
||||
cerr << " --swift-secret=<key> Swift key\n";
|
||||
cerr << " --gen-access-key generate random access key\n";
|
||||
cerr << " --secret=<key> specify secret key\n";
|
||||
cerr << " --gen-access-key generate random access key (for S3)\n";
|
||||
cerr << " --gen-secret generate random secret key\n";
|
||||
cerr << " --key-type=<type> key type, options are: swift, s3\n";
|
||||
cerr << " --access=<access> Set access permissions for sub-user, should be one\n";
|
||||
cerr << " of read, write, readwrite, full\n";
|
||||
cerr << " --display-name=<name>\n";
|
||||
@ -291,8 +290,6 @@ static void show_user_info(RGWUserInfo& info, Formatter *formatter)
|
||||
formatter->dump_int("rados_uid", info.auid);
|
||||
formatter->dump_string("display_name", info.display_name.c_str());
|
||||
formatter->dump_string("email", info.user_email.c_str());
|
||||
formatter->dump_string("swift_user", info.swift_name.c_str());
|
||||
formatter->dump_string("swift_key", info.swift_key.c_str());
|
||||
formatter->dump_int("suspended", (int)info.suspended);
|
||||
|
||||
// keys
|
||||
@ -323,6 +320,18 @@ static void show_user_info(RGWUserInfo& info, Formatter *formatter)
|
||||
}
|
||||
formatter->close_section();
|
||||
|
||||
formatter->open_array_section("swift_keys");
|
||||
for (kiter = info.swift_keys.begin(); kiter != info.swift_keys.end(); ++kiter) {
|
||||
RGWAccessKey& k = kiter->second;
|
||||
const char *sep = (k.subuser.empty() ? "" : ":");
|
||||
const char *subuser = (k.subuser.empty() ? "" : k.subuser.c_str());
|
||||
formatter->open_object_section("key");
|
||||
formatter->dump_format("user", "%s%s%s", info.user_id.c_str(), sep, subuser);
|
||||
formatter->dump_string("secret_key", k.key);
|
||||
formatter->close_section();
|
||||
}
|
||||
formatter->close_section();
|
||||
|
||||
formatter->close_section();
|
||||
formatter->flush(cout);
|
||||
}
|
||||
@ -391,12 +400,16 @@ static void remove_old_indexes(RGWUserInfo& old_info, RGWUserInfo new_info)
|
||||
}
|
||||
}
|
||||
|
||||
if (!old_info.swift_name.empty() &&
|
||||
old_info.swift_name.compare(new_info.swift_name) != 0) {
|
||||
ret = rgw_remove_swift_name_index(new_info.user_id, old_info.swift_name);
|
||||
if (ret < 0 && ret != -ENOENT) {
|
||||
cerr << "ERROR: could not remove index for swift_name " << old_info.swift_name << " return code: " << ret << std::endl;
|
||||
success = false;
|
||||
map<string, RGWAccessKey>::iterator old_iter;
|
||||
for (old_iter = old_info.swift_keys.begin(); old_iter != old_info.swift_keys.end(); ++old_iter) {
|
||||
RGWAccessKey& swift_key = old_iter->second;
|
||||
map<string, RGWAccessKey>::iterator new_iter = new_info.swift_keys.find(swift_key.id);
|
||||
if (new_iter == new_info.swift_keys.end()) {
|
||||
ret = rgw_remove_swift_name_index(new_info.user_id, swift_key.id);
|
||||
if (ret < 0 && ret != -ENOENT) {
|
||||
cerr << "ERROR: could not remove index for swift_name " << swift_key.id << " return code: " << ret << std::endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,6 +456,11 @@ int bucket_stats(rgw_bucket& bucket, Formatter *formatter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum KeyType {
|
||||
KEY_TYPE_SWIFT,
|
||||
KEY_TYPE_S3,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
vector<const char*> args;
|
||||
@ -453,8 +471,10 @@ int main(int argc, char **argv)
|
||||
common_init_finish(g_ceph_context);
|
||||
|
||||
std::string user_id, access_key, secret_key, user_email, display_name;
|
||||
std::string bucket_name, pool_name, object, swift_user, swift_key;
|
||||
std::string bucket_name, pool_name, object;
|
||||
std::string date, time, subuser, access, format;
|
||||
std::string key_type_str;
|
||||
KeyType key_type = KEY_TYPE_S3;
|
||||
rgw_bucket bucket;
|
||||
uint32_t perm_mask = 0;
|
||||
uint64_t auid = -1;
|
||||
@ -500,6 +520,16 @@ int main(int argc, char **argv)
|
||||
pool_name = val;
|
||||
} else if (ceph_argparse_witharg(args, i, &val, "-o", "--object", (char*)NULL)) {
|
||||
object = val;
|
||||
} else if (ceph_argparse_witharg(args, i, &val, "--key-type", (char*)NULL)) {
|
||||
key_type_str = val;
|
||||
if (key_type_str.compare("swift") == 0) {
|
||||
key_type = KEY_TYPE_SWIFT;
|
||||
} else if (key_type_str.compare("s3") == 0) {
|
||||
key_type = KEY_TYPE_S3;
|
||||
} else {
|
||||
cerr << "bad key type: " << key_type_str << std::endl;
|
||||
return usage();
|
||||
}
|
||||
} else if (ceph_argparse_flag(args, i, "--gen-access-key", (char*)NULL)) {
|
||||
gen_key = true;
|
||||
} else if (ceph_argparse_flag(args, i, "--gen-secret", (char*)NULL)) {
|
||||
@ -510,10 +540,6 @@ int main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
auid = tmp;
|
||||
} else if (ceph_argparse_witharg(args, i, &val, "--swift-user", (char*)NULL)) {
|
||||
swift_user = val;
|
||||
} else if (ceph_argparse_witharg(args, i, &val, "--swift-secret", (char*)NULL)) {
|
||||
swift_key = val;
|
||||
} else if (ceph_argparse_witharg(args, i, &val, "--date", (char*)NULL)) {
|
||||
date = val;
|
||||
} else if (ceph_argparse_witharg(args, i, &val, "--time", (char*)NULL)) {
|
||||
@ -631,13 +657,6 @@ int main(int argc, char **argv)
|
||||
cerr << "could not find user by specified access key" << std::endl;
|
||||
}
|
||||
}
|
||||
if (!found && (!swift_user.empty())) {
|
||||
s = swift_user;
|
||||
if (rgw_get_user_info_by_swift(s, info) >= 0) {
|
||||
found = true;
|
||||
} else
|
||||
cerr << "could not find user by specified swift username" << std::endl;
|
||||
}
|
||||
if (found)
|
||||
user_id = info.user_id.c_str();
|
||||
}
|
||||
@ -760,15 +779,23 @@ int main(int argc, char **argv)
|
||||
case OPT_KEY_CREATE:
|
||||
if (!user_id.empty())
|
||||
info.user_id = user_id;
|
||||
if (key_type == KEY_TYPE_SWIFT)
|
||||
access_key = subuser;
|
||||
if ((!access_key.empty()) && (!secret_key.empty())) {
|
||||
RGWAccessKey k;
|
||||
k.id = access_key;
|
||||
k.key = secret_key;
|
||||
if (!subuser.empty())
|
||||
k.subuser = subuser;
|
||||
info.access_keys[access_key] = k;
|
||||
if (key_type == KEY_TYPE_SWIFT)
|
||||
info.swift_keys[access_key] = k;
|
||||
else
|
||||
info.access_keys[access_key] = k;
|
||||
} else if ((!access_key.empty()) || (!secret_key.empty())) {
|
||||
cerr << "access key modification requires both access key and secret key" << std::endl;
|
||||
if (key_type == KEY_TYPE_SWIFT)
|
||||
cerr << "swift key modification requires both subuser and secret key" << std::endl;
|
||||
else
|
||||
cerr << "access key modification requires both access key and secret key" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (!display_name.empty())
|
||||
@ -777,10 +804,6 @@ int main(int argc, char **argv)
|
||||
info.user_email = user_email;
|
||||
if (auid != (uint64_t)-1)
|
||||
info.auid = auid;
|
||||
if (!swift_user.empty())
|
||||
info.swift_name = swift_user;
|
||||
if (!swift_key.empty())
|
||||
info.swift_key = swift_key;
|
||||
if (!subuser.empty()) {
|
||||
RGWSubUser u;
|
||||
u.name = subuser;
|
||||
|
@ -57,7 +57,7 @@ using ceph::crypto::MD5;
|
||||
|
||||
#define RGW_BUCKETS_OBJ_PREFIX ".buckets"
|
||||
|
||||
#define USER_INFO_VER 7
|
||||
#define USER_INFO_VER 8
|
||||
|
||||
#define RGW_MAX_CHUNK_SIZE (512*1024)
|
||||
#define RGW_MAX_PENDING_CHUNKS 16
|
||||
@ -279,9 +279,8 @@ struct RGWUserInfo
|
||||
string user_id;
|
||||
string display_name;
|
||||
string user_email;
|
||||
string swift_name;
|
||||
string swift_key;
|
||||
map<string, RGWAccessKey> access_keys;
|
||||
map<string, RGWAccessKey> swift_keys;
|
||||
map<string, RGWSubUser> subusers;
|
||||
__u8 suspended;
|
||||
|
||||
@ -303,12 +302,21 @@ struct RGWUserInfo
|
||||
::encode(secret_key, bl);
|
||||
::encode(display_name, bl);
|
||||
::encode(user_email, bl);
|
||||
string swift_name;
|
||||
string swift_key;
|
||||
if (!swift_keys.empty()) {
|
||||
map<string, RGWAccessKey>::const_iterator iter = swift_keys.begin();
|
||||
const RGWAccessKey& k = iter->second;
|
||||
swift_name = k.id;
|
||||
swift_key = k.key;
|
||||
}
|
||||
::encode(swift_name, bl);
|
||||
::encode(swift_key, bl);
|
||||
::encode(user_id, bl);
|
||||
::encode(access_keys, bl);
|
||||
::encode(subusers, bl);
|
||||
::encode(suspended, bl);
|
||||
::encode(swift_keys, bl);
|
||||
}
|
||||
void decode(bufferlist::iterator& bl) {
|
||||
__u32 ver;
|
||||
@ -327,6 +335,8 @@ struct RGWUserInfo
|
||||
}
|
||||
::decode(display_name, bl);
|
||||
::decode(user_email, bl);
|
||||
string swift_name;
|
||||
string swift_key;
|
||||
if (ver >= 3) ::decode(swift_name, bl);
|
||||
if (ver >= 4) ::decode(swift_key, bl);
|
||||
if (ver >= 5)
|
||||
@ -341,6 +351,9 @@ struct RGWUserInfo
|
||||
if (ver >= 7) {
|
||||
::decode(suspended, bl);
|
||||
}
|
||||
if (ver >= 8) {
|
||||
::decode(swift_keys, bl);
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
|
@ -12,9 +12,9 @@ using namespace ceph::crypto;
|
||||
|
||||
static RGW_SWIFT_Auth_Get rgw_swift_auth_get;
|
||||
|
||||
static int build_token(string& os_user, string& key, uint64_t nonce, utime_t& expiration, bufferlist& bl)
|
||||
static int build_token(string& swift_user, string& key, uint64_t nonce, utime_t& expiration, bufferlist& bl)
|
||||
{
|
||||
::encode(os_user, bl);
|
||||
::encode(swift_user, bl);
|
||||
::encode(nonce, bl);
|
||||
::encode(expiration, bl);
|
||||
|
||||
@ -38,7 +38,7 @@ static int build_token(string& os_user, string& key, uint64_t nonce, utime_t& ex
|
||||
|
||||
}
|
||||
|
||||
static int encode_token(string& os_user, string& key, bufferlist& bl)
|
||||
static int encode_token(string& swift_user, string& key, bufferlist& bl)
|
||||
{
|
||||
uint64_t nonce;
|
||||
|
||||
@ -49,7 +49,7 @@ static int encode_token(string& os_user, string& key, bufferlist& bl)
|
||||
utime_t expiration = ceph_clock_now(g_ceph_context);
|
||||
expiration += RGW_SWIFT_TOKEN_EXPIRATION; // 15 minutes
|
||||
|
||||
ret = build_token(os_user, key, nonce, expiration, bl);
|
||||
ret = build_token(swift_user, key, nonce, expiration, bl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -79,10 +79,10 @@ int rgw_swift_verify_signed_token(const char *token, RGWUserInfo& info)
|
||||
|
||||
uint64_t nonce;
|
||||
utime_t expiration;
|
||||
string os_user;
|
||||
string swift_user;
|
||||
|
||||
try {
|
||||
::decode(os_user, iter);
|
||||
::decode(swift_user, iter);
|
||||
::decode(nonce, iter);
|
||||
::decode(expiration, iter);
|
||||
} catch (buffer::error& err) {
|
||||
@ -94,13 +94,18 @@ int rgw_swift_verify_signed_token(const char *token, RGWUserInfo& info)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if ((ret = rgw_get_user_info_by_swift(os_user, info)) < 0)
|
||||
if ((ret = rgw_get_user_info_by_swift(swift_user, info)) < 0)
|
||||
return ret;
|
||||
|
||||
dout(10) << "os_user=" << os_user << dendl;
|
||||
dout(10) << "swift_user=" << swift_user << dendl;
|
||||
|
||||
map<string, RGWAccessKey>::iterator siter = info.swift_keys.find(swift_user);
|
||||
if (siter == info.swift_keys.end())
|
||||
return -EPERM;
|
||||
RGWAccessKey& swift_key = siter->second;
|
||||
|
||||
bufferlist tok;
|
||||
ret = build_token(os_user, info.swift_key, nonce, expiration, tok);
|
||||
ret = build_token(swift_user, swift_key.key, nonce, expiration, tok);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -131,6 +136,8 @@ void RGW_SWIFT_Auth_Get::execute()
|
||||
string user_str = user;
|
||||
RGWUserInfo info;
|
||||
bufferlist bl;
|
||||
RGWAccessKey *swift_key;
|
||||
map<string, RGWAccessKey>::iterator siter;
|
||||
|
||||
if (g_conf->rgw_swift_url.length() == 0 ||
|
||||
g_conf->rgw_swift_url_prefix.length() == 0) {
|
||||
@ -145,7 +152,14 @@ void RGW_SWIFT_Auth_Get::execute()
|
||||
if ((ret = rgw_get_user_info_by_swift(user_str, info)) < 0)
|
||||
goto done;
|
||||
|
||||
if (info.swift_key.compare(key) != 0) {
|
||||
siter = info.swift_keys.find(user_str);
|
||||
if (siter == info.swift_keys.end()) {
|
||||
ret = -EPERM;
|
||||
goto done;
|
||||
}
|
||||
swift_key = &siter->second;
|
||||
|
||||
if (swift_key->key.compare(key) != 0) {
|
||||
dout(0) << "RGW_SWIFT_Auth_Get::execute(): bad swift key" << dendl;
|
||||
ret = -EPERM;
|
||||
goto done;
|
||||
@ -154,7 +168,7 @@ void RGW_SWIFT_Auth_Get::execute()
|
||||
CGI_PRINTF(s, "X-Storage-Url: %s/%s/v1/AUTH_rgw\n", g_conf->rgw_swift_url.c_str(),
|
||||
g_conf->rgw_swift_url_prefix.c_str());
|
||||
|
||||
if ((ret = encode_token(info.swift_name, info.swift_key, bl)) < 0)
|
||||
if ((ret = encode_token(swift_key->id, swift_key->key, bl)) < 0)
|
||||
goto done;
|
||||
|
||||
{
|
||||
|
@ -48,10 +48,12 @@ int rgw_store_user_info(RGWUserInfo& info)
|
||||
int ret;
|
||||
map<string,bufferlist> attrs;
|
||||
|
||||
if (info.swift_name.size()) {
|
||||
map<string, RGWAccessKey>::iterator iter;
|
||||
for (iter = info.swift_keys.begin(); iter != info.swift_keys.end(); ++iter) {
|
||||
RGWAccessKey& k = iter->second;
|
||||
/* check if swift mapping exists */
|
||||
RGWUserInfo inf;
|
||||
int r = rgw_get_user_info_by_swift(info.swift_name, inf);
|
||||
int r = rgw_get_user_info_by_swift(k.id, inf);
|
||||
if (r >= 0 && inf.user_id.compare(info.user_id) != 0) {
|
||||
dout(0) << "can't store user info, swift id already mapped to another user" << dendl;
|
||||
return -EEXIST;
|
||||
@ -98,8 +100,13 @@ int rgw_store_user_info(RGWUserInfo& info)
|
||||
}
|
||||
}
|
||||
|
||||
if (info.swift_name.size())
|
||||
ret = rgw_put_obj(info.user_id, ui_swift_bucket, info.swift_name, uid_bl.c_str(), uid_bl.length());
|
||||
map<string, RGWAccessKey>::iterator siter;
|
||||
for (siter = info.swift_keys.begin(); siter != info.swift_keys.end(); ++siter) {
|
||||
RGWAccessKey& k = siter->second;
|
||||
ret = rgw_put_obj(info.user_id, ui_swift_bucket, k.id, uid_bl.c_str(), uid_bl.length());
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -28,15 +28,14 @@
|
||||
specified date (and optional time)
|
||||
options:
|
||||
--uid=<id> user id
|
||||
--auth-uid=<auid> librados uid
|
||||
--subuser=<name> subuser name
|
||||
--access-key=<key> S3 access key
|
||||
--swift-user=<group:name> Swift user
|
||||
--email=<email>
|
||||
--auth_uid=<auid> librados uid
|
||||
--secret=<key> S3 key
|
||||
--swift-secret=<key> Swift key
|
||||
--gen-access-key generate random access key
|
||||
--secret=<key> specify secret key
|
||||
--gen-access-key generate random access key (for S3)
|
||||
--gen-secret generate random secret key
|
||||
--key-type=<type> key type, options are: swift, s3
|
||||
--access=<access> Set access permissions for sub-user, should be one
|
||||
of read, write, readwrite, full
|
||||
--display-name=<name>
|
||||
|
Loading…
Reference in New Issue
Block a user