Skip to content

Commit

Permalink
rgw/sts: code for runtime evaluation of Condition
Browse files Browse the repository at this point in the history
element of an IAM policy.

Signed-off-by: Pritha Srivastava <[email protected]>
  • Loading branch information
pritha-srivastava committed Sep 1, 2021
1 parent ba19b3a commit 5d85c65
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
40 changes: 31 additions & 9 deletions src/rgw/rgw_iam_policy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,17 @@ bool ParseState::do_string(CephContext* cct, const char* s, size_t l) {
<< dendl;
} else if (w->kind == TokenKind::cond_key) {
auto& t = pp->policy.statements.back();
if (l > 0 && *s == '$') {
if (l >= 2 && *(s+1) == '{') {
if (l > 0 && *(s+l-1) == '}') {
t.conditions.back().isruntime = true;
} else {
return false;
}
} else {
return false;
}
}
t.conditions.back().vals.emplace_back(s, l);

// Principals
Expand Down Expand Up @@ -676,6 +687,7 @@ ostream& operator <<(ostream& m, const MaskedIP& ip) {
}

bool Condition::eval(const Environment& env) const {
std::vector<std::string> runtime_vals;
auto i = env.find(key);
if (op == TokenID::Null) {
return i == env.end() ? true : false;
Expand All @@ -690,6 +702,16 @@ bool Condition::eval(const Environment& env) const {
return ifexists;
}
}

if (isruntime) {
string k = vals.back();
k.erase(0,2); //erase $, {
k.erase(k.length() - 1, 1); //erase }
const auto& it = env.equal_range(k);
for (auto itr = it.first; itr != it.second; itr++) {
runtime_vals.emplace_back(itr->second);
}
}
const auto& s = i->second;

const auto& itr = env.equal_range(key);
Expand All @@ -698,34 +720,34 @@ bool Condition::eval(const Environment& env) const {
// String!
case TokenID::ForAnyValueStringEquals:
case TokenID::StringEquals:
return orrible(std::equal_to<std::string>(), itr, vals);
return orrible(std::equal_to<std::string>(), itr, isruntime? runtime_vals : vals);

case TokenID::StringNotEquals:
return orrible(std::not_fn(std::equal_to<std::string>()),
itr, vals);
itr, isruntime? runtime_vals : vals);

case TokenID::ForAnyValueStringEqualsIgnoreCase:
case TokenID::StringEqualsIgnoreCase:
return orrible(ci_equal_to(), itr, vals);
return orrible(ci_equal_to(), itr, isruntime? runtime_vals : vals);

case TokenID::StringNotEqualsIgnoreCase:
return orrible(std::not_fn(ci_equal_to()), itr, vals);
return orrible(std::not_fn(ci_equal_to()), itr, isruntime? runtime_vals : vals);

case TokenID::ForAnyValueStringLike:
case TokenID::StringLike:
return orrible(string_like(), itr, vals);
return orrible(string_like(), itr, isruntime? runtime_vals : vals);

case TokenID::StringNotLike:
return orrible(std::not_fn(string_like()), itr, vals);
return orrible(std::not_fn(string_like()), itr, isruntime? runtime_vals : vals);

case TokenID::ForAllValuesStringEquals:
return andible(std::equal_to<std::string>(), itr, vals);
return andible(std::equal_to<std::string>(), itr, isruntime? runtime_vals : vals);

case TokenID::ForAllValuesStringLike:
return andible(string_like(), itr, vals);
return andible(string_like(), itr, isruntime? runtime_vals : vals);

case TokenID::ForAllValuesStringEqualsIgnoreCase:
return andible(ci_equal_to(), itr, vals);
return andible(ci_equal_to(), itr, isruntime? runtime_vals : vals);

// Numeric
case TokenID::NumericEquals:
Expand Down
1 change: 1 addition & 0 deletions src/rgw/rgw_iam_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ struct Condition {
// In future development, use symbol internment.
std::string key;
bool ifexists = false;
bool isruntime = false; //Is evaluated during run-time
// Much to my annoyance there is no actual way to do this in a
// typed way that is compatible with AWS. I know this because I've
// seen examples where the same value is used as a string in one
Expand Down

0 comments on commit 5d85c65

Please sign in to comment.