Related trackers:
- https://tracker.ceph.com/issues/67179
- https://tracker.ceph.com/issues/66867
+* RGW: IAM policy evaluation now supports conditions ArnEquals and ArnLike, along
+ with their Not and IfExists variants.
>=18.2.4
--------
return m;
}
+// Case-sensitive matching of the ARN. Each of the six colon-delimited
+// components of the ARN is checked separately and each can include multi-
+// character match wildcards (*) or single-character match wildcards (?).
+static bool arn_like(const std::string& input, const std::string& pattern)
+{
+ constexpr auto delim = [] (char c) { return c == ':'; };
+ if (std::count_if(input.begin(), input.end(), delim) != 5) {
+ return false;
+ }
+ return match_policy(pattern, input, MATCH_POLICY_ARN);
+}
+
bool Condition::eval(const Environment& env) const {
std::vector<std::string> runtime_vals;
auto i = env.find(key);
return true;
}
-#if 0
- // Amazon Resource Names! (Does S3 need this?)
- TokenID::ArnEquals, TokenID::ArnNotEquals, TokenID::ArnLike,
- TokenID::ArnNotLike,
-#endif
+ // Amazon Resource Names!
+ // The ArnEquals and ArnLike condition operators behave identically.
+ case TokenID::ArnEquals:
+ case TokenID::ArnLike:
+ return orrible(arn_like, itr, isruntime? runtime_vals : vals);
+ case TokenID::ArnNotEquals:
+ case TokenID::ArnNotLike:
+ return orrible(std::not_fn(arn_like), itr, isruntime? runtime_vals : vals);
default:
return false;
using rgw::IAM::Environment;
using rgw::Partition;
using rgw::IAM::Policy;
+using rgw::IAM::Condition;
using rgw::IAM::s3All;
using rgw::IAM::s3Count;
using rgw::IAM::s3GetAccelerateConfiguration;
EXPECT_EQ(stsAllValue, set_range_bits(iamAll+1, stsAll));
EXPECT_EQ(allValue , set_range_bits(0, allCount));
}
+
+TEST(Condition, ArnLike)
+{
+ const std::string key = "aws:SourceArn";
+ {
+ Condition ArnLike{TokenID::ArnLike, key.data(), key.size(), false};
+ ArnLike.vals.push_back("arn:aws:s3:::bucket");
+
+ EXPECT_FALSE(ArnLike.eval({}));
+ EXPECT_TRUE(ArnLike.eval({{key, "arn:aws:s3:::bucket"}}));
+ EXPECT_FALSE(ArnLike.eval({{key, "arn:aws:s3:::BUCKET"}}));
+ EXPECT_FALSE(ArnLike.eval({{key, "arn:aws:s3:::user"}}));
+ }
+ {
+ Condition ArnLike{TokenID::ArnLike, key.data(), key.size(), false};
+ ArnLike.vals.push_back("arn:aws:s3:::b*");
+
+ EXPECT_FALSE(ArnLike.eval({}));
+ EXPECT_TRUE(ArnLike.eval({{key, "arn:aws:s3:::b"}}));
+ EXPECT_TRUE(ArnLike.eval({{key, "arn:aws:s3:::bucket"}}));
+ EXPECT_FALSE(ArnLike.eval({{key, "arn:aws:s3:::BUCKET"}}));
+ EXPECT_FALSE(ArnLike.eval({{key, "arn:aws:s3:::user"}}));
+ }
+}