summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2012-10-30 17:34:06 -0700
committerYehuda Sadeh <yehuda@inktank.com>2012-10-30 17:34:06 -0700
commit88f482335d011af11a0d5f32528c72f16b3b30b5 (patch)
tree2705282493b0048113862e84cf1f316f4312f606
parent421c352e33e5ff557abb61875343341405ee248e (diff)
downloadceph-88f482335d011af11a0d5f32528c72f16b3b30b5.tar.gz
rgw: handle keystone roles
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/common/config_opts.h1
-rw-r--r--src/rgw/rgw_swift.cc40
2 files changed, 41 insertions, 0 deletions
diff --git a/src/common/config_opts.h b/src/common/config_opts.h
index 3e45bbf48c7..b2fe128587e 100644
--- a/src/common/config_opts.h
+++ b/src/common/config_opts.h
@@ -423,6 +423,7 @@ OPTION(rgw_swift_auth_entry, OPT_STR, "auth") // entry point for which a url is
OPTION(rgw_swift_use_keystone, OPT_BOOL, false) // should swift use keystone?
OPTION(rgw_swift_keystone_url, OPT_STR, "") // url for keystone server
OPTION(rgw_swift_keystone_admin_token, OPT_STR, "") // keystone admin token (shared secret)
+OPTION(rgw_swift_keystone_operator_roles, OPT_STR, "swiftoperator, admin") // roles required to serve requests
OPTION(rgw_admin_entry, OPT_STR, "admin") // entry point for which a url is considered an admin request
OPTION(rgw_enforce_swift_acls, OPT_BOOL, true)
OPTION(rgw_print_continue, OPT_BOOL, true) // enable if 100-Continue works
diff --git a/src/rgw/rgw_swift.cc b/src/rgw/rgw_swift.cc
index 47d67a76cea..14c0b958e72 100644
--- a/src/rgw/rgw_swift.cc
+++ b/src/rgw/rgw_swift.cc
@@ -9,6 +9,8 @@
#include "rgw_user.h"
#include "rgw_http_client.h"
+#include "include/str_list.h"
+
#define dout_subsys ceph_subsys_rgw
class RGWValidateSwiftToken : public RGWHTTPClient {
@@ -102,6 +104,8 @@ public:
string user_name;
string expires;
+ map<string, bool> roles;
+
KeystoneTokenResponseParser() {}
int parse(bufferlist& bl);
@@ -134,6 +138,23 @@ int KeystoneTokenResponseParser::parse(bufferlist& bl)
return -EINVAL;
}
+ JSONObjIter riter = user->find("roles");
+ if (riter.end()) {
+ dout(0) << "token response is missing roles section" << dendl;
+ return -EINVAL;
+ }
+
+ for (; !riter.end(); ++riter) {
+ JSONObj *o = *riter;
+ JSONObj *role_name = o->find_obj("name");
+ if (!role_name) {
+ dout(0) << "token response is missing role name section" << dendl;
+ return -EINVAL;
+ }
+ string role = role_name->get_data();
+ roles[role] = true;
+ }
+
JSONObj *token = access_obj->find_obj("token");
if (!user) {
dout(0) << "missing token section in response" << dendl;
@@ -173,6 +194,25 @@ static int rgw_parse_keystone_token_response(bufferlist& bl, struct rgw_swift_au
if (ret < 0)
return ret;
+ list<string> roles_list;
+
+ get_str_list(g_conf->rgw_swift_keystone_operator_roles, roles_list);
+
+ bool found = false;
+ list<string>::iterator iter;
+ for (iter = roles_list.begin(); iter != roles_list.end(); ++iter) {
+ const string& role = *iter;
+ if (p.roles.find(role) != p.roles.end()) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ dout(0) << "user does not hold a matching role; required roles: " << g_conf->rgw_swift_keystone_operator_roles << dendl;
+ return -EPERM;
+ }
+
dout(0) << "validated token: " << p.tenant_name << ":" << p.user_name << " expires: " << p.expires << dendl;
info->user = p.tenant_name;