]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Allow an implicit tenant in case of Keystone 8139/head
authorPete Zaitcev <zaitcev@kotori.zaitcev.us>
Wed, 9 Mar 2016 06:13:29 +0000 (23:13 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Tue, 15 Mar 2016 23:48:00 +0000 (16:48 -0700)
This, unfortunately, introduces possible double lookups, but
they should be cached. Also, the logic appears somewhat convoluted,
although the intent is quite simple: if you're an OpenStack user
with a Keystone authentication, we allow an implicit tenant of
the same name as the user.

Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Conflicts:
src/rgw/rgw_swift.cc

doc/radosgw/keystone.rst
src/common/config_opts.h
src/rgw/rgw_swift.cc
src/rgw/rgw_swift.h

index e1876a3c96dcfe2654d002b34ac7531ef61b0626..0e37c965f88a209d8e94a50bf3820f11596020a2 100644 (file)
@@ -16,6 +16,7 @@ The following configuration options are available for Keystone integration::
        rgw keystone accepted roles = {accepted user roles}
        rgw keystone token cache size = {number of tokens to cache}
        rgw keystone revocation interval = {number of seconds before checking revoked tickets}
+       rgw keystone make new tenants = {true for private tenant for each new user}
        rgw s3 auth use keystone = true
        nss db path = {path to nss db}
 
index a0c60d457be3a7f961401ebf5bfe5b2bde055461..743514b98a116eb2eb8096c99ee4f0dcbe54ba5c 100644 (file)
@@ -1240,6 +1240,7 @@ OPTION(rgw_keystone_accepted_roles, OPT_STR, "Member, admin")  // roles required
 OPTION(rgw_keystone_token_cache_size, OPT_INT, 10000)  // max number of entries in keystone token cache
 OPTION(rgw_keystone_revocation_interval, OPT_INT, 15 * 60)  // seconds between tokens revocation check
 OPTION(rgw_keystone_verify_ssl, OPT_BOOL, true) // should we try to verify keystone's ssl
+OPTION(rgw_keystone_implicit_tenants, OPT_BOOL, false)  // create new users in their own tenants of the same name
 OPTION(rgw_s3_auth_use_rados, OPT_BOOL, true)  // should we try to use the internal credentials for s3?
 OPTION(rgw_s3_auth_use_keystone, OPT_BOOL, false)  // should we try to use keystone for s3?
 
index 5f442a6028bbf1d99fe500c10c7c4c36ea590338..0fdb310f30e61df0daf5512a55b76bc248b3d834 100644 (file)
@@ -62,7 +62,7 @@ int RGWValidateSwiftToken::receive_header(void *ptr, size_t len)
           l++;
  
         if (strcmp(tok, "HTTP") == 0) {
-          info->status = atoi(l);
+          ;
         } else if (strcasecmp(tok, "X-Auth-Groups") == 0) {
           info->auth_groups = l;
           char *s = strchr(l, ',');
@@ -375,7 +375,6 @@ static void rgw_set_keystone_token_auth_info(KeystoneToken& token, struct rgw_sw
 {
   info->user = token.get_project_id();
   info->display_name = token.get_project_name();
-  info->status = 200;
 }
 
 int RGWSwift::parse_keystone_token_response(const string& token,
@@ -413,24 +412,59 @@ int RGWSwift::parse_keystone_token_response(const string& token,
 
 int RGWSwift::update_user_info(RGWRados *store, struct rgw_swift_auth_info *info, RGWUserInfo& user_info)
 {
-  if (rgw_get_user_info_by_uid(store, info->user, user_info) < 0) {
-    ldout(cct, 0) << "NOTICE: couldn't map swift user" << dendl;
-    user_info.user_id = info->user;
-    user_info.display_name = info->display_name;
-
-    int ret = rgw_store_user_info(store, user_info, NULL, NULL, real_time(), true);
-    if (ret < 0) {
-      ldout(cct, 0) << "ERROR: failed to store new user's info: ret=" << ret << dendl;
-      return ret;
+  ldout(cct, 20) << "updating user=" << info->user << dendl; // P3 XXX
+  /*
+   * Normally once someone parsed the token, the tenant and user are set
+   * in rgw_swift_auth_info. If .tenant is empty in it, the client has
+   * authenticated with the empty legacy tenant. But when we authenticate
+   * with Keystone, we have a special compatibility kludge. First, we try
+   * the same tenant as the user. If that user exists, we use it. This way,
+   * migrated OpenStack users can get their namespaced containers and
+   * nobody's the wiser. If that fails, we look up the user in the empty
+   * tenant. If neither is found, make one, and those migrating can
+   * set a special configurable rgw_keystone_implicit_tenants to create
+   * suitable tenantized users.
+   */
+  if (info->user.tenant.empty()) {
+    rgw_user uid;
+    uid.tenant = info->user.id;
+    uid.id = info->user.id;
+    if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
+      uid.tenant.clear();
+      if (rgw_get_user_info_by_uid(store, uid, user_info) < 0) {
+        ldout(cct, 0) << "NOTICE: couldn't map swift user " << uid << dendl;
+        if (g_conf->rgw_keystone_implicit_tenants) {
+          uid.tenant = info->user.id;
+        }
+        user_info.user_id = uid;
+        user_info.display_name = info->display_name;
+        int ret = rgw_store_user_info(store, user_info, NULL, NULL, real_time(), true);
+        if (ret < 0) {
+          ldout(cct, 0) << "ERROR: failed to store new user info: user=" << user_info.user_id << " ret=" << ret << dendl;
+          return ret;
+        }
+      }
+    }
+  } else {
+    if (rgw_get_user_info_by_uid(store, info->user, user_info) < 0) {
+      ldout(cct, 0) << "NOTICE: couldn't map swift user " << info->user << dendl;
+      user_info.user_id = info->user;
+      user_info.display_name = info->display_name;
+      int ret = rgw_store_user_info(store, user_info, NULL, NULL, real_time(), true);
+      if (ret < 0) {
+        ldout(cct, 0) << "ERROR: failed to store new user info: user=" << user_info.user_id << " ret=" << ret << dendl;
+        return ret;
+      }
     }
   }
   return 0;
 }
 
-int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, struct rgw_swift_auth_info *info,
+int RGWSwift::validate_keystone_token(RGWRados *store, const string& token,
                                      RGWUserInfo& rgw_user)
 {
   KeystoneToken t;
+  struct rgw_swift_auth_info info;
 
   string token_id;
   rgw_get_token_id(token, token_id);
@@ -439,11 +473,11 @@ int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, stru
 
   /* check cache first */
   if (keystone_token_cache->find(token_id, t)) {
-    rgw_set_keystone_token_auth_info(t, info);
+    rgw_set_keystone_token_auth_info(t, &info);
 
     ldout(cct, 20) << "cached token.project.id=" << t.get_project_id() << dendl;
 
-    int ret = update_user_info(store, info, rgw_user);
+    int ret = update_user_info(store, &info, rgw_user);
     if (ret < 0)
       return ret;
 
@@ -495,7 +529,7 @@ int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, stru
 
   ldout(cct, 20) << "received response: " << bl.c_str() << dendl;
 
-  int ret = parse_keystone_token_response(token, bl, info, t);
+  int ret = parse_keystone_token_response(token, bl, &info, t);
   if (ret < 0)
     return ret;
 
@@ -508,7 +542,7 @@ int RGWSwift::validate_keystone_token(RGWRados *store, const string& token, stru
 
   keystone_token_cache->add(token_id, t);
 
-  ret = update_user_info(store, info, rgw_user);
+  ret = update_user_info(store, &info, rgw_user);
   if (ret < 0)
     return ret;
 
@@ -726,23 +760,17 @@ bool RGWSwift::do_verify_swift_token(RGWRados *store, req_state *s)
   if (strncmp(s->os_auth_token, "AUTH_rgwtk", 10) == 0) {
     int ret = rgw_swift_verify_signed_token(s->cct, store, s->os_auth_token,
                                            *(s->user), &s->swift_user);
-    if (ret < 0)
-      return false;
-
-    return  true;
+    return (ret >= 0);
   }
 
-  struct rgw_swift_auth_info info;
-
-  info.status = 401; // start with access denied, validate_token might change that
-
-  int ret;
-
   if (supports_keystone()) {
-    ret = validate_keystone_token(store, s->os_auth_token, &info, *(s->user));
+    int ret = validate_keystone_token(store, s->os_auth_token, *(s->user));
     return (ret >= 0);
   }
 
+  struct rgw_swift_auth_info info;
+  int ret;
+
   ret = validate_token(s->os_auth_token, &info);
   if (ret < 0)
     return false;
@@ -847,4 +875,3 @@ void RGWSwift::KeystoneRevokeThread::stop()
   Mutex::Locker l(lock);
   cond.Signal();
 }
-
index 3bffc26dae1a37870864962fbbc3fbc5d9979e23..d41d2cecd4e3c9212f9dad6ffa4b4c4383b6db5a 100644 (file)
@@ -14,13 +14,12 @@ class RGWRados;
 class KeystoneToken;
 
 struct rgw_swift_auth_info {
-  int status;
   string auth_groups;
   rgw_user user;
   string display_name;
   long long ttl;
 
-  rgw_swift_auth_info() : status(0), ttl(0) {}
+  rgw_swift_auth_info() : ttl(0) {}
 };
 
 class RGWSwift {
@@ -28,7 +27,7 @@ class RGWSwift {
   atomic_t down_flag;
 
   int validate_token(const char *token, struct rgw_swift_auth_info *info);
-  int validate_keystone_token(RGWRados *store, const string& token, struct rgw_swift_auth_info *info,
+  int validate_keystone_token(RGWRados *store, const string& token,
                              RGWUserInfo& rgw_user);
 
   int parse_keystone_token_response(const string& token,