diff options
Diffstat (limited to 'src/mds/MDSAuthCaps.cc')
-rw-r--r-- | src/mds/MDSAuthCaps.cc | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/src/mds/MDSAuthCaps.cc b/src/mds/MDSAuthCaps.cc index d983f2d58..22383445e 100644 --- a/src/mds/MDSAuthCaps.cc +++ b/src/mds/MDSAuthCaps.cc @@ -33,6 +33,7 @@ using std::ostream; using std::string; using std::vector; +using std::string_view; namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace phoenix = boost::phoenix; @@ -53,6 +54,8 @@ struct MDSCapParser : qi::grammar<Iterator, MDSAuthCaps()> using qi::_1; using qi::_2; using qi::_3; + using qi::_4; + using qi::_5; using qi::eps; using qi::lit; @@ -65,25 +68,13 @@ struct MDSCapParser : qi::grammar<Iterator, MDSAuthCaps()> network_str %= +char_("/.:a-fA-F0-9]["); fs_name_str %= +char_("a-zA-Z0-9_.-"); - // match := [path=<path>] [uid=<uid> [gids=<gid>[,<gid>...]] - // TODO: allow fsname, and root_squash to be specified with uid, and gidlist - path %= (spaces >> lit("path") >> lit('=') >> (quoted_path | unquoted_path)); - uid %= (spaces >> lit("uid") >> lit('=') >> uint_); + path %= -(spaces >> lit("path") >> lit('=') >> (quoted_path | unquoted_path)); + uid %= -(spaces >> lit("uid") >> lit('=') >> uint_); uintlist %= (uint_ % lit(',')); gidlist %= -(spaces >> lit("gids") >> lit('=') >> uintlist); fs_name %= -(spaces >> lit("fsname") >> lit('=') >> fs_name_str); - root_squash %= (spaces >> lit("root_squash") >> attr(true)); - match = -( - (fs_name >> path >> root_squash)[_val = phoenix::construct<MDSCapMatch>(_2, _1, _3)] | - (uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2)] | - (path >> uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2, _3)] | - (fs_name >> path)[_val = phoenix::construct<MDSCapMatch>(_2, _1)] | - (fs_name >> root_squash)[_val = phoenix::construct<MDSCapMatch>(std::string(), _1, _2)] | - (path >> root_squash)[_val = phoenix::construct<MDSCapMatch>(_1, std::string(), _2)] | - (path)[_val = phoenix::construct<MDSCapMatch>(_1)] | - (root_squash)[_val = phoenix::construct<MDSCapMatch>(std::string(), std::string(), _1)] | - (fs_name)[_val = phoenix::construct<MDSCapMatch>(std::string(), - _1)]); + root_squash %= -(spaces >> lit("root_squash") >> attr(true)); + match = (fs_name >> path >> root_squash >> uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2, _3, _4, _5)]; // capspec = * | r[w][f][p][s] capspec = spaces >> ( @@ -122,11 +113,11 @@ struct MDSCapParser : qi::grammar<Iterator, MDSAuthCaps()> qi::rule<Iterator, bool()> root_squash; qi::rule<Iterator, MDSCapSpec()> capspec; qi::rule<Iterator, uint32_t()> uid; - qi::rule<Iterator, std::vector<uint32_t>() > uintlist; - qi::rule<Iterator, std::vector<uint32_t>() > gidlist; + qi::rule<Iterator, vector<uint32_t>() > uintlist; + qi::rule<Iterator, vector<uint32_t>() > gidlist; qi::rule<Iterator, MDSCapMatch()> match; qi::rule<Iterator, MDSCapGrant()> grant; - qi::rule<Iterator, std::vector<MDSCapGrant>()> grants; + qi::rule<Iterator, vector<MDSCapGrant>()> grants; qi::rule<Iterator, MDSAuthCaps()> mdscaps; }; @@ -142,7 +133,7 @@ void MDSCapMatch::normalize_path() // drop .. } -bool MDSCapMatch::match(std::string_view target_path, +bool MDSCapMatch::match(string_view target_path, const int caller_uid, const int caller_gid, const vector<uint64_t> *caller_gid_list) const @@ -174,7 +165,7 @@ bool MDSCapMatch::match(std::string_view target_path, return true; } -bool MDSCapMatch::match_path(std::string_view target_path) const +bool MDSCapMatch::match_path(string_view target_path) const { if (path.length()) { if (target_path.find(path) != 0) @@ -200,7 +191,7 @@ void MDSCapGrant::parse_network() * Is the client *potentially* able to access this path? Actual * permission will depend on uids/modes in the full is_capable. */ -bool MDSAuthCaps::path_capable(std::string_view inode_path) const +bool MDSAuthCaps::path_capable(string_view inode_path) const { for (const auto &i : grants) { if (i.match.match_path(inode_path)) { @@ -218,7 +209,7 @@ bool MDSAuthCaps::path_capable(std::string_view inode_path) const * This is true if any of the 'grant' clauses in the capability match the * requested path + op. */ -bool MDSAuthCaps::is_capable(std::string_view inode_path, +bool MDSAuthCaps::is_capable(string_view inode_path, uid_t inode_uid, gid_t inode_gid, unsigned inode_mode, uid_t caller_uid, gid_t caller_gid, @@ -338,7 +329,7 @@ void MDSAuthCaps::set_allow_all() {})); } -bool MDSAuthCaps::parse(std::string_view str, ostream *err) +bool MDSAuthCaps::parse(string_view str, ostream *err) { // Special case for legacy caps if (str == "allow") { @@ -363,10 +354,15 @@ bool MDSAuthCaps::parse(std::string_view str, ostream *err) // Make sure no grants are kept after parsing failed! grants.clear(); - if (err) - *err << "mds capability parse failed, stopped at '" - << std::string(iter, end) - << "' of '" << str << "'"; + if (err) { + if (string(iter, end).find("allow") != string::npos) { + *err << "Permission flags in MDS caps must start with 'r' or " << + "'rw' or be '*' or 'all'"; + } else { + *err << "mds capability parse failed, stopped at '" + << string(iter, end) << "' of '" << str << "'"; + } + } return false; } } @@ -465,3 +461,9 @@ ostream &operator<<(ostream &out, const MDSAuthCaps &cap) return out; } +ostream &operator<<(ostream &out, const MDSCapAuth &auth) +{ + out << "MDSCapAuth(" << auth.match << "readable=" + << auth.readable << ", writeable=" << auth.writeable << ")"; + return out; +} |