From 6cb1cc8a8679a6961cf231be2ed355abeb7c7c48 Mon Sep 17 00:00:00 2001 From: Abhishek Lekshmanan Date: Mon, 31 Jul 2017 15:00:51 +0200 Subject: [PATCH] rgw: add s3 conditions for PutObject IAM policies Adding the following s3 conditions for PutObject operation s3:x-amz-canned-acl (caveat: only strings are supported, we don't support a list of canned acls yet) s3:x-amz-copy-source s3:x-amz-server-side-encryption s3:x-amz-server-side-encryption-aws-kms-key-id s3:RequestObjectTag/ A still TODO is to tackle is s3:RequestObjectTagKeys which supports a list as an argument and s3:x-amz-grant- (which should be easier to support) Signed-off-by: Abhishek Lekshmanan --- src/rgw/rgw_iam_policy_keywords.gperf | 1 + src/rgw/rgw_iam_policy_keywords.h | 1 + src/rgw/rgw_op.cc | 44 ++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/rgw/rgw_iam_policy_keywords.gperf b/src/rgw/rgw_iam_policy_keywords.gperf index 57a732c02fb3..cc84fb72c233 100644 --- a/src/rgw/rgw_iam_policy_keywords.gperf +++ b/src/rgw/rgw_iam_policy_keywords.gperf @@ -109,6 +109,7 @@ Null, TokenKind::cond_op, TokenID::Null, (uint64_t) Type::null, true, true #s3:authType, TokenKind::cond_key, TokenID::s3authType, (uint64_t) Type::string, true, false #s3:signatureAge, TokenKind::cond_key, TokenID::s3signatureAge, (uint64_t) Type::number, true, false #s3:x-amz-content-sha256, TokenKind::cond_key, TokenID::s3x_amz_content_sha256, (uint64_t) Type::string, true, false +#s3:RequestObjectTag, TokenKind::cond_key, TokenID::s3RequestObjectTag, (uint64_t) Type::string, true, false # # Version Keywords # diff --git a/src/rgw/rgw_iam_policy_keywords.h b/src/rgw/rgw_iam_policy_keywords.h index a0cd34b6286e..9ce06de54096 100644 --- a/src/rgw/rgw_iam_policy_keywords.h +++ b/src/rgw/rgw_iam_policy_keywords.h @@ -87,6 +87,7 @@ enum class TokenID { s3authType, s3signatureAge, s3x_amz_content_sha256, + s3RequestObjectTag, #else CondKey, #endif diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 1710bdfd54cf..9bfe60c323e6 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -562,6 +562,12 @@ int rgw_build_object_policies(RGWRados *store, struct req_state *s, return ret; } +void rgw_add_to_iam_environment(rgw::IAM::Environment& e, const std::string& key, const std::string& val){ + e.emplace(std::piecewise_construct, + std::forward_as_tuple(key), + std::forward_as_tuple(val)); +} + rgw::IAM::Environment rgw_build_iam_environment(RGWRados* store, struct req_state* s) { @@ -2950,6 +2956,7 @@ int RGWPutObj::verify_permission() return -EACCES; } + rgw_add_to_iam_environment(s->env, "s3:x-amz-copy-source", copy_source); /* admin request overrides permission checks */ if (! s->auth.identity->is_admin_of(cs_acl.get_owner().get_id())) { if (policy) { @@ -2972,7 +2979,39 @@ int RGWPutObj::verify_permission() } } + + auto op_ret = get_params(); + if (op_ret < 0) { + ldout(s->cct, 20) << "get_params() returned ret=" << op_ret << dendl; + return op_ret; + } + if (s->iam_policy) { + if (!s->canned_acl.empty()){ + rgw_add_to_iam_environment(s->env, "s3:x-amz-acl", s->canned_acl); + } + + if (obj_tags != nullptr && obj_tags->count() > 0){ + auto tags = obj_tags->get_tags(); + for (const auto& kv: tags){ + rgw_add_to_iam_environment(s->env, "s3:RequestObjectTag/"+kv.first, kv.second); + } + } + + constexpr auto encrypt_attr = "x-amz-server-side-encryption"; + constexpr auto s3_encrypt_attr = "s3:x-amz-server-side-encryption"; + auto enc_header = s->info.x_meta_map.find(encrypt_attr); + if (enc_header != s->info.x_meta_map.end()){ + rgw_add_to_iam_environment(s->env, s3_encrypt_attr, enc_header->second); + } + + constexpr auto kms_attr = "x-amz-server-side-encryption-aws-kms-key-id"; + constexpr auto s3_kms_attr = "s3:x-amz-server-side-encryption-aws-kms-key-id"; + auto kms_header = s->info.x_meta_map.find(kms_attr); + if (kms_header != s->info.x_meta_map.end()){ + rgw_add_to_iam_environment(s->env, s3_kms_attr, kms_header->second); + } + auto e = s->iam_policy->eval(s->env, *s->auth.identity, rgw::IAM::s3PutObject, rgw_obj(s->bucket, s->object)); @@ -3306,11 +3345,6 @@ void RGWPutObj::execute() return; } - op_ret = get_params(); - if (op_ret < 0) { - ldout(s->cct, 20) << "get_params() returned ret=" << op_ret << dendl; - goto done; - } op_ret = get_system_versioning_params(s, &olh_epoch, &version_id); if (op_ret < 0) { -- 2.47.3