summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_rest_role.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/rgw/rgw_rest_role.cc
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/rgw/rgw_rest_role.cc')
-rw-r--r--src/rgw/rgw_rest_role.cc1022
1 files changed, 1022 insertions, 0 deletions
diff --git a/src/rgw/rgw_rest_role.cc b/src/rgw/rgw_rest_role.cc
new file mode 100644
index 000000000..e71dff570
--- /dev/null
+++ b/src/rgw/rgw_rest_role.cc
@@ -0,0 +1,1022 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#include <errno.h>
+#include <regex>
+
+#include "common/errno.h"
+#include "common/Formatter.h"
+#include "common/ceph_json.h"
+
+#include "include/types.h"
+#include "rgw_string.h"
+
+#include "rgw_common.h"
+#include "rgw_op.h"
+#include "rgw_rest.h"
+#include "rgw_role.h"
+#include "rgw_rest_role.h"
+#include "rgw_sal.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+using namespace std;
+
+int RGWRestRole::verify_permission(optional_yield y)
+{
+ if (s->auth.identity->is_anonymous()) {
+ return -EACCES;
+ }
+
+ string role_name = s->info.args.get("RoleName");
+ std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name,
+ s->user->get_tenant());
+ if (op_ret = role->get(s, y); op_ret < 0) {
+ if (op_ret == -ENOENT) {
+ op_ret = -ERR_NO_ROLE_FOUND;
+ }
+ return op_ret;
+ }
+
+ if (int ret = check_caps(s->user->get_caps()); ret == 0) {
+ _role = std::move(role);
+ return ret;
+ }
+
+ string resource_name = role->get_path() + role_name;
+ uint64_t op = get_op();
+ if (!verify_user_permission(this,
+ s,
+ rgw::ARN(resource_name,
+ "role",
+ s->user->get_tenant(), true),
+ op)) {
+ return -EACCES;
+ }
+
+ _role = std::move(role);
+
+ return 0;
+}
+
+int RGWRestRole::parse_tags()
+{
+ vector<string> keys, vals;
+ auto val_map = s->info.args.get_params();
+ const regex pattern_key("Tags.member.([0-9]+).Key");
+ const regex pattern_value("Tags.member.([0-9]+).Value");
+ for (auto& v : val_map) {
+ string key_index="", value_index="";
+ for(sregex_iterator it = sregex_iterator(
+ v.first.begin(), v.first.end(), pattern_key);
+ it != sregex_iterator(); it++) {
+ smatch match;
+ match = *it;
+ key_index = match.str(1);
+ ldout(s->cct, 20) << "Key index: " << match.str(1) << dendl;
+ if (!key_index.empty()) {
+ int index = stoi(key_index);
+ auto pos = keys.begin() + (index-1);
+ keys.insert(pos, v.second);
+ }
+ }
+ for(sregex_iterator it = sregex_iterator(
+ v.first.begin(), v.first.end(), pattern_value);
+ it != sregex_iterator(); it++) {
+ smatch match;
+ match = *it;
+ value_index = match.str(1);
+ ldout(s->cct, 20) << "Value index: " << match.str(1) << dendl;
+ if (!value_index.empty()) {
+ int index = stoi(value_index);
+ auto pos = vals.begin() + (index-1);
+ vals.insert(pos, v.second);
+ }
+ }
+ }
+ if (keys.size() != vals.size()) {
+ ldout(s->cct, 0) << "No. of keys doesn't match with no. of values in tags" << dendl;
+ return -EINVAL;
+ }
+ for (size_t i = 0; i < keys.size(); i++) {
+ tags.emplace(keys[i], vals[i]);
+ ldout(s->cct, 0) << "Tag Key: " << keys[i] << " Tag Value is: " << vals[i] << dendl;
+ }
+ return 0;
+}
+
+void RGWRestRole::send_response()
+{
+ if (op_ret) {
+ set_req_state_err(s, op_ret);
+ }
+ dump_errno(s);
+ end_header(s, this);
+}
+
+int RGWRoleRead::check_caps(const RGWUserCaps& caps)
+{
+ return caps.check_cap("roles", RGW_CAP_READ);
+}
+
+int RGWRoleWrite::check_caps(const RGWUserCaps& caps)
+{
+ return caps.check_cap("roles", RGW_CAP_WRITE);
+}
+
+int RGWCreateRole::verify_permission(optional_yield y)
+{
+ if (s->auth.identity->is_anonymous()) {
+ return -EACCES;
+ }
+
+ if (int ret = check_caps(s->user->get_caps()); ret == 0) {
+ return ret;
+ }
+
+ string role_name = s->info.args.get("RoleName");
+ string role_path = s->info.args.get("Path");
+
+ string resource_name = role_path + role_name;
+ if (!verify_user_permission(this,
+ s,
+ rgw::ARN(resource_name,
+ "role",
+ s->user->get_tenant(), true),
+ get_op())) {
+ return -EACCES;
+ }
+ return 0;
+}
+
+int RGWCreateRole::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+ role_path = s->info.args.get("Path");
+ trust_policy = s->info.args.get("AssumeRolePolicyDocument");
+ max_session_duration = s->info.args.get("MaxSessionDuration");
+
+ if (role_name.empty() || trust_policy.empty()) {
+ ldpp_dout(this, 20) << "ERROR: one of role name or assume role policy document is empty"
+ << dendl;
+ return -EINVAL;
+ }
+
+ bufferlist bl = bufferlist::static_from_string(trust_policy);
+ try {
+ const rgw::IAM::Policy p(
+ s->cct, s->user->get_tenant(), bl,
+ s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
+ }
+ catch (rgw::IAM::PolicyParseException& e) {
+ ldpp_dout(this, 5) << "failed to parse policy: " << e.what() << dendl;
+ s->err.message = e.what();
+ return -ERR_MALFORMED_DOC;
+ }
+
+ int ret = parse_tags();
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (tags.size() > 50) {
+ ldout(s->cct, 0) << "No. tags is greater than 50" << dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void RGWCreateRole::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+ std::string user_tenant = s->user->get_tenant();
+ std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name,
+ user_tenant,
+ role_path,
+ trust_policy,
+ max_session_duration,
+ tags);
+ if (!user_tenant.empty() && role->get_tenant() != user_tenant) {
+ ldpp_dout(this, 20) << "ERROR: the tenant provided in the role name does not match with the tenant of the user creating the role"
+ << dendl;
+ op_ret = -EINVAL;
+ return;
+ }
+
+ std::string role_id;
+
+ if (!driver->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 = driver->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) {
+ 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();
+ }
+}
+
+int RGWDeleteRole::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+
+ if (role_name.empty()) {
+ ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+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 (!driver->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 = driver->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) {
+ //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");
+ 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(optional_yield y)
+{
+ return 0;
+}
+
+int RGWGetRole::_verify_permission(const rgw::sal::RGWRole* role)
+{
+ if (s->auth.identity->is_anonymous()) {
+ return -EACCES;
+ }
+
+ if (int ret = check_caps(s->user->get_caps()); ret == 0) {
+ return ret;
+ }
+
+ string resource_name = role->get_path() + role->get_name();
+ if (!verify_user_permission(this,
+ s,
+ rgw::ARN(resource_name,
+ "role",
+ s->user->get_tenant(), true),
+ get_op())) {
+ return -EACCES;
+ }
+ return 0;
+}
+
+int RGWGetRole::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+
+ if (role_name.empty()) {
+ ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void RGWGetRole::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+ std::unique_ptr<rgw::sal::RGWRole> role = driver->get_role(role_name,
+ s->user->get_tenant());
+ op_ret = role->get(s, y);
+
+ if (op_ret == -ENOENT) {
+ op_ret = -ERR_NO_ROLE_FOUND;
+ return;
+ }
+
+ op_ret = _verify_permission(role.get());
+
+ if (op_ret == 0) {
+ 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();
+ }
+}
+
+int RGWModifyRoleTrustPolicy::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+ trust_policy = s->info.args.get("PolicyDocument");
+
+ if (role_name.empty() || trust_policy.empty()) {
+ ldpp_dout(this, 20) << "ERROR: One of role name or trust policy is empty"<< dendl;
+ return -EINVAL;
+ }
+ JSONParser p;
+ if (!p.parse(trust_policy.c_str(), trust_policy.length())) {
+ ldpp_dout(this, 20) << "ERROR: failed to parse assume role policy doc" << dendl;
+ return -ERR_MALFORMED_DOC;
+ }
+
+ return 0;
+}
+
+void RGWModifyRoleTrustPolicy::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ if (!driver->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 = driver->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);
+
+ 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(optional_yield y)
+{
+ if (s->auth.identity->is_anonymous()) {
+ return -EACCES;
+ }
+
+ if (int ret = check_caps(s->user->get_caps()); ret == 0) {
+ return ret;
+ }
+
+ if (!verify_user_permission(this,
+ s,
+ rgw::ARN(),
+ get_op())) {
+ return -EACCES;
+ }
+
+ return 0;
+}
+
+int RGWListRoles::get_params()
+{
+ path_prefix = s->info.args.get("PathPrefix");
+
+ return 0;
+}
+
+void RGWListRoles::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+ vector<std::unique_ptr<rgw::sal::RGWRole>> result;
+ op_ret = driver->get_roles(s, y, path_prefix, s->user->get_tenant(), result);
+
+ if (op_ret == 0) {
+ s->formatter->open_array_section("ListRolesResponse");
+ s->formatter->open_array_section("ListRolesResult");
+ s->formatter->open_object_section("Roles");
+ for (const auto& it : result) {
+ s->formatter->open_object_section("member");
+ it->dump(s->formatter);
+ s->formatter->close_section();
+ }
+ 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();
+ }
+}
+
+int RGWPutRolePolicy::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+ policy_name = s->info.args.get("PolicyName");
+ perm_policy = s->info.args.get("PolicyDocument");
+
+ if (role_name.empty() || policy_name.empty() || perm_policy.empty()) {
+ ldpp_dout(this, 20) << "ERROR: One of role name, policy name or perm policy is empty"<< dendl;
+ return -EINVAL;
+ }
+ bufferlist bl = bufferlist::static_from_string(perm_policy);
+ try {
+ const rgw::IAM::Policy p(
+ s->cct, s->user->get_tenant(), bl,
+ s->cct->_conf.get_val<bool>("rgw_policy_reject_invalid_principals"));
+ }
+ catch (rgw::IAM::PolicyParseException& e) {
+ ldpp_dout(this, 20) << "failed to parse policy: " << e.what() << dendl;
+ s->err.message = e.what();
+ return -ERR_MALFORMED_DOC;
+ }
+ return 0;
+}
+
+void RGWPutRolePolicy::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ if (!driver->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 = driver->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);
+
+ 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()
+{
+ role_name = s->info.args.get("RoleName");
+ policy_name = s->info.args.get("PolicyName");
+
+ if (role_name.empty() || policy_name.empty()) {
+ ldpp_dout(this, 20) << "ERROR: One of role name or policy name is empty"<< dendl;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void RGWGetRolePolicy::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ string perm_policy;
+ op_ret = _role->get_role_policy(this, 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("PolicyDocument", perm_policy);
+ s->formatter->close_section();
+ s->formatter->close_section();
+ }
+}
+
+int RGWListRolePolicies::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+
+ if (role_name.empty()) {
+ ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void RGWListRolePolicies::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ 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()
+{
+ role_name = s->info.args.get("RoleName");
+ policy_name = s->info.args.get("PolicyName");
+
+ if (role_name.empty() || policy_name.empty()) {
+ ldpp_dout(this, 20) << "ERROR: One of role name or policy name is empty"<< dendl;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void RGWDeleteRolePolicy::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ if (!driver->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 = driver->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) {
+ op_ret = _role->update(this, y);
+ }
+
+ 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();
+}
+
+int RGWTagRole::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+
+ if (role_name.empty()) {
+ ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
+ return -EINVAL;
+ }
+ int ret = parse_tags();
+ if (ret < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+void RGWTagRole::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ if (!driver->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 = driver->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);
+ }
+
+ if (op_ret == 0) {
+ s->formatter->open_object_section("TagRoleResponse");
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->close_section();
+ }
+}
+
+int RGWListRoleTags::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+
+ if (role_name.empty()) {
+ ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void RGWListRoleTags::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ boost::optional<multimap<string,string>> tag_map = _role->get_tags();
+ s->formatter->open_object_section("ListRoleTagsResponse");
+ s->formatter->open_object_section("ListRoleTagsResult");
+ if (tag_map) {
+ s->formatter->open_array_section("Tags");
+ for (const auto& it : tag_map.get()) {
+ s->formatter->open_object_section("Key");
+ encode_json("Key", it.first, s->formatter);
+ s->formatter->close_section();
+ s->formatter->open_object_section("Value");
+ encode_json("Value", it.second, s->formatter);
+ s->formatter->close_section();
+ }
+ 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();
+}
+
+int RGWUntagRole::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+
+ if (role_name.empty()) {
+ ldout(s->cct, 0) << "ERROR: Role name is empty" << dendl;
+ return -EINVAL;
+ }
+
+ auto val_map = s->info.args.get_params();
+ for (auto& it : val_map) {
+ if (it.first.find("TagKeys.member.") != string::npos) {
+ tagKeys.emplace_back(it.second);
+ }
+ }
+ return 0;
+}
+
+void RGWUntagRole::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ if (!driver->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 = driver->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);
+
+ if (op_ret == 0) {
+ s->formatter->open_object_section("UntagRoleResponse");
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->close_section();
+ }
+}
+
+int RGWUpdateRole::get_params()
+{
+ role_name = s->info.args.get("RoleName");
+ max_session_duration = s->info.args.get("MaxSessionDuration");
+
+ if (role_name.empty()) {
+ ldpp_dout(this, 20) << "ERROR: Role name is empty"<< dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void RGWUpdateRole::execute(optional_yield y)
+{
+ op_ret = get_params();
+ if (op_ret < 0) {
+ return;
+ }
+
+ if (!driver->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("MaxSessionDuration");
+ 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 = driver->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;
+ }
+ }
+
+ if (!_role->validate_max_session_duration(this)) {
+ op_ret = -EINVAL;
+ return;
+ }
+
+ _role->update_max_session_duration(max_session_duration);
+ op_ret = _role->update(this, y);
+
+ s->formatter->open_object_section("UpdateRoleResponse");
+ s->formatter->open_object_section("UpdateRoleResult");
+ s->formatter->open_object_section("ResponseMetadata");
+ s->formatter->dump_string("RequestId", s->trans_id);
+ s->formatter->close_section();
+ s->formatter->close_section();
+}