]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: implementation of forward_request_to_master()
authorPritha Srivastava <prsrivas@redhat.com>
Mon, 24 Jan 2022 05:31:08 +0000 (11:01 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Mon, 6 Jun 2022 10:49:43 +0000 (16:19 +0530)
for role REST APIs.

Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
29 files changed:
src/rgw/rgw_admin.cc
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_auth_s3.h
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_rest_client.cc
src/rgw/rgw_rest_client.h
src/rgw/rgw_rest_conn.cc
src/rgw/rgw_rest_conn.h
src/rgw/rgw_rest_iam.cc
src/rgw/rgw_rest_iam.h
src/rgw/rgw_rest_role.cc
src/rgw/rgw_rest_role.h
src/rgw/rgw_rest_s3.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_motr.cc
src/rgw/rgw_sal_motr.h
src/rgw/rgw_sal_rados.cc
src/rgw/rgw_sal_rados.h
src/rgw/services/svc_meta_be.cc
src/rgw/services/svc_meta_be.h
src/rgw/services/svc_meta_be_otp.cc
src/rgw/services/svc_meta_be_otp.h
src/rgw/services/svc_meta_be_sobj.cc
src/rgw/services/svc_meta_be_sobj.h

index c8369b471037e799a2a0282397723843e1ba48fa..404414a3a562dd341be1345ce27b811d3d7196ea 100644 (file)
@@ -6577,7 +6577,7 @@ int main(int argc, const char **argv)
         return -EINVAL;
       }
       std::unique_ptr<rgw::sal::RGWRole> 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;
       }
index e46bf32681b8be292f9924bdaffe0e6443524777..62fe354b457b26ad7f5e4b717bd0c4fe9c951b7d 100644 (file)
@@ -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<string, string>& m,
-                                        std::map<string, string> *result)
+                                        std::map<string, string> *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<string, string>& 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<std::string, std::string> 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();
index edec31a3c6b1382fc6dc3e4dc4144a5bbca8949d..37496df00eee5d9e47d7da399aa191836b64c47a 100644 (file)
@@ -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<std::string>
 get_v4_canonical_headers(const req_info& info,
index 2411b7cffc8f57bbbc4f6df363657e7d0a9f2785..750157edd5671173b1e90ce06f503949cc678aac 100644 (file)
@@ -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) {
index 711607b98eb11fc804849b49be6ee60e5031ea79..9e3096a2795a3bfdf4c5fe504d8a504c1be97c4a 100644 (file)
@@ -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<const std::string&>
index 68b40324ce268f5285b2ab3c300392472a831568..16730cfda1f74340a61091532fbeb9668868208f 100644 (file)
@@ -189,7 +189,7 @@ void RGWHTTPSimpleRequest::get_out_headers(map<string, string> *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)
+                           stringservice)
 {
   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<string> api_name,
                                 string *region,
-                                string *service)
+                                stringservice)
 {
-  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, &region, &service);
+  scope_from_api_name(dpp, cct, host, api_name, &region, 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<string> api_name)
 {
-  scope_from_api_name(this, cct, host, api_name, &region, &service);
+  scope_from_api_name(this, cct, host, api_name, &region, service);
 
   string params_str;
   map<string, string>& args = new_info->args.get_params();
index caf6ffa35c80274391ec9a86a5da4e4895d039c2..5beeb389589ccff9b4ed30c766ba06a8843a1955 100644 (file)
@@ -65,7 +65,7 @@ public:
                        param_vec_t *_headers, param_vec_t *_params,
                        std::optional<std::string> _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 {
index a93e855e99dffeb49f39afa73e3cb7e175c2c69f..510cdd40049d2fe153247304246ca41bbf77150f 100644 (file)
@@ -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, &params, 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;
index 4069f5394b9a9043b8bd17017c56c7f6adcdf63b..f697c58220eded69596fd80b60cfcfc0a0812a62 100644 (file)
@@ -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);
index 7b01133fce4a18ce4a5720e8bb613f99fd0b134d..f63018d189b3b9dd723e68dc8a5f15ca661ec5d2 100644 (file)
@@ -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);
 }
index 0822f6f7e68932ef1d9526b0bfa5f3b47f4ba614..d2421b603210a9b894f78f661a9ab5bbe262426b 100644 (file)
@@ -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,
index 0fa0f8f011554cf755b1aaf36f69ec2edcf3ad25..7ae70e6a097e818ad99616d5980dc0f658799d49 100644 (file)
@@ -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<std::multimap<std::string, std::string>::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);
 
index a8beb2b54052c2fbb44201db769e6b618d42e049..f007d2ec23fa6dd41c9c8a11af528ad329e0f8b8 100644 (file)
@@ -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"; }
index db7d54cdcf3efce10fe784f653e595270c4de4ce..2cfc2eacd63c8be1c344e808a011e18729fbfb10 100644 (file)
@@ -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();
 
index 93cfa9e64803550824a278b0d4ff5d11297a54c0..b30653deb0015c42c4994d95ba01ec347a08802e 100644 (file)
@@ -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<rgw::sal::RGWRole> 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;
   }
 };
index ac124d777719cfb500235864896cb97ed939b9f0..6ea23e090e9b8bca056a4116c104d188de2d4402 100644 (file)
@@ -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);
index 74a5fa5731c1b458a24c2b65a1050e1c4bc488c3..594b13e661951840ebba0e2d14a5151211e73ea7 100644 (file)
@@ -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. */
index ac39fa721b3048595c5caf25ab778467054bd823..9cebbc81e0df917827333364ec19645e09ee10bf 100644 (file)
@@ -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 "";
index 36b51a13671d0eb89a3b482226a5d7ff76d11959..18c7d6aa5ac225b298d99de4041ed55ab49e3a7f 100644 (file)
@@ -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;
index 49bb92454c9719eadfca7aa04ff25b0fda83d769..5623b2efa2813de46b54398a48983ae1725b43f8 100644 (file)
@@ -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 "";
index dd990a693cd3790bf40d9bca757d2fb327a30c9b..928890689a366f8bda43719dd616342c5db0602b 100644 (file)
@@ -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;
index c7ed4bdd6f65a8ccede26634d9a09eec7e0e3f1b..158d54752bacd070da232fa4c2bf9df4a0bc7ced 100644 (file)
@@ -18,6 +18,7 @@
 #include <system_error>
 #include <unistd.h>
 #include <sstream>
+#include <boost/algorithm/string.hpp>
 
 #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 = "&quot;";
+  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<string, bufferlist> attrs;
+    attrs.emplace("tagging", bl_tags);
 
-  RGWSI_MBSObj_PutParams params(bl, &info.attrs, info.mtime, exclusive);
-  std::unique_ptr<RGWSI_MetaBackend::Context> 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<RGWSI_MetaBackend::Context> 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<RGWSI_MetaBackend::Context> 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<RGWSI_MetaBackend::Context> 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) {
index a11ce994360c640d5407ed387859f998581c346a..b2eb958a54474cb4057747c36b4dd2fa8dd37ca5 100644 (file)
@@ -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
index 5037ae536277d117f0b123d1f976f9a7c5841c1e..9d030e3148113549ecd349f8cc44cc11de99abc6 100644 (file)
@@ -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,
index 79f0a4aa1ae8ed5e1ee4556c1a766864117b1178..b2b5784f6ba6fec708035bc0d65011f9a9984441 100644 (file)
@@ -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 &params,
                   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,
index e8c8b7864d143e97c1d512b09ac037819c9d669a..bc5db46145551f5cc49d8dc5904ab0af774574a6 100644 (file)
@@ -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<RGWSI_MBOTP_GetParams&>(_params);
 
index 52ea66b337359b8a45cd17f7566473940623a0bc..fc17d761fcd2f50ebf86e7f0da77bc0970fbd225 100644 (file)
@@ -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,
index 6c06182af477f7431385121faa081a1e7bc89907..208f6045f588efce9799cb70dd2142ebade52149 100644 (file)
@@ -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<RGWSI_MetaBackend_SObj::Context_SObj *>(_ctx);
   RGWSI_MBSObj_GetParams& params = static_cast<RGWSI_MBSObj_GetParams&>(_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, 
index 8183617d437b0bfc9b9de502fdafb5648485e11b..fe3230ec8d979c99915ff68696415012ddf5b764 100644 (file)
@@ -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,