From: Pritha Srivastava Date: Tue, 27 Oct 2020 17:12:52 +0000 (+0530) Subject: rgw/sts: fix for copy object operation using sts X-Git-Tag: v17.1.0~1524^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F37866%2Fhead;p=ceph.git rgw/sts: fix for copy object operation using sts temporary credentials Fixes: https://tracker.ceph.com/issues/47809 Signed-off-by: Pritha Srivastava --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index ecd4fdab62ac..e4ac84cb3330 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -5021,15 +5021,57 @@ int RGWCopyObj::verify_permission(optional_yield y) /* admin request overrides permission checks */ if (!s->auth.identity->is_admin_of(src_acl.get_owner().get_id())) { - if (src_policy) { - auto e = src_policy->eval(s->env, *s->auth.identity, - src_object->get_instance().empty() ? - rgw::IAM::s3GetObject : - rgw::IAM::s3GetObjectVersion, - ARN(src_object->get_obj())); + if (src_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, + src_object->get_instance().empty() ? + rgw::IAM::s3GetObject : + rgw::IAM::s3GetObjectVersion, + ARN(src_object->get_obj())); + if (identity_policy_res == Effect::Deny) { + return -EACCES; + } + auto e = Effect::Pass; + rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other; + if (src_policy) { + e = src_policy->eval(s->env, *s->auth.identity, + src_object->get_instance().empty() ? + rgw::IAM::s3GetObject : + rgw::IAM::s3GetObjectVersion, + ARN(src_object->get_obj()), + princ_type); + } if (e == Effect::Deny) { return -EACCES; - } else if (e == Effect::Pass && + } + if (!s->session_policies.empty()) { + auto session_policy_res = eval_identity_or_session_policies(s->session_policies, s->env, + boost::none, + src_object->get_instance().empty() ? + rgw::IAM::s3GetObject : + rgw::IAM::s3GetObjectVersion, + ARN(src_object->get_obj())); + if (session_policy_res == Effect::Deny) { + return -EACCES; + } + if (princ_type == rgw::IAM::PolicyPrincipal::Role) { + //Intersection of session policy and identity policy plus intersection of session policy and bucket policy + if ((session_policy_res != Effect::Allow || identity_policy_res != Effect::Allow) && + (session_policy_res != Effect::Allow || e != Effect::Allow)) { + return -EACCES; + } + } else if (princ_type == rgw::IAM::PolicyPrincipal::Session) { + //Intersection of session policy and identity policy plus bucket policy + if ((session_policy_res != Effect::Allow || identity_policy_res != Effect::Allow) && e != Effect::Allow) { + return -EACCES; + } + } else if (princ_type == rgw::IAM::PolicyPrincipal::Other) {// there was no match in the bucket policy + if (session_policy_res != Effect::Allow || identity_policy_res != Effect::Allow) { + return -EACCES; + } + } + } + if (identity_policy_res == Effect::Pass && e == Effect::Pass && !src_acl.verify_permission(this, *s->auth.identity, s->perm_mask, RGW_PERM_READ)) { return -EACCES; @@ -5051,6 +5093,7 @@ int RGWCopyObj::verify_permission(optional_yield y) op_ret = store->get_bucket(this, s->user.get(), dest_tenant_name, dest_bucket_name, &dest_bucket, y); if (op_ret < 0) { if (op_ret == -ENOENT) { + ldpp_dout(this, 0) << "ERROR: Destination Bucket not found for user: " << s->user->get_id().to_str() << dendl; op_ret = -ERR_NO_SUCH_BUCKET; } return op_ret; @@ -5071,18 +5114,53 @@ int RGWCopyObj::verify_permission(optional_yield y) auto dest_iam_policy = get_iam_policy_from_attr(s->cct, dest_bucket->get_attrs(), dest_bucket->get_tenant()); /* admin request overrides permission checks */ if (! s->auth.identity->is_admin_of(dest_policy.get_owner().get_id())){ - if (dest_iam_policy != boost::none) { + if (dest_iam_policy != boost::none || ! s->iam_user_policies.empty() || !s->session_policies.empty()) { 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", *md_directive); - auto e = dest_iam_policy->eval(s->env, *s->auth.identity, - rgw::IAM::s3PutObject, - ARN(dest_object->get_obj())); + auto identity_policy_res = eval_identity_or_session_policies(s->iam_user_policies, + s->env, boost::none, + rgw::IAM::s3PutObject, + ARN(dest_object->get_obj())); + if (identity_policy_res == Effect::Deny) { + return -EACCES; + } + auto e = Effect::Pass; + rgw::IAM::PolicyPrincipal princ_type = rgw::IAM::PolicyPrincipal::Other; + if (dest_iam_policy) { + e = dest_iam_policy->eval(s->env, *s->auth.identity, + rgw::IAM::s3PutObject, + ARN(dest_object->get_obj()), + princ_type); + } if (e == Effect::Deny) { return -EACCES; - } else if (e == Effect::Pass && + } + if (!s->session_policies.empty()) { + auto session_policy_res = eval_identity_or_session_policies(s->session_policies, s->env, boost::none, rgw::IAM::s3PutObject, ARN(dest_object->get_obj())); + if (session_policy_res == Effect::Deny) { + return false; + } + if (princ_type == rgw::IAM::PolicyPrincipal::Role) { + //Intersection of session policy and identity policy plus intersection of session policy and bucket policy + if ((session_policy_res != Effect::Allow || identity_policy_res != Effect::Allow) && + (session_policy_res != Effect::Allow || e == Effect::Allow)) { + return -EACCES; + } + } else if (princ_type == rgw::IAM::PolicyPrincipal::Session) { + //Intersection of session policy and identity policy plus bucket policy + if ((session_policy_res != Effect::Allow || identity_policy_res != Effect::Allow) && e != Effect::Allow) { + return -EACCES; + } + } else if (princ_type == rgw::IAM::PolicyPrincipal::Other) {// there was no match in the bucket policy + if (session_policy_res != Effect::Allow || identity_policy_res != Effect::Allow) { + return -EACCES; + } + } + } + if (identity_policy_res == Effect::Pass && e == Effect::Pass && ! dest_bucket_policy.verify_permission(this, *s->auth.identity, s->perm_mask, diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 46d237eb9d65..1cb54e68654b 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -4670,7 +4670,13 @@ int RGWHandler_REST_S3::postauth_init(optional_yield y) } if (!t->src_bucket.empty()) { - rgw_parse_url_bucket(t->src_bucket, s->user->get_tenant(), + string auth_tenant; + if (s->auth.identity->get_identity_type() == TYPE_ROLE) { + auth_tenant = s->auth.identity->get_role_tenant(); + } else { + auth_tenant = s->user->get_tenant(); + } + rgw_parse_url_bucket(t->src_bucket, auth_tenant, s->src_tenant_name, s->src_bucket_name); ret = rgw_validate_tenant_name(s->src_tenant_name); if (ret)