From: Casey Bodley Date: Thu, 20 Jul 2017 20:06:27 +0000 (-0400) Subject: rgw: policy can parse IfExists conditions X-Git-Tag: v12.1.2~74^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2bb7408b60cffe0e9a0886cd2f344223e75e5c9d;p=ceph.git rgw: policy can parse IfExists conditions when ParseState::key() encounters a condition statement ending with IfExists, it looks up the token by its prefix only because this prefix is not null-terminated, the gperf-generated comparison has to be modified to use strncmp() instead of strcmp() by adding the %compare-strncmp flag to the gperf file Signed-off-by: Casey Bodley --- diff --git a/src/rgw/rgw_iam_policy.cc b/src/rgw/rgw_iam_policy.cc index 22a4bbbf542..f90bfac7883 100644 --- a/src/rgw/rgw_iam_policy.cc +++ b/src/rgw/rgw_iam_policy.cc @@ -473,6 +473,7 @@ struct ParseState { bool arraying = false; bool objecting = false; + bool cond_ifexists = false; void reset(); @@ -645,13 +646,22 @@ bool ParseState::obj_end() { } bool ParseState::key(const char* s, size_t l) { - auto k = pp->tokens.lookup(s, l); + auto token_len = l; + bool ifexists = false; + if (w->id == TokenID::Condition && w->kind == TokenKind::statement) { + static constexpr char IfExists[] = "IfExists"; + if (boost::algorithm::ends_with(boost::string_view{s, l}, IfExists)) { + ifexists = true; + token_len -= sizeof(IfExists)-1; + } + } + auto k = pp->tokens.lookup(s, token_len); if (!k) { if (w->kind == TokenKind::cond_op) { auto& t = pp->policy.statements.back(); pp->s.emplace_back(pp, cond_key); - t.conditions.emplace_back(w->id, s, l); + t.conditions.emplace_back(w->id, s, l, cond_ifexists); return true; } else { return false; @@ -680,6 +690,7 @@ bool ParseState::key(const char* s, size_t l) { } else if ((w->id == TokenID::Condition) && (k->kind == TokenKind::cond_op)) { pp->s.emplace_back(pp, k); + pp->s.back().cond_ifexists = ifexists; return true; } return false; diff --git a/src/rgw/rgw_iam_policy.h b/src/rgw/rgw_iam_policy.h index 674d7be0889..55f420f0ae7 100644 --- a/src/rgw/rgw_iam_policy.h +++ b/src/rgw/rgw_iam_policy.h @@ -26,6 +26,7 @@ #include "fnmatch.h" +#include "rgw_acl.h" #include "rgw_basic_types.h" #include "rgw_iam_policy_keywords.h" @@ -273,18 +274,8 @@ struct Condition { std::vector vals; Condition() = default; - Condition(TokenID op, const char* s, std::size_t len) : op(op) { - static constexpr char ifexistr[] = "IfExists"; - auto l = static_cast(memmem(static_cast(s), len, - static_cast(ifexistr), - sizeof(ifexistr) -1)); - if (l && ((l + sizeof(ifexistr) - 1 == (s + len)))) { - ifexists = true; - key.assign(s, static_cast(l) - s); - } else { - key.assign(s, len); - } - } + Condition(TokenID op, const char* s, std::size_t len, bool ifexists) + : op(op), key(s, len), ifexists(ifexists) {} bool eval(const Environment& e) const; diff --git a/src/rgw/rgw_iam_policy_keywords.gperf b/src/rgw/rgw_iam_policy_keywords.gperf index d37fa6aff65..57a732c02fb 100644 --- a/src/rgw/rgw_iam_policy_keywords.gperf +++ b/src/rgw/rgw_iam_policy_keywords.gperf @@ -1,6 +1,7 @@ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab %language=C++ +%compare-strncmp %define class-name keyword_hash %define lookup-function-name lookup %struct-type