Skip to content

Commit 3320016

Browse files
authored
Merge pull request ceph#65606 from VVoidV/fix-stringnotequals-logic
rgw/iam: fix NotEquals handling for multiple values
2 parents 8996723 + c8372be commit 3320016

File tree

3 files changed

+268
-54
lines changed

3 files changed

+268
-54
lines changed

src/rgw/rgw_iam_policy.cc

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -905,120 +905,104 @@ bool Condition::eval(const Environment& env) const {
905905
// String!
906906
case TokenID::ForAnyValueStringEquals:
907907
case TokenID::StringEquals:
908-
return orrible(std::equal_to<std::string>(), itr, isruntime? runtime_vals : vals);
908+
return multimap_any(std::equal_to<std::string>(), itr, isruntime? runtime_vals : vals);
909909

910910
case TokenID::StringNotEquals:
911-
return orrible(std::not_fn(std::equal_to<std::string>()),
912-
itr, isruntime? runtime_vals : vals);
911+
return multimap_none(std::equal_to<std::string>(),
912+
itr, isruntime? runtime_vals : vals);
913913

914914
case TokenID::ForAnyValueStringEqualsIgnoreCase:
915915
case TokenID::StringEqualsIgnoreCase:
916-
return orrible(ci_equal_to(), itr, isruntime? runtime_vals : vals);
916+
return multimap_any(ci_equal_to(), itr, isruntime? runtime_vals : vals);
917917

918918
case TokenID::StringNotEqualsIgnoreCase:
919-
return orrible(std::not_fn(ci_equal_to()), itr, isruntime? runtime_vals : vals);
919+
return multimap_none(ci_equal_to(), itr, isruntime? runtime_vals : vals);
920920

921921
case TokenID::ForAnyValueStringLike:
922922
case TokenID::StringLike:
923-
return orrible(string_like(), itr, isruntime? runtime_vals : vals);
923+
return multimap_any(string_like(), itr, isruntime? runtime_vals : vals);
924924

925925
case TokenID::StringNotLike:
926-
return orrible(std::not_fn(string_like()), itr, isruntime? runtime_vals : vals);
926+
return multimap_none(string_like(), itr, isruntime? runtime_vals : vals);
927927

928928
case TokenID::ForAllValuesStringEquals:
929-
return andible(std::equal_to<std::string>(), itr, isruntime? runtime_vals : vals);
929+
return multimap_all(std::equal_to<std::string>(), itr, isruntime? runtime_vals : vals);
930930

931931
case TokenID::ForAllValuesStringLike:
932-
return andible(string_like(), itr, isruntime? runtime_vals : vals);
932+
return multimap_all(string_like(), itr, isruntime? runtime_vals : vals);
933933

934934
case TokenID::ForAllValuesStringEqualsIgnoreCase:
935-
return andible(ci_equal_to(), itr, isruntime? runtime_vals : vals);
935+
return multimap_all(ci_equal_to(), itr, isruntime? runtime_vals : vals);
936936

937937
// Numeric
938938
case TokenID::NumericEquals:
939-
return shortible(std::equal_to<double>(), as_number, s, vals);
939+
return typed_any(std::equal_to<double>(), as_number, s, vals);
940940

941941
case TokenID::NumericNotEquals:
942-
return shortible(std::not_fn(std::equal_to<double>()),
943-
as_number, s, vals);
942+
return typed_none(std::equal_to<double>(),
943+
as_number, s, vals);
944944

945945

946946
case TokenID::NumericLessThan:
947-
return shortible(std::less<double>(), as_number, s, vals);
947+
return typed_any(std::less<double>(), as_number, s, vals);
948948

949949

950950
case TokenID::NumericLessThanEquals:
951-
return shortible(std::less_equal<double>(), as_number, s, vals);
951+
return typed_any(std::less_equal<double>(), as_number, s, vals);
952952

953953
case TokenID::NumericGreaterThan:
954-
return shortible(std::greater<double>(), as_number, s, vals);
954+
return typed_any(std::greater<double>(), as_number, s, vals);
955955

956956
case TokenID::NumericGreaterThanEquals:
957-
return shortible(std::greater_equal<double>(), as_number, s, vals);
957+
return typed_any(std::greater_equal<double>(), as_number, s,
958+
vals);
958959

959960
// Date!
960961
case TokenID::DateEquals:
961-
return shortible(std::equal_to<ceph::real_time>(), as_date, s, vals);
962+
return typed_any(std::equal_to<ceph::real_time>(), as_date, s, vals);
962963

963964
case TokenID::DateNotEquals:
964-
return shortible(std::not_fn(std::equal_to<ceph::real_time>()),
965-
as_date, s, vals);
966-
965+
return typed_none(std::equal_to<ceph::real_time>(),
966+
as_date, s, vals);
967967
case TokenID::DateLessThan:
968-
return shortible(std::less<ceph::real_time>(), as_date, s, vals);
968+
return typed_any(std::less<ceph::real_time>(), as_date, s, vals);
969969

970970

971971
case TokenID::DateLessThanEquals:
972-
return shortible(std::less_equal<ceph::real_time>(), as_date, s, vals);
972+
return typed_any(std::less_equal<ceph::real_time>(), as_date, s, vals);
973973

974974
case TokenID::DateGreaterThan:
975-
return shortible(std::greater<ceph::real_time>(), as_date, s, vals);
975+
return typed_any(std::greater<ceph::real_time>(), as_date, s, vals);
976976

977977
case TokenID::DateGreaterThanEquals:
978-
return shortible(std::greater_equal<ceph::real_time>(), as_date, s,
978+
return typed_any(std::greater_equal<ceph::real_time>(), as_date, s,
979979
vals);
980980

981981
// Bool!
982982
case TokenID::Bool:
983-
return shortible(std::equal_to<bool>(), as_bool, s, vals);
983+
return typed_any(std::equal_to<bool>(), as_bool, s, vals);
984984

985985
// Binary!
986986
case TokenID::BinaryEquals:
987-
return shortible(std::equal_to<ceph::bufferlist>(), as_binary, s,
987+
return typed_any(std::equal_to<ceph::bufferlist>(), as_binary, s,
988988
vals);
989989

990990
// IP Address!
991991
case TokenID::IpAddress:
992-
return shortible(std::equal_to<MaskedIP>(), as_network, s, vals);
992+
return typed_any(std::equal_to<MaskedIP>(), as_network, s, vals);
993993

994994
case TokenID::NotIpAddress:
995-
{
996-
auto xc = as_network(s);
997-
if (!xc) {
998-
return false;
999-
}
1000-
1001-
for (const string& d : vals) {
1002-
auto xd = as_network(d);
1003-
if (!xd) {
1004-
continue;
1005-
}
1006-
1007-
if (xc == xd) {
1008-
return false;
1009-
}
1010-
}
1011-
return true;
1012-
}
995+
return typed_none(std::equal_to<MaskedIP>(),
996+
as_network, s, vals);
1013997

1014998
// Amazon Resource Names!
1015999
// The ArnEquals and ArnLike condition operators behave identically.
10161000
case TokenID::ArnEquals:
10171001
case TokenID::ArnLike:
1018-
return orrible(arn_like, itr, isruntime? runtime_vals : vals);
1002+
return multimap_any(arn_like, itr, isruntime? runtime_vals : vals);
10191003
case TokenID::ArnNotEquals:
10201004
case TokenID::ArnNotLike:
1021-
return orrible(std::not_fn(arn_like), itr, isruntime? runtime_vals : vals);
1005+
return multimap_none(arn_like, itr, isruntime? runtime_vals : vals);
10221006

10231007
default:
10241008
return false;

src/rgw/rgw_iam_policy.h

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,8 @@ struct Condition {
486486
using unordered_multimap_it_pair = std::pair <std::unordered_multimap<std::string,std::string>::const_iterator, std::unordered_multimap<std::string,std::string>::const_iterator>;
487487

488488
template<typename F>
489-
static bool andible(F&& f, const unordered_multimap_it_pair& it,
490-
const std::vector<std::string>& v) {
489+
static bool multimap_all(F&& f, const unordered_multimap_it_pair& it,
490+
const std::vector<std::string>& v) {
491491
for (auto itr = it.first; itr != it.second; itr++) {
492492
bool matched = false;
493493
for (const auto& d : v) {
@@ -502,8 +502,8 @@ struct Condition {
502502
}
503503

504504
template<typename F>
505-
static bool orrible(F&& f, const unordered_multimap_it_pair& it,
506-
const std::vector<std::string>& v) {
505+
static bool multimap_any(F&& f, const unordered_multimap_it_pair& it,
506+
const std::vector<std::string>& v) {
507507
for (auto itr = it.first; itr != it.second; itr++) {
508508
for (const auto& d : v) {
509509
if (f(itr->second, d)) {
@@ -514,9 +514,22 @@ struct Condition {
514514
return false;
515515
}
516516

517+
template<typename F>
518+
static bool multimap_none(F&& f, const unordered_multimap_it_pair& it,
519+
const std::vector<std::string>& v) {
520+
for (auto itr = it.first; itr != it.second; itr++) {
521+
for (const auto& d : v) {
522+
if (f(itr->second, d)) {
523+
return false;
524+
}
525+
}
526+
}
527+
return true;
528+
}
529+
517530
template<typename F, typename X>
518-
static bool shortible(F&& f, X& x, const std::string& c,
519-
const std::vector<std::string>& v) {
531+
static bool typed_any(F&& f, X& x, const std::string& c,
532+
const std::vector<std::string>& v) {
520533
auto xc = std::forward<X>(x)(c);
521534
if (!xc) {
522535
return false;
@@ -535,6 +548,27 @@ struct Condition {
535548
return false;
536549
}
537550

551+
template<typename F, typename X>
552+
static bool typed_none(F&& f, X& x, const std::string& c,
553+
const std::vector<std::string>& v) {
554+
auto xc = std::forward<X>(x)(c);
555+
if (!xc) {
556+
return false;
557+
}
558+
559+
for (const auto& d : v) {
560+
auto xd = x(d);
561+
if (!xd) {
562+
continue;
563+
}
564+
565+
if (f(*xc, *xd)) {
566+
return false;
567+
}
568+
}
569+
return true;
570+
}
571+
538572
template <typename F>
539573
bool has_key_p(const std::string& _key, F p) const {
540574
return p(key, _key);

0 commit comments

Comments
 (0)