]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Adding 'iam' namespace for Role and User Policy related REST APIs. 32437/head
authorPritha Srivastava <prsrivas@redhat.com>
Mon, 25 Mar 2019 07:07:23 +0000 (12:37 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Mon, 27 Jan 2020 05:57:01 +0000 (11:27 +0530)
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
(cherry picked from commit 121a2695544bd56973459fad9b4f545b4ee412f8)

Conflicts:
src/common/options.cc
src/rgw/CMakeLists.txt
src/rgw/rgw_main.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h

15 files changed:
src/common/options.cc
src/rgw/CMakeLists.txt
src/rgw/rgw_common.cc
src/rgw/rgw_common.h
src/rgw/rgw_http_errors.h
src/rgw/rgw_main.cc
src/rgw/rgw_rest.cc
src/rgw/rgw_rest_iam.cc [new file with mode: 0644]
src/rgw/rgw_rest_iam.h [new file with mode: 0644]
src/rgw/rgw_rest_role.cc
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_rest_user_policy.cc
src/rgw/rgw_role.cc

index 2bee6e90fd60c1a37a322463b0be73d27f2ee163..b7403d95ec366f2c18ab012ad6374b6dd4f2a644 100644 (file)
@@ -5712,7 +5712,7 @@ std::vector<Option> get_rgw_options() {
         "will be located in the path that is specified here. "),
 
     Option("rgw_enable_apis", Option::TYPE_STR, Option::LEVEL_ADVANCED)
-    .set_default("s3, s3website, swift, swift_auth, admin, sts, pubsub")
+    .set_default("s3, s3website, swift, swift_auth, admin, sts, iam, pubsub")
     .set_description("A list of set of RESTful APIs that rgw handles."),
 
     Option("rgw_cache_enabled", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
index 82f5181f5b1bcb6988614a8788753d2e1e8a4953..d184c783de76a4f519623161f73ab5e6e6e49aff 100644 (file)
@@ -119,7 +119,8 @@ set(librgw_common_srcs
   rgw_sts.cc
   rgw_rest_sts.cc
   rgw_perf_counters.cc
-  rgw_object_lock.cc)
+  rgw_object_lock.cc
+  rgw_rest_iam.cc)
 
 if(WITH_RADOSGW_AMQP_ENDPOINT)
   list(APPEND librgw_common_srcs rgw_amqp.cc)
index fffc1b289cb5f8a9aa255d67d21fac62bddb1185..8936cb30fd276c202db45f3a7ed392d94e3f95a3 100644 (file)
@@ -105,8 +105,6 @@ rgw_http_errors rgw_http_s3_errors({
     { ERR_EMAIL_EXIST, {409, "EmailExists" }},
     { ERR_KEY_EXIST, {409, "KeyExists"}},
     { ERR_TAG_CONFLICT, {409, "OperationAborted"}},
-    { ERR_ROLE_EXISTS, {409, "EntityAlreadyExists"}},
-    { ERR_DELETE_CONFLICT, {409, "DeleteConflict"}},
     { ERR_POSITION_NOT_EQUAL_TO_LENGTH, {409, "PositionNotEqualToLength"}},
     { ERR_OBJECT_NOT_APPENDABLE, {409, "ObjectNotAppendable"}},
     { ERR_INVALID_BUCKET_STATE, {409, "InvalidBucketState"}},
@@ -149,6 +147,11 @@ rgw_http_errors rgw_http_sts_errors({
     { ERR_INVALID_IDENTITY_TOKEN, {400, "InvalidIdentityToken" }},
 });
 
+rgw_http_errors rgw_http_iam_errors({
+    { ERR_ROLE_EXISTS, {409, "EntityAlreadyExists"}},
+    { ERR_DELETE_CONFLICT, {409, "DeleteConflict"}},
+});
+
 using namespace ceph::crypto;
 
 rgw_err::
@@ -303,6 +306,11 @@ void set_req_state_err(struct rgw_err& err,        /* out */
       return;
   }
 
+  if (prot_flags & RGW_REST_IAM) {
+    if (search_err(rgw_http_iam_errors, err_no, err.http_ret, err.err_code))
+      return;
+  }
+
   //Default to searching in s3 errors
   if (search_err(rgw_http_s3_errors, err_no, err.http_ret, err.err_code))
       return;
index 2f684972182dfe356ceb508bd0221c2e0eedd595..4d0fe2541243d1d5cfaa42d18a8d4fcb5232117b 100644 (file)
@@ -146,6 +146,7 @@ using ceph::crypto::MD5;
 #define RGW_REST_S3             0x4
 #define RGW_REST_WEBSITE     0x8
 #define RGW_REST_STS            0x10
+#define RGW_REST_IAM            0x20
 
 #define RGW_SUSPENDED_USER_AUID (uint64_t)-2
 
index 98bb20f8443fd8378a602054bb03c9c052839695..2211344891ac794ae6e531058a5779787140bf87 100644 (file)
@@ -14,6 +14,8 @@ extern rgw_http_errors rgw_http_swift_errors;
 
 extern rgw_http_errors rgw_http_sts_errors;
 
+extern rgw_http_errors rgw_http_iam_errors;
+
 static inline int rgw_http_error_to_errno(int http_err)
 {
   if (http_err >= 200 && http_err <= 299)
index fa5cc7f633b260eba3d020682617162524bb6a2f..a27c4beba9f8124e118d399f694bb87eb39b5095 100644 (file)
@@ -360,13 +360,14 @@ int main(int argc, const char **argv)
   // S3 website mode is a specialization of S3
   const bool s3website_enabled = apis_map.count("s3website") > 0;
   const bool sts_enabled = apis_map.count("sts") > 0;
+  const bool iam_enabled = apis_map.count("iam") > 0;
   const bool pubsub_enabled = apis_map.count("pubsub") > 0;
   // Swift API entrypoint could placed in the root instead of S3
   const bool swift_at_root = g_conf()->rgw_swift_url_prefix == "/";
   if (apis_map.count("s3") > 0 || s3website_enabled) {
     if (! swift_at_root) {
       rest.register_default_mgr(set_logging(rest_filter(store, RGW_REST_S3,
-                                                        new RGWRESTMgr_S3(s3website_enabled, sts_enabled, pubsub_enabled))));
+                                                        new RGWRESTMgr_S3(s3website_enabled, sts_enabled, iam_enabled, pubsub_enabled))));
     } else {
       derr << "Cannot have the S3 or S3 Website enabled together with "
            << "Swift API placed in the root of hierarchy" << dendl;
index c95e41a45224babcc88bd000e63688d9bfe4fa74..d969b8f5102f5c5d5b9cdefaa478156044480b58 100644 (file)
@@ -6,6 +6,7 @@
 #include <limits.h>
 
 #include <boost/algorithm/string.hpp>
+#include <boost/tokenizer.hpp>
 #include "common/Formatter.h"
 #include "common/HTMLFormatter.h"
 #include "common/utf8.h"
@@ -13,6 +14,7 @@
 #include "rgw_common.h"
 #include "rgw_rados.h"
 #include "rgw_zone.h"
+#include "rgw_auth_s3.h"
 #include "rgw_formats.h"
 #include "rgw_op.h"
 #include "rgw_rest.h"
diff --git a/src/rgw/rgw_rest_iam.cc b/src/rgw/rgw_rest_iam.cc
new file mode 100644 (file)
index 0000000..ef0e958
--- /dev/null
@@ -0,0 +1,147 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <boost/tokenizer.hpp>
+
+#include "rgw_rest.h"
+#include "rgw_rest_iam.h"
+
+#include "rgw_request.h"
+#include "rgw_process.h"
+
+#include "rgw_rest_role.h"
+#include "rgw_rest_user_policy.h"
+
+#define dout_context g_ceph_context
+#define dout_subsys ceph_subsys_rgw
+
+void RGWHandler_REST_IAM::rgw_iam_parse_input()
+{
+  if (post_body.size() > 0) {
+    ldout(s->cct, 10) << "Content of POST: " << post_body << dendl;
+
+    if (post_body.find("Action") != string::npos) {
+      boost::char_separator<char> sep("&");
+      boost::tokenizer<boost::char_separator<char>> tokens(post_body, sep);
+      for (const auto& t : tokens) {
+        auto pos = t.find("=");
+        if (pos != string::npos) {
+          std::string key = t.substr(0, pos);
+          std::string value = t.substr(pos + 1, t.size() - 1);
+          if (key == "AssumeRolePolicyDocument" || key == "Path" || key == "PolicyDocument") {
+            value = url_decode(value);
+          }
+          s->info.args.append(key, value);
+        }
+      }
+    }
+  }
+  auto payload_hash = rgw::auth::s3::calc_v4_payload_hash(post_body);
+  s->info.args.append("PayloadHash", payload_hash);
+}
+
+RGWOp *RGWHandler_REST_IAM::op_post()
+{
+  rgw_iam_parse_input();
+
+  if (s->info.args.exists("Action")) {
+    string action = s->info.args.get("Action");
+    if (action.compare("CreateRole") == 0)
+      return new RGWCreateRole;
+    if (action.compare("DeleteRole") == 0)
+      return new RGWDeleteRole;
+    if (action.compare("GetRole") == 0)
+      return new RGWGetRole;
+    if (action.compare("UpdateAssumeRolePolicy") == 0)
+      return new RGWModifyRole;
+    if (action.compare("ListRoles") == 0)
+      return new RGWListRoles;
+    if (action.compare("PutRolePolicy") == 0)
+      return new RGWPutRolePolicy;
+    if (action.compare("GetRolePolicy") == 0)
+      return new RGWGetRolePolicy;
+    if (action.compare("ListRolePolicies") == 0)
+      return new RGWListRolePolicies;
+    if (action.compare("DeleteRolePolicy") == 0)
+      return new RGWDeleteRolePolicy;
+    if (action.compare("PutUserPolicy") == 0)
+      return new RGWPutUserPolicy;
+    if (action.compare("GetUserPolicy") == 0)
+      return new RGWGetUserPolicy;
+    if (action.compare("ListUserPolicies") == 0)
+      return new RGWListUserPolicies;
+    if (action.compare("DeleteUserPolicy") == 0)
+      return new RGWDeleteUserPolicy;
+  }
+
+  return nullptr;
+}
+
+int RGWHandler_REST_IAM::init(RGWRados *store,
+                              struct req_state *s,
+                              rgw::io::BasicClient *cio)
+{
+  s->dialect = "iam";
+
+  if (int ret = RGWHandler_REST_IAM::init_from_header(s, RGW_FORMAT_XML, true); ret < 0) {
+    ldout(s->cct, 10) << "init_from_header returned err=" << ret <<  dendl;
+    return ret;
+  }
+
+  return RGWHandler_REST::init(store, s, cio);
+}
+
+int RGWHandler_REST_IAM::authorize(const DoutPrefixProvider* dpp)
+{
+  return RGW_Auth_S3::authorize(dpp, store, auth_registry, s);
+}
+
+int RGWHandler_REST_IAM::init_from_header(struct req_state* s,
+                                          int default_formatter,
+                                          bool configurable_format)
+{
+  string req;
+  string first;
+
+  s->prot_flags = RGW_REST_IAM;
+
+  const char *p, *req_name;
+  if (req_name = s->relative_uri.c_str(); *req_name == '?') {
+    p = req_name;
+  } else {
+    p = s->info.request_params.c_str();
+  }
+
+  s->info.args.set(p);
+  s->info.args.parse();
+
+  /* must be called after the args parsing */
+  if (int ret = allocate_formatter(s, default_formatter, configurable_format); ret < 0)
+    return ret;
+
+  if (*req_name != '/')
+    return 0;
+
+  req_name++;
+
+  if (!*req_name)
+    return 0;
+
+  req = req_name;
+  int pos = req.find('/');
+  if (pos >= 0) {
+    first = req.substr(0, pos);
+  } else {
+    first = req;
+  }
+
+  return 0;
+}
+
+RGWHandler_REST*
+RGWRESTMgr_IAM::get_handler(struct req_state* const s,
+                              const rgw::auth::StrategyRegistry& auth_registry,
+                              const std::string& frontend_prefix)
+{
+  return new RGWHandler_REST_IAM(auth_registry);
+}
diff --git a/src/rgw/rgw_rest_iam.h b/src/rgw/rgw_rest_iam.h
new file mode 100644 (file)
index 0000000..e9dbfcd
--- /dev/null
@@ -0,0 +1,49 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_RGW_REST_IAM_H
+#define CEPH_RGW_REST_IAM_H
+
+#include "rgw_auth.h"
+#include "rgw_auth_filters.h"
+
+class RGWHandler_REST_IAM : public RGWHandler_REST {
+  const rgw::auth::StrategyRegistry& auth_registry;
+  const string& post_body;
+  RGWOp *op_post() override;
+  void rgw_iam_parse_input();
+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 string& post_body="")
+    : RGWHandler_REST(),
+      auth_registry(auth_registry),
+      post_body(post_body) {}
+  ~RGWHandler_REST_IAM() override = default;
+
+  int init(RGWRados *store,
+           struct req_state *s,
+           rgw::io::BasicClient *cio) override;
+  int authorize(const DoutPrefixProvider* dpp) override;
+  int postauth_init() override { return 0; }
+};
+
+class RGWRESTMgr_IAM : public RGWRESTMgr {
+public:
+  RGWRESTMgr_IAM() = default;
+  ~RGWRESTMgr_IAM() override = default;
+
+  RGWRESTMgr *get_resource_mgr(struct req_state* const s,
+                               const std::string& uri,
+                               std::string* const out_uri) override {
+    return this;
+  }
+
+  RGWHandler_REST* get_handler(struct req_state*,
+                               const rgw::auth::StrategyRegistry&,
+                               const std::string&) override;
+};
+
+#endif /* CEPH_RGW_REST_STS_H */
+
index 300aebbe5511952816e9df1124f2a5d9983149e4..7dc772c3f670fa3a96d0d78032d444c15e5e972e 100644 (file)
@@ -60,7 +60,7 @@ void RGWRestRole::send_response()
     set_req_state_err(s, op_ret);
   }
   dump_errno(s);
-  end_header(s);
+  end_header(s, this);
 }
 
 int RGWRoleRead::check_caps(RGWUserCaps& caps)
@@ -138,9 +138,16 @@ void RGWCreateRole::execute()
   }
 
   if (op_ret == 0) {
-    s->formatter->open_object_section("role");
+    s->formatter->open_object_section("CreateRoleResponse");
+    s->formatter->open_object_section("CreateRoleResult");
+    s->formatter->open_object_section("Role");
     role.dump(s->formatter);
     s->formatter->close_section();
+    s->formatter->close_section();
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -168,6 +175,12 @@ void RGWDeleteRole::execute()
   if (op_ret == -ENOENT) {
     op_ret = -ERR_NO_ROLE_FOUND;
   }
+
+  s->formatter->open_object_section("DeleteRoleResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->close_section();
 }
 
 int RGWGetRole::verify_permission()
@@ -226,9 +239,16 @@ void RGWGetRole::execute()
   op_ret = _verify_permission(role);
 
   if (op_ret == 0) {
-    s->formatter->open_object_section("role");
+    s->formatter->open_object_section("GetRoleResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->open_object_section("GetRoleResult");
+    s->formatter->open_object_section("Role");
     role.dump(s->formatter);
     s->formatter->close_section();
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -260,6 +280,11 @@ void RGWModifyRole::execute()
   _role.update_trust_policy(trust_policy);
   op_ret = _role.update();
 
+  s->formatter->open_object_section("UpdateAssumeRolePolicyResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->close_section();
 }
 
 int RGWListRoles::verify_permission()
@@ -299,13 +324,20 @@ void RGWListRoles::execute()
   op_ret = RGWRole::get_roles_by_path_prefix(store, s->cct, path_prefix, s->user->user_id.tenant, result);
 
   if (op_ret == 0) {
-    s->formatter->open_array_section("Roles");
+    s->formatter->open_array_section("ListRolesResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->open_array_section("ListRolesResult");
+    s->formatter->open_object_section("Roles");
     for (const auto& it : result) {
-      s->formatter->open_object_section("role");
+      s->formatter->open_object_section("member");
       it.dump(s->formatter);
       s->formatter->close_section();
     }
     s->formatter->close_section();
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -339,6 +371,14 @@ void RGWPutRolePolicy::execute()
 
   _role.set_perm_policy(policy_name, perm_policy);
   op_ret = _role.update();
+
+  if (op_ret == 0) {
+    s->formatter->open_object_section("PutRolePolicyResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->close_section();
+  }
 }
 
 int RGWGetRolePolicy::get_params()
@@ -362,12 +402,21 @@ void RGWGetRolePolicy::execute()
 
   string perm_policy;
   op_ret = _role.get_role_policy(policy_name, perm_policy);
+  if (op_ret == -ENOENT) {
+    op_ret = -ERR_NO_SUCH_ENTITY;
+  }
+
   if (op_ret == 0) {
+    s->formatter->open_object_section("GetRolePolicyResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
     s->formatter->open_object_section("GetRolePolicyResult");
     s->formatter->dump_string("PolicyName", policy_name);
     s->formatter->dump_string("RoleName", role_name);
     s->formatter->dump_string("Permission policy", perm_policy);
     s->formatter->close_section();
+    s->formatter->close_section();
   }
 }
 
@@ -390,11 +439,18 @@ void RGWListRolePolicies::execute()
   }
 
   std::vector<string> policy_names = _role.get_role_policy_names();
+  s->formatter->open_object_section("ListRolePoliciesResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->open_object_section("ListRolePoliciesResult");
   s->formatter->open_array_section("PolicyNames");
   for (const auto& it : policy_names) {
     s->formatter->dump_string("member", it);
   }
   s->formatter->close_section();
+  s->formatter->close_section();
+  s->formatter->close_section();
 }
 
 int RGWDeleteRolePolicy::get_params()
@@ -424,4 +480,10 @@ void RGWDeleteRolePolicy::execute()
   if (op_ret == 0) {
     op_ret = _role.update();
   }
+
+  s->formatter->open_object_section("DeleteRolePoliciesResponse");
+  s->formatter->open_object_section("ResponseMetadata");
+  s->formatter->dump_string("RequestId", s->trans_id);
+  s->formatter->close_section();
+  s->formatter->close_section();
 }
index 4c2d9167efb24542c0d3a619005c211d113b8e63..f5f340b25ecdb259f1961f68d5f49d8296b6a723 100644 (file)
@@ -53,6 +53,7 @@
 #include "include/ceph_assert.h"
 #include "rgw_role.h"
 #include "rgw_rest_sts.h"
+#include "rgw_rest_iam.h"
 #include "rgw_sts.h"
 
 #define dout_context g_ceph_context
@@ -3470,46 +3471,12 @@ RGWOp *RGWHandler_REST_Service_S3::op_post()
 {
   const auto max_size = s->cct->_conf->rgw_max_put_param_size;
 
-  int ret;
+  int ret = 0;
   bufferlist data;
   std::tie(ret, data) = rgw_rest_read_all_input(s, max_size, false);
-  if (ret < 0) {
-      return nullptr;
-  }
+  string post_body = data.to_str();
 
-  const auto post_body = data.to_str();
-
-  if (s->info.args.exists("Action")) {
-    string action = s->info.args.get("Action");
-    if (action.compare("CreateRole") == 0)
-      return new RGWCreateRole;
-    if (action.compare("DeleteRole") == 0)
-      return new RGWDeleteRole;
-    if (action.compare("GetRole") == 0)
-      return new RGWGetRole;
-    if (action.compare("UpdateAssumeRolePolicy") == 0)
-      return new RGWModifyRole;
-    if (action.compare("ListRoles") == 0)
-      return new RGWListRoles;
-    if (action.compare("PutRolePolicy") == 0)
-      return new RGWPutRolePolicy;
-    if (action.compare("GetRolePolicy") == 0)
-      return new RGWGetRolePolicy;
-    if (action.compare("ListRolePolicies") == 0)
-      return new RGWListRolePolicies;
-    if (action.compare("DeleteRolePolicy") == 0)
-      return new RGWDeleteRolePolicy;
-    if (action.compare("PutUserPolicy") == 0)
-      return new RGWPutUserPolicy;
-    if (action.compare("GetUserPolicy") == 0)
-      return new RGWGetUserPolicy;
-    if (action.compare("ListUserPolicies") == 0)
-      return new RGWListUserPolicies;
-    if (action.compare("DeleteUserPolicy") == 0)
-      return new RGWDeleteUserPolicy;
-  }
-
-  if (isSTSenabled) {
+  if (this->isSTSenabled) {
     RGWHandler_REST_STS sts_handler(auth_registry, post_body);
     sts_handler.init(store, s, s->cio);
     auto op = sts_handler.get_op(store);
@@ -3517,13 +3484,20 @@ RGWOp *RGWHandler_REST_Service_S3::op_post()
       return op;
     }
   }
+
+  if (this->isIAMenabled) {
+    RGWHandler_REST_IAM iam_handler(auth_registry, post_body);
+    iam_handler.init(store, s, s->cio);
+    auto op = iam_handler.get_op(store);
+    if (op) {
+      return op;
+    }
+  }
+
   if (isPSenabled) {
     RGWHandler_REST_PSTopic_AWS topic_handler(auth_registry, post_body);
     topic_handler.init(store, s, s->cio);
     auto op = topic_handler.get_op(store);
-    if (op) {
-      return op;
-    }
   }
 
   return NULL;
@@ -4061,7 +4035,7 @@ RGWHandler_REST* RGWRESTMgr_S3::get_handler(struct req_state* const s,
     }
   } else {
     if (s->init_state.url_bucket.empty()) {
-      handler = new RGWHandler_REST_Service_S3(auth_registry, enable_sts, enable_pubsub);
+      handler = new RGWHandler_REST_Service_S3(auth_registry, enable_sts, enable_iam, enable_pubsub);
     } else if (s->object.empty()) {
       handler = new RGWHandler_REST_Bucket_S3(auth_registry, enable_pubsub);
     } else {
@@ -4410,7 +4384,20 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s,
   bool is_non_s3_op = false;
   if (s->op_type == RGW_STS_GET_SESSION_TOKEN ||
       s->op_type == RGW_STS_ASSUME_ROLE ||
-      s->op_type == RGW_STS_ASSUME_ROLE_WEB_IDENTITY) {
+      s->op_type == RGW_STS_ASSUME_ROLE_WEB_IDENTITY ||
+      s->op_type == RGW_OP_CREATE_ROLE ||
+      s->op_type == RGW_OP_DELETE_ROLE ||
+      s->op_type == RGW_OP_GET_ROLE ||
+      s->op_type == RGW_OP_MODIFY_ROLE ||
+      s->op_type == RGW_OP_LIST_ROLES ||
+      s->op_type == RGW_OP_PUT_ROLE_POLICY ||
+      s->op_type == RGW_OP_GET_ROLE_POLICY ||
+      s->op_type == RGW_OP_LIST_ROLE_POLICIES ||
+      s->op_type == RGW_OP_DELETE_ROLE_POLICY ||
+      s->op_type == RGW_OP_PUT_USER_POLICY ||
+      s->op_type == RGW_OP_GET_USER_POLICY ||
+      s->op_type == RGW_OP_LIST_USER_POLICIES ||
+      s->op_type == RGW_OP_DELETE_USER_POLICY) {
     is_non_s3_op = true;
   }
 
index e659c088061ff5800a02d28d004538dbeb474cb5..8031f9303e497f3b86ae5ab553591d5331accc4d 100644 (file)
@@ -586,6 +586,7 @@ public:
 class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
 protected:
     const bool isSTSenabled;
+    bool isIAMenabled;
     const bool isPSenabled;
     bool is_usage_op() {
     return s->info.args.exists("usage");
@@ -595,8 +596,8 @@ protected:
   RGWOp *op_post() override;
 public:
    RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry& auth_registry,
-                              bool _isSTSenabled, bool _isPSenabled) :
-      RGWHandler_REST_S3(auth_registry), isSTSenabled(_isSTSenabled), isPSenabled(_isPSenabled) {}
+                              bool _isSTSenabled, bool _isIAMenabled, bool _isPSenabled) :
+      RGWHandler_REST_S3(auth_registry), isSTSenabled(_isSTSenabled), isIAMenabled(_isIAMenabled), isPSenabled(_isPSenabled) {}
   ~RGWHandler_REST_Service_S3() override = default;
 };
 
@@ -679,11 +680,13 @@ class RGWRESTMgr_S3 : public RGWRESTMgr {
 private:
   bool enable_s3website;
   bool enable_sts;
+  bool enable_iam;
   const bool enable_pubsub;
 public:
-  explicit RGWRESTMgr_S3(bool enable_s3website = false, bool enable_sts = false, bool _enable_pubsub = false)
+  explicit RGWRESTMgr_S3(bool enable_s3website = false, bool enable_sts = false, bool enable_iam = false, bool _enable_pubsub = false)
     : enable_s3website(enable_s3website),
       enable_sts(enable_sts),
+      enable_iam(enable_iam),
       enable_pubsub(_enable_pubsub) {
   }
 
index a988b5d903743ebe54fb8a8730cc85bf3fc8d74d..bd00eeb127a20ea81ec882e4292f0797d24998ba 100644 (file)
@@ -17,7 +17,6 @@
 #include "rgw_auth.h"
 #include "rgw_auth_registry.h"
 #include "rgw_rest_sts.h"
-#include "rgw_auth_s3.h"
 
 #include "rgw_formats.h"
 #include "rgw_client_io.h"
@@ -359,7 +358,6 @@ void RGWHandler_REST_STS::rgw_sts_parse_input()
            if (key == "RoleArn" || key == "Policy") {
             value = url_decode(value);
            }
-           ldout(s->cct, 10) << "Key: " << key << "Value: " << value << dendl;
            s->info.args.append(key, value);
          }
        }
@@ -416,7 +414,7 @@ int RGWHandler_REST_STS::init_from_header(struct req_state* s,
   string req;
   string first;
 
-  s->prot_flags |= RGW_REST_STS;
+  s->prot_flags = RGW_REST_STS;
 
   const char *p, *req_name;
   if (req_name = s->relative_uri.c_str(); *req_name == '?') {
index 2b4ffe21d97bfdfe47e9280305790146aab82342..d93f69aee2ea9f8fbab15e36194164be2c814cab 100644 (file)
@@ -22,9 +22,9 @@ using rgw::IAM::Policy;
 
 void RGWRestUserPolicy::dump(Formatter *f) const
 {
-  encode_json("policyname", policy_name , f);
-  encode_json("username", user_name , f);
-  encode_json("policydocument", policy, f);
+  encode_json("Policyname", policy_name , f);
+  encode_json("Username", user_name , f);
+  encode_json("Policydocument", policy, f);
 }
 
 void RGWRestUserPolicy::send_response()
@@ -152,6 +152,14 @@ void RGWPutUserPolicy::execute()
     ldout(s->cct, 20) << "failed to parse policy: " << e.what() << dendl;
     op_ret = -ERR_MALFORMED_DOC;
   }
+
+  if (op_ret == 0) {
+    s->formatter->open_object_section("PutUserPolicyResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->close_section();
+  }
 }
 
 uint64_t RGWGetUserPolicy::get_op()
@@ -190,15 +198,18 @@ void RGWGetUserPolicy::execute()
   }
 
   if (op_ret == 0) {
+    s->formatter->open_object_section("GetUserPolicyResponse");
+    s->formatter->open_object_section("ResponseMetadata");
+    s->formatter->dump_string("RequestId", s->trans_id);
+    s->formatter->close_section();
+    s->formatter->open_object_section("GetUserPolicyResult");
     map<string, string> policies;
     if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) {
       bufferlist bl = uattrs[RGW_ATTR_USER_POLICY];
       decode(policies, bl);
       if (auto it = policies.find(policy_name); it != policies.end()) {
         policy = policies[policy_name];
-        s->formatter->open_object_section("userpolicy");
         dump(s->formatter);
-        s->formatter->close_section();
       } else {
         ldout(s->cct, 0) << "ERROR: policy not found" << policy << dendl;
         op_ret = -ERR_NO_SUCH_ENTITY;
@@ -209,6 +220,8 @@ void RGWGetUserPolicy::execute()
       op_ret = -ERR_NO_SUCH_ENTITY;
       return;
     }
+    s->formatter->close_section();
+    s->formatter->close_section();
   }
   if (op_ret < 0) {
     op_ret = -ERR_INTERNAL_ERROR;
@@ -251,13 +264,20 @@ void RGWListUserPolicies::execute()
   if (op_ret == 0) {
     map<string, string> policies;
     if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) {
+      s->formatter->open_object_section("ListUserPoliciesResponse");
+      s->formatter->open_object_section("ResponseMetadata");
+      s->formatter->dump_string("RequestId", s->trans_id);
+      s->formatter->close_section();
+      s->formatter->open_object_section("ListUserPoliciesResult");
       bufferlist bl = uattrs[RGW_ATTR_USER_POLICY];
       decode(policies, bl);
       for (const auto& p : policies) {
-        s->formatter->open_object_section("policies");
-        s->formatter->dump_string("policy", p.first);
+        s->formatter->open_object_section("PolicyNames");
+        s->formatter->dump_string("member", p.first);
         s->formatter->close_section();
       }
+      s->formatter->close_section();
+      s->formatter->close_section();
     } else {
       ldout(s->cct, 0) << "ERROR: RGW_ATTR_USER_POLICY not found" << dendl;
       op_ret = -ERR_NO_SUCH_ENTITY;
@@ -325,6 +345,13 @@ void RGWDeleteUserPolicy::execute()
       if (op_ret < 0) {
         op_ret = -ERR_INTERNAL_ERROR;
       }
+      if (op_ret == 0) {
+        s->formatter->open_object_section("DeleteUserPoliciesResponse");
+        s->formatter->open_object_section("ResponseMetadata");
+        s->formatter->dump_string("RequestId", s->trans_id);
+        s->formatter->close_section();
+        s->formatter->close_section();
+      }
     } else {
       op_ret = -ERR_NO_SUCH_ENTITY;
       return;
index 9a7e3735ae6b85de4b5a4101411ba71be801cf9e..6e6b137a71f61f6063b1248e8707fcc0b0144de0 100644 (file)
@@ -257,7 +257,7 @@ int RGWRole::get_role_policy(const string& policy_name, string& perm_policy)
   const auto it = perm_policy_map.find(policy_name);
   if (it == perm_policy_map.end()) {
     ldout(cct, 0) << "ERROR: Policy name: " << policy_name << " not found" << dendl;
-    return -EINVAL;
+    return -ENOENT;
   } else {
     perm_policy = it->second;
   }
@@ -278,13 +278,13 @@ int RGWRole::delete_policy(const string& policy_name)
 
 void RGWRole::dump(Formatter *f) const
 {
-  encode_json("id", id , f);
-  encode_json("name", name , f);
-  encode_json("path", path, f);
-  encode_json("arn", arn, f);
-  encode_json("create_date", creation_date, f);
-  encode_json("max_session_duration", max_session_duration, f);
-  encode_json("assume_role_policy_document", trust_policy, f);
+  encode_json("RoleId", id , f);
+  encode_json("RoleName", name , f);
+  encode_json("Path", path, f);
+  encode_json("Arn", arn, f);
+  encode_json("CreateDate", creation_date, f);
+  encode_json("MaxSessionDuration", max_session_duration, f);
+  encode_json("AssumeRolePolicyDocument", trust_policy, f);
 }
 
 void RGWRole::decode_json(JSONObj *obj)