// this probably should belong in the rgw_iam_policy_keywords, I'll get it to it
// at some point
static constexpr auto S3_EXISTING_OBJTAG = "s3:ExistingObjectTag";
+static constexpr auto S3_RESOURCE_TAG = "s3:ResourceTag";
+static constexpr auto S3_RUNTIME_RESOURCE_VAL = "${s3:ResourceTag";
int RGWGetObj::parse_range(void)
{
return ret;
}
+static int rgw_iam_remove_objtags(const DoutPrefixProvider *dpp, struct req_state* s, rgw::sal::Object* object, bool has_existing_obj_tag, bool has_resource_tag) {
+ object->set_atomic(s->obj_ctx);
+ int op_ret = object->get_obj_attrs(s->obj_ctx, s->yield, dpp);
+ if (op_ret < 0)
+ return op_ret;
+ rgw::sal::Attrs attrs = object->get_attrs();
+ auto tags = attrs.find(RGW_ATTR_TAGS);
+ if (tags != attrs.end()) {
+ RGWObjTags tagset;
+ try {
+ auto bliter = tags->second.cbegin();
+ tagset.decode(bliter);
+ } catch (buffer::error& err) {
+ ldpp_dout(s, 0) << "ERROR: caught buffer::error, couldn't decode TagSet" << dendl;
+ return -EIO;
+ }
+ for (auto& tag: tagset.get_tags()) {
+ if (has_existing_obj_tag) {
+ vector<std::unordered_multimap<string, string>::iterator> iters;
+ string key = "s3:ExistingObjectTag/" + tag.first;
+ auto result = s->env.equal_range(key);
+ for (auto& it = result.first; it != result.second; ++it)
+ {
+ if (tag.second == it->second) {
+ iters.emplace_back(it);
+ }
+ }
+ for (auto& it : iters) {
+ s->env.erase(it);
+ }
+ }//end if has_existing_obj_tag
+ if (has_resource_tag) {
+ vector<std::unordered_multimap<string, string>::iterator> iters;
+ string key = "s3:ResourceTag/" + tag.first;
+ auto result = s->env.equal_range(key);
+ for (auto& it = result.first; it != result.second; ++it)
+ {
+ if (tag.second == it->second) {
+ iters.emplace_back(it);
+ }
+ }
+ for (auto& it : iters) {
+ s->env.erase(it);
+ }
+ }//end if has_resource_tag
+ }
+ }
+ return 0;
+}
+
void rgw_add_to_iam_environment(rgw::IAM::Environment& e, std::string_view key, std::string_view val){
// This variant just adds non empty key pairs to IAM env., values can be empty
// in certain cases like tagging
e.emplace(key,val);
}
-static int rgw_iam_add_tags_from_bl(struct req_state* s, bufferlist& bl){
+static int rgw_iam_add_tags_from_bl(struct req_state* s, bufferlist& bl, bool has_existing_obj_tag=false, bool has_resource_tag=false){
RGWObjTags& tagset = s->tagset;
try {
auto bliter = bl.cbegin();
}
for (const auto& tag: tagset.get_tags()){
- rgw_add_to_iam_environment(s->env, "s3:ExistingObjectTag/" + tag.first, tag.second);
+ if (has_existing_obj_tag)
+ rgw_add_to_iam_environment(s->env, "s3:ExistingObjectTag/" + tag.first, tag.second);
+ if (has_resource_tag)
+ rgw_add_to_iam_environment(s->env, "s3:ResourceTag/" + tag.first, tag.second);
}
return 0;
}
-static int rgw_iam_add_existing_objtags(const DoutPrefixProvider *dpp, rgw::sal::Store* store, struct req_state* s, std::uint64_t action) {
- s->object->set_atomic(s->obj_ctx);
- int op_ret = s->object->get_obj_attrs(s->obj_ctx, s->yield, dpp);
+static int rgw_iam_add_objtags(const DoutPrefixProvider *dpp, struct req_state* s, rgw::sal::Object* object, bool has_existing_obj_tag, bool has_resource_tag) {
+ object->set_atomic(s->obj_ctx);
+ int op_ret = object->get_obj_attrs(s->obj_ctx, s->yield, dpp);
if (op_ret < 0)
return op_ret;
- rgw::sal::Attrs attrs = s->object->get_attrs();
+ rgw::sal::Attrs attrs = object->get_attrs();
auto tags = attrs.find(RGW_ATTR_TAGS);
if (tags != attrs.end()){
- return rgw_iam_add_tags_from_bl(s, tags->second);
+ return rgw_iam_add_tags_from_bl(s, tags->second, has_existing_obj_tag, has_resource_tag);
}
return 0;
}
+static int rgw_iam_add_objtags(const DoutPrefixProvider *dpp, struct req_state* s, bool has_existing_obj_tag, bool has_resource_tag) {
+ if (!rgw::sal::Object::empty(s->object.get())) {
+ return rgw_iam_add_objtags(dpp, s, s->object.get(), has_existing_obj_tag, has_resource_tag);
+ }
+ return 0;
+}
+
+static int rgw_iam_add_buckettags(const DoutPrefixProvider *dpp, struct req_state* s, rgw::sal::Bucket* bucket) {
+ rgw::sal::Attrs attrs = bucket->get_attrs();
+ auto tags = attrs.find(RGW_ATTR_TAGS);
+ if (tags != attrs.end()) {
+ return rgw_iam_add_tags_from_bl(s, tags->second, false, true);
+ }
+ return 0;
+}
+
+static int rgw_iam_add_buckettags(const DoutPrefixProvider *dpp, struct req_state* s) {
+ return rgw_iam_add_buckettags(dpp, s, s->bucket.get());
+}
+
+static std::tuple<bool, bool> rgw_check_policy_condition(const DoutPrefixProvider *dpp,
+ boost::optional<rgw::IAM::Policy> iam_policy,
+ boost::optional<vector<rgw::IAM::Policy>> identity_policies,
+ boost::optional<vector<rgw::IAM::Policy>> session_policies,
+ bool check_obj_exist_tag=true) {
+ bool has_existing_obj_tag = false, has_resource_tag = false;
+ bool iam_policy_s3_exist_tag = false, iam_policy_s3_resource_tag = false;
+ if (iam_policy) {
+ if (check_obj_exist_tag) {
+ iam_policy_s3_exist_tag = iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG);
+ }
+ iam_policy_s3_resource_tag = iam_policy->has_partial_conditional(S3_RESOURCE_TAG) || iam_policy->has_partial_conditional_value(S3_RUNTIME_RESOURCE_VAL);
+ }
+
+ bool identity_policy_s3_exist_tag = false, identity_policy_s3_resource_tag = false;
+ if (identity_policies) {
+ for (auto& identity_policy : identity_policies.get()) {
+ if (check_obj_exist_tag) {
+ if (identity_policy.has_partial_conditional(S3_EXISTING_OBJTAG))
+ identity_policy_s3_exist_tag = true;
+ }
+ if (identity_policy.has_partial_conditional(S3_RESOURCE_TAG) || identity_policy.has_partial_conditional_value(S3_RUNTIME_RESOURCE_VAL))
+ identity_policy_s3_resource_tag = true;
+ if (identity_policy_s3_exist_tag && identity_policy_s3_resource_tag) // check all policies till both are set to true
+ break;
+ }
+ }
+
+ bool session_policy_s3_exist_tag = false, session_policy_s3_resource_flag = false;
+ if (session_policies) {
+ for (auto& session_policy : session_policies.get()) {
+ if (check_obj_exist_tag) {
+ if (session_policy.has_partial_conditional(S3_EXISTING_OBJTAG))
+ session_policy_s3_exist_tag = true;
+ }
+ if (session_policy.has_partial_conditional(S3_RESOURCE_TAG) || session_policy.has_partial_conditional_value(S3_RUNTIME_RESOURCE_VAL))
+ session_policy_s3_resource_flag = true;
+ if (session_policy_s3_exist_tag && session_policy_s3_resource_flag)
+ break;
+ }
+ }
+
+ has_existing_obj_tag = iam_policy_s3_exist_tag || identity_policy_s3_exist_tag || session_policy_s3_exist_tag;
+ has_resource_tag = iam_policy_s3_resource_tag || identity_policy_s3_resource_tag || session_policy_s3_resource_flag;
+ return make_tuple(has_existing_obj_tag, has_resource_tag);
+}
+
+static std::tuple<bool, bool> rgw_check_policy_condition(const DoutPrefixProvider *dpp, struct req_state* s, bool check_obj_exist_tag=true) {
+ return rgw_check_policy_condition(dpp, s->iam_policy, s->iam_user_policies, s->session_policies, check_obj_exist_tag);
+}
+
static void rgw_add_grant_to_iam_environment(rgw::IAM::Environment& e, struct req_state *s){
using header_pair_t = std::pair <const char*, const char*>;
s->object->set_prefetch_data(s->obj_ctx);
}
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (torrent.get_flag()) {
if (s->object->get_instance().empty()) {
action = rgw::IAM::s3GetObjectTorrent;
} else {
action = rgw::IAM::s3GetObjectVersion;
}
- if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG))
- rgw_iam_add_existing_objtags(this, store, s, action);
- if (! s->iam_user_policies.empty()) {
- for (auto& user_policy : s->iam_user_policies) {
- if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG))
- rgw_iam_add_existing_objtags(this, store, s, action);
- }
- }
}
if (!verify_object_permission(this, s, action)) {
auto iam_action = s->object->get_instance().empty()?
rgw::IAM::s3GetObjectTagging:
rgw::IAM::s3GetObjectVersionTagging;
- // TODO since we are parsing the bl now anyway, we probably change
- // the send_response function to accept RGWObjTag instead of a bl
- if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- if (! s->iam_user_policies.empty()) {
- for (auto& user_policy : s->iam_user_policies) {
- if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) {
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- }
- }
+
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
if (!verify_object_permission(this, s,iam_action))
return -EACCES;
rgw::IAM::s3PutObjectTagging:
rgw::IAM::s3PutObjectVersionTagging;
- if(s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- if (! s->iam_user_policies.empty()) {
- for (auto& user_policy : s->iam_user_policies) {
- if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) {
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- }
- }
+ //Using buckets tags for authorization makes more sense.
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, true);
+ if (has_s3_existing_tag)
+ rgw_iam_add_objtags(this, s, true, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
if (!verify_object_permission(this, s,iam_action))
return -EACCES;
return 0;
rgw::IAM::s3DeleteObjectTagging:
rgw::IAM::s3DeleteObjectVersionTagging;
- if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- if (! s->iam_user_policies.empty()) {
- for (auto& user_policy : s->iam_user_policies) {
- if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) {
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- }
- }
- if (!verify_object_permission(this, s, iam_action))
- return -EACCES;
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+ if (!verify_object_permission(this, s, iam_action))
+ return -EACCES;
}
return 0;
}
int RGWGetBucketTags::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketTagging)) {
return -EACCES;
}
int RGWPutBucketTags::verify_permission(optional_yield y) {
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketTagging);
}
int RGWDeleteBucketTags::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketTagging);
}
int RGWGetBucketReplication::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3GetReplicationConfiguration)) {
return -EACCES;
}
}
int RGWPutBucketReplication::verify_permission(optional_yield y) {
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutReplicationConfiguration);
}
int RGWDeleteBucketReplication::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3DeleteReplicationConfiguration);
}
int RGWGetBucketVersioning::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketVersioning);
}
int RGWSetBucketVersioning::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketVersioning);
}
int RGWGetBucketWebsite::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketWebsite);
}
int RGWSetBucketWebsite::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketWebsite);
}
int RGWDeleteBucketWebsite::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3DeleteBucketWebsite);
}
int RGWStatBucket::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
// This (a HEAD request on a bucket) is governed by the s3:ListBucket permission.
if (!verify_bucket_permission(this, s, rgw::IAM::s3ListBucket)) {
return -EACCES;
s->env.emplace("s3:max-keys", std::to_string(max));
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this,
s,
list_versions ?
int RGWGetBucketLogging::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketLogging);
}
int RGWGetBucketLocation::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketLocation);
}
int RGWDeleteBucket::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3DeleteBucket)) {
return -EACCES;
}
/* admin request overrides permission checks */
if (! s->auth.identity->is_admin_of(cs_acl.get_owner().get_id())) {
- if (policy || ! s->iam_user_policies.empty()) {
+ if (policy || ! s->iam_user_policies.empty() || !s->session_policies.empty()) {
+ //add source object tags for permission evaluation
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, policy, s->iam_user_policies, s->session_policies);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, cs_object.get(), has_s3_existing_tag, has_s3_resource_tag);
auto usr_policy_res = Effect::Pass;
for (auto& user_policy : s->iam_user_policies) {
if (usr_policy_res = user_policy.eval(s->env, *s->auth.identity,
RGW_PERM_READ)) {
return -EACCES;
}
+ rgw_iam_remove_objtags(this, s, cs_object.get(), has_s3_existing_tag, has_s3_resource_tag);
} else if (!cs_acl.verify_permission(this, *s->auth.identity, s->perm_mask,
RGW_PERM_READ)) {
return -EACCES;
return op_ret;
}
- if (s->iam_policy || ! s->iam_user_policies.empty()) {
+ if (s->iam_policy || ! s->iam_user_policies.empty() || !s->session_policies.empty()) {
rgw_add_grant_to_iam_environment(s->env, s);
rgw_add_to_iam_environment(s->env, "s3:x-amz-acl", s->canned_acl);
/* Object needs a bucket from this point */
s->object->set_bucket(s->bucket.get());
+ // Add bucket tags for authorization
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
auto identity_policy_res = eval_identity_or_session_policies(s->iam_user_policies, s->env,
boost::none,
rgw::IAM::s3PutObject,
if (op_ret) {
return op_ret;
}
+
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (s->iam_policy || ! s->iam_user_policies.empty() || ! s->session_policies.empty()) {
if (s->bucket->get_info().obj_lock_enabled() && bypass_governance_mode) {
auto r = eval_identity_or_session_policies(s->iam_user_policies, s->env, boost::none,
/* admin request overrides permission checks */
if (!s->auth.identity->is_admin_of(src_acl.get_owner().get_id())) {
if (src_policy || ! s->iam_user_policies.empty() || !s->session_policies.empty()) {
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, src_policy, s->iam_user_policies, s->session_policies);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, src_object.get(), has_s3_existing_tag, has_s3_resource_tag);
+
auto identity_policy_res = eval_identity_or_session_policies(s->iam_user_policies, s->env,
boost::none,
src_object->get_instance().empty() ?
RGW_PERM_READ)) {
return -EACCES;
}
+ //remove src object tags as it may interfere with policy evaluation of destination obj
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_remove_objtags(this, s, src_object.get(), has_s3_existing_tag, has_s3_resource_tag);
+
} else if (!src_acl.verify_permission(this, *s->auth.identity,
s->perm_mask,
RGW_PERM_READ)) {
/* admin request overrides permission checks */
if (! s->auth.identity->is_admin_of(dest_policy.get_owner().get_id())){
if (dest_iam_policy != boost::none || ! s->iam_user_policies.empty() || !s->session_policies.empty()) {
+ //Add destination bucket tags for authorization
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, dest_iam_policy, s->iam_user_policies, s->session_policies);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s, dest_bucket.get());
+
rgw_add_to_iam_environment(s->env, "s3:x-amz-copy-source", copy_source);
if (md_directive)
rgw_add_to_iam_environment(s->env, "s3:x-amz-metadata-directive",
int RGWGetACLs::verify_permission(optional_yield y)
{
bool perm;
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
if (!rgw::sal::Object::empty(s->object.get())) {
auto iam_action = s->object->get_instance().empty() ?
rgw::IAM::s3GetObjectAcl :
rgw::IAM::s3GetObjectVersionAcl;
-
- if (s->iam_policy && s->iam_policy->has_partial_conditional(S3_EXISTING_OBJTAG)){
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- if (! s->iam_user_policies.empty()) {
- for (auto& user_policy : s->iam_user_policies) {
- if (user_policy.has_partial_conditional(S3_EXISTING_OBJTAG)) {
- rgw_iam_add_existing_objtags(this, store, s, iam_action);
- }
- }
- }
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
perm = verify_object_permission(this, s, iam_action);
} else {
if (!s->bucket_exists) {
return -ERR_NO_SUCH_BUCKET;
}
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
perm = verify_bucket_permission(this, s, rgw::IAM::s3GetBucketAcl);
}
if (!perm)
rgw_add_grant_to_iam_environment(s->env, s);
if (!rgw::sal::Object::empty(s->object.get())) {
auto iam_action = s->object->get_instance().empty() ? rgw::IAM::s3PutObjectAcl : rgw::IAM::s3PutObjectVersionAcl;
- op_ret = rgw_iam_add_existing_objtags(this, store, s, iam_action);
+ op_ret = rgw_iam_add_objtags(this, s, true, true);
perm = verify_object_permission(this, s, iam_action);
} else {
+ op_ret = rgw_iam_add_buckettags(this, s);
perm = verify_bucket_permission(this, s, rgw::IAM::s3PutBucketAcl);
}
if (!perm)
int RGWGetLC::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
bool perm;
perm = verify_bucket_permission(this, s, rgw::IAM::s3GetLifecycleConfiguration);
if (!perm)
int RGWPutLC::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
bool perm;
perm = verify_bucket_permission(this, s, rgw::IAM::s3PutLifecycleConfiguration);
if (!perm)
int RGWDeleteLC::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
bool perm;
perm = verify_bucket_permission(this, s, rgw::IAM::s3PutLifecycleConfiguration);
if (!perm)
int RGWGetCORS::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketCORS);
}
int RGWPutCORS::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketCORS);
}
int RGWDeleteCORS::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
// No separate delete permission
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketCORS);
}
int RGWGetRequestPayment::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketRequestPayment);
}
int RGWSetRequestPayment::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketRequestPayment);
}
int RGWInitMultipart::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (s->iam_policy || ! s->iam_user_policies.empty() || !s->session_policies.empty()) {
auto identity_policy_res = eval_identity_or_session_policies(s->iam_user_policies, s->env,
boost::none,
int RGWCompleteMultipart::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (s->iam_policy || ! s->iam_user_policies.empty() || ! s->session_policies.empty()) {
auto identity_policy_res = eval_identity_or_session_policies(s->iam_user_policies, s->env,
boost::none,
int RGWAbortMultipart::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (s->iam_policy || ! s->iam_user_policies.empty() || !s->session_policies.empty()) {
auto identity_policy_res = eval_identity_or_session_policies(s->iam_user_policies, s->env,
boost::none,
int RGWListMultipart::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (!verify_object_permission(this, s, rgw::IAM::s3ListMultipartUploadParts))
return -EACCES;
int RGWListBucketMultiparts::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this,
s,
rgw::IAM::s3ListBucketMultipartUploads))
return op_ret;
}
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (s->iam_policy || ! s->iam_user_policies.empty() || ! s->session_policies.empty()) {
if (s->bucket->get_info().obj_lock_enabled() && bypass_governance_mode) {
auto r = eval_identity_or_session_policies(s->iam_user_policies, s->env, boost::none,
{
s->object->set_atomic(s->obj_ctx);
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
auto iam_action = s->object->get_instance().empty() ?
rgw::IAM::s3GetObject :
rgw::IAM::s3GetObjectVersion;
int RGWPutBucketPolicy::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketPolicy)) {
return -EACCES;
}
int RGWGetBucketPolicy::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicy)) {
return -EACCES;
}
int RGWDeleteBucketPolicy::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3DeleteBucketPolicy)) {
return -EACCES;
}
int RGWPutBucketObjectLock::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3PutBucketObjectLockConfiguration);
}
int RGWGetBucketObjectLock::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
return verify_bucket_owner_or_policy(s, rgw::IAM::s3GetBucketObjectLockConfiguration);
}
int RGWPutObjRetention::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (!verify_object_permission(this, s, rgw::IAM::s3PutObjectRetention)) {
return -EACCES;
}
int RGWGetObjRetention::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (!verify_object_permission(this, s, rgw::IAM::s3GetObjectRetention)) {
return -EACCES;
}
int RGWPutObjLegalHold::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (!verify_object_permission(this, s, rgw::IAM::s3PutObjectLegalHold)) {
return -EACCES;
}
int RGWGetObjLegalHold::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s);
+ if (has_s3_existing_tag || has_s3_resource_tag)
+ rgw_iam_add_objtags(this, s, has_s3_existing_tag, has_s3_resource_tag);
+
if (!verify_object_permission(this, s, rgw::IAM::s3GetObjectLegalHold)) {
return -EACCES;
}
int RGWGetBucketPolicyStatus::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicyStatus)) {
return -EACCES;
}
int RGWPutBucketPublicAccessBlock::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketPublicAccessBlock)) {
return -EACCES;
}
int RGWGetBucketPublicAccessBlock::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3GetBucketPolicy)) {
return -EACCES;
}
int RGWDeleteBucketPublicAccessBlock::verify_permission(optional_yield y)
{
+ auto [has_s3_existing_tag, has_s3_resource_tag] = rgw_check_policy_condition(this, s, false);
+ if (has_s3_resource_tag)
+ rgw_iam_add_buckettags(this, s);
+
if (!verify_bucket_permission(this, s, rgw::IAM::s3PutBucketPublicAccessBlock)) {
return -EACCES;
}