From: Casey Bodley Date: Tue, 23 Jan 2024 14:22:55 +0000 (-0500) Subject: rgw/role: role APIs support account users X-Git-Tag: testing/wip-pdonnell-testing-20240416.232051-debug~25^2~95 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=0571ca82d4c243922389a850d08ed052a6cb66fd;p=ceph-ci.git rgw/role: role APIs support account users Signed-off-by: Casey Bodley --- diff --git a/src/rgw/driver/daos/rgw_sal_daos.cc b/src/rgw/driver/daos/rgw_sal_daos.cc index 75e85f20749..86529befbaa 100644 --- a/src/rgw/driver/daos/rgw_sal_daos.cc +++ b/src/rgw/driver/daos/rgw_sal_daos.cc @@ -2078,7 +2078,7 @@ int DaosMultipartWriter::complete( } std::unique_ptr 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 tags) { RGWRole* p = nullptr; diff --git a/src/rgw/driver/daos/rgw_sal_daos.h b/src/rgw/driver/daos/rgw_sal_daos.h index 3d544673447..2b61347b807 100644 --- a/src/rgw/driver/daos/rgw_sal_daos.h +++ b/src/rgw/driver/daos/rgw_sal_daos.h @@ -994,7 +994,7 @@ class DaosStore : public StoreDriver { std::unique_ptr get_lua_manager(const DoutPrefixProvider *dpp = nullptr, const std::string& luarocks_path = "") override; virtual std::unique_ptr 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 tags = {}) override; virtual std::unique_ptr get_role(const RGWRoleInfo& info) override; diff --git a/src/rgw/driver/motr/rgw_sal_motr.cc b/src/rgw/driver/motr/rgw_sal_motr.cc index 07ccab041e8..7160cf01aa8 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.cc +++ b/src/rgw/driver/motr/rgw_sal_motr.cc @@ -3029,6 +3029,7 @@ int MotrMultipartWriter::complete(size_t accounted_size, const std::string& etag std::unique_ptr 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, diff --git a/src/rgw/driver/motr/rgw_sal_motr.h b/src/rgw/driver/motr/rgw_sal_motr.h index e856c34e0b2..64d16824471 100644 --- a/src/rgw/driver/motr/rgw_sal_motr.h +++ b/src/rgw/driver/motr/rgw_sal_motr.h @@ -1058,6 +1058,7 @@ class MotrStore : public StoreDriver { std::unique_ptr get_lua_manager(const DoutPrefixProvider *dpp = nullptr, const std::string& luarocks_path = "") override; virtual std::unique_ptr 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="", diff --git a/src/rgw/driver/rados/rgw_sal_rados.cc b/src/rgw/driver/rados/rgw_sal_rados.cc index 61b1159104a..b809a32c716 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.cc +++ b/src/rgw/driver/rados/rgw_sal_rados.cc @@ -1206,21 +1206,13 @@ int RadosStore::load_account_role_by_name(const DoutPrefixProvider* dpp, std::string_view rolename, std::unique_ptr* 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 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 RadosStore::get_lua_manager(const std::string& luaro std::unique_ptr 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 tags) { - return std::make_unique(this, name, tenant, path, trust_policy, max_session_duration_str, tags); + return std::make_unique(this, name, tenant, std::move(account_id), path, trust_policy, max_session_duration_str, tags); } std::unique_ptr 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::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 diff --git a/src/rgw/driver/rados/rgw_sal_rados.h b/src/rgw/driver/rados/rgw_sal_rados.h index cfee6b87266..759bfad54ce 100644 --- a/src/rgw/driver/rados/rgw_sal_rados.h +++ b/src/rgw/driver/rados/rgw_sal_rados.h @@ -331,6 +331,7 @@ class RadosStore : public StoreDriver { std::unique_ptr get_lua_manager(const std::string& luarocks_path) override; virtual std::unique_ptr 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 tags) : RGWRole(name, tenant, path, trust_policy, max_session_duration, tags), store(_store) {} + std::multimap 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) {} diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 33355ec2735..2fa7d56c1d4 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -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 role = driver->get_role(role_name, tenant, path, + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr 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 role = driver->get_role(role_name, tenant); + std::unique_ptr role = driver->get_role(role_name, tenant, account_id); ret = role->get(dpp(), null_yield); if (ret < 0) { return -ret; diff --git a/src/rgw/rgw_rest_role.cc b/src/rgw/rgw_rest_role.cc index 463ed5eb08c..f8cf22d00a7 100644 --- a/src/rgw/rgw_rest_role.cc +++ b/src/rgw/rgw_rest_role.cc @@ -113,35 +113,60 @@ static int load_role(const DoutPrefixProvider* dpp, optional_yield y, std::unique_ptr& role, rgw::ARN& resource, std::string& message) { + auto arn_account = std::ref(tenant); if (const auto* id = std::get_if(&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(&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 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(&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"); diff --git a/src/rgw/rgw_rest_sts.cc b/src/rgw/rgw_rest_sts.cc index 210d310313f..4ec0d211687 100644 --- a/src/rgw/rgw_rest_sts.cc +++ b/src/rgw/rgw_rest_sts.cc @@ -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 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 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> 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); diff --git a/src/rgw/rgw_role.cc b/src/rgw/rgw_role.cc index 12e79d433ea..1f7648e690f 100644 --- a/src/rgw/rgw_role.cc +++ b/src/rgw/rgw_role.cc @@ -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 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); diff --git a/src/rgw/rgw_role.h b/src/rgw/rgw_role.h index 77d315fc96e..90a4a6a3128 100644 --- a/src/rgw/rgw_role.h +++ b/src/rgw/rgw_role.h @@ -30,13 +30,14 @@ struct RGWRoleInfo std::map 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;} diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index 910a4e5b142..01d06205f16 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -565,6 +565,7 @@ class Driver { /** Get an IAM Role by name etc. */ virtual std::unique_ptr 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="", diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 4a0015e046d..e2873fb71ba 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -1390,6 +1390,7 @@ namespace rgw::sal { std::unique_ptr 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, diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index 9a0f638e3da..bc037688eb6 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -904,6 +904,7 @@ public: std::unique_ptr get_lua_manager(const std::string& luarocks_path) override; virtual std::unique_ptr 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="", diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index 6b17cd36d53..ddcde348821 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -552,12 +552,13 @@ std::unique_ptr FilterDriver::get_lua_manager(const std::string& lua std::unique_ptr 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 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 FilterDriver::get_role(std::string id) diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index 7b31f9c751f..fde1a4dda95 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -389,6 +389,7 @@ public: virtual std::unique_ptr get_lua_manager(const std::string& luarocks_path) override; virtual std::unique_ptr get_role(std::string name, std::string tenant, + rgw_account_id account_id, std::string path="", std::string trust_policy="", std::string diff --git a/src/rgw/rgw_sts.cc b/src/rgw/rgw_sts.cc index 557bcf24f2b..1486868e1e1 100644 --- a/src/rgw/rgw_sts.cc +++ b/src/rgw/rgw_sts.cc @@ -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 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 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 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;