From: David Zafman Date: Fri, 28 Jun 2013 22:45:27 +0000 (-0700) Subject: osd: Add the ability to set capabilities on namespaces X-Git-Tag: v0.67-rc1~127^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8c501651f9cdb165dbba2ba48ab954b9c7f2bc79;p=ceph.git osd: Add the ability to set capabilities on namespaces Parse namespace spec in osd caps and use in is_match() Add test cases to unit test feature: #4983 (OSD: namespaces pt 2 (caps)) Signed-off-by: David Zafman --- diff --git a/src/osd/OSDCap.cc b/src/osd/OSDCap.cc index 268b06d75254..ee77f0ea43d0 100644 --- a/src/osd/OSDCap.cc +++ b/src/osd/OSDCap.cc @@ -64,10 +64,18 @@ ostream& operator<<(ostream& out, const OSDCapMatch& m) if (m.pool_name.length()) { out << "pool " << m.pool_name << " "; } + if (m.is_nspace) { + out << "namespace "; + if (m.nspace.length() == 0) + out << "\"\""; + else + out << m.nspace; + out << " "; + } return out; } -bool OSDCapMatch::is_match(const string& pn, int64_t pool_auid, const string& object) const +bool OSDCapMatch::is_match(const string& pn, const string& ns, int64_t pool_auid, const string& object) const { if (auid >= 0) { if (auid != pool_auid) @@ -77,6 +85,10 @@ bool OSDCapMatch::is_match(const string& pn, int64_t pool_auid, const string& ob if (pool_name != pn) return false; } + if (is_nspace) { + if (nspace != ns) + return false; + } if (object_prefix.length()) { if (object.find(object_prefix) != 0) return false; @@ -90,6 +102,8 @@ bool OSDCapMatch::is_match_all() const return false; if (pool_name.length()) return false; + if (is_nspace) + return false; if (object_prefix.length()) return false; return true; @@ -115,7 +129,7 @@ void OSDCap::set_allow_all() grants.push_back(OSDCapGrant(OSDCapMatch(), OSDCapSpec(OSD_CAP_ANY))); } -bool OSDCap::is_capable(const string& pool_name, int64_t pool_auid, +bool OSDCap::is_capable(const string& pool_name, const string& ns, int64_t pool_auid, const string& object, bool op_may_read, bool op_may_write, bool op_may_class_read, bool op_may_class_write) const @@ -123,7 +137,7 @@ bool OSDCap::is_capable(const string& pool_name, int64_t pool_auid, osd_rwxa_t allow = 0; for (vector::const_iterator p = grants.begin(); p != grants.end(); ++p) { - if (p->match.is_match(pool_name, pool_auid, object)) { + if (p->match.is_match(pool_name, ns, pool_auid, object)) { allow = allow | p->spec.allow; if ((op_may_read && !(allow & OSD_CAP_R)) || (op_may_write && !(allow & OSD_CAP_W)) || @@ -161,18 +175,24 @@ struct OSDCapParser : qi::grammar quoted_string %= lexeme['"' >> +(char_ - '"') >> '"'] | lexeme['\'' >> +(char_ - '\'') >> '\'']; + equoted_string %= + lexeme['"' >> *(char_ - '"') >> '"'] | + lexeme['\'' >> *(char_ - '\'') >> '\'']; unquoted_word %= +char_("a-zA-Z0-9_-"); str %= quoted_string | unquoted_word; + estr %= equoted_string | unquoted_word; spaces = +lit(' '); - // match := [pool[=] | auid <123>] [object_prefix ] + // match := [pool[=] [namespace[=]] | auid <123>] [object_prefix ] pool_name %= -(spaces >> lit("pool") >> (lit('=') | spaces) >> str); + nspace %= (spaces >> lit("namespace") >> (lit('=') | spaces) >> estr); auid %= (spaces >> lit("auid") >> spaces >> int_); object_prefix %= -(spaces >> lit("object_prefix") >> spaces >> str); match = ( (auid >> object_prefix) [_val = phoenix::construct(_1, _2)] | - (pool_name >> object_prefix) [_val = phoenix::construct(_1, _2)]); + (pool_name >> nspace >> object_prefix) [_val = phoenix::construct(_1, _2, _3)] | + (pool_name >> object_prefix) [_val = phoenix::construct(_1, _2)]); // rwxa := * | [r][w][x] [class-read] [class-write] rwxa = @@ -203,12 +223,13 @@ struct OSDCapParser : qi::grammar } qi::rule spaces; qi::rule rwxa; - qi::rule quoted_string; + qi::rule quoted_string, equoted_string; qi::rule unquoted_word; - qi::rule str; + qi::rule str, estr; qi::rule auid; qi::rule capspec; qi::rule pool_name; + qi::rule nspace; qi::rule object_prefix; qi::rule match; qi::rule grant; diff --git a/src/osd/OSDCap.h b/src/osd/OSDCap.h index 9b2ac8865ae2..3fc7fb67953c 100644 --- a/src/osd/OSDCap.h +++ b/src/osd/OSDCap.h @@ -73,26 +73,32 @@ ostream& operator<<(ostream& out, const OSDCapSpec& s); struct OSDCapMatch { - // auid and pool_name are mutually exclusive + // auid and pool_name/nspace are mutually exclusive int64_t auid; std::string pool_name; + bool is_nspace; // true if nspace is defined; false if not constrained. + std::string nspace; std::string object_prefix; - OSDCapMatch() : auid(CEPH_AUTH_UID_DEFAULT) {} - OSDCapMatch(std::string pl, std::string pre) : auid(CEPH_AUTH_UID_DEFAULT), pool_name(pl), object_prefix(pre) {} - OSDCapMatch(uint64_t auid, std::string pre) : auid(auid), object_prefix(pre) {} + OSDCapMatch() : auid(CEPH_AUTH_UID_DEFAULT), is_nspace(false) {} + OSDCapMatch(std::string pl, std::string pre) : + auid(CEPH_AUTH_UID_DEFAULT), pool_name(pl), is_nspace(false), object_prefix(pre) {} + OSDCapMatch(std::string pl, std::string ns, std::string pre) : + auid(CEPH_AUTH_UID_DEFAULT), pool_name(pl), is_nspace(true), nspace(ns), object_prefix(pre) {} + OSDCapMatch(uint64_t auid, std::string pre) : auid(auid), is_nspace(false), object_prefix(pre) {} /** * check if given request parameters match our constraints * * @param auid requesting user's auid * @param pool_name pool name + * @param nspace_name namespace name * @param pool_auid pool's auid * @param object object name * @return true if we match, false otherwise */ - bool is_match(const std::string& pool_name, int64_t pool_auid, const std::string& object) const; + bool is_match(const std::string& pool_name, const std::string& nspace_name, int64_t pool_auid, const std::string& object) const; bool is_match_all() const; }; @@ -128,6 +134,7 @@ struct OSDCap { * against pool, pool auid, and object name prefix. * * @param pool_name name of the pool we are accessing + * @param ns name of the namespace we are accessing * @param pool_auid owner of the pool we are accessing * @param object name of the object we are accessing * @param op_may_read whether the operation may need to read @@ -138,7 +145,7 @@ struct OSDCap { * write class method * @return true if the operation is allowed, false otherwise */ - bool is_capable(const string& pool_name, int64_t pool_auid, + bool is_capable(const string& pool_name, const string& ns, int64_t pool_auid, const string& object, bool op_may_read, bool op_may_write, bool op_may_class_read, bool op_may_class_write) const; }; diff --git a/src/osd/PG.cc b/src/osd/PG.cc index d925ff247207..e47a4d621222 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -1337,13 +1337,15 @@ bool PG::op_has_sufficient_caps(OpRequestRef op) if (key.length() == 0) key = req->get_oid().name; - bool cap = caps.is_capable(pool.name, pool.auid, key, + bool cap = caps.is_capable(pool.name, req->get_object_locator().nspace, + pool.auid, key, op->need_read_cap(), op->need_write_cap(), op->need_class_read_cap(), op->need_class_write_cap()); dout(20) << "op_has_sufficient_caps pool=" << pool.id << " (" << pool.name + << " " << req->get_object_locator().nspace << ") owner=" << pool.auid << " need_read_cap=" << op->need_read_cap() << " need_write_cap=" << op->need_write_cap() diff --git a/src/test/osd/osdcap.cc b/src/test/osd/osdcap.cc index a26a843057ef..5f7c607deec4 100644 --- a/src/test/osd/osdcap.cc +++ b/src/test/osd/osdcap.cc @@ -62,6 +62,12 @@ const char *parse_good[] = { "allow r pool foo object_prefix blah ; allow w auid 5", "allow class-read object_prefix rbd_children, allow pool libvirt-pool-test rwx", "allow class-read object_prefix rbd-children, allow pool libvirt_pool_test rwx", + "allow pool foo namespace nfoo rwx, allow pool bar namespace=nbar r", + "allow pool foo namespace=nfoo rwx ; allow pool bar namespace=nbar r", + "allow pool foo namespace nfoo rwx ;allow pool bar namespace nbar r", + "allow pool foo namespace=nfoo rwx; allow pool bar namespace nbar object_prefix rbd r", + "allow pool foo namespace=\"\" rwx; allow pool bar namespace='' object_prefix rbd r", + "allow pool foo namespace \"\" rwx; allow pool bar namespace '' object_prefix rbd r", 0 }; @@ -89,6 +95,13 @@ const char *parse_bad[] = { "allow xrwx pool foo,, allow r pool bar", ";allow rwx pool foo rwx ; allow r pool bar", "allow rwx pool foo ;allow r pool bar gibberish", + "allow rwx auid 123 pool asdf namespace=foo", + "allow rwx auid 123 namespace", + "allow rwx namespace", + "allow namespace", + "allow namespace=foo", + "allow rwx auid 123 namespace asdf", + "allow wwx pool ''", 0 }; @@ -135,7 +148,10 @@ TEST(OSDCap, AllowAll) { ASSERT_TRUE(cap.parse("allow *", NULL)); ASSERT_TRUE(cap.allow_all()); - ASSERT_TRUE(cap.is_capable("foo", 0, "asdf", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "asdf", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "anamespace", 0, "asdf", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "asdf", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "anamespace", 0, "asdf", true, true, true, true)); } TEST(OSDCap, AllowPool) { @@ -143,8 +159,10 @@ TEST(OSDCap, AllowPool) { bool r = cap.parse("allow rwx pool foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("foo", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, true, true)); } TEST(OSDCap, AllowPools) { @@ -152,10 +170,14 @@ TEST(OSDCap, AllowPools) { bool r = cap.parse("allow rwx pool foo, allow r pool bar", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("foo", 0, "", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("baz", "ns", 0, "", true, false, false, false)); } TEST(OSDCap, AllowPools2) { @@ -163,9 +185,9 @@ TEST(OSDCap, AllowPools2) { bool r = cap.parse("allow r, allow rwx pool foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("foo", 0, "", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "", true, false, false, false)); } TEST(OSDCap, ObjectPrefix) { @@ -173,13 +195,13 @@ TEST(OSDCap, ObjectPrefix) { bool r = cap.parse("allow rwx object_prefix foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "food", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo_bar", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "_foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, " foo ", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "fo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "_foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, " foo ", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "fo", true, true, true, true)); } TEST(OSDCap, ObjectPoolAndPrefix) { @@ -187,203 +209,324 @@ TEST(OSDCap, ObjectPoolAndPrefix) { bool r = cap.parse("allow rwx pool bar object_prefix foo", NULL); ASSERT_TRUE(r); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "food", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo_bar", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "food", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo_bar", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "food", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "fo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "food", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "fo", true, true, true, true)); } TEST(OSDCap, BasicR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow r", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); } TEST(OSDCap, BasicW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow w", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); } TEST(OSDCap, BasicX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow x", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); } TEST(OSDCap, BasicRW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rw", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); } TEST(OSDCap, BasicRX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); } TEST(OSDCap, BasicWX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow wx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); } TEST(OSDCap, BasicRWX) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rwx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); } TEST(OSDCap, BasicRWClassRClassW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow rw class-read class-write", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, true, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); } TEST(OSDCap, ClassR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow class-read", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, false, false, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); } TEST(OSDCap, ClassW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow class-write", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, false, true, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); } TEST(OSDCap, ClassRW) { OSDCap cap; ASSERT_TRUE(cap.parse("allow class-read class-write", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, false, true)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); } TEST(OSDCap, BasicRClassR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow r class-read", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + + ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "any", 0, "foo", true, false, false, false)); + + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "any", 0, "foo", true, true, false, false)); } TEST(OSDCap, PoolClassR) { OSDCap cap; ASSERT_TRUE(cap.parse("allow pool bar r class-read, allow pool foo rwx", NULL)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", false, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, true, false)); - ASSERT_TRUE(cap.is_capable("bar", 0, "foo", true, false, false, false)); - - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", false, true, false, false)); - ASSERT_FALSE(cap.is_capable("bar", 0, "foo", true, true, false, false)); - - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", false, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", false, false, true, true)); - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", false, true, true, true)); - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, false, false, true)); - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, false, false, false)); - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, true, false, true)); - ASSERT_TRUE(cap.is_capable("foo", 0, "foo", true, true, true, false)); - - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", false, false, false, false)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", false, false, true, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", false, true, true, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, false, false, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, false, false, false)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, false, true)); - ASSERT_FALSE(cap.is_capable("baz", 0, "foo", true, true, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "ns", 0, "foo", true, false, false, false)); + + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, true, false, false)); + + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, false)); + + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, false)); + + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, false, false)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, false, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, false)); +} + +TEST(OSDCap, PoolClassRNS) { + OSDCap cap; + ASSERT_TRUE(cap.parse("allow pool bar namespace='' r class-read, allow pool foo namespace=ns rwx", NULL)); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, true, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "", 0, "foo", true, true, false, false)); + + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", false, false, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "ns", 0, "foo", true, false, false, false)); + + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("bar", "other", 0, "foo", true, true, false, false)); + + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, false, false)); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, false, true, true)); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, false, true)); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, false, true)); + ASSERT_FALSE(cap.is_capable("foo", "", 0, "foo", true, true, true, false)); + + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "ns", 0, "foo", true, true, true, false)); + + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, false, false)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, false, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", false, true, true, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, false, true)); + ASSERT_FALSE(cap.is_capable("baz", "", 0, "foo", true, true, true, false)); +} + +TEST(OSDCap, NSClassR) { + OSDCap cap; + ASSERT_TRUE(cap.parse("allow namespace '' rw class-read class-write, allow namespace test r", NULL)); + + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, false, true)); + ASSERT_TRUE(cap.is_capable("bar", "", 0, "foo", true, true, true, false)); + + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, false, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", false, true, true, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, false, false, false)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, false, true)); + ASSERT_TRUE(cap.is_capable("foo", "", 0, "foo", true, true, true, false)); + + ASSERT_TRUE(cap.is_capable("bar", "test", 0, "foo", true, false, false, false)); + + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, false, true, false)); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("bar", "test", 0, "foo", true, true, false, false)); + + ASSERT_TRUE(cap.is_capable("foo", "test", 0, "foo", true, false, false, false)); + + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, false, true, false)); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, true, true)); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", false, true, false, true)); + ASSERT_FALSE(cap.is_capable("foo", "test", 0, "foo", true, true, false, false)); + + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", true, false, false, false)); + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, true, false, false)); + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, true, false)); + ASSERT_FALSE(cap.is_capable("foo", "bad", 0, "foo", false, false, false, true)); } TEST(OSDCap, OutputParsed) @@ -419,6 +562,14 @@ TEST(OSDCap, OutputParsed) "osdcap[grant(pool images w)]"}, {"allow pool images x", "osdcap[grant(pool images x)]"}, + {"allow r pool images namespace ''", + "osdcap[grant(pool images namespace \"\" r)]"}, + {"allow r pool images namespace foo", + "osdcap[grant(pool images namespace foo r)]"}, + {"allow r pool images namespace \"\"", + "osdcap[grant(pool images namespace \"\" r)]"}, + {"allow r namespace foo", + "osdcap[grant(namespace foo r)]"}, {"allow pool images r; allow pool rbd rwx", "osdcap[grant(pool images r),grant(pool rbd rwx)]"}, {"allow pool images r, allow pool rbd rwx",