]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/MonCap: enforce network constraint (if present)
authorSage Weil <sage@redhat.com>
Thu, 5 Jul 2018 16:40:06 +0000 (11:40 -0500)
committerSage Weil <sage@redhat.com>
Sun, 12 Aug 2018 22:01:05 +0000 (17:01 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/mon/MonCap.cc
src/mon/MonCap.h
src/test/mon/moncap.cc

index 1fbf2c8200a8a68e38b435b087e0912c570f71a8..ad1e61a8332574b921dd5a27cb62e66d70325d29 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "MonCap.h"
 #include "include/stringify.h"
+#include "include/ipaddr.h"
 #include "common/debug.h"
 #include "common/Formatter.h"
 
@@ -138,6 +139,12 @@ BOOST_FUSION_ADAPT_STRUCT(StringConstraint,
 
 // </magic>
 
+void MonCapGrant::parse_network()
+{
+  network_valid = ::parse_network(network.c_str(), &network_parsed,
+                                 &network_prefix);
+}
+
 void MonCapGrant::expand_profile(int daemon_type, const EntityName& name) const
 {
   // only generate this list once
@@ -398,11 +405,21 @@ bool MonCap::is_capable(
                   << " addr " << addr
                   << " on cap " << *this
                   << dendl;
+
   mon_rwxa_t allow = 0;
   for (vector<MonCapGrant>::const_iterator p = grants.begin();
        p != grants.end(); ++p) {
     if (cct)
-      ldout(cct, 20) << " allow so far " << allow << ", doing grant " << *p << dendl;
+      ldout(cct, 20) << " allow so far " << allow << ", doing grant " << *p
+                    << dendl;
+
+    if (p->network.size() &&
+       (!p->network_valid ||
+        !network_contains(p->network_parsed,
+                          p->network_prefix,
+                          addr))) {
+      continue;
+    }
 
     if (p->is_allow_all()) {
       if (cct)
@@ -585,6 +602,9 @@ bool MonCap::parse(const string& str, ostream *err)
   //bool r = qi::phrase_parse(iter, end, g, ascii::space, foo);
   if (r && iter == end) {
     text = str;
+    for (auto& g : grants) {
+      g.parse_network();
+    }
     return true;
   }
 
index b0fe6e73e335eb00720562fa3f0a5ef6cde4aac6..67ed105ebda518d182381753e1bc8db7e874c3ce 100644 (file)
@@ -83,6 +83,13 @@ struct MonCapGrant {
   // restrict by network
   std::string network;
 
+  // these are filled in by parse_network(), called by MonCap::parse()
+  entity_addr_t network_parsed;
+  unsigned network_prefix = 0;
+  bool network_valid = true;
+
+  void parse_network();
+
   mon_rwxa_t allow;
 
   // explicit grants that a profile grant expands to; populated as
index 93598774e8bfc24b8f11d41a8dfcb97a30939cf6..680266d7f06ffbe2beefbc1afe848b547e93075c 100644 (file)
@@ -197,6 +197,30 @@ TEST(MonCap, AllowAll) {
   ASSERT_TRUE(cap2.is_allow_all());
 }
 
+TEST(MonCap, Network) {
+  MonCap cap;
+  bool r = cap.parse("allow * network 192.168.0.0/16, allow * network 10.0.0.0/8", NULL);
+  ASSERT_TRUE(r);
+
+  entity_addr_t a, b, c;
+  a.parse("10.1.2.3");
+  b.parse("192.168.2.3");
+  c.parse("192.167.2.3");
+
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON, EntityName(),
+                            "foo", "asdf", map<string,string>(),
+                            true, true, true,
+                            a));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON, EntityName(),
+                            "foo", "asdf", map<string,string>(),
+                            true, true, true,
+                            b));
+  ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON, EntityName(),
+                            "foo", "asdf", map<string,string>(),
+                            true, true, true,
+                            c));
+}
+
 TEST(MonCap, ProfileOSD) {
   MonCap cap;
   bool r = cap.parse("allow profile osd", NULL);