]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds/MDSAuthCaps: parse optional gid list
authorSage Weil <sage@redhat.com>
Thu, 28 May 2015 04:33:07 +0000 (00:33 -0400)
committerSage Weil <sage@redhat.com>
Thu, 1 Oct 2015 13:39:29 +0000 (09:39 -0400)
Signed-off-by: Sage Weil <sage@redhat.com>
src/mds/MDSAuthCaps.cc
src/mds/MDSAuthCaps.h
src/test/mds/TestMDSAuthCaps.cc

index a8eec5c3d5d09b52bab87e0d9d391816ede6c975..9aa65c5f43663a634d71e4b5c74a7179e9788ade 100644 (file)
@@ -52,12 +52,14 @@ struct MDSCapParser : qi::grammar<Iterator, MDSAuthCaps()>
       lexeme[lit("'") >> *(char_ - '\'') >> '\''];
     unquoted_path %= +char_("a-zA-Z0-9_.-/");
 
-    // match := [path=<path>] [uid=<uid>]
-    uid %= (spaces >> lit("uid") >> lit('=') >> int_);
+    // match := [path=<path>] [uid=<uid> [gids=<gid>[,<gid>...]]
     path %= (spaces >> lit("path") >> lit('=') >> (quoted_path | unquoted_path));
+    uid %= (spaces >> lit("uid") >> lit('=') >> int_);
+    intlist %= (int_ % lit(','));
+    gidlist %= -(spaces >> lit("gids") >> lit('=') >> intlist);
     match = -(
-             (uid)[_val = phoenix::construct<MDSCapMatch>(_1)] |
-             (path >> uid)[_val = phoenix::construct<MDSCapMatch>(_1, _2)] | 
+            (uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2)] |
+            (path >> uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2, _3)] |
              (path)[_val = phoenix::construct<MDSCapMatch>(_1)]);
 
     // capspec = * | r[w]
@@ -78,6 +80,8 @@ struct MDSCapParser : qi::grammar<Iterator, MDSAuthCaps()>
   qi::rule<Iterator, MDSCapSpec()> capspec;
   qi::rule<Iterator, string()> path;
   qi::rule<Iterator, int()> uid;
+  qi::rule<Iterator, std::vector<int>() > intlist;
+  qi::rule<Iterator, std::vector<int>() > gidlist;
   qi::rule<Iterator, MDSCapMatch()> match;
   qi::rule<Iterator, MDSCapGrant()> grant;
   qi::rule<Iterator, std::vector<MDSCapGrant>()> grants;
@@ -160,11 +164,22 @@ ostream &operator<<(ostream &out, const MDSCapMatch &match)
   if (match.path != MDSCapMatch::MDS_AUTH_PATH_ROOT) {
     out << "path=\"" << match.path << "\"";
   }
-  if (match.path != MDSCapMatch::MDS_AUTH_PATH_ROOT && match.uid != MDSCapMatch::MDS_AUTH_UID_ANY) {
+  if (match.path != MDSCapMatch::MDS_AUTH_PATH_ROOT &&
+      match.uid != MDSCapMatch::MDS_AUTH_UID_ANY) {
     out << " ";
   }
   if (match.uid != MDSCapMatch::MDS_AUTH_UID_ANY) {
     out << "uid=" << match.uid;
+    if (!match.gids.empty()) {
+      out << " gids=";
+      for (std::vector<int>::const_iterator p = match.gids.begin();
+          p != match.gids.end();
+          ++p) {
+       if (p != match.gids.begin())
+         out << ',';
+       out << *p;
+      }
+    }
   }
 
   return out;
index 202c26f9ecfe66776d6f9a159423946b57d5ff8e..c243ef424caf44e326a203e68e45529c236ecb38 100644 (file)
@@ -20,7 +20,7 @@
 #include <string>
 #include <sstream>
 
-
+// what we can do
 struct MDSCapSpec {
   bool read;
   bool write;
@@ -34,17 +34,21 @@ struct MDSCapSpec {
   }
 };
 
+// conditions before we are allowed to do it
 struct MDSCapMatch {
   static const int MDS_AUTH_UID_ANY = -1;
   static const std::string MDS_AUTH_PATH_ROOT;
 
-  int uid;  // Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
+  int uid;           // Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
+  std::vector<int> gids;  // Use these GIDs
   std::string path;  // Require path to be child of this (may be "/" for any)
 
   MDSCapMatch() : uid(MDS_AUTH_UID_ANY), path(MDS_AUTH_PATH_ROOT) {}
-  MDSCapMatch(int uid_) : uid(uid_), path(MDS_AUTH_PATH_ROOT) {}
+  MDSCapMatch(int uid_, std::vector<int>& gids_)
+    : uid(uid_), gids(gids_), path(MDS_AUTH_PATH_ROOT) {}
   MDSCapMatch(std::string path_) : uid(MDS_AUTH_UID_ANY), path(path_) {}
-  MDSCapMatch(std::string path_, int uid_) : uid(uid_), path(path_) {}
+  MDSCapMatch(std::string path_, int uid_, std::vector<int>& gids_)
+    : uid(uid_), gids(gids_), path(path_) {}
   
   bool is_match_all() const
   {
index 74cec8a7618f82ed89a6692cf355428bcc2f3dc2..aa463ebf5b1a6fc32403f1b5b4d45eab5fa70cad 100644 (file)
@@ -23,6 +23,7 @@ using std::string;
 using std::cout;
 
 const char *parse_good[] = {
+  "allow rw uid=1 gids=1",
   "allow * path=\"/foo\"",
   "allow * path=/foo",
   "allow * path=\"/foo bar/baz\"",
@@ -31,6 +32,8 @@ const char *parse_good[] = {
   "allow *",
   "allow r",
   "allow rw",
+  "allow rw uid=1 gids=1,2,3",
+  "allow rw path=/foo uid=1 gids=1,2,3",
   0
 };
 
@@ -66,6 +69,10 @@ const char *parse_bad[] = {
   "allow namespace=foo",
   "allow rwx auid 123 namespace asdf",
   "allow wwx pool ''",
+  "allow rw gids=1",
+  "allow rw gids=1,2,3",
+  "allow rw uid=123 gids=asdf",
+  "allow rw uid=123 gids=1,2,asdf",
   0
 };
 
@@ -133,12 +140,18 @@ TEST(MDSAuthCaps, OutputParsed) {
      "MDSAuthCaps[allow rw]"},
     {"allow * uid=1",
      "MDSAuthCaps[allow * uid=1]"},
+    {"allow * uid=1 gids=1",
+     "MDSAuthCaps[allow * uid=1 gids=1]"},
+    {"allow * uid=1 gids=1,2,3",
+     "MDSAuthCaps[allow * uid=1 gids=1,2,3]"},
     {"allow * path=/foo",
      "MDSAuthCaps[allow * path=\"/foo\"]"},
     {"allow * path=\"/foo\"",
      "MDSAuthCaps[allow * path=\"/foo\"]"},
     {"allow * path=\"/foo\" uid=1",
      "MDSAuthCaps[allow * path=\"/foo\" uid=1]"},
+    {"allow * path=\"/foo\" uid=1 gids=1,2,3",
+     "MDSAuthCaps[allow * path=\"/foo\" uid=1 gids=1,2,3]"},
   };
   size_t num_tests = sizeof(test_values) / sizeof(*test_values);
   for (size_t i = 0; i < num_tests; ++i) {