From: Pritha Srivastava Date: Thu, 8 Apr 2021 09:04:23 +0000 (+0530) Subject: rgw/sts: code for aws:TagKeys to be used as Condition X-Git-Tag: v17.1.0~969^2~11 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=ba19b3a03b9db690bd1423ffa3c0d80b8d38a00d;p=ceph-ci.git rgw/sts: code for aws:TagKeys to be used as Condition element of a role's trust and permission policy. This also includes implementation of ForAnyValue and ForAllValues to be used in conjunction with StringLike, StringEquals and StringEqualsIgnoreCase which are used alongwith aws:TagKeys. Signed-off-by: Pritha Srivastava --- diff --git a/src/rgw/rgw_auth.cc b/src/rgw/rgw_auth.cc index af23c23d71c..ea4f9ffd2e7 100644 --- a/src/rgw/rgw_auth.cc +++ b/src/rgw/rgw_auth.cc @@ -473,6 +473,9 @@ void rgw::auth::WebIdentityApplier::modify_request_state(const DoutPrefixProvide s->env.emplace(e_key, val); ldpp_dout(dpp, 10) << "RGW Env Tag Key: " << e_key << " Value: " << val << dendl; + s->env.emplace("aws:TagKeys", key); + ldpp_dout(dpp, 10) << "aws:TagKeys: " << key << dendl; + if (s->principal_tags.size() == 50) { ldpp_dout(dpp, 0) << "ERROR: Number of tag/value pairs exceeding 50, hence skipping the rest" << dendl; break; @@ -867,6 +870,11 @@ void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp, for (auto& m : token_attrs.principal_tags) { s->env.emplace(m.first, m.second); + ldpp_dout(dpp, 10) << "Principal Tag Key: " << m.first << " Value: " << m.second << dendl; + std::size_t pos = m.first.find('/'); + string key = m.first.substr(pos + 1); + s->env.emplace("aws:TagKeys", key); + ldpp_dout(dpp, 10) << "aws:TagKeys: " << key << dendl; } s->token_claims.emplace_back("sts"); diff --git a/src/rgw/rgw_iam_policy.cc b/src/rgw/rgw_iam_policy.cc index f91a349aee7..8fe9d3a64cc 100644 --- a/src/rgw/rgw_iam_policy.cc +++ b/src/rgw/rgw_iam_policy.cc @@ -682,7 +682,13 @@ bool Condition::eval(const Environment& env) const { } if (i == env.end()) { - return ifexists; + if (op == TokenID::ForAllValuesStringEquals || + op == TokenID::ForAllValuesStringEqualsIgnoreCase || + op == TokenID::ForAllValuesStringLike) { + return true; + } else { + return ifexists; + } } const auto& s = i->second; @@ -690,6 +696,7 @@ bool Condition::eval(const Environment& env) const { switch (op) { // String! + case TokenID::ForAnyValueStringEquals: case TokenID::StringEquals: return orrible(std::equal_to(), itr, vals); @@ -697,18 +704,29 @@ bool Condition::eval(const Environment& env) const { return orrible(std::not_fn(std::equal_to()), itr, vals); + case TokenID::ForAnyValueStringEqualsIgnoreCase: case TokenID::StringEqualsIgnoreCase: return orrible(ci_equal_to(), itr, vals); case TokenID::StringNotEqualsIgnoreCase: return orrible(std::not_fn(ci_equal_to()), itr, vals); + case TokenID::ForAnyValueStringLike: case TokenID::StringLike: return orrible(string_like(), itr, vals); case TokenID::StringNotLike: return orrible(std::not_fn(string_like()), itr, vals); + case TokenID::ForAllValuesStringEquals: + return andible(std::equal_to(), itr, vals); + + case TokenID::ForAllValuesStringLike: + return andible(string_like(), itr, vals); + + case TokenID::ForAllValuesStringEqualsIgnoreCase: + return andible(ci_equal_to(), itr, vals); + // Numeric case TokenID::NumericEquals: return shortible(std::equal_to(), as_number, s, vals); diff --git a/src/rgw/rgw_iam_policy.h b/src/rgw/rgw_iam_policy.h index 84dce04cf24..4a0f8f3b30f 100644 --- a/src/rgw/rgw_iam_policy.h +++ b/src/rgw/rgw_iam_policy.h @@ -391,6 +391,23 @@ struct Condition { }; using unordered_multimap_it_pair = std::pair ::const_iterator, std::unordered_multimap::const_iterator>; + + template + static bool andible(F&& f, const unordered_multimap_it_pair& it, + const std::vector& v) { + for (auto itr = it.first; itr != it.second; itr++) { + bool matched = false; + for (const auto& d : v) { + if (std::forward(f)(itr->second, d)) { + matched = true; + } + } + if (!matched) + return false; + } + return true; + } + template static bool orrible(F&& f, const unordered_multimap_it_pair& it, const std::vector& v) { diff --git a/src/rgw/rgw_iam_policy_keywords.gperf b/src/rgw/rgw_iam_policy_keywords.gperf index 4f6f22a9b73..af73dd13074 100644 --- a/src/rgw/rgw_iam_policy_keywords.gperf +++ b/src/rgw/rgw_iam_policy_keywords.gperf @@ -41,6 +41,12 @@ StringEqualsIgnoreCase, TokenKind::cond_op, TokenID::StringEqualsIgnoreCase, (ui StringNotEqualsIgnoreCase, TokenKind::cond_op, TokenID::StringNotEqualsIgnoreCase, (uint64_t) Type::string, true, true StringLike, TokenKind::cond_op, TokenID::StringLike, (uint64_t) Type::string, true, true, StringNotLike, TokenKind::cond_op, TokenID::StringNotLike, (uint64_t) Type::string, true, true +ForAllValues:StringEquals, TokenKind::cond_op, TokenID::ForAllValuesStringEquals, (uint64_t) Type::string, true, true +ForAnyValue:StringEquals, TokenKind::cond_op, TokenID::ForAnyValueStringEquals, (uint64_t) Type::string, true, true +ForAllValues:StringLike, TokenKind::cond_op, TokenID::ForAllValuesStringLike, (uint64_t) Type::string, true, true +ForAnyValue:StringLike, TokenKind::cond_op, TokenID::ForAnyValueStringLike, (uint64_t) Type::string, true, true +ForAllValues:StringEqualsIgnoreCase, TokenKind::cond_op, TokenID::ForAllValuesStringEqualsIgnoreCase, (uint64_t) Type::string, true, true +ForAnyValue:StringEqualsIgnoreCase, TokenKind::cond_op, TokenID::ForAnyValueStringEqualsIgnoreCase, (uint64_t) Type::string, true, true # Numeric NumericEquals, TokenKind::cond_op, TokenID::NumericEquals, (uint64_t) Type::number, true, true NumericNotEquals, TokenKind::cond_op, TokenID::NumericNotEquals, (uint64_t) Type::number, true, true diff --git a/src/rgw/rgw_iam_policy_keywords.h b/src/rgw/rgw_iam_policy_keywords.h index 584a2580b6d..1c94dfe1710 100644 --- a/src/rgw/rgw_iam_policy_keywords.h +++ b/src/rgw/rgw_iam_policy_keywords.h @@ -29,6 +29,9 @@ enum class TokenID { // String! StringEquals, StringNotEquals, StringEqualsIgnoreCase, StringNotEqualsIgnoreCase, StringLike, StringNotLike, + ForAllValuesStringEquals, ForAnyValueStringEquals, + ForAllValuesStringLike, ForAnyValueStringLike, + ForAllValuesStringEqualsIgnoreCase, ForAnyValueStringEqualsIgnoreCase, // Numeric! NumericEquals, NumericNotEquals, NumericLessThan, NumericLessThanEquals,