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";
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
}
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);
}
}
}
- 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;
+ }
}
}
return 0;
}
+enum KeyType {
+ KEY_TYPE_SWIFT,
+ KEY_TYPE_S3,
+};
+
int main(int argc, char **argv)
{
vector<const char*> args;
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;
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)) {
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)) {
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();
}
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())
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;
#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
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;
::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;
}
::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)
if (ver >= 7) {
::decode(suspended, bl);
}
+ if (ver >= 8) {
+ ::decode(swift_keys, bl);
+ }
}
void clear() {
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);
}
-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;
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;
}
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) {
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;
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) {
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;
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;
{