]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/role: role APIs support account users
authorCasey Bodley <cbodley@redhat.com>
Tue, 23 Jan 2024 14:22:55 +0000 (09:22 -0500)
committerCasey Bodley <cbodley@redhat.com>
Wed, 10 Apr 2024 17:09:15 +0000 (13:09 -0400)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
17 files changed:
src/rgw/driver/daos/rgw_sal_daos.cc
src/rgw/driver/daos/rgw_sal_daos.h
src/rgw/driver/motr/rgw_sal_motr.cc
src/rgw/driver/motr/rgw_sal_motr.h
src/rgw/driver/rados/rgw_sal_rados.cc
src/rgw/driver/rados/rgw_sal_rados.h
src/rgw/rgw_admin.cc
src/rgw/rgw_rest_role.cc
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_role.cc
src/rgw/rgw_role.h
src/rgw/rgw_sal.h
src/rgw/rgw_sal_dbstore.cc
src/rgw/rgw_sal_dbstore.h
src/rgw/rgw_sal_filter.cc
src/rgw/rgw_sal_filter.h
src/rgw/rgw_sts.cc

index 75e85f207497636c407b57070bdbe97f7dd705c1..86529befbaad7a13e1b9a127ed0dc1cfec2e46ce 100644 (file)
@@ -2078,7 +2078,7 @@ int DaosMultipartWriter::complete(
 }
 
 std::unique_ptr<RGWRole> DaosStore::get_role(
-    std::string name, std::string tenant, std::string path,
+    std::string name, std::string tenant, rgw_account_id account_id, std::string path,
     std::string trust_policy, std::string max_session_duration_str,
     std::multimap<std::string, std::string> tags) {
   RGWRole* p = nullptr;
index 3d5446734477b2519f3d29f401565ea4b4c45509..2b61347b807d1f6c816611931a2bf577a227741e 100644 (file)
@@ -994,7 +994,7 @@ class DaosStore : public StoreDriver {
 
   std::unique_ptr<LuaManager> get_lua_manager(const DoutPrefixProvider *dpp = nullptr, const std::string& luarocks_path = "") override;
   virtual std::unique_ptr<RGWRole> get_role(
-      std::string name, std::string tenant, std::string path = "",
+      std::string name, std::string tenant, rgw_account_id account_id, std::string path = "",
       std::string trust_policy = "", std::string max_session_duration_str = "",
       std::multimap<std::string, std::string> tags = {}) override;
   virtual std::unique_ptr<RGWRole> get_role(const RGWRoleInfo& info) override;
index 07ccab041e8f72857ac924d9f5883348eacc2d5e..7160cf01aa8ad735eb3575668fa71ebc0d3d2ac5 100644 (file)
@@ -3029,6 +3029,7 @@ int MotrMultipartWriter::complete(size_t accounted_size, const std::string& etag
 
 std::unique_ptr<RGWRole> MotrStore::get_role(std::string name,
     std::string tenant,
+    rgw_account_id account_id,
     std::string path,
     std::string trust_policy,
     std::string max_session_duration_str,
index e856c34e0b2e9f741eb0a1d0fb9b39f731d238f0..64d16824471dad4ef810dccc9abc0b19cfd86c8d 100644 (file)
@@ -1058,6 +1058,7 @@ class MotrStore : public StoreDriver {
     std::unique_ptr<LuaManager> get_lua_manager(const DoutPrefixProvider *dpp = nullptr, const std::string& luarocks_path = "") override;
     virtual std::unique_ptr<RGWRole> get_role(std::string name,
         std::string tenant,
+        rgw_account_id account_id,
         std::string path="",
         std::string trust_policy="",
         std::string max_session_duration_str="",
index 61b1159104ae32fe736f243fb8b2d4a7e223c62c..b809a32c71633c26892226ea80973c6d6ffd698d 100644 (file)
@@ -1206,21 +1206,13 @@ int RadosStore::load_account_role_by_name(const DoutPrefixProvider* dpp,
                                           std::string_view rolename,
                                           std::unique_ptr<RGWRole>* role)
 {
-  std::string id;
-  librados::Rados& rados = *getRados()->get_rados_handle();
-  const RGWZoneParams& zone = svc()->zone->get_zone_params();
-  const rgw_raw_obj& obj = rgwrados::account::get_roles_obj(zone, account_id);
-  int r = rgwrados::roles::get(dpp, y, rados, obj, rolename, id);
+  RGWRoleInfo info;
+  info.account_id = account_id;
+  info.name = rolename;
+  auto p = get_role(info);
+  int r = p->get(dpp, y);
   if (r < 0) {
-    ldpp_dout(dpp, 20) << "failed to find account rolename " << rolename
-        << ": " << cpp_strerror(r) << dendl;
-    return r;
-  }
-
-  std::unique_ptr<RGWRole> p = get_role(id);
-  r = p->read_info(dpp, y);
-  if (r < 0) {
-    ldpp_dout(dpp, 20) << "failed to load account role " << id
+    ldpp_dout(dpp, 20) << "failed to load account role " << rolename
         << ": " << cpp_strerror(r) << dendl;
     return r;
   }
@@ -1786,12 +1778,13 @@ std::unique_ptr<LuaManager> RadosStore::get_lua_manager(const std::string& luaro
 
 std::unique_ptr<RGWRole> RadosStore::get_role(std::string name,
                                              std::string tenant,
+                                             rgw_account_id account_id,
                                              std::string path,
                                              std::string trust_policy,
                                              std::string max_session_duration_str,
                 std::multimap<std::string,std::string> tags)
 {
-  return std::make_unique<RadosRole>(this, name, tenant, path, trust_policy, max_session_duration_str, tags);
+  return std::make_unique<RadosRole>(this, name, tenant, std::move(account_id), path, trust_policy, max_session_duration_str, tags);
 }
 
 std::unique_ptr<RGWRole> RadosStore::get_role(std::string id)
@@ -4019,13 +4012,27 @@ int RadosRole::store_info(const DoutPrefixProvider *dpp, bool exclusive, optiona
   }
 }
 
+static std::string role_name_oid(const RGWRoleInfo& r, std::string_view prefix)
+{
+  if (!r.account_id.empty()) {
+    // names are case-insensitive, so store them in lower case
+    std::string lower_name = r.name;
+    boost::algorithm::to_lower(lower_name);
+    // use account id as prefix
+    return string_cat_reserve(r.account_id, prefix, lower_name);
+  } else {
+    // use tenant as prefix
+    return string_cat_reserve(r.tenant, prefix, r.name);
+  }
+}
+
 int RadosRole::store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
 {
   auto sysobj = store->svc()->sysobj;
   RGWNameToId nameToId;
   nameToId.obj_id = info.id;
 
-  std::string oid = info.tenant + get_names_oid_prefix() + info.name;
+  std::string oid = role_name_oid(info, get_names_oid_prefix());
 
   bufferlist bl;
   using ceph::encode;
@@ -4036,6 +4043,14 @@ int RadosRole::store_name(const DoutPrefixProvider *dpp, bool exclusive, optiona
 
 int RadosRole::store_path(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
 {
+  if (!info.account_id.empty()) {
+    librados::Rados& rados = *store->getRados()->get_rados_handle();
+    const RGWZoneParams& zone = store->svc()->zone->get_zone_params();
+    const rgw_raw_obj& obj = rgwrados::account::get_roles_obj(zone, info.account_id);
+    constexpr uint32_t no_limit = std::numeric_limits<uint32_t>::max();
+    return rgwrados::roles::add(dpp, y, rados, obj, info, false, no_limit);
+  }
+
   auto sysobj = store->svc()->sysobj;
   std::string oid = info.tenant + get_path_oid_prefix() + info.path + get_info_oid_prefix() + info.id;
 
@@ -4071,7 +4086,7 @@ int RadosRole::read_id(const DoutPrefixProvider *dpp, const std::string& role_na
 int RadosRole::read_name(const DoutPrefixProvider *dpp, optional_yield y)
 {
   auto sysobj = store->svc()->sysobj;
-  std::string oid = info.tenant + get_names_oid_prefix() + info.name;
+  std::string oid = role_name_oid(info, get_names_oid_prefix());
   bufferlist bl;
 
   int ret = rgw_get_system_obj(sysobj, store->svc()->zone->get_zone_params().roles_pool, oid, bl, nullptr, nullptr, y, dpp);
@@ -4171,7 +4186,8 @@ int RadosRole::create(const DoutPrefixProvider *dpp, bool exclusive, const std::
   }
 
   //arn
-  info.arn = role_arn_prefix + info.tenant + ":role" + info.path + info.name;
+  std::string_view account = !info.account_id.empty() ? info.account_id : info.tenant;
+  info.arn = string_cat_reserve(role_arn_prefix, account, ":role", info.path, info.name);
 
   // Creation time
   real_clock::time_point t = real_clock::now();
@@ -4221,7 +4237,7 @@ int RadosRole::create(const DoutPrefixProvider *dpp, bool exclusive, const std::
                   << info.id << ": " << cpp_strerror(-info_ret) << dendl;
     }
     //Delete role name that was stored in previous call
-    oid = info.tenant + get_names_oid_prefix() + info.name;
+    oid = role_name_oid(info, get_names_oid_prefix());
     int name_ret = rgw_delete_system_obj(dpp, store->svc()->sysobj, pool, oid, nullptr, y);
     if (name_ret < 0) {
       ldpp_dout(dpp, 0) << "ERROR: cleanup of role name from Role pool: "
@@ -4261,7 +4277,7 @@ int RadosRole::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
   }
 
   // Delete name
-  std::string oid = info.tenant + get_names_oid_prefix() + info.name;
+  std::string oid = role_name_oid(info, get_names_oid_prefix());
   ret = rgw_delete_system_obj(dpp, store->svc()->sysobj, pool, oid, nullptr, y);
   if (ret < 0) {
     ldpp_dout(dpp, 0) << "ERROR: deleting role name from Role pool: "
@@ -4269,13 +4285,24 @@ int RadosRole::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
   }
 
   // Delete path
-  oid = info.tenant + get_path_oid_prefix() + info.path + get_info_oid_prefix() + info.id;
-  ret = rgw_delete_system_obj(dpp, store->svc()->sysobj, pool, oid, nullptr, y);
-  if (ret < 0) {
-    ldpp_dout(dpp, 0) << "ERROR: deleting role path from Role pool: "
-                  << info.path << ": " << cpp_strerror(-ret) << dendl;
+  if (!info.account_id.empty()) {
+    librados::Rados& rados = *store->getRados()->get_rados_handle();
+    const RGWZoneParams& zone = store->svc()->zone->get_zone_params();
+    const rgw_raw_obj& obj = rgwrados::account::get_roles_obj(zone, info.account_id);
+    ret = rgwrados::roles::remove(dpp, y, rados, obj, info.name);
+    if (ret < 0) {
+      ldpp_dout(dpp, 4) << "ERROR: deleting role path from account list: "
+                    << info.path << ": " << cpp_strerror(-ret) << dendl;
+    }
+  } else {
+    oid = info.tenant + get_path_oid_prefix() + info.path + get_info_oid_prefix() + info.id;
+    ret = rgw_delete_system_obj(dpp, store->svc()->sysobj, pool, oid, nullptr, y);
+    if (ret < 0) {
+      ldpp_dout(dpp, 4) << "ERROR: deleting role path from Role pool: "
+                    << info.path << ": " << cpp_strerror(-ret) << dendl;
+    }
   }
-  return ret;
+  return 0;
 }
 
 } // namespace rgw::sal
index cfee6b872662c2a11c55eee68c0ac38f2ce39860..759bfad54ced23deb7bcae5971e7dade7a48c368 100644 (file)
@@ -331,6 +331,7 @@ class RadosStore : public StoreDriver {
     std::unique_ptr<LuaManager> get_lua_manager(const std::string& luarocks_path) override;
     virtual std::unique_ptr<RGWRole> get_role(std::string name,
                                              std::string tenant,
+                                             rgw_account_id account_id,
                                              std::string path="",
                                              std::string trust_policy="",
                                              std::string max_session_duration_str="",
@@ -1079,10 +1080,12 @@ class RadosRole : public RGWRole {
 public:
   RadosRole(RadosStore* _store, std::string name,
           std::string tenant,
+          rgw_account_id account_id,
           std::string path,
           std::string trust_policy,
           std::string max_session_duration,
-          std::multimap<std::string,std::string> tags) : RGWRole(name, tenant, path, trust_policy, max_session_duration, tags), store(_store) {}
+          std::multimap<std::string,std::string> tags)
+    : RGWRole(name, tenant, std::move(account_id), path, trust_policy, max_session_duration, tags), store(_store) {}
   RadosRole(RadosStore* _store, std::string id) : RGWRole(id), store(_store) {}
   RadosRole(RadosStore* _store, const RGWRoleInfo& info) : RGWRole(info), store(_store) {}
   RadosRole(RadosStore* _store) : store(_store) {}
index 33355ec273514c1909ce409e6ccb9b0763831808..2fa7d56c1d40a9268c87aea6b7142a1bf637b107 100644 (file)
@@ -3334,7 +3334,7 @@ int main(int argc, const char **argv)
   string tenant;
   string user_ns;
   string account_name;
-  string account_id;
+  rgw_account_id account_id;
   rgw_user new_user_id;
   std::string access_key, secret_key, user_email, display_name;
   std::string bucket_name, pool_name, object;
@@ -6786,7 +6786,7 @@ int main(int argc, const char **argv)
         cerr << "failed to parse policy: " << e.what() << std::endl;
         return -EINVAL;
       }
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, path,
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id, path,
                                                                  assume_role_doc, max_session_duration);
       ret = role->create(dpp(), true, "", null_yield);
       if (ret < 0) {
@@ -6802,7 +6802,7 @@ int main(int argc, const char **argv)
         cerr << "ERROR: empty role name" << std::endl;
         return -EINVAL;
       }
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       ret = role->delete_obj(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
@@ -6816,7 +6816,7 @@ int main(int argc, const char **argv)
         cerr << "ERROR: empty role name" << std::endl;
         return -EINVAL;
       }
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       ret = role->get(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
@@ -6847,7 +6847,7 @@ int main(int argc, const char **argv)
         return -EINVAL;
       }
 
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       ret = role->get(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
@@ -6876,8 +6876,16 @@ int main(int argc, const char **argv)
         constexpr int32_t max_chunk = 100;
         int32_t count = std::min(max_chunk, remaining);
 
-        ret = driver->list_roles(dpp(), null_yield, tenant, path_prefix,
-                                 listing.next_marker, count, listing);
+        if (!account_id.empty()) {
+          // list roles in the account
+          ret = driver->list_account_roles(dpp(), null_yield, account_id,
+                                           path_prefix, listing.next_marker,
+                                           count, listing);
+        } else {
+          // list roles in the tenant
+          ret = driver->list_roles(dpp(), null_yield, tenant, path_prefix,
+                                   listing.next_marker, count, listing);
+        }
         if (ret < 0) {
           return -ret;
         }
@@ -6936,7 +6944,7 @@ int main(int argc, const char **argv)
         return -EINVAL;
       }
 
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       ret = role->get(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
@@ -6955,7 +6963,7 @@ int main(int argc, const char **argv)
         cerr << "ERROR: Role name is empty" << std::endl;
         return -EINVAL;
       }
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       ret = role->get(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
@@ -6975,7 +6983,7 @@ int main(int argc, const char **argv)
         cerr << "ERROR: policy name is empty" << std::endl;
         return -EINVAL;
       }
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       int ret = role->get(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
@@ -6999,7 +7007,7 @@ int main(int argc, const char **argv)
         cerr << "ERROR: policy name is empty" << std::endl;
         return -EINVAL;
       }
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       ret = role->get(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
@@ -7023,7 +7031,7 @@ int main(int argc, const char **argv)
         return -EINVAL;
       }
 
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant);
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, tenant, account_id);
       ret = role->get(dpp(), null_yield);
       if (ret < 0) {
         return -ret;
index 463ed5eb08c8156e4cf916103d00488ef6603f31..f8cf22d00a7d5190266322a918d822aea7e5123f 100644 (file)
@@ -113,35 +113,60 @@ static int load_role(const DoutPrefixProvider* dpp, optional_yield y,
                      std::unique_ptr<rgw::sal::RGWRole>& role,
                      rgw::ARN& resource, std::string& message)
 {
+  auto arn_account = std::ref(tenant);
   if (const auto* id = std::get_if<rgw_account_id>(&owner); id) {
     account_id = *id;
-
-    // look up account role by RoleName
-    int r = driver->load_account_role_by_name(dpp, y, account_id, name, &role);
-    if (r == -ENOENT) {
-      message = "No such RoleName in the account";
-      return -ERR_NO_ROLE_FOUND;
-    }
-    if (r >= 0) {
-      resource = make_role_arn(role->get_path(), role->get_name(), account_id);
-    }
-    return r;
+    arn_account = std::ref(account_id);
   }
 
-  role = driver->get_role(name, tenant);
+  role = driver->get_role(name, tenant, account_id);
   const int r = role->get(dpp, y);
   if (r == -ENOENT) {
     message = "No such RoleName in the tenant";
     return -ERR_NO_ROLE_FOUND;
   }
   if (r >= 0) {
+    // construct the ARN once we know the path
     resource = make_role_arn(role->get_path(),
                              role->get_name(),
-                             role->get_tenant());
+                             arn_account);
   }
   return r;
 }
 
+// check the current role count against account limit
+int check_role_limit(const DoutPrefixProvider* dpp, optional_yield y,
+                     rgw::sal::Driver* driver, std::string_view account_id,
+                     std::string& err)
+{
+  RGWAccountInfo account;
+  rgw::sal::Attrs attrs; // unused
+  RGWObjVersionTracker objv; // unused
+  int r = driver->load_account_by_id(dpp, y, account_id, account, attrs, objv);
+  if (r < 0) {
+    ldpp_dout(dpp, 4) << "failed to load iam account "
+        << account_id << ": " << cpp_strerror(r) << dendl;
+    return r;
+  }
+
+  if (account.max_roles < 0) { // max_roles < 0 means unlimited
+    return 0;
+  }
+
+  uint32_t count = 0;
+  r = driver->count_account_roles(dpp, y, account_id, count);
+  if (r < 0) {
+    ldpp_dout(dpp, 4) << "failed to count roles for iam account "
+        << account_id << ": " << cpp_strerror(r) << dendl;
+    return r;
+  }
+  if (std::cmp_greater_equal(count, account.max_roles)) {
+    err = fmt::format("Role limit {} exceeded", account.max_roles);
+    return -ERR_LIMIT_EXCEEDED;
+  }
+  return 0;
+}
+
 
 int RGWCreateRole::init_processing(optional_yield y)
 {
@@ -188,7 +213,13 @@ int RGWCreateRole::init_processing(optional_yield y)
 
 
   if (const auto* id = std::get_if<rgw_account_id>(&s->owner.id); id) {
+    account_id = *id;
     resource = make_role_arn(role_path, role_name, *id);
+
+    ret = check_role_limit(this, y, driver, account_id, s->err.message);
+    if (ret < 0) {
+      return ret;
+    }
   } else {
     resource = make_role_arn(role_path, role_name, s->user->get_tenant());
   }
@@ -200,6 +231,7 @@ void RGWCreateRole::execute(optional_yield y)
   std::string user_tenant = s->user->get_tenant();
   std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name,
                                                            user_tenant,
+                                                           account_id,
                                                            role_path,
                                                            trust_policy,
                                                            max_session_duration,
@@ -453,15 +485,24 @@ int RGWListRoles::init_processing(optional_yield y)
     return -EINVAL;
   }
 
+  if (const auto* id = std::get_if<rgw_account_id>(&s->owner.id); id) {
+    account_id = *id;
+  }
   return 0;
 }
 
 void RGWListRoles::execute(optional_yield y)
 {
-  // TODO: list_account_roles() for account owner
   rgw::sal::RoleList listing;
-  op_ret = driver->list_roles(s, y, s->user->get_tenant(), path_prefix,
-                              marker, max_items, listing);
+  if (!account_id.empty()) {
+    // list roles from the account
+    op_ret = driver->list_account_roles(this, y, account_id, path_prefix,
+                                        marker, max_items, listing);
+  } else {
+    // list roles from the tenant
+    op_ret = driver->list_roles(this, y, s->auth.identity->get_tenant(),
+                                path_prefix, marker, max_items, listing);
+  }
 
   if (op_ret == 0) {
     s->formatter->open_object_section("ListRolesResponse");
index 210d310313fd583e5da9ec51e09af259b1527914..4ec0d211687929a93030f6028225d379fb4a3b7d 100644 (file)
@@ -21,6 +21,7 @@
 #include "common/ceph_json.h"
 
 #include "rgw_rest.h"
+#include "rgw_account.h"
 #include "rgw_auth.h"
 #include "rgw_auth_registry.h"
 #include "jwt-cpp/jwt.h"
@@ -496,14 +497,21 @@ WebTokenEngine::authenticate( const DoutPrefixProvider* dpp,
       string role_arn = s->info.args.get("RoleArn");
       string role_tenant = get_role_tenant(role_arn);
       string role_name = get_role_name(role_arn);
-      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, role_tenant);
+
+      rgw_account_id role_account;
+      if (rgw::account::validate_id(role_tenant)) {
+        role_account = std::move(role_tenant);
+        role_tenant.clear();
+      }
+
+      std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name, role_tenant, role_account);
       int ret = role->get(dpp, y);
       if (ret < 0) {
         ldpp_dout(dpp, 0) << "Role not found: name:" << role_name << " tenant: " << role_tenant << dendl;
         return result_t::deny(-EACCES);
       }
       boost::optional<multimap<string,string>> role_tags = role->get_tags();
-      auto apl = apl_factory->create_apl_web_identity(cct, s, role_session, role_tenant, *t, role_tags, princ_tags);
+      auto apl = apl_factory->create_apl_web_identity(cct, s, role_session, role->get_tenant(), *t, role_tags, princ_tags);
       return result_t::grant(std::move(apl));
     }
     return result_t::deny(-EACCES);
index 12e79d433ea13e64c9e361cacffd519abd719f79..1f7648e690ff9f8fd73b1fc8fcfa3b7d76a0b4b1 100644 (file)
@@ -52,6 +52,7 @@ void RGWRoleInfo::dump(Formatter *f) const
   encode_json("CreateDate", creation_date, f);
   encode_json("MaxSessionDuration", max_session_duration, f);
   encode_json("AssumeRolePolicyDocument", trust_policy, f);
+  encode_json("AccountId", account_id, f);
   if (!perm_policy_map.empty()) {
     f->open_array_section("PermissionPolicies");
     for (const auto& it : perm_policy_map) {
@@ -83,6 +84,7 @@ void RGWRoleInfo::decode_json(JSONObj *obj)
   JSONDecoder::decode_json("CreateDate", creation_date, obj);
   JSONDecoder::decode_json("MaxSessionDuration", max_session_duration, obj);
   JSONDecoder::decode_json("AssumeRolePolicyDocument", trust_policy, obj);
+  JSONDecoder::decode_json("AccountId", account_id, obj);
 
   auto tags_iter = obj->find_first("Tags");
   if (!tags_iter.end()) {
@@ -118,12 +120,14 @@ void RGWRoleInfo::decode_json(JSONObj *obj)
 
 RGWRole::RGWRole(std::string name,
               std::string tenant,
+              rgw_account_id account_id,
               std::string path,
               std::string trust_policy,
               std::string max_session_duration_str,
               std::multimap<std::string,std::string> tags)
 {
   info.name = std::move(name);
+  info.account_id = std::move(account_id);
   info.path = std::move(path);
   info.trust_policy = std::move(trust_policy);
   info.tenant = std::move(tenant);
index 77d315fc96e3a3dc1478cdf5534ba281d87ff448..90a4a6a31289112124eeac7a6e48443cda55fe0f 100644 (file)
@@ -30,13 +30,14 @@ struct RGWRoleInfo
   std::map<std::string, bufferlist> attrs;
   RGWObjVersionTracker objv_tracker;
   real_time mtime;
+  rgw_account_id account_id;
 
   RGWRoleInfo() = default;
 
   ~RGWRoleInfo() = default;
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(3, 1, bl);
+    ENCODE_START(4, 1, bl);
     encode(id, bl);
     encode(name, bl);
     encode(path, bl);
@@ -46,11 +47,12 @@ struct RGWRoleInfo
     encode(perm_policy_map, bl);
     encode(tenant, bl);
     encode(max_session_duration, bl);
+    encode(account_id, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(3, bl);
+    DECODE_START(4, bl);
     decode(id, bl);
     decode(name, bl);
     decode(path, bl);
@@ -64,6 +66,9 @@ struct RGWRoleInfo
     if (struct_v >= 3) {
       decode(max_session_duration, bl);
     }
+    if (struct_v >= 4) {
+      decode(account_id, bl);
+    }
     DECODE_FINISH(bl);
   }
 
@@ -98,6 +103,7 @@ public:
 
   RGWRole(std::string name,
               std::string tenant,
+              rgw_account_id account_id,
               std::string path="",
               std::string trust_policy="",
               std::string max_session_duration_str="",
@@ -114,6 +120,7 @@ public:
   const std::string& get_id() const { return info.id; }
   const std::string& get_name() const { return info.name; }
   const std::string& get_tenant() const { return info.tenant; }
+  const rgw_account_id& get_account_id() const { return info.account_id; }
   const std::string& get_path() const { return info.path; }
   const std::string& get_create_date() const { return info.creation_date; }
   const std::string& get_assume_role_policy() const { return info.trust_policy;}
index 910a4e5b142cb3364833f977cdc28b24a77ed8dd..01d06205f1651c26b5c07646d945bdf4c380bd47 100644 (file)
@@ -565,6 +565,7 @@ class Driver {
     /** Get an IAM Role by name etc. */
     virtual std::unique_ptr<RGWRole> get_role(std::string name,
                                              std::string tenant,
+                                             rgw_account_id account_id,
                                              std::string path="",
                                              std::string trust_policy="",
                                              std::string max_session_duration_str="",
index 4a0015e046d51b4744407a171e882c850f89c5b1..e2873fb71badc4b497f7fc4954d78905f38457b3 100644 (file)
@@ -1390,6 +1390,7 @@ namespace rgw::sal {
 
   std::unique_ptr<RGWRole> DBStore::get_role(std::string name,
       std::string tenant,
+      rgw_account_id account_id,
       std::string path,
       std::string trust_policy,
       std::string max_session_duration_str,
index 9a0f638e3da5b46651335fd7fcbaf5aca3da43e8..bc037688eb6b6e507443b59ce23eaade5386b6f3 100644 (file)
@@ -904,6 +904,7 @@ public:
       std::unique_ptr<LuaManager> get_lua_manager(const std::string& luarocks_path) override;
       virtual std::unique_ptr<RGWRole> get_role(std::string name,
           std::string tenant,
+          rgw_account_id account_id,
           std::string path="",
           std::string trust_policy="",
           std::string max_session_duration_str="",
index 6b17cd36d5349e05cf27781df6cebbd159b3c66c..ddcde348821f39310c2bdfdd32f51f04adcea92c 100644 (file)
@@ -552,12 +552,13 @@ std::unique_ptr<LuaManager> FilterDriver::get_lua_manager(const std::string& lua
 
 std::unique_ptr<RGWRole> FilterDriver::get_role(std::string name,
                                              std::string tenant,
+                                             rgw_account_id account_id,
                                              std::string path,
                                              std::string trust_policy,
                                              std::string max_session_duration_str,
                 std::multimap<std::string,std::string> tags)
 {
-  return next->get_role(name, tenant, path, trust_policy, max_session_duration_str, tags);
+  return next->get_role(name, tenant, std::move(account_id), path, trust_policy, max_session_duration_str, tags);
 }
 
 std::unique_ptr<RGWRole> FilterDriver::get_role(std::string id)
index 7b31f9c751fdce2b7b90d22f138cc486b57caebc..fde1a4dda9511b17cb6cf3c988d4001b48f2f75f 100644 (file)
@@ -389,6 +389,7 @@ public:
   virtual std::unique_ptr<LuaManager> get_lua_manager(const std::string& luarocks_path) override;
   virtual std::unique_ptr<RGWRole> get_role(std::string name,
                                            std::string tenant,
+                                           rgw_account_id account_id,
                                            std::string path="",
                                            std::string trust_policy="",
                                            std::string
index 557bcf24f2b3139877c5795fc831e0a306273770..1486868e1e14880de74247baa6d587317d064032 100644 (file)
@@ -18,6 +18,7 @@
 #include "include/types.h"
 #include "rgw_string.h"
 
+#include "rgw_account.h"
 #include "rgw_b64.h"
 #include "rgw_common.h"
 #include "rgw_tools.h"
@@ -290,7 +291,15 @@ std::tuple<int, rgw::sal::RGWRole*> STSService::getRoleInfo(const DoutPrefixProv
   if (auto r_arn = rgw::ARN::parse(arn); r_arn) {
     auto pos = r_arn->resource.find_last_of('/');
     string roleName = r_arn->resource.substr(pos + 1);
-    std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(roleName, r_arn->account);
+    string tenant = r_arn->account;
+
+    rgw_account_id account;
+    if (rgw::account::validate_id(tenant)) {
+      account = std::move(tenant);
+      tenant.clear();
+    }
+
+    std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(roleName, tenant, account);
     if (int ret = role->get(dpp, y); ret < 0) {
       if (ret == -ENOENT) {
         ldpp_dout(dpp, 0) << "Role doesn't exist: " << roleName << dendl;