{
if (s.allow)
return out << s.allow;
- if (s.class_name.length())
- return out << "class '" << s.class_name << "' '" << s.class_allow << "'";
+ if (s.class_name.length()) {
+ out << "class '" << s.class_name << "'";
+ if (!s.method_name.empty()) {
+ out << " '" << s.method_name << "'";
+ }
+ }
return out;
}
// compare this grant to each class in the operation
for (size_t i = 0; i < classes.size(); ++i) {
- // check 'allow class foo'
+ // check 'allow class foo [method_name]'
if (!spec.class_name.empty() &&
- classes[i].class_name == spec.class_name) {
+ classes[i].class_name == spec.class_name &&
+ (spec.method_name.empty() ||
+ classes[i].method_name == spec.method_name)) {
(*class_allowed)[i] = true;
continue;
}
( (spaces >> lit("class-read")[_val |= OSD_CAP_CLS_R]) ||
(spaces >> lit("class-write")[_val |= OSD_CAP_CLS_W]) ));
- // capspec := * | rwx | class <name> [classcap]
+ // capspec := * | rwx | class <name> [<method name>]
class_name %= (spaces >> lit("class") >> spaces >> str);
- class_cap %= -(spaces >> str);
+ method_name %= -(spaces >> str);
capspec = (
- (rwxa) [_val = phoenix::construct<OSDCapSpec>(_1)] |
- (class_name >> class_cap) [_val = phoenix::construct<OSDCapSpec>(_1, _2)]);
+ (rwxa) [_val = phoenix::construct<OSDCapSpec>(_1)] |
+ (class_name >> method_name) [_val = phoenix::construct<OSDCapSpec>(_1, _2)]);
// profile := profile <name> [pool[=]<pool> [namespace[=]<namespace>]]
profile_name %= (lit("profile") >> (lit('=') | spaces) >> str);
qi::rule<Iterator, string()> wildcard;
qi::rule<Iterator, int()> auid;
qi::rule<Iterator, string()> class_name;
- qi::rule<Iterator, string()> class_cap;
+ qi::rule<Iterator, string()> method_name;
qi::rule<Iterator, OSDCapSpec()> capspec;
qi::rule<Iterator, string()> pool_name;
qi::rule<Iterator, string()> nspace;
ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "", true, true, false}}));
}
+TEST(OSDCap, AllowClassMethod) {
+ OSDCap cap;
+ ASSERT_TRUE(cap.parse("allow class foo xyz", NULL));
+
+ // can call the xyz method on class foo regardless of whitelist status
+ ASSERT_TRUE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"foo", "xyz", true, false, true}}));
+ ASSERT_TRUE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"foo", "xyz", false, true, true}}));
+ ASSERT_TRUE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"foo", "xyz", true, true, true}}));
+ ASSERT_TRUE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"foo", "xyz", true, false, false}}));
+ ASSERT_TRUE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"foo", "xyz", false, true, false}}));
+ ASSERT_TRUE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"foo", "xyz", true, true, false}}));
+
+ // does not permit invoking class bar
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "", true, false, true}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "", false, true, true}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "", true, true, true}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "", true, false, false}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "", false, true, false}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "", true, true, false}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "xyz", true, false, true}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "xyz", false, true, true}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "xyz", true, true, true}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "xyz", true, false, false}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "xyz", false, true, false}}));
+ ASSERT_FALSE(cap.is_capable("bar", "", 0, {}, "foo", false, false, {{"bar", "xyz", true, true, false}}));
+}
+
TEST(OSDCap, AllowClass2) {
OSDCap cap;
ASSERT_TRUE(cap.parse("allow class foo, allow class bar", NULL));