]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/MonCap: pass entity type (mgr, mon) to is_capable
authorSage Weil <sage@redhat.com>
Tue, 7 Mar 2017 21:28:24 +0000 (16:28 -0500)
committerSage Weil <sage@redhat.com>
Wed, 29 Mar 2017 15:39:26 +0000 (11:39 -0400)
This lets us define different meanings for profiles on
the mon and mgr.

Signed-off-by: Sage Weil <sage@redhat.com>
src/mgr/DaemonServer.cc
src/mon/MonCap.cc
src/mon/MonCap.h
src/mon/Monitor.cc
src/mon/OSDMonitor.cc
src/mon/Session.h
src/test/mon/moncap.cc

index b154b8eee2bfcb840c7dc2c7d2eca78ed9d1369e..b6e2bc6079b5b8213b3beff85ff0f9dc1ee2dc8c 100644 (file)
@@ -351,11 +351,15 @@ bool DaemonServer::_allowed_command(
   bool cmd_w = this_cmd->requires_perm('w');
   bool cmd_x = this_cmd->requires_perm('x');
 
-  bool capable = s->caps.is_capable(g_ceph_context, s->entity_name,
-                                    module, prefix, param_str_map,
-                                    cmd_r, cmd_w, cmd_x);
-
-  dout(10) << " " << (capable ? "" : "not ") << "capable" << dendl;
+  bool capable = s->caps.is_capable(
+    g_ceph_context,
+    CEPH_ENTITY_TYPE_MGR,
+    s->entity_name,
+    module, prefix, param_str_map,
+    cmd_r, cmd_w, cmd_x);
+
+  dout(10) << " " << s->entity_name << " "
+          << (capable ? "" : "not ") << "capable" << dendl;
   return capable;
 }
 
index 972d51651fa6f63b0c6aca736bb41f1319c47422..7f3582976b5c91d03f4189482daf88cba6673c76 100644 (file)
@@ -113,12 +113,42 @@ BOOST_FUSION_ADAPT_STRUCT(StringConstraint,
 
 // </magic>
 
-void MonCapGrant::expand_profile(EntityName name) const
+void MonCapGrant::expand_profile(int daemon_type, const EntityName& name) const
 {
   // only generate this list once
   if (!profile_grants.empty())
     return;
 
+  if (profile == "read-only") {
+    // grants READ-ONLY caps monitor-wide
+    // 'auth' requires MON_CAP_X even for RO, which we do not grant here.
+    profile_grants.push_back(mon_rwxa_t(MON_CAP_R));
+    return;
+  }
+
+  if (profile == "read-write") {
+    // grants READ-WRITE caps monitor-wide
+    // 'auth' requires MON_CAP_X for all operations, which we do not grant.
+    profile_grants.push_back(mon_rwxa_t(MON_CAP_R | MON_CAP_W));
+    return;
+  }
+
+  switch (daemon_type) {
+  case CEPH_ENTITY_TYPE_MON:
+    expand_profile_mon(name);
+    return;
+  case CEPH_ENTITY_TYPE_MGR:
+    expand_profile_mgr(name);
+    return;
+  }
+}
+
+void MonCapGrant::expand_profile_mgr(const EntityName& name) const
+{
+}
+
+void MonCapGrant::expand_profile_mon(const EntityName& name) const
+{
   if (profile == "mon") {
     profile_grants.push_back(MonCapGrant("mon", MON_CAP_ALL));
     profile_grants.push_back(MonCapGrant("log", MON_CAP_ALL));
@@ -209,18 +239,6 @@ void MonCapGrant::expand_profile(EntityName name) const
     profile_grants.push_back(MonCapGrant("pg", MON_CAP_R));
   }
 
-  if (profile == "read-only") {
-    // grants READ-ONLY caps monitor-wide
-    // 'auth' requires MON_CAP_X even for RO, which we do not grant here.
-    profile_grants.push_back(mon_rwxa_t(MON_CAP_R));
-  }
-
-  if (profile == "read-write") {
-    // grants READ-WRITE caps monitor-wide
-    // 'auth' requires MON_CAP_X for all operations, which we do not grant.
-    profile_grants.push_back(mon_rwxa_t(MON_CAP_R | MON_CAP_W));
-  }
-
   if (profile == "role-definer") {
     // grants ALL caps to the auth subsystem, read-only on the
     // monitor subsystem and nothing else.
@@ -230,16 +248,17 @@ void MonCapGrant::expand_profile(EntityName name) const
 }
 
 mon_rwxa_t MonCapGrant::get_allowed(CephContext *cct,
+                                   int daemon_type,
                                    EntityName name,
                                    const std::string& s, const std::string& c,
                                    const map<string,string>& c_args) const
 {
   if (profile.length()) {
-    expand_profile(name);
+    expand_profile(daemon_type, name);
     mon_rwxa_t a;
     for (list<MonCapGrant>::const_iterator p = profile_grants.begin();
         p != profile_grants.end(); ++p)
-      a = a | p->get_allowed(cct, name, s, c, c_args);
+      a = a | p->get_allowed(cct, daemon_type, name, s, c, c_args);
     return a;
   }
   if (service.length()) {
@@ -296,6 +315,7 @@ void MonCap::set_allow_all()
 }
 
 bool MonCap::is_capable(CephContext *cct,
+                       int daemon_type,
                        EntityName name,
                        const string& service,
                        const string& command, const map<string,string>& command_args,
@@ -321,7 +341,8 @@ bool MonCap::is_capable(CephContext *cct,
     }
 
     // check enumerated caps
-    allow = allow | p->get_allowed(cct, name, service, command, command_args);
+    allow = allow | p->get_allowed(cct, daemon_type, name, service, command,
+                                  command_args);
     if ((!op_may_read || (allow & MON_CAP_R)) &&
        (!op_may_write || (allow & MON_CAP_W)) &&
        (!op_may_exec || (allow & MON_CAP_X))) {
index 3bdd5479838b308bf80a456cf96af65bfe765402..25684d307624d8bf91edee790e7f5d8326020d15 100644 (file)
@@ -78,7 +78,9 @@ struct MonCapGrant {
   // needed by expand_profile() (via is_match()) and cached here.
   mutable list<MonCapGrant> profile_grants;
 
-  void expand_profile(EntityName name) const;
+  void expand_profile(int daemon_type, const EntityName& name) const;
+  void expand_profile_mon(const EntityName& name) const;
+  void expand_profile_mgr(const EntityName& name) const;
 
   MonCapGrant() : allow(0) {}
   // cppcheck-suppress noExplicitConstructor
@@ -101,6 +103,7 @@ struct MonCapGrant {
    * @return bits we allow
    */
   mon_rwxa_t get_allowed(CephContext *cct,
+                        int daemon_type, ///< CEPH_ENTITY_TYPE_*
                         EntityName name,
                         const std::string& service,
                         const std::string& command,
@@ -138,6 +141,7 @@ struct MonCap {
    * This method actually checks a description of a particular operation against
    * what the capability has specified.
    *
+   * @param daemon_type CEPH_ENTITY_TYPE_* for the service (MON or MGR)
    * @param service service name
    * @param command command id
    * @param command_args
@@ -147,6 +151,7 @@ struct MonCap {
    * @return true if the operation is allowed, false otherwise
    */
   bool is_capable(CephContext *cct,
+                 int daemon_type,
                  EntityName name,
                  const string& service,
                  const string& command, const map<string,string>& command_args,
index 46a7ed55f29338e214c444b33e915fa7cd28c437..bf2410e59525ef0b651257eae21131369e7e43dd 100644 (file)
@@ -2683,9 +2683,12 @@ bool Monitor::_allowed_command(MonSession *s, string &module, string &prefix,
   bool cmd_w = this_cmd->requires_perm('w');
   bool cmd_x = this_cmd->requires_perm('x');
 
-  bool capable = s->caps.is_capable(g_ceph_context, s->entity_name,
-                                    module, prefix, param_str_map,
-                                    cmd_r, cmd_w, cmd_x);
+  bool capable = s->caps.is_capable(
+    g_ceph_context,
+    CEPH_ENTITY_TYPE_MON,
+    s->entity_name,
+    module, prefix, param_str_map,
+    cmd_r, cmd_w, cmd_x);
 
   dout(10) << __func__ << " " << (capable ? "" : "not ") << "capable" << dendl;
   return capable;
index c6453f3478b78e55e49e7daf53f943f4ae69c41d..3147d6066ad59888ea5d0e0518119013e6782ec3 100644 (file)
@@ -2674,7 +2674,10 @@ bool OSDMonitor::preprocess_remove_snaps(MonOpRequestRef op)
   MonSession *session = m->get_session();
   if (!session)
     goto ignore;
-  if (!session->caps.is_capable(g_ceph_context, session->entity_name,
+  if (!session->caps.is_capable(
+       g_ceph_context,
+       CEPH_ENTITY_TYPE_MON,
+       session->entity_name,
         "osd", "osd pool rmsnap", {}, true, true, false)) {
     dout(0) << "got preprocess_remove_snaps from entity with insufficient caps "
            << session->caps << dendl;
index 0f253fce3b5c94cfe1150d4b7e74eb41a242029c..75051bf6312fa7158adafc12cc9fa09dfe7cd0b6 100644 (file)
@@ -78,10 +78,12 @@ struct MonSession : public RefCountedObject {
 
   bool is_capable(string service, int mask) {
     map<string,string> args;
-    return caps.is_capable(g_ceph_context,
-                          entity_name,
-                          service, "", args,
-                          mask & MON_CAP_R, mask & MON_CAP_W, mask & MON_CAP_X);
+    return caps.is_capable(
+      g_ceph_context,
+      CEPH_ENTITY_TYPE_MON,
+      entity_name,
+      service, "", args,
+      mask & MON_CAP_R, mask & MON_CAP_W, mask & MON_CAP_X);
   }
 };
 
index f9a0b5c06e785f17287918750f1b7b863ab96634..8b55719fe16e77620880d4017fb07e1d7a024ca1 100644 (file)
@@ -177,7 +177,7 @@ TEST(MonCap, AllowAll) {
 
   ASSERT_TRUE(cap.parse("allow *", NULL));
   ASSERT_TRUE(cap.is_allow_all());
-  ASSERT_TRUE(cap.is_capable(NULL, EntityName(),
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON, EntityName(),
                             "foo", "asdf", map<string,string>(), true, true, true));
 
   MonCap cap2;
@@ -195,29 +195,46 @@ TEST(MonCap, ProfileOSD) {
   name.from_str("osd.123");
   map<string,string> ca;
 
-  ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, false, false));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, true, false));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, true, true));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "osd", "", ca, true, true, true));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "mon", "", ca, true, false,false));
-
-  ASSERT_FALSE(cap.is_capable(NULL, name, "mds", "", ca, true, true, true));
-  ASSERT_FALSE(cap.is_capable(NULL, name, "mon", "", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "osd", "", ca, true, false, false));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "osd", "", ca, true, true, false));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "osd", "", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "osd", "", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "mon", "", ca, true, false,false));
+
+  ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "mds", "", ca, true, true, true));
+  ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "mon", "", ca, true, true, true));
 
   ca.clear();
-  ASSERT_FALSE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true, true));
+  ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key get", ca, true, true, true));
   ca["key"] = "daemon-private/osd.123";
-  ASSERT_FALSE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true, true));
+  ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key get", ca, true, true, true));
   ca["key"] = "daemon-private/osd.12/asdf";
-  ASSERT_FALSE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true, true));
+  ASSERT_FALSE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key get", ca, true, true, true));
   ca["key"] = "daemon-private/osd.123/";
-  ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true, true));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true, true));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key get", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key get", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key get", ca, true, true, true));
   ca["key"] = "daemon-private/osd.123/foo";
-  ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key get", ca, true, true, true));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key put", ca, true, true, true));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key exists", ca, true, true, true));
-  ASSERT_TRUE(cap.is_capable(NULL, name, "", "config-key delete", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key get", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key put", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key exists", ca, true, true, true));
+  ASSERT_TRUE(cap.is_capable(NULL, CEPH_ENTITY_TYPE_MON,
+                            name, "", "config-key delete", ca, true, true, true));
 }