From d28c05cb77d0e8ed8a76429ffbb2e6f7a575f588 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Fri, 17 Nov 2023 21:29:25 -0500 Subject: [PATCH] rgw/acl/s3: parse_policy() as free function s3 acl parsing classes no longer inherit from the acl classes themselves, and are all encapsulated in rgw_acl_s3.cc behind a single rgw::s3::parse_policy() function Signed-off-by: Casey Bodley --- src/rgw/driver/rados/rgw_bucket.cc | 2 +- src/rgw/rgw_acl.cc | 4 +- src/rgw/rgw_acl.h | 2 +- src/rgw/rgw_acl_s3.cc | 339 +++++++++++++++++------------ src/rgw/rgw_acl_s3.h | 81 +------ src/rgw/rgw_op.cc | 62 ++---- src/rgw/rgw_op.h | 5 +- src/rgw/rgw_rest_s3.cc | 50 +---- src/rgw/rgw_rest_s3.h | 3 +- 9 files changed, 241 insertions(+), 307 deletions(-) diff --git a/src/rgw/driver/rados/rgw_bucket.cc b/src/rgw/driver/rados/rgw_bucket.cc index 6cbcbeae9a2..64d8e31cc3c 100644 --- a/src/rgw/driver/rados/rgw_bucket.cc +++ b/src/rgw/driver/rados/rgw_bucket.cc @@ -972,7 +972,7 @@ int RGWBucketAdminOp::get_policy(rgw::sal::Driver* driver, RGWBucketAdminOpState int RGWBucketAdminOp::dump_s3_policy(rgw::sal::Driver* driver, RGWBucketAdminOpState& op_state, ostream& os, const DoutPrefixProvider *dpp, optional_yield y) { - RGWAccessControlPolicy_S3 policy; + RGWAccessControlPolicy policy; int ret = get_policy(driver, op_state, policy, dpp, y); if (ret < 0) diff --git a/src/rgw/rgw_acl.cc b/src/rgw/rgw_acl.cc index 6e3aafe762a..316af76ecf0 100644 --- a/src/rgw/rgw_acl.cc +++ b/src/rgw/rgw_acl.cc @@ -419,9 +419,9 @@ void RGWAccessControlPolicy::dump(Formatter *f) const encode_json("owner", owner, f); } -ACLGroupTypeEnum ACLGrant::uri_to_group(string& uri) +ACLGroupTypeEnum ACLGrant::uri_to_group(std::string_view uri) { // this is required for backward compatibility - return ACLGrant_S3::uri_to_group(uri); + return rgw::s3::acl_uri_to_group(uri); } diff --git a/src/rgw/rgw_acl.h b/src/rgw/rgw_acl.h index c69ee88404e..afa63d8cdfb 100644 --- a/src/rgw/rgw_acl.h +++ b/src/rgw/rgw_acl.h @@ -111,7 +111,7 @@ public: void dump(Formatter *f) const; static void generate_test_instances(std::list& o); - ACLGroupTypeEnum uri_to_group(std::string& uri); + static ACLGroupTypeEnum uri_to_group(std::string_view uri); void set_canon(const rgw_user& _id, const std::string& _name, const uint32_t perm) { type.set(ACL_TYPE_CANON_USER); diff --git a/src/rgw/rgw_acl_s3.cc b/src/rgw/rgw_acl_s3.cc index f663e383092..f4e4221f2c0 100644 --- a/src/rgw/rgw_acl_s3.cc +++ b/src/rgw/rgw_acl_s3.cc @@ -25,6 +25,14 @@ using namespace std; static string rgw_uri_all_users = RGW_URI_ALL_USERS; static string rgw_uri_auth_users = RGW_URI_AUTH_USERS; +class ACLPermission_S3 : public XMLObj +{ +public: + uint32_t flags = 0; + + bool xml_end(const char *el) override; +}; + void to_xml(ACLPermission perm, std::ostream& out) { const uint32_t flags = perm.get_permissions(); @@ -42,8 +50,7 @@ void to_xml(ACLPermission perm, std::ostream& out) } } -bool ACLPermission_S3:: -xml_end(const char *el) +bool ACLPermission_S3::xml_end(const char *el) { const char *s = data.c_str(); if (strcasecmp(s, "READ") == 0) { @@ -97,6 +104,15 @@ public: } }; +class ACLGrantee_S3 : public XMLObj +{ +public: + ACLGrantee_S3() {} + virtual ~ACLGrantee_S3() override {} + + bool xml_start(const char *el, const char **attr); +}; + class ACLID_S3 : public XMLObj { public: @@ -126,6 +142,15 @@ public: ~ACLDisplayName_S3() override {} }; +class ACLOwner_S3 : public XMLObj +{ +public: + std::string id; + std::string display_name; + + bool xml_end(const char *el) override; +}; + bool ACLOwner_S3::xml_end(const char *el) { ACLID_S3 *acl_id = static_cast(find_first("ID")); ACLID_S3 *acl_name = static_cast(find_first("DisplayName")); @@ -156,12 +181,25 @@ void to_xml(const ACLOwner& o, std::ostream& out) out << ""; } +class ACLGrant_S3 : public XMLObj +{ +public: + ACLGranteeType type; + std::string id; + std::string name; + std::string uri; + std::string email; + ACLPermission_S3* permission = nullptr; + + bool xml_end(const char *el) override; + bool xml_start(const char *el, const char **attr); +}; + bool ACLGrant_S3::xml_end(const char *el) { ACLGrantee_S3 *acl_grantee; ACLID_S3 *acl_id; ACLURI_S3 *acl_uri; ACLEmail_S3 *acl_email; - ACLPermission_S3 *acl_permission; ACLDisplayName_S3 *acl_name; string uri; @@ -171,17 +209,12 @@ bool ACLGrant_S3::xml_end(const char *el) { string type_str; if (!acl_grantee->get_attr("xsi:type", type_str)) return false; - ACLGranteeType_S3::set(type_str.c_str(), type); - - acl_permission = static_cast(find_first("Permission")); - if (!acl_permission) - return false; - permission = *acl_permission; + ACLGranteeType_S3::set(type_str.c_str(), type); - id.clear(); - name.clear(); - email.clear(); + permission = static_cast(find_first("Permission")); + if (!permission) + return false; switch (type.get_type()) { case ACL_TYPE_CANON_USER: @@ -198,7 +231,6 @@ bool ACLGrant_S3::xml_end(const char *el) { if (!acl_uri) return false; uri = acl_uri->get_data(); - group = uri_to_group(uri); break; case ACL_TYPE_EMAIL_USER: acl_email = static_cast(acl_grantee->find_first("EmailAddress")); @@ -236,7 +268,7 @@ void to_xml(const ACLGrant& grant, ostream& out) out << "" << grant.email << ""; break; case ACL_TYPE_GROUP: - if (!ACLGrant_S3::group_to_uri(grant.group, uri)) { + if (!rgw::s3::acl_group_to_uri(grant.group, uri)) { break; } out << "" << uri << ""; @@ -249,27 +281,13 @@ void to_xml(const ACLGrant& grant, ostream& out) out << ""; } -bool ACLGrant_S3::group_to_uri(ACLGroupTypeEnum group, string& uri) +class RGWAccessControlList_S3 : public XMLObj { - switch (group) { - case ACL_GROUP_ALL_USERS: - uri = rgw_uri_all_users; - return true; - case ACL_GROUP_AUTHENTICATED_USERS: - uri = rgw_uri_auth_users; - return true; - default: - return false; - } -} +public: + bool xml_end(const char *el) override; +}; bool RGWAccessControlList_S3::xml_end(const char *el) { - XMLObjIter iter = find("Grant"); - ACLGrant_S3 *grant = static_cast(iter.get_next()); - while (grant) { - add_grant(*grant); - grant = static_cast(iter.get_next()); - } return true; } @@ -318,7 +336,7 @@ static int parse_grantee_str(const DoutPrefixProvider* dpp, grant.set_canon(user->get_id(), user->get_display_name(), rgw_perm); } else if (strcasecmp(id_type.c_str(), "uri") == 0) { - ACLGroupTypeEnum gid = grant.uri_to_group(id_val); + ACLGroupTypeEnum gid = rgw::s3::acl_uri_to_group(id_val); if (gid == ACL_GROUP_NONE) return -EINVAL; @@ -401,18 +419,21 @@ static int create_canned(const ACLOwner& owner, const ACLOwner& bucket_owner, return 0; } +class RGWAccessControlPolicy_S3 : public XMLObj +{ +public: + bool xml_end(const char *el) override; +}; + bool RGWAccessControlPolicy_S3::xml_end(const char *el) { RGWAccessControlList_S3 *s3acl = static_cast(find_first("AccessControlList")); if (!s3acl) return false; - acl = *s3acl; - - ACLOwner *owner_p = static_cast(find_first("Owner")); + ACLOwner_S3 *owner_p = static_cast(find_first("Owner")); if (!owner_p) return false; - owner = *owner_p; return true; } @@ -433,117 +454,68 @@ static const s3_acl_header acl_header_perms[] = { {0, NULL} }; -/* - can only be called on object that was parsed - */ -int RGWAccessControlPolicy_S3::rebuild(const DoutPrefixProvider *dpp, - rgw::sal::Driver* driver, ACLOwner *owner, - RGWAccessControlPolicy& dest, std::string &err_msg) +static int resolve_grant(const DoutPrefixProvider* dpp, optional_yield y, + rgw::sal::Driver* driver, ACLGrant_S3& xml_grant, + ACLGrant& grant, std::string& err_msg) { - if (!owner || owner->id.empty()) { - return -EINVAL; - } + const uint32_t perm = xml_grant.permission->flags; - ACLOwner *requested_owner = static_cast(find_first("Owner")); - if (requested_owner && requested_owner->id != owner->id) { - return -EPERM; - } + std::unique_ptr user; + switch (xml_grant.type.get_type()) { + case ACL_TYPE_EMAIL_USER: + if (xml_grant.email.empty()) { + return -EINVAL; + } + if (driver->get_user_by_email(dpp, xml_grant.email, y, &user) < 0) { + ldpp_dout(dpp, 10) << "grant user email not found or other error" << dendl; + err_msg = "The e-mail address you provided does not match any account on record."; + return -ERR_UNRESOLVABLE_EMAIL; + } + grant.set_canon(user->get_id(), user->get_display_name(), perm); + return 0; - std::unique_ptr user = driver->get_user(owner->id); - if (user->load_user(dpp, null_yield) < 0) { - ldpp_dout(dpp, 10) << "owner info does not exist" << dendl; - err_msg = "Invalid id"; - return -EINVAL; - } - ACLOwner& dest_owner = dest.get_owner(); - dest_owner.id = owner->id; - dest_owner.display_name = user->get_display_name(); - - ldpp_dout(dpp, 20) << "owner id=" << owner->id << dendl; - ldpp_dout(dpp, 20) << "dest owner id=" << dest.get_owner().id << dendl; - - RGWAccessControlList& dst_acl = dest.get_acl(); - - multimap& grant_map = acl.get_grant_map(); - multimap::iterator iter; - for (iter = grant_map.begin(); iter != grant_map.end(); ++iter) { - ACLGrant& src_grant = iter->second; - ACLGranteeType type = src_grant.get_type(); - ACLGrant new_grant; - bool grant_ok = false; - rgw_user uid; - RGWUserInfo grant_user; - switch (type.get_type()) { - case ACL_TYPE_EMAIL_USER: - { - string email; - rgw_user u; - if (!src_grant.get_id(u)) { - ldpp_dout(dpp, 0) << "ERROR: src_grant.get_id() failed" << dendl; - return -EINVAL; - } - email = u.id; - ldpp_dout(dpp, 10) << "grant user email=" << email << dendl; - if (driver->get_user_by_email(dpp, email, null_yield, &user) < 0) { - ldpp_dout(dpp, 10) << "grant user email not found or other error" << dendl; - err_msg = "The e-mail address you provided does not match any account on record."; - return -ERR_UNRESOLVABLE_EMAIL; - } - grant_user = user->get_info(); - uid = grant_user.user_id; - } - case ACL_TYPE_CANON_USER: - { - if (type.get_type() == ACL_TYPE_CANON_USER) { - if (!src_grant.get_id(uid)) { - ldpp_dout(dpp, 0) << "ERROR: src_grant.get_id() failed" << dendl; - err_msg = "Invalid id"; - return -EINVAL; - } - } - - if (grant_user.user_id.empty()) { - user = driver->get_user(uid); - if (user->load_user(dpp, null_yield) < 0) { - ldpp_dout(dpp, 10) << "grant user does not exist:" << uid << dendl; - err_msg = "Invalid id"; - return -EINVAL; - } else { - grant_user = user->get_info(); - } - } - ACLPermission perm = src_grant.get_permission(); - new_grant.set_canon(uid, grant_user.display_name, perm.get_permissions()); - grant_ok = true; - rgw_user new_id; - new_grant.get_id(new_id); - ldpp_dout(dpp, 10) << "new grant: " << new_id << ":" << grant_user.display_name << dendl; - } - break; - case ACL_TYPE_GROUP: - { - string uri; - if (ACLGrant_S3::group_to_uri(src_grant.get_group(), uri)) { - new_grant = src_grant; - grant_ok = true; - ldpp_dout(dpp, 10) << "new grant: " << uri << dendl; - } else { - ldpp_dout(dpp, 10) << "bad grant group:" << (int)src_grant.get_group() << dendl; - err_msg = "Invalid group uri"; - return -EINVAL; - } - } - default: - break; + case ACL_TYPE_CANON_USER: + user = driver->get_user(rgw_user{xml_grant.id}); + if (user->load_user(dpp, y) < 0) { + ldpp_dout(dpp, 10) << "grant user does not exist: " << xml_grant.id << dendl; + err_msg = "Invalid CanonicalUser id"; + return -EINVAL; } - if (grant_ok) { - dst_acl.add_grant(new_grant); + grant.set_canon(user->get_id(), user->get_display_name(), perm); + return 0; + + case ACL_TYPE_GROUP: + if (const auto group = rgw::s3::acl_uri_to_group(xml_grant.uri); + group != ACL_GROUP_NONE) { + grant.set_group(group, perm); + return 0; + } else { + ldpp_dout(dpp, 10) << "bad grant group: " << xml_grant.uri << dendl; + err_msg = "Invalid group uri"; + return -EINVAL; } - } - return 0; + case ACL_TYPE_REFERER: + case ACL_TYPE_UNKNOWN: + default: + err_msg = "Invalid Grantee type"; + return -EINVAL; + } } +/** + * Interfaces with the webserver's XML handling code + * to parse it in a way that makes sense for the rgw. + */ +class RGWACLXMLParser_S3 : public RGWXMLParser +{ + CephContext *cct; + + XMLObj *alloc_obj(const char *el) override; +public: + explicit RGWACLXMLParser_S3(CephContext *_cct) : cct(_cct) {} +}; + XMLObj *RGWACLXMLParser_S3::alloc_obj(const char *el) { XMLObj * obj = NULL; @@ -572,18 +544,97 @@ XMLObj *RGWACLXMLParser_S3::alloc_obj(const char *el) return obj; } -ACLGroupTypeEnum ACLGrant_S3::uri_to_group(string& uri) +namespace rgw::s3 { + +ACLGroupTypeEnum acl_uri_to_group(std::string_view uri) { - if (uri.compare(rgw_uri_all_users) == 0) + if (uri == rgw_uri_all_users) return ACL_GROUP_ALL_USERS; - else if (uri.compare(rgw_uri_auth_users) == 0) + else if (uri == rgw_uri_auth_users) return ACL_GROUP_AUTHENTICATED_USERS; return ACL_GROUP_NONE; } +bool acl_group_to_uri(ACLGroupTypeEnum group, std::string& uri) +{ + switch (group) { + case ACL_GROUP_ALL_USERS: + uri = rgw_uri_all_users; + return true; + case ACL_GROUP_AUTHENTICATED_USERS: + uri = rgw_uri_auth_users; + return true; + default: + return false; + } +} -namespace rgw::s3 { +int parse_policy(const DoutPrefixProvider* dpp, optional_yield y, + rgw::sal::Driver* driver, std::string_view document, + RGWAccessControlPolicy& policy, std::string& err_msg) +{ + RGWACLXMLParser_S3 parser(dpp->get_cct()); + if (!parser.init()) { + return -EINVAL; + } + if (!parser.parse(document.data(), document.size(), 1)) { + return -EINVAL; + } + + const auto xml_root = static_cast( + parser.find_first("AccessControlPolicy")); + if (!xml_root) { + err_msg = "Missing element AccessControlPolicy"; + return -EINVAL; + } + + const auto xml_owner = static_cast( + xml_root->find_first("Owner")); + if (!xml_owner) { + err_msg = "Missing element Owner"; + return -EINVAL; + } + + // owner must exist + std::unique_ptr user = + driver->get_user(rgw_user{xml_owner->id}); + if (user->load_user(dpp, y) < 0) { + ldpp_dout(dpp, 10) << "acl owner does not exist" << dendl; + err_msg = "Invalid Owner ID"; + return -EINVAL; + } + + ACLOwner& owner = policy.get_owner(); + owner.id = xml_owner->id; + if (!xml_owner->display_name.empty()) { + owner.display_name = xml_owner->display_name; + } else { + owner.display_name = user->get_display_name(); + } + + const auto xml_acl = static_cast( + xml_root->find_first("AccessControlList")); + if (!xml_acl) { + err_msg = "Missing element AccessControlList"; + return -EINVAL; + } + + // iterate parsed grants + XMLObjIter iter = xml_acl->find("Grant"); + ACLGrant_S3* xml_grant = static_cast(iter.get_next()); + while (xml_grant) { + ACLGrant grant; + int r = resolve_grant(dpp, y, driver, *xml_grant, grant, err_msg); + if (r < 0) { + return r; + } + policy.get_acl().add_grant(grant); + xml_grant = static_cast(iter.get_next()); + } + + return 0; +} void write_policy_xml(const RGWAccessControlPolicy& policy, std::ostream& out) diff --git a/src/rgw/rgw_acl_s3.h b/src/rgw/rgw_acl_s3.h index 7b848929971..2341461783f 100644 --- a/src/rgw/rgw_acl_s3.h +++ b/src/rgw/rgw_acl_s3.h @@ -8,85 +8,24 @@ #include #include -#include "include/str_list.h" +#include "common/async/yield_context.h" #include "rgw_xml.h" #include "rgw_acl.h" #include "rgw_sal_fwd.h" -class RGWUserCtl; - -class ACLPermission_S3 : public ACLPermission, public XMLObj -{ -public: - ACLPermission_S3() {} - virtual ~ACLPermission_S3() override {} - - bool xml_end(const char *el) override; -}; - -class ACLGrantee_S3 : public XMLObj -{ -public: - ACLGrantee_S3() {} - virtual ~ACLGrantee_S3() override {} - - bool xml_start(const char *el, const char **attr); -}; - - -class ACLGrant_S3 : public ACLGrant, public XMLObj -{ -public: - ACLGrant_S3() {} - virtual ~ACLGrant_S3() override {} - - bool xml_end(const char *el) override; - bool xml_start(const char *el, const char **attr); - - static ACLGroupTypeEnum uri_to_group(std::string& uri); - static bool group_to_uri(ACLGroupTypeEnum group, std::string& uri); -}; - -class RGWAccessControlList_S3 : public RGWAccessControlList, public XMLObj -{ -public: - bool xml_end(const char *el) override; -}; - -class ACLOwner_S3 : public ACLOwner, public XMLObj -{ -public: - ACLOwner_S3() {} - virtual ~ACLOwner_S3() override {} - - bool xml_end(const char *el) override; -}; - class RGWEnv; -class RGWAccessControlPolicy_S3 : public RGWAccessControlPolicy, public XMLObj -{ -public: - bool xml_end(const char *el) override; - - int rebuild(const DoutPrefixProvider *dpp, rgw::sal::Driver* driver, ACLOwner *owner, - RGWAccessControlPolicy& dest, std::string &err_msg); -}; - -/** - * Interfaces with the webserver's XML handling code - * to parse it in a way that makes sense for the rgw. - */ -class RGWACLXMLParser_S3 : public RGWXMLParser -{ - CephContext *cct; +namespace rgw::s3 { - XMLObj *alloc_obj(const char *el) override; -public: - explicit RGWACLXMLParser_S3(CephContext *_cct) : cct(_cct) {} -}; +ACLGroupTypeEnum acl_uri_to_group(std::string_view uri); +bool acl_group_to_uri(ACLGroupTypeEnum group, std::string& uri); -namespace rgw::s3 { +/// Construct a policy from an AccessControlPolicy xml document. Email grantees +/// are looked up and converted to a corresponding CanonicalUser grant. All user +/// ids are verified to exist. +int parse_policy(const DoutPrefixProvider* dpp, optional_yield y, + rgw::sal::Driver* driver, std::string_view document, + RGWAccessControlPolicy& policy, std::string& err_msg); /// Write an AccessControlPolicy xml document for the given policy. void write_policy_xml(const RGWAccessControlPolicy& policy, diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index f822c13932d..8a0d19526ad 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -512,7 +512,7 @@ int rgw_build_bucket_policies(const DoutPrefixProvider *dpp, rgw::sal::Driver* d } if(s->dialect.compare("s3") == 0) { - s->bucket_acl = std::make_unique(); + s->bucket_acl = std::make_unique(); } else if(s->dialect.compare("swift") == 0) { /* We aren't allocating the account policy for those operations using * the Swift's infrastructure that don't really need req_state::user. @@ -5982,25 +5982,10 @@ void RGWDeleteLC::pre_exec() void RGWPutACLs::execute(optional_yield y) { - bufferlist bl; - - RGWAccessControlPolicy_S3 *policy = NULL; - RGWACLXMLParser_S3 parser(s->cct); - RGWAccessControlPolicy_S3 new_policy; - stringstream ss; - - op_ret = 0; /* XXX redundant? */ - - if (!parser.init()) { - op_ret = -EINVAL; - return; - } - - RGWAccessControlPolicy* const existing_policy = \ (rgw::sal::Object::empty(s->object.get()) ? s->bucket_acl.get() : s->object_acl.get()); - owner = existing_policy->get_owner(); + const ACLOwner& existing_owner = existing_policy->get_owner(); op_ret = get_params(y); if (op_ret < 0) { @@ -6023,26 +6008,24 @@ void RGWPutACLs::execute(optional_yield y) return; } + RGWAccessControlPolicy new_policy; if (!s->canned_acl.empty() || s->has_acl_header) { - op_ret = get_policy_from_state(driver, s, ss); - if (op_ret < 0) - return; - - data.clear(); - data.append(ss.str()); + op_ret = get_policy_from_state(existing_owner, new_policy); + } else { + op_ret = rgw::s3::parse_policy(this, y, driver, {data.c_str(), data.length()}, + new_policy, s->err.message); } - - if (!parser.parse(data.c_str(), data.length(), 1)) { - op_ret = -EINVAL; + if (op_ret < 0) return; - } - policy = static_cast(parser.find_first("AccessControlPolicy")); - if (!policy) { - op_ret = -EINVAL; + + if (!existing_owner.id.empty() && + existing_owner.id != new_policy.get_owner().id) { + s->err.message = "Cannot modify ACL Owner"; + op_ret = -EPERM; return; } - const RGWAccessControlList& req_acl = policy->get_acl(); + const RGWAccessControlList& req_acl = new_policy.get_acl(); const multimap& req_grant_map = req_acl.get_grant_map(); #define ACL_GRANTS_MAX_NUM 100 int max_num = s->cct->_conf->rgw_acl_grants_max_num; @@ -6063,13 +6046,8 @@ void RGWPutACLs::execute(optional_yield y) // forward bucket acl requests to meta master zone if ((rgw::sal::Object::empty(s->object.get()))) { - bufferlist in_data; - // include acl data unless it was generated from a canned_acl - if (s->canned_acl.empty()) { - in_data.append(data); - } op_ret = rgw_forward_request_to_master(this, *s->penv.site, s->user->get_id(), - &in_data, nullptr, s->info, y); + &data, nullptr, s->info, y); if (op_ret < 0) { ldpp_dout(this, 0) << "forward_request_to_master returned ret=" << op_ret << dendl; return; @@ -6078,15 +6056,9 @@ void RGWPutACLs::execute(optional_yield y) if (s->cct->_conf->subsys.should_gather()) { ldpp_dout(this, 15) << "Old AccessControlPolicy"; - rgw::s3::write_policy_xml(*policy, *_dout); + rgw::s3::write_policy_xml(*existing_policy, *_dout); *_dout << dendl; - } - - op_ret = policy->rebuild(this, driver, &owner, new_policy, s->err.message); - if (op_ret < 0) - return; - if (s->cct->_conf->subsys.should_gather()) { ldpp_dout(this, 15) << "New AccessControlPolicy:"; rgw::s3::write_policy_xml(new_policy, *_dout); *_dout << dendl; @@ -6098,6 +6070,8 @@ void RGWPutACLs::execute(optional_yield y) op_ret = -EACCES; return; } + + bufferlist bl; new_policy.encode(bl); map attrs; diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 70266cbfc66..948b68f54d8 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1576,7 +1576,6 @@ public: class RGWPutACLs : public RGWOp { protected: bufferlist data; - ACLOwner owner; public: RGWPutACLs() {} @@ -1586,7 +1585,8 @@ public: void pre_exec() override; void execute(optional_yield y) override; - virtual int get_policy_from_state(rgw::sal::Driver* driver, req_state *s, std::stringstream& ss) { return 0; } + virtual int get_policy_from_state(const ACLOwner& owner, + RGWAccessControlPolicy& p) { return 0; } virtual int get_params(optional_yield y) = 0; void send_response() override = 0; const char* name() const override { return "put_acls"; } @@ -1636,7 +1636,6 @@ public: void pre_exec() override; void execute(optional_yield y) override; -// virtual int get_policy_from_state(RGWRados* driver, req_state *s, std::stringstream& ss) { return 0; } virtual int get_params(optional_yield y) = 0; void send_response() override = 0; const char* name() const override { return "put_lifecycle"; } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 73f16e449e9..ed8e1afa7b7 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -2383,7 +2383,7 @@ void RGWStatBucket_ObjStore_S3::send_response() } static int create_s3_policy(req_state *s, rgw::sal::Driver* driver, - RGWAccessControlPolicy_S3& s3policy, + RGWAccessControlPolicy& policy, const ACLOwner& owner) { if (s->has_acl_header) { @@ -2391,11 +2391,11 @@ static int create_s3_policy(req_state *s, rgw::sal::Driver* driver, return -ERR_INVALID_REQUEST; return rgw::s3::create_policy_from_headers(s, driver, owner, - *s->info.env, s3policy); + *s->info.env, policy); } return rgw::s3::create_canned_acl(owner, s->bucket_owner, - s->canned_acl, s3policy); + s->canned_acl, policy); } class RGWLocationConstraint : public XMLObj @@ -2449,7 +2449,6 @@ public: int RGWCreateBucket_ObjStore_S3::get_params(optional_yield y) { - RGWAccessControlPolicy_S3 s3policy; bool relaxed_names = s->cct->_conf->rgw_relaxed_s3_bucket_names; int r; @@ -2458,12 +2457,10 @@ int RGWCreateBucket_ObjStore_S3::get_params(optional_yield y) if (r) return r; } - r = create_s3_policy(s, driver, s3policy, s->owner); + r = create_s3_policy(s, driver, policy, s->owner); if (r < 0) return r; - policy = s3policy; - const auto max_size = s->cct->_conf->rgw_max_put_param_size; int op_ret = 0; @@ -2591,13 +2588,10 @@ int RGWPutObj_ObjStore_S3::get_params(optional_yield y) return ret; } - RGWAccessControlPolicy_S3 s3policy; - ret = create_s3_policy(s, driver, s3policy, s->owner); + ret = create_s3_policy(s, driver, policy, s->owner); if (ret < 0) return ret; - policy = s3policy; - if_match = s->info.env->get("HTTP_IF_MATCH"); if_nomatch = s->info.env->get("HTTP_IF_NONE_MATCH"); @@ -3451,16 +3445,8 @@ void RGWDeleteObj_ObjStore_S3::send_response() int RGWCopyObj_ObjStore_S3::init_dest_policy() { - RGWAccessControlPolicy_S3 s3policy; - /* build a policy for the target object */ - int r = create_s3_policy(s, driver, s3policy, s->owner); - if (r < 0) - return r; - - dest_policy = s3policy; - - return 0; + return create_s3_policy(s, driver, dest_policy, s->owner); } int RGWCopyObj_ObjStore_S3::get_params(optional_yield y) @@ -3622,25 +3608,16 @@ int RGWPutACLs_ObjStore_S3::get_params(optional_yield y) return ret; } -int RGWPutACLs_ObjStore_S3::get_policy_from_state(rgw::sal::Driver* driver, - req_state *s, - stringstream& ss) +int RGWPutACLs_ObjStore_S3::get_policy_from_state(const ACLOwner& owner, + RGWAccessControlPolicy& policy) { - RGWAccessControlPolicy_S3 s3policy; - // bucket-* canned acls do not apply to bucket if (rgw::sal::Object::empty(s->object.get())) { if (s->canned_acl.find("bucket") != string::npos) s->canned_acl.clear(); } - int r = create_s3_policy(s, driver, s3policy, owner); - if (r < 0) - return r; - - rgw::s3::write_policy_xml(s3policy, ss); - - return 0; + return create_s3_policy(s, driver, policy, owner); } void RGWPutACLs_ObjStore_S3::send_response() @@ -3973,14 +3950,7 @@ int RGWInitMultipart_ObjStore_S3::get_params(optional_yield y) return ret; } - RGWAccessControlPolicy_S3 s3policy; - ret = create_s3_policy(s, driver, s3policy, s->owner); - if (ret < 0) - return ret; - - policy = s3policy; - - return 0; + return create_s3_policy(s, driver, policy, s->owner); } void RGWInitMultipart_ObjStore_S3::send_response() diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index c73971a5fe6..d15ddaba35a 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -355,7 +355,8 @@ public: RGWPutACLs_ObjStore_S3() {} ~RGWPutACLs_ObjStore_S3() override {} - int get_policy_from_state(rgw::sal::Driver* driver, req_state *s, std::stringstream& ss) override; + int get_policy_from_state(const ACLOwner& owner, + RGWAccessControlPolicy& p) override; void send_response() override; int get_params(optional_yield y) override; }; -- 2.39.5