From c129eda137c0f70422adf53f2383d3f5a604a3f4 Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Mon, 24 Jan 2022 11:01:08 +0530 Subject: [PATCH] rgw: implementation of forward_request_to_master() for role REST APIs. Signed-off-by: Pritha Srivastava --- src/rgw/rgw_admin.cc | 2 +- src/rgw/rgw_auth_s3.cc | 11 +- src/rgw/rgw_auth_s3.h | 2 +- src/rgw/rgw_common.cc | 18 ++ src/rgw/rgw_common.h | 1 + src/rgw/rgw_rest_client.cc | 58 ++++-- src/rgw/rgw_rest_client.h | 2 +- src/rgw/rgw_rest_conn.cc | 18 ++ src/rgw/rgw_rest_conn.h | 3 + src/rgw/rgw_rest_iam.cc | 18 +- src/rgw/rgw_rest_iam.h | 6 +- src/rgw/rgw_rest_role.cc | 278 ++++++++++++++++++++++++++- src/rgw/rgw_rest_role.h | 21 +- src/rgw/rgw_rest_s3.cc | 4 +- src/rgw/rgw_role.cc | 9 +- src/rgw/rgw_role.h | 2 +- src/rgw/rgw_sal.h | 4 + src/rgw/rgw_sal_dbstore.cc | 8 + src/rgw/rgw_sal_dbstore.h | 4 + src/rgw/rgw_sal_motr.cc | 8 + src/rgw/rgw_sal_motr.h | 4 + src/rgw/rgw_sal_rados.cc | 66 ++++++- src/rgw/rgw_sal_rados.h | 6 +- src/rgw/services/svc_meta_be.cc | 5 +- src/rgw/services/svc_meta_be.h | 6 +- src/rgw/services/svc_meta_be_otp.cc | 3 +- src/rgw/services/svc_meta_be_otp.h | 3 +- src/rgw/services/svc_meta_be_sobj.cc | 10 +- src/rgw/services/svc_meta_be_sobj.h | 3 +- 29 files changed, 512 insertions(+), 71 deletions(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index c8369b471037e..404414a3a562d 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -6577,7 +6577,7 @@ int main(int argc, const char **argv) return -EINVAL; } std::unique_ptr role = store->get_role(role_name, tenant, path, assume_role_doc); - ret = role->create(dpp(), true, null_yield); + ret = role->create(dpp(), true, "", null_yield); if (ret < 0) { return -ret; } diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index e46bf32681b8b..62fe354b457b2 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -610,11 +610,12 @@ std::string get_v4_canonical_qs(const req_info& info, const bool using_qs) } static void add_v4_canonical_params_from_map(const map& m, - std::map *result) + std::map *result, + bool is_non_s3_op) { for (auto& entry : m) { const auto& key = entry.first; - if (key.empty()) { + if (key.empty() || (is_non_s3_op && key == "PayloadHash")) { continue; } @@ -622,12 +623,12 @@ static void add_v4_canonical_params_from_map(const map& m, } } -std::string gen_v4_canonical_qs(const req_info& info) +std::string gen_v4_canonical_qs(const req_info& info, bool is_non_s3_op) { std::map canonical_qs_map; - add_v4_canonical_params_from_map(info.args.get_params(), &canonical_qs_map); - add_v4_canonical_params_from_map(info.args.get_sys_params(), &canonical_qs_map); + add_v4_canonical_params_from_map(info.args.get_params(), &canonical_qs_map, is_non_s3_op); + add_v4_canonical_params_from_map(info.args.get_sys_params(), &canonical_qs_map, false); if (canonical_qs_map.empty()) { return string(); diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index edec31a3c6b13..37496df00eee5 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -601,7 +601,7 @@ static inline bool is_v4_payload_streamed(const char* const exp_payload_hash) std::string get_v4_canonical_qs(const req_info& info, bool using_qs); -std::string gen_v4_canonical_qs(const req_info& info); +std::string gen_v4_canonical_qs(const req_info& info, bool is_non_s3_op); boost::optional get_v4_canonical_headers(const req_info& info, diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 2411b7cffc8f5..750157edd5671 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -869,6 +869,24 @@ int RGWHTTPArgs::parse(const DoutPrefixProvider *dpp) return 0; } +void RGWHTTPArgs::remove(const string& name) +{ + auto val_iter = val_map.find(name); + if (val_iter != std::end(val_map)) { + val_map.erase(val_iter); + } + + auto sys_val_iter = sys_val_map.find(name); + if (sys_val_iter != std::end(sys_val_map)) { + sys_val_map.erase(sys_val_iter); + } + + auto subres_iter = sub_resources.find(name); + if (subres_iter != std::end(sub_resources)) { + sub_resources.erase(subres_iter); + } +} + void RGWHTTPArgs::append(const string& name, const string& val) { if (name.compare(0, sizeof(RGW_SYS_PARAM_PREFIX) - 1, RGW_SYS_PARAM_PREFIX) == 0) { diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 711607b98eb11..9e3096a2795a3 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -348,6 +348,7 @@ class RGWHTTPArgs { /** parse the received arguments */ int parse(const DoutPrefixProvider *dpp); void append(const std::string& name, const std::string& val); + void remove(const std::string& name); /** Get the value for a specific argument parameter */ const std::string& get(const std::string& name, bool *exists = NULL) const; boost::optional diff --git a/src/rgw/rgw_rest_client.cc b/src/rgw/rgw_rest_client.cc index 68b40324ce268..16730cfda1f74 100644 --- a/src/rgw/rgw_rest_client.cc +++ b/src/rgw/rgw_rest_client.cc @@ -189,7 +189,7 @@ void RGWHTTPSimpleRequest::get_out_headers(map *pheaders) out_headers.clear(); } -static int sign_request_v2(const DoutPrefixProvider *dpp, RGWAccessKey& key, +static int sign_request_v2(const DoutPrefixProvider *dpp, const RGWAccessKey& key, const string& region, const string& service, RGWEnv& env, req_info& info, const bufferlist *opt_content) @@ -230,7 +230,7 @@ static int sign_request_v2(const DoutPrefixProvider *dpp, RGWAccessKey& key, return 0; } -static int sign_request_v4(const DoutPrefixProvider *dpp, RGWAccessKey& key, +static int sign_request_v4(const DoutPrefixProvider *dpp, const RGWAccessKey& key, const string& region, const string& service, RGWEnv& env, req_info& info, const bufferlist *opt_content) @@ -248,7 +248,12 @@ static int sign_request_v4(const DoutPrefixProvider *dpp, RGWAccessKey& key, } } - auto sigv4_data = rgw::auth::s3::AWSSignerV4::prepare(dpp, key.id, region, service, info, opt_content, true); + rgw::auth::s3::AWSSignerV4::prepare_result_t sigv4_data; + if (service == "s3") { + sigv4_data = rgw::auth::s3::AWSSignerV4::prepare(dpp, key.id, region, service, info, opt_content, true); + } else { + sigv4_data = rgw::auth::s3::AWSSignerV4::prepare(dpp, key.id, region, service, info, opt_content, false); + } auto sigv4_headers = sigv4_data.signature_factory(dpp, key.key, sigv4_data); for (auto& entry : sigv4_headers) { @@ -259,7 +264,7 @@ static int sign_request_v4(const DoutPrefixProvider *dpp, RGWAccessKey& key, return 0; } -static int sign_request(const DoutPrefixProvider *dpp, RGWAccessKey& key, +static int sign_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, const string& region, const string& service, RGWEnv& env, req_info& info, const bufferlist *opt_content) @@ -289,7 +294,7 @@ static bool identify_scope(const DoutPrefixProvider *dpp, CephContext *cct, const string& host, string *region, - string *service) + string& service) { if (!boost::algorithm::ends_with(host, "amazonaws.com")) { ldpp_dout(dpp, 20) << "NOTICE: cannot identify region for connection to: " << host << dendl; @@ -300,14 +305,18 @@ static bool identify_scope(const DoutPrefixProvider *dpp, get_str_vec(host, ".", vec); - *service = "s3"; /* default */ + string ser = service; + if (service.empty()) { + service = "s3"; /* default */ + } for (auto iter = vec.begin(); iter != vec.end(); ++iter) { auto& s = *iter; if (s == "s3" || - s == "execute-api") { + s == "execute-api" || + s == "iam") { if (s == "execute-api") { - *service = s; + service = s; } ++iter; if (iter == vec.end()) { @@ -335,22 +344,26 @@ static void scope_from_api_name(const DoutPrefixProvider *dpp, const string& host, std::optional api_name, string *region, - string *service) + string& service) { - if (api_name) { + if (api_name && service.empty()) { *region = *api_name; - *service = "s3"; + service = "s3"; return; } if (!identify_scope(dpp, cct, host, region, service)) { - *region = cct->_conf->rgw_zonegroup; - *service = "s3"; + if (service == "iam") { + *region = cct->_conf->rgw_zonegroup; + } else { + *region = cct->_conf->rgw_zonegroup; + service = "s3"; + } return; } } -int RGWRESTSimpleRequest::forward_request(const DoutPrefixProvider *dpp, RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y) +int RGWRESTSimpleRequest::forward_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y, std::string service) { string date_str; @@ -381,21 +394,28 @@ int RGWRESTSimpleRequest::forward_request(const DoutPrefixProvider *dpp, RGWAcce } string region; - string service; + string s; + if (!service.empty()) { + s = service; + } - scope_from_api_name(dpp, cct, host, api_name, ®ion, &service); + scope_from_api_name(dpp, cct, host, api_name, ®ion, s); const char *maybe_payload_hash = info.env->get("HTTP_X_AMZ_CONTENT_SHA256"); - if (maybe_payload_hash) { + if (maybe_payload_hash && s != "iam") { new_env.set("HTTP_X_AMZ_CONTENT_SHA256", maybe_payload_hash); } - int ret = sign_request(dpp, key, region, service, new_env, new_info, nullptr); + int ret = sign_request(dpp, key, region, s, new_env, new_info, nullptr); if (ret < 0) { ldpp_dout(dpp, 0) << "ERROR: failed to sign request" << dendl; return ret; } + if (s == "iam") { + info.args.remove("PayloadHash"); + } + for (const auto& kv: new_env.get_map()) { headers.emplace_back(kv); } @@ -559,7 +579,7 @@ void RGWRESTGenerateHTTPHeaders::init(const string& _method, const string& host, const string& resource, const param_vec_t& params, std::optional api_name) { - scope_from_api_name(this, cct, host, api_name, ®ion, &service); + scope_from_api_name(this, cct, host, api_name, ®ion, service); string params_str; map& args = new_info->args.get_params(); diff --git a/src/rgw/rgw_rest_client.h b/src/rgw/rgw_rest_client.h index caf6ffa35c802..5beeb389589cc 100644 --- a/src/rgw/rgw_rest_client.h +++ b/src/rgw/rgw_rest_client.h @@ -65,7 +65,7 @@ public: param_vec_t *_headers, param_vec_t *_params, std::optional _api_name) : RGWHTTPSimpleRequest(_cct, _method, _url, _headers, _params), api_name(_api_name) {} - int forward_request(const DoutPrefixProvider *dpp, RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y); + int forward_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y, std::string service=""); }; class RGWWriteDrainCB { diff --git a/src/rgw/rgw_rest_conn.cc b/src/rgw/rgw_rest_conn.cc index a93e855e99dff..510cdd40049d2 100644 --- a/src/rgw/rgw_rest_conn.cc +++ b/src/rgw/rgw_rest_conn.cc @@ -109,6 +109,24 @@ int RGWRESTConn::forward(const DoutPrefixProvider *dpp, const rgw_user& uid, req return req.forward_request(dpp, key, info, max_response, inbl, outbl, y); } +int RGWRESTConn::forward_iam_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y) +{ + string url; + int ret = get_url(url); + if (ret < 0) + return ret; + param_vec_t params; + if (objv) { + params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "tag", objv->tag)); + char buf[16]; + snprintf(buf, sizeof(buf), "%lld", (long long)objv->ver); + params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "ver", buf)); + } + std::string service = "iam"; + RGWRESTSimpleRequest req(cct, info.method, url, NULL, ¶ms, api_name); + return req.forward_request(dpp, key, info, max_response, inbl, outbl, y, service); +} + int RGWRESTConn::put_obj_send_init(rgw::sal::Object* obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req) { string url; diff --git a/src/rgw/rgw_rest_conn.h b/src/rgw/rgw_rest_conn.h index 4069f5394b9a9..f697c58220ede 100644 --- a/src/rgw/rgw_rest_conn.h +++ b/src/rgw/rgw_rest_conn.h @@ -130,6 +130,9 @@ public: /* sync request */ int forward(const DoutPrefixProvider *dpp, const rgw_user& uid, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y); + /* sync request */ + int forward_iam_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y); + /* async requests */ int put_obj_send_init(rgw::sal::Object* obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req); diff --git a/src/rgw/rgw_rest_iam.cc b/src/rgw/rgw_rest_iam.cc index 7b01133fce4a1..f63018d189b3b 100644 --- a/src/rgw/rgw_rest_iam.cc +++ b/src/rgw/rgw_rest_iam.cc @@ -20,6 +20,7 @@ using namespace std; void RGWHandler_REST_IAM::rgw_iam_parse_input() { + std::string post_body = bl_post_body.to_str(); if (post_body.size() > 0) { ldpp_dout(s, 10) << "Content of POST: " << post_body << dendl; @@ -46,23 +47,23 @@ RGWOp *RGWHandler_REST_IAM::op_post() if (s->info.args.exists("Action")) { string action = s->info.args.get("Action"); if (action.compare("CreateRole") == 0) - return new RGWCreateRole; + return new RGWCreateRole(this->bl_post_body); if (action.compare("DeleteRole") == 0) - return new RGWDeleteRole; + return new RGWDeleteRole(this->bl_post_body); if (action.compare("GetRole") == 0) return new RGWGetRole; if (action.compare("UpdateAssumeRolePolicy") == 0) - return new RGWModifyRole; + return new RGWModifyRole(this->bl_post_body); if (action.compare("ListRoles") == 0) return new RGWListRoles; if (action.compare("PutRolePolicy") == 0) - return new RGWPutRolePolicy; + return new RGWPutRolePolicy(this->bl_post_body); if (action.compare("GetRolePolicy") == 0) return new RGWGetRolePolicy; if (action.compare("ListRolePolicies") == 0) return new RGWListRolePolicies; if (action.compare("DeleteRolePolicy") == 0) - return new RGWDeleteRolePolicy; + return new RGWDeleteRolePolicy(this->bl_post_body); if (action.compare("PutUserPolicy") == 0) return new RGWPutUserPolicy; if (action.compare("GetUserPolicy") == 0) @@ -80,11 +81,11 @@ RGWOp *RGWHandler_REST_IAM::op_post() if (action.compare("DeleteOpenIDConnectProvider") == 0) return new RGWDeleteOIDCProvider; if (action.compare("TagRole") == 0) - return new RGWTagRole; + return new RGWTagRole(this->bl_post_body); if (action.compare("ListRoleTags") == 0) return new RGWListRoleTags; if (action.compare("UntagRole") == 0) - return new RGWUntagRole; + return new RGWUntagRole(this->bl_post_body); } return nullptr; @@ -157,5 +158,6 @@ RGWRESTMgr_IAM::get_handler(rgw::sal::Store* store, const rgw::auth::StrategyRegistry& auth_registry, const std::string& frontend_prefix) { - return new RGWHandler_REST_IAM(auth_registry); + bufferlist bl; + return new RGWHandler_REST_IAM(auth_registry, bl); } diff --git a/src/rgw/rgw_rest_iam.h b/src/rgw/rgw_rest_iam.h index 0822f6f7e6893..d2421b603210a 100644 --- a/src/rgw/rgw_rest_iam.h +++ b/src/rgw/rgw_rest_iam.h @@ -9,7 +9,7 @@ class RGWHandler_REST_IAM : public RGWHandler_REST { const rgw::auth::StrategyRegistry& auth_registry; - const std::string& post_body; + bufferlist bl_post_body; RGWOp *op_post() override; void rgw_iam_parse_input(); public: @@ -17,10 +17,10 @@ public: static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format); RGWHandler_REST_IAM(const rgw::auth::StrategyRegistry& auth_registry, - const std::string& post_body="") + bufferlist& bl_post_body) : RGWHandler_REST(), auth_registry(auth_registry), - post_body(post_body) {} + bl_post_body(bl_post_body) {} ~RGWHandler_REST_IAM() override = default; int init(rgw::sal::Store* store, diff --git a/src/rgw/rgw_rest_role.cc b/src/rgw/rgw_rest_role.cc index 0fa0f8f011554..7ae70e6a097e8 100644 --- a/src/rgw/rgw_rest_role.cc +++ b/src/rgw/rgw_rest_role.cc @@ -203,9 +203,85 @@ void RGWCreateRole::execute(optional_yield y) op_ret = -EINVAL; return; } - op_ret = role->create(s, true, y); + + std::string role_id; + + if (!store->is_meta_master()) { + RGWXMLDecoder::XMLParser parser; + if (!parser.init()) { + ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl; + op_ret = -EINVAL; + return; + } + + bufferlist data; + s->info.args.remove("RoleName"); + s->info.args.remove("Path"); + s->info.args.remove("AssumeRolePolicyDocument"); + s->info.args.remove("MaxSessionDuration"); + s->info.args.remove("Action"); + s->info.args.remove("Version"); + auto& val_map = s->info.args.get_params(); + for (auto it = val_map.begin(); it!= val_map.end(); it++) { + if (it->first.find("Tags.member.") == 0) { + val_map.erase(it); + } + } + + RGWUserInfo info = s->user->get_info(); + const auto& it = info.access_keys.begin(); + RGWAccessKey key; + if (it != info.access_keys.end()) { + key.id = it->first; + RGWAccessKey cred = it->second; + key.key = cred.key; + } + op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y); + if (op_ret < 0) { + ldpp_dout(this, 20) << "ERROR: forward_iam_request_to_master failed with error code: " << op_ret << dendl; + return; + } + + XMLObj* create_role_resp_obj = parser.find_first("CreateRoleResponse");; + if (!create_role_resp_obj) { + ldpp_dout(this, 5) << "ERROR: unexpected xml: CreateRoleResponse" << dendl; + op_ret = -EINVAL; + return; + } + + XMLObj* create_role_res_obj = create_role_resp_obj->find_first("CreateRoleResult"); + if (!create_role_res_obj) { + ldpp_dout(this, 5) << "ERROR: unexpected xml: CreateRoleResult" << dendl; + op_ret = -EINVAL; + return; + } + + XMLObj* role_obj = nullptr; + if (create_role_res_obj) { + role_obj = create_role_res_obj->find_first("Role"); + } + if (!role_obj) { + ldpp_dout(this, 5) << "ERROR: unexpected xml: Role" << dendl; + op_ret = -EINVAL; + return; + } + + try { + if (role_obj) { + RGWXMLDecoder::decode_xml("RoleId", role_id, role_obj, true); + } + } catch (RGWXMLDecoder::err& err) { + ldpp_dout(this, 5) << "ERROR: unexpected xml: RoleId" << dendl; + op_ret = -EINVAL; + return; + } + ldpp_dout(this, 0) << "role_id decoded from master zonegroup response is" << role_id << dendl; + } + + op_ret = role->create(s, true, role_id, y); if (op_ret == -EEXIST) { op_ret = -ERR_ROLE_EXISTS; + return; } if (op_ret == 0) { @@ -236,15 +312,52 @@ int RGWDeleteRole::get_params() void RGWDeleteRole::execute(optional_yield y) { + bool is_master = true; + int master_op_ret = 0; op_ret = get_params(); if (op_ret < 0) { return; } + if (!store->is_meta_master()) { + is_master = false; + RGWXMLDecoder::XMLParser parser; + if (!parser.init()) { + ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl; + op_ret = -EINVAL; + } + + bufferlist data; + s->info.args.remove("RoleName"); + s->info.args.remove("Action"); + s->info.args.remove("Version"); + + RGWUserInfo info = s->user->get_info(); + const auto& it = info.access_keys.begin(); + RGWAccessKey key; + if (it != info.access_keys.end()) { + key.id = it->first; + RGWAccessKey cred = it->second; + key.key = cred.key; + } + master_op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y); + if (master_op_ret < 0) { + op_ret = master_op_ret; + ldpp_dout(this, 0) << "forward_iam_request_to_master returned ret=" << op_ret << dendl; + return; + } + } + op_ret = _role->delete_obj(s, y); if (op_ret == -ENOENT) { - op_ret = -ERR_NO_ROLE_FOUND; + //Role has been deleted since metadata from master has synced up + if (!is_master && master_op_ret == 0) { + op_ret = 0; + } else { + op_ret = -ERR_NO_ROLE_FOUND; + } + return; } if (!op_ret) { s->formatter->open_object_section("DeleteRoleResponse"); @@ -350,6 +463,35 @@ void RGWModifyRole::execute(optional_yield y) return; } + if (!store->is_meta_master()) { + RGWXMLDecoder::XMLParser parser; + if (!parser.init()) { + ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl; + op_ret = -EINVAL; + return; + } + + bufferlist data; + s->info.args.remove("RoleName"); + s->info.args.remove("PolicyDocument"); + s->info.args.remove("Action"); + s->info.args.remove("Version"); + + RGWUserInfo info = s->user->get_info(); + const auto& it = info.access_keys.begin(); + RGWAccessKey key; + if (it != info.access_keys.end()) { + key.id = it->first; + RGWAccessKey cred = it->second; + key.key = cred.key; + } + op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y); + if (op_ret < 0) { + ldpp_dout(this, 20) << "ERROR: forward_iam_request_to_master failed with error code: " << op_ret << dendl; + return; + } + } + _role->update_trust_policy(trust_policy); op_ret = _role->update(this, y); @@ -442,6 +584,36 @@ void RGWPutRolePolicy::execute(optional_yield y) return; } + if (!store->is_meta_master()) { + RGWXMLDecoder::XMLParser parser; + if (!parser.init()) { + ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl; + op_ret = -EINVAL; + return; + } + + bufferlist data; + s->info.args.remove("RoleName"); + s->info.args.remove("PolicyName"); + s->info.args.remove("PolicyDocument"); + s->info.args.remove("Action"); + s->info.args.remove("Version"); + + RGWUserInfo info = s->user->get_info(); + const auto& it = info.access_keys.begin(); + RGWAccessKey key; + if (it != info.access_keys.end()) { + key.id = it->first; + RGWAccessKey cred = it->second; + key.key = cred.key; + } + op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y); + if (op_ret < 0) { + ldpp_dout(this, 20) << "ERROR: forward_iam_request_to_master failed with error code: " << op_ret << dendl; + return; + } + } + _role->set_perm_policy(policy_name, perm_policy); op_ret = _role->update(this, y); @@ -545,9 +717,39 @@ void RGWDeleteRolePolicy::execute(optional_yield y) return; } + if (!store->is_meta_master()) { + RGWXMLDecoder::XMLParser parser; + if (!parser.init()) { + ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl; + op_ret = -EINVAL; + return; + } + + bufferlist data; + s->info.args.remove("RoleName"); + s->info.args.remove("PolicyName"); + s->info.args.remove("Action"); + s->info.args.remove("Version"); + + RGWUserInfo info = s->user->get_info(); + const auto& it = info.access_keys.begin(); + RGWAccessKey key; + if (it != info.access_keys.end()) { + key.id = it->first; + RGWAccessKey cred = it->second; + key.key = cred.key; + } + op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y); + if (op_ret < 0) { + ldpp_dout(this, 20) << "ERROR: forward_iam_request_to_master failed with error code: " << op_ret << dendl; + return; + } + } + op_ret = _role->delete_policy(this, policy_name); if (op_ret == -ENOENT) { op_ret = -ERR_NO_ROLE_FOUND; + return; } if (op_ret == 0) { @@ -584,6 +786,40 @@ void RGWTagRole::execute(optional_yield y) return; } + if (!store->is_meta_master()) { + RGWXMLDecoder::XMLParser parser; + if (!parser.init()) { + ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl; + op_ret = -EINVAL; + return; + } + + bufferlist data; + s->info.args.remove("RoleName"); + s->info.args.remove("Action"); + s->info.args.remove("Version"); + auto& val_map = s->info.args.get_params(); + for (auto it = val_map.begin(); it!= val_map.end(); it++) { + if (it->first.find("Tags.member.") == 0) { + val_map.erase(it); + } + } + + RGWUserInfo info = s->user->get_info(); + const auto& it = info.access_keys.begin(); + RGWAccessKey key; + if (it != info.access_keys.end()) { + key.id = it->first; + RGWAccessKey cred = it->second; + key.key = cred.key; + } + op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y); + if (op_ret < 0) { + ldpp_dout(this, 20) << "ERROR: forward_iam_request_to_master failed with error code: " << op_ret << dendl; + return; + } + } + op_ret = _role->set_tags(this, tags); if (op_ret == 0) { op_ret = _role->update(this, y); @@ -664,6 +900,44 @@ void RGWUntagRole::execute(optional_yield y) return; } + if (!store->is_meta_master()) { + RGWXMLDecoder::XMLParser parser; + if (!parser.init()) { + ldpp_dout(this, 0) << "ERROR: failed to initialize xml parser" << dendl; + op_ret = -EINVAL; + return; + } + + bufferlist data; + s->info.args.remove("RoleName"); + s->info.args.remove("Action"); + s->info.args.remove("Version"); + auto& val_map = s->info.args.get_params(); + std::vector::iterator> iters; + for (auto it = val_map.begin(); it!= val_map.end(); it++) { + if (it->first.find("Tags.member.") == 0) { + iters.emplace_back(it); + } + } + + for (auto& it : iters) { + val_map.erase(it); + } + RGWUserInfo info = s->user->get_info(); + const auto& it = info.access_keys.begin(); + RGWAccessKey key; + if (it != info.access_keys.end()) { + key.id = it->first; + RGWAccessKey cred = it->second; + key.key = cred.key; + } + op_ret = store->forward_iam_request_to_master(s, key, nullptr, bl_post_body, &parser, s->info, y); + if (op_ret < 0) { + ldpp_dout(this, 20) << "ERROR: forward_iam_request_to_master failed with error code: " << op_ret << dendl; + return; + } + } + _role->erase_tags(tagKeys); op_ret = _role->update(this, y); diff --git a/src/rgw/rgw_rest_role.h b/src/rgw/rgw_rest_role.h index a8beb2b54052c..f007d2ec23fa6 100644 --- a/src/rgw/rgw_rest_role.h +++ b/src/rgw/rgw_rest_role.h @@ -39,8 +39,9 @@ public: }; class RGWCreateRole : public RGWRoleWrite { + bufferlist bl_post_body; public: - RGWCreateRole() = default; + RGWCreateRole(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {}; int verify_permission(optional_yield y) override; void execute(optional_yield y) override; int get_params(); @@ -50,8 +51,9 @@ public: }; class RGWDeleteRole : public RGWRoleWrite { + bufferlist bl_post_body; public: - RGWDeleteRole() = default; + RGWDeleteRole(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {}; void execute(optional_yield y) override; int get_params(); const char* name() const override { return "delete_role"; } @@ -72,8 +74,9 @@ public: }; class RGWModifyRole : public RGWRoleWrite { + bufferlist bl_post_body; public: - RGWModifyRole() = default; + RGWModifyRole(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {}; void execute(optional_yield y) override; int get_params(); const char* name() const override { return "modify_role"; } @@ -93,8 +96,9 @@ public: }; class RGWPutRolePolicy : public RGWRoleWrite { + bufferlist bl_post_body; public: - RGWPutRolePolicy() = default; + RGWPutRolePolicy(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {}; void execute(optional_yield y) override; int get_params(); const char* name() const override { return "put_role_policy"; } @@ -123,8 +127,9 @@ public: }; class RGWDeleteRolePolicy : public RGWRoleWrite { + bufferlist bl_post_body; public: - RGWDeleteRolePolicy() = default; + RGWDeleteRolePolicy(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {}; void execute(optional_yield y) override; int get_params(); const char* name() const override { return "delete_role_policy"; } @@ -133,8 +138,9 @@ public: }; class RGWTagRole : public RGWRoleWrite { + bufferlist bl_post_body; public: - RGWTagRole() = default; + RGWTagRole(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {}; void execute(optional_yield y) override; int get_params(); const char* name() const override { return "tag_role"; } @@ -153,8 +159,9 @@ public: }; class RGWUntagRole : public RGWRoleWrite { + bufferlist bl_post_body; public: - RGWUntagRole() = default; + RGWUntagRole(const bufferlist& bl_post_body) : bl_post_body(bl_post_body) {}; void execute(optional_yield y) override; int get_params(); const char* name() const override { return "untag_role"; } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index db7d54cdcf3ef..2cfc2eacd63c8 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -4451,7 +4451,7 @@ RGWOp *RGWHandler_REST_Service_S3::op_post() } if (isIAMEnabled) { - RGWHandler_REST_IAM iam_handler(auth_registry, post_body); + RGWHandler_REST_IAM iam_handler(auth_registry, data); iam_handler.init(store, s, s->cio); auto op = iam_handler.get_op(); if (op) { @@ -5445,7 +5445,7 @@ AWSSignerV4::prepare(const DoutPrefixProvider *dpp, /* Craft canonical query string. std::moving later so non-const here. */ - auto canonical_qs = rgw::auth::s3::gen_v4_canonical_qs(info); + auto canonical_qs = rgw::auth::s3::gen_v4_canonical_qs(info, is_non_s3_op); auto cct = dpp->get_cct(); diff --git a/src/rgw/rgw_role.cc b/src/rgw/rgw_role.cc index 93cfa9e648035..b30653deb0015 100644 --- a/src/rgw/rgw_role.cc +++ b/src/rgw/rgw_role.cc @@ -39,7 +39,12 @@ const string RGWRole::role_arn_prefix = "arn:aws:iam::"; void RGWRoleInfo::dump(Formatter *f) const { encode_json("RoleId", id , f); - std::string role_name = tenant + '$' + name; + std::string role_name; + if (tenant.empty()) { + role_name = name; + } else { + role_name = tenant + '$' + name; + } encode_json("RoleName", role_name , f); encode_json("Path", path, f); encode_json("Arn", arn, f); @@ -361,7 +366,7 @@ public: auto* store = mdo->get_store(); info.mtime = mtime; std::unique_ptr role = store->get_role(info); - int ret = role->create(dpp, true, y); + int ret = role->create(dpp, true, info.id, y); return ret < 0 ? ret : STATUS_APPLIED; } }; diff --git a/src/rgw/rgw_role.h b/src/rgw/rgw_role.h index ac124d777719c..6ea23e090e9b8 100644 --- a/src/rgw/rgw_role.h +++ b/src/rgw/rgw_role.h @@ -126,7 +126,7 @@ public: void set_id(const std::string& id) { this->info.id = id; } void set_mtime(const real_time& mtime) { this->info.mtime = mtime; } - virtual int create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) = 0; + virtual int create(const DoutPrefixProvider *dpp, bool exclusive, const std::string &role_id, optional_yield y) = 0; virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) = 0; int get(const DoutPrefixProvider *dpp, optional_yield y); int get_by_id(const DoutPrefixProvider *dpp, optional_yield y); diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index 74a5fa5731c1b..594b13e661951 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -320,6 +320,10 @@ class Store { virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv, bufferlist& in_data, JSONParser* jp, req_info& info, optional_yield y) = 0; + virtual int forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) = 0; /** Get zone info for this store */ virtual Zone* get_zone() = 0; /** Get a unique ID specific to this zone. */ diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index ac39fa721b304..9cebbc81e0df9 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -1732,6 +1732,14 @@ namespace rgw::sal { return 0; } + int DBStore::forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) + { + return 0; + } + std::string DBStore::zone_unique_id(uint64_t unique_num) { return ""; diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index 36b51a13671d0..18c7d6aa5ac22 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -766,6 +766,10 @@ public: virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv, bufferlist& in_data, JSONParser *jp, req_info& info, optional_yield y) override; + virtual int forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) override; virtual Zone* get_zone() { return &zone; } virtual std::string zone_unique_id(uint64_t unique_num) override; virtual std::string zone_unique_trans_id(const uint64_t unique_num) override; diff --git a/src/rgw/rgw_sal_motr.cc b/src/rgw/rgw_sal_motr.cc index 49bb92454c971..5623b2efa2813 100644 --- a/src/rgw/rgw_sal_motr.cc +++ b/src/rgw/rgw_sal_motr.cc @@ -2936,6 +2936,14 @@ int MotrStore::forward_request_to_master(const DoutPrefixProvider *dpp, User* us return 0; } +int MotrStore::forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) +{ + return 0; +} + std::string MotrStore::zone_unique_id(uint64_t unique_num) { return ""; diff --git a/src/rgw/rgw_sal_motr.h b/src/rgw/rgw_sal_motr.h index dd990a693cd37..928890689a366 100644 --- a/src/rgw/rgw_sal_motr.h +++ b/src/rgw/rgw_sal_motr.h @@ -914,6 +914,10 @@ class MotrStore : public Store { virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv, bufferlist& in_data, JSONParser *jp, req_info& info, optional_yield y) override; + virtual int forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) override; virtual Zone* get_zone() { return &zone; } virtual std::string zone_unique_id(uint64_t unique_num) override; virtual std::string zone_unique_trans_id(const uint64_t unique_num) override; diff --git a/src/rgw/rgw_sal_rados.cc b/src/rgw/rgw_sal_rados.cc index c7ed4bdd6f65a..158d54752bacd 100644 --- a/src/rgw/rgw_sal_rados.cc +++ b/src/rgw/rgw_sal_rados.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include "common/Clock.h" #include "common/errno.h" @@ -1131,6 +1132,45 @@ int RadosStore::forward_request_to_master(const DoutPrefixProvider *dpp, User* u return 0; } +int RadosStore::forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) +{ + if (is_meta_master()) { + /* We're master, don't forward */ + return 0; + } + + if (!svc()->zone->get_master_conn()) { + ldpp_dout(dpp, 0) << "rest connection is invalid" << dendl; + return -EINVAL; + } + ldpp_dout(dpp, 0) << "sending request to master zonegroup" << dendl; + bufferlist response; +#define MAX_REST_RESPONSE (128 * 1024) // we expect a very small response + int ret = svc()->zone->get_master_conn()->forward_iam_request(dpp, key, info, + objv, MAX_REST_RESPONSE, + &in_data, &response, y); + if (ret < 0) + return ret; + + ldpp_dout(dpp, 20) << "response: " << response.c_str() << dendl; + + std::string r = response.c_str(); + std::string str_to_search = """; + std::string str_to_replace = "\""; + boost::replace_all(r, str_to_search, str_to_replace); + ldpp_dout(dpp, 20) << "r: " << r.c_str() << dendl; + + if (parser && !parser->parse(r.c_str(), r.length(), 1)) { + ldpp_dout(dpp, 0) << "ERROR: failed to parse response from master zonegroup" << dendl; + return -EIO; + } + + return 0; +} + std::string RadosStore::zone_unique_id(uint64_t unique_num) { return svc()->zone_utils->unique_id(unique_num); @@ -3080,13 +3120,19 @@ int RadosRole::store_info(const DoutPrefixProvider *dpp, bool exclusive, optiona if (!this->info.tags.empty()) { bufferlist bl_tags; encode(this->info.tags, bl_tags); - info.attrs.emplace("tagging", bl_tags); - } + map attrs; + attrs.emplace("tagging", bl_tags); - RGWSI_MBSObj_PutParams params(bl, &info.attrs, info.mtime, exclusive); - std::unique_ptr ctx(store->svc()->role->svc.meta_be->alloc_ctx()); - ctx->init(store->svc()->role->get_be_handler()); - return store->svc()->role->svc.meta_be->put(ctx.get(), oid, params, &info.objv_tracker, y, dpp); + RGWSI_MBSObj_PutParams params(bl, &attrs, info.mtime, exclusive); + std::unique_ptr ctx(store->svc()->role->svc.meta_be->alloc_ctx()); + ctx->init(store->svc()->role->get_be_handler()); + return store->svc()->role->svc.meta_be->put(ctx.get(), oid, params, &info.objv_tracker, y, dpp); + } else { + RGWSI_MBSObj_PutParams params(bl, nullptr, info.mtime, exclusive); + std::unique_ptr ctx(store->svc()->role->svc.meta_be->alloc_ctx()); + ctx->init(store->svc()->role->get_be_handler()); + return store->svc()->role->svc.meta_be->put(ctx.get(), oid, params, &info.objv_tracker, y, dpp); + } } int RadosRole::store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) @@ -3177,7 +3223,7 @@ int RadosRole::read_info(const DoutPrefixProvider *dpp, optional_yield y) RGWSI_MBSObj_GetParams params(&bl, &info.attrs, &info.mtime); std::unique_ptr ctx(store->svc()->role->svc.meta_be->alloc_ctx()); ctx->init(store->svc()->role->get_be_handler()); - int ret = store->svc()->role->svc.meta_be->get(ctx.get(), oid, params, &info.objv_tracker, y, dpp); + int ret = store->svc()->role->svc.meta_be->get(ctx.get(), oid, params, &info.objv_tracker, y, dpp, true); if (ret < 0) { ldpp_dout(dpp, 0) << "ERROR: failed reading role info from Role pool: " << info.id << ": " << cpp_strerror(-ret) << dendl; return ret; @@ -3208,7 +3254,7 @@ int RadosRole::read_info(const DoutPrefixProvider *dpp, optional_yield y) return 0; } -int RadosRole::create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) +int RadosRole::create(const DoutPrefixProvider *dpp, bool exclusive, const std::string& role_id, optional_yield y) { int ret; @@ -3216,6 +3262,10 @@ int RadosRole::create(const DoutPrefixProvider *dpp, bool exclusive, optional_yi return -EINVAL; } + if (!role_id.empty()) { + info.id = role_id; + } + /* check to see the name is not used */ ret = read_id(dpp, info.name, info.tenant, info.id, y); if (exclusive && ret == 0) { diff --git a/src/rgw/rgw_sal_rados.h b/src/rgw/rgw_sal_rados.h index a11ce994360c6..b2eb958a54474 100644 --- a/src/rgw/rgw_sal_rados.h +++ b/src/rgw/rgw_sal_rados.h @@ -141,6 +141,10 @@ class RadosStore : public Store { virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv, bufferlist& in_data, JSONParser* jp, req_info& info, optional_yield y) override; + virtual int forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv, + bufferlist& in_data, + RGWXMLDecoder::XMLParser* parser, req_info& info, + optional_yield y) override; virtual Zone* get_zone() { return zone.get(); } virtual std::string zone_unique_id(uint64_t unique_num) override; virtual std::string zone_unique_trans_id(const uint64_t unique_num) override; @@ -914,7 +918,7 @@ public: virtual int read_id(const DoutPrefixProvider *dpp, const std::string& role_name, const std::string& tenant, std::string& role_id, optional_yield y) override; virtual int read_name(const DoutPrefixProvider *dpp, optional_yield y) override; virtual int read_info(const DoutPrefixProvider *dpp, optional_yield y) override; - virtual int create(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y) override; + virtual int create(const DoutPrefixProvider *dpp, bool exclusive, const std::string& role_id, optional_yield y) override; virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override; }; }} // namespace rgw::sal diff --git a/src/rgw/services/svc_meta_be.cc b/src/rgw/services/svc_meta_be.cc index 5037ae536277d..9d030e3148113 100644 --- a/src/rgw/services/svc_meta_be.cc +++ b/src/rgw/services/svc_meta_be.cc @@ -115,9 +115,10 @@ int RGWSI_MetaBackend::get(Context *ctx, GetParams& params, RGWObjVersionTracker *objv_tracker, optional_yield y, - const DoutPrefixProvider *dpp) + const DoutPrefixProvider *dpp, + bool get_raw_attrs) { - return get_entry(ctx, key, params, objv_tracker, y, dpp); + return get_entry(ctx, key, params, objv_tracker, y, dpp, get_raw_attrs); } int RGWSI_MetaBackend::put(Context *ctx, diff --git a/src/rgw/services/svc_meta_be.h b/src/rgw/services/svc_meta_be.h index 79f0a4aa1ae8e..b2b5784f6ba6f 100644 --- a/src/rgw/services/svc_meta_be.h +++ b/src/rgw/services/svc_meta_be.h @@ -145,7 +145,8 @@ public: RGWSI_MetaBackend::GetParams& params, RGWObjVersionTracker *objv_tracker, optional_yield y, - const DoutPrefixProvider *dpp) = 0; + const DoutPrefixProvider *dpp, + bool get_raw_attrs=false) = 0; virtual int put_entry(const DoutPrefixProvider *dpp, RGWSI_MetaBackend::Context *ctx, const std::string& key, @@ -184,7 +185,8 @@ public: GetParams ¶ms, RGWObjVersionTracker *objv_tracker, optional_yield y, - const DoutPrefixProvider *dpp); + const DoutPrefixProvider *dpp, + bool get_raw_attrs=false); virtual int put(Context *ctx, const std::string& key, diff --git a/src/rgw/services/svc_meta_be_otp.cc b/src/rgw/services/svc_meta_be_otp.cc index e8c8b7864d143..bc5db46145551 100644 --- a/src/rgw/services/svc_meta_be_otp.cc +++ b/src/rgw/services/svc_meta_be_otp.cc @@ -46,7 +46,8 @@ int RGWSI_MetaBackend_OTP::get_entry(RGWSI_MetaBackend::Context *_ctx, RGWSI_MetaBackend::GetParams& _params, RGWObjVersionTracker *objv_tracker, optional_yield y, - const DoutPrefixProvider *dpp) + const DoutPrefixProvider *dpp, + bool get_raw_attrs) { RGWSI_MBOTP_GetParams& params = static_cast(_params); diff --git a/src/rgw/services/svc_meta_be_otp.h b/src/rgw/services/svc_meta_be_otp.h index 52ea66b337359..fc17d761fcd2f 100644 --- a/src/rgw/services/svc_meta_be_otp.h +++ b/src/rgw/services/svc_meta_be_otp.h @@ -78,7 +78,8 @@ public: RGWSI_MetaBackend::GetParams& _params, RGWObjVersionTracker *objv_tracker, optional_yield y, - const DoutPrefixProvider *dpp); + const DoutPrefixProvider *dpp, + bool get_raw_attrs=false); int put_entry(const DoutPrefixProvider *dpp, RGWSI_MetaBackend::Context *ctx, const std::string& key, diff --git a/src/rgw/services/svc_meta_be_sobj.cc b/src/rgw/services/svc_meta_be_sobj.cc index 6c06182af477f..208f6045f588e 100644 --- a/src/rgw/services/svc_meta_be_sobj.cc +++ b/src/rgw/services/svc_meta_be_sobj.cc @@ -143,7 +143,8 @@ int RGWSI_MetaBackend_SObj::get_entry(RGWSI_MetaBackend::Context *_ctx, GetParams& _params, RGWObjVersionTracker *objv_tracker, optional_yield y, - const DoutPrefixProvider *dpp) + const DoutPrefixProvider *dpp, + bool get_raw_attrs) { RGWSI_MetaBackend_SObj::Context_SObj *ctx = static_cast(_ctx); RGWSI_MBSObj_GetParams& params = static_cast(_params); @@ -152,11 +153,14 @@ int RGWSI_MetaBackend_SObj::get_entry(RGWSI_MetaBackend::Context *_ctx, string oid; ctx->module->get_pool_and_oid(key, &pool, &oid); - return rgw_get_system_obj(*ctx->obj_ctx, pool, oid, *params.pbl, + int ret = 0; + ret = rgw_get_system_obj(*ctx->obj_ctx, pool, oid, *params.pbl, objv_tracker, params.pmtime, y, dpp, params.pattrs, params.cache_info, - params.refresh_version); + params.refresh_version, get_raw_attrs); + + return ret; } int RGWSI_MetaBackend_SObj::put_entry(const DoutPrefixProvider *dpp, diff --git a/src/rgw/services/svc_meta_be_sobj.h b/src/rgw/services/svc_meta_be_sobj.h index 8183617d437b0..fe3230ec8d979 100644 --- a/src/rgw/services/svc_meta_be_sobj.h +++ b/src/rgw/services/svc_meta_be_sobj.h @@ -151,7 +151,8 @@ public: RGWSI_MetaBackend::GetParams& params, RGWObjVersionTracker *objv_tracker, optional_yield y, - const DoutPrefixProvider *dpp) override; + const DoutPrefixProvider *dpp, + bool get_raw_attrs=false) override; int put_entry(const DoutPrefixProvider *dpp, RGWSI_MetaBackend::Context *ctx, const std::string& key, -- 2.39.5