for role REST APIs.
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
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;
}
}
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;
}
}
}
-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();
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,
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) {
/** 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&>
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)
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)
}
}
- 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) {
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)
CephContext *cct,
const string& host,
string *region,
- string *service)
+ string& service)
{
if (!boost::algorithm::ends_with(host, "amazonaws.com")) {
ldpp_dout(dpp, 20) << "NOTICE: cannot identify region for connection to: " << host << dendl;
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()) {
const string& host,
std::optional<string> api_name,
string *region,
- string *service)
+ string& service)
{
- if (api_name) {
+ if (api_name && service.empty()) {
*region = *api_name;
- *service = "s3";
+ service = "s3";
return;
}
if (!identify_scope(dpp, cct, host, region, service)) {
- *region = cct->_conf->rgw_zonegroup;
- *service = "s3";
+ if (service == "iam") {
+ *region = cct->_conf->rgw_zonegroup;
+ } else {
+ *region = cct->_conf->rgw_zonegroup;
+ service = "s3";
+ }
return;
}
}
-int RGWRESTSimpleRequest::forward_request(const DoutPrefixProvider *dpp, RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y)
+int RGWRESTSimpleRequest::forward_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, req_info& info, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y, std::string service)
{
string date_str;
}
string region;
- string service;
+ string s;
+ if (!service.empty()) {
+ s = service;
+ }
- scope_from_api_name(dpp, cct, host, api_name, ®ion, &service);
+ scope_from_api_name(dpp, cct, host, api_name, ®ion, s);
const char *maybe_payload_hash = info.env->get("HTTP_X_AMZ_CONTENT_SHA256");
- if (maybe_payload_hash) {
+ if (maybe_payload_hash && s != "iam") {
new_env.set("HTTP_X_AMZ_CONTENT_SHA256", maybe_payload_hash);
}
- int ret = sign_request(dpp, key, region, service, new_env, new_info, nullptr);
+ int ret = sign_request(dpp, key, region, s, new_env, new_info, nullptr);
if (ret < 0) {
ldpp_dout(dpp, 0) << "ERROR: failed to sign request" << dendl;
return ret;
}
+ if (s == "iam") {
+ info.args.remove("PayloadHash");
+ }
+
for (const auto& kv: new_env.get_map()) {
headers.emplace_back(kv);
}
const string& resource, const param_vec_t& params,
std::optional<string> api_name)
{
- scope_from_api_name(this, cct, host, api_name, ®ion, &service);
+ scope_from_api_name(this, cct, host, api_name, ®ion, service);
string params_str;
map<string, string>& args = new_info->args.get_params();
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 {
return req.forward_request(dpp, key, info, max_response, inbl, outbl, y);
}
+int RGWRESTConn::forward_iam_request(const DoutPrefixProvider *dpp, const RGWAccessKey& key, req_info& info, obj_version *objv, size_t max_response, bufferlist *inbl, bufferlist *outbl, optional_yield y)
+{
+ string url;
+ int ret = get_url(url);
+ if (ret < 0)
+ return ret;
+ param_vec_t params;
+ if (objv) {
+ params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "tag", objv->tag));
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%lld", (long long)objv->ver);
+ params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "ver", buf));
+ }
+ std::string service = "iam";
+ RGWRESTSimpleRequest req(cct, info.method, url, NULL, ¶ms, api_name);
+ return req.forward_request(dpp, key, info, max_response, inbl, outbl, y, service);
+}
+
int RGWRESTConn::put_obj_send_init(rgw::sal::Object* obj, const rgw_http_param_pair *extra_params, RGWRESTStreamS3PutObj **req)
{
string url;
/* 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);
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;
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)
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;
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);
}
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:
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,
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) {
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");
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);
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);
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) {
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);
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);
};
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();
};
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"; }
};
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"; }
};
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"; }
};
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"; }
};
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"; }
};
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"; }
}
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) {
/* 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();
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);
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;
}
};
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);
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. */
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 "";
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;
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 "";
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;
#include <system_error>
#include <unistd.h>
#include <sstream>
+#include <boost/algorithm/string.hpp>
#include "common/Clock.h"
#include "common/errno.h"
return 0;
}
+int RadosStore::forward_iam_request_to_master(const DoutPrefixProvider *dpp, const RGWAccessKey& key, obj_version* objv,
+ bufferlist& in_data,
+ RGWXMLDecoder::XMLParser* parser, req_info& info,
+ optional_yield y)
+{
+ if (is_meta_master()) {
+ /* We're master, don't forward */
+ return 0;
+ }
+
+ if (!svc()->zone->get_master_conn()) {
+ ldpp_dout(dpp, 0) << "rest connection is invalid" << dendl;
+ return -EINVAL;
+ }
+ ldpp_dout(dpp, 0) << "sending request to master zonegroup" << dendl;
+ bufferlist response;
+#define MAX_REST_RESPONSE (128 * 1024) // we expect a very small response
+ int ret = svc()->zone->get_master_conn()->forward_iam_request(dpp, key, info,
+ objv, MAX_REST_RESPONSE,
+ &in_data, &response, y);
+ if (ret < 0)
+ return ret;
+
+ ldpp_dout(dpp, 20) << "response: " << response.c_str() << dendl;
+
+ std::string r = response.c_str();
+ std::string str_to_search = """;
+ std::string str_to_replace = "\"";
+ boost::replace_all(r, str_to_search, str_to_replace);
+ ldpp_dout(dpp, 20) << "r: " << r.c_str() << dendl;
+
+ if (parser && !parser->parse(r.c_str(), r.length(), 1)) {
+ ldpp_dout(dpp, 0) << "ERROR: failed to parse response from master zonegroup" << dendl;
+ return -EIO;
+ }
+
+ return 0;
+}
+
std::string RadosStore::zone_unique_id(uint64_t unique_num)
{
return svc()->zone_utils->unique_id(unique_num);
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)
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;
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;
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) {
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;
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
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,
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,
GetParams ¶ms,
RGWObjVersionTracker *objv_tracker,
optional_yield y,
- const DoutPrefixProvider *dpp);
+ const DoutPrefixProvider *dpp,
+ bool get_raw_attrs=false);
virtual int put(Context *ctx,
const std::string& key,
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);
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,
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);
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,
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,