]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: move session setup into ms_handle_authentication
authorSage Weil <sage@redhat.com>
Tue, 11 Sep 2018 19:38:05 +0000 (14:38 -0500)
committerSage Weil <sage@redhat.com>
Sun, 14 Oct 2018 16:59:20 +0000 (11:59 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/mds/MDSDaemon.cc
src/mds/MDSDaemon.h

index 99f12fc7eda2a0ba6aad30511562c2e7b2fdec3d..cd6bc4e032e712c8694bba08f0e6ee29c89adc30 100644 (file)
@@ -1323,14 +1323,12 @@ bool MDSDaemon::ms_verify_authorizer(Connection *con, int peer_type,
     return true;
   }
 
-  AuthCapsInfo caps_info;
-  EntityName name;
-  uint64_t global_id;
-
   if (auto keys = monc->rotating_secrets.get(); keys) {
     is_valid = authorize_handler->verify_authorizer(
       cct, keys,
-      authorizer_data, authorizer_reply, name, global_id, caps_info,
+      authorizer_data, authorizer_reply,
+      con->peer_name, con->peer_global_id,
+      con->peer_caps_info,
       session_key, challenge);
   } else {
     dout(10) << __func__ << " no rotating_keys (yet), denied" << dendl;
@@ -1338,85 +1336,94 @@ bool MDSDaemon::ms_verify_authorizer(Connection *con, int peer_type,
   }
 
   if (is_valid) {
-    entity_name_t n(con->get_peer_type(), global_id);
+    ms_handle_authentication(con);
+  }
+  return true;
+}
 
-    // We allow connections and assign Session instances to connections
-    // even if we have not been assigned a rank, because clients with
-    // "allow *" are allowed to connect and do 'tell' operations before
-    // we have a rank.
-    Session *s = NULL;
-    if (mds_rank) {
-      // If we do hold a rank, see if this is an existing client establishing
-      // a new connection, rather than a new client
-      s = mds_rank->sessionmap.get_session(n);
-    }
+int MDSDaemon::ms_handle_authentication(Connection *con)
+{
+  int ret = 0;
+  entity_name_t n(con->get_peer_type(), con->get_peer_global_id());
+
+  // We allow connections and assign Session instances to connections
+  // even if we have not been assigned a rank, because clients with
+  // "allow *" are allowed to connect and do 'tell' operations before
+  // we have a rank.
+  Session *s = NULL;
+  if (mds_rank) {
+    // If we do hold a rank, see if this is an existing client establishing
+    // a new connection, rather than a new client
+    s = mds_rank->sessionmap.get_session(n);
+  }
 
-    // Wire up a Session* to this connection
-    // It doesn't go into a SessionMap instance until it sends an explicit
-    // request to open a session (initial state of Session is `closed`)
-    if (!s) {
-      s = new Session(con);
-      s->info.auth_name = name;
-      s->info.inst.addr = con->get_peer_addr();
-      s->info.inst.name = n;
-      dout(10) << " new session " << s << " for " << s->info.inst << " con " << con << dendl;
-      con->set_priv(RefCountedPtr{s, false});
-      if (mds_rank) {
-        mds_rank->kick_waiters_for_any_client_connection();
-      }
-    } else {
-      dout(10) << " existing session " << s << " for " << s->info.inst
-              << " existing con " << s->get_connection()
-              << ", new/authorizing con " << con << dendl;
-      con->set_priv(RefCountedPtr{s});
-
-
-
-      // Wait until we fully accept the connection before setting
-      // s->connection.  In particular, if there are multiple incoming
-      // connection attempts, they will all get their authorizer
-      // validated, but some of them may "lose the race" and get
-      // dropped.  We only want to consider the winner(s).  See
-      // ms_handle_accept().  This is important for Sessions we replay
-      // from the journal on recovery that don't have established
-      // messenger state; we want the con from only the winning
-      // connect attempt(s).  (Normal reconnects that don't follow MDS
-      // recovery are reconnected to the existing con by the
-      // messenger.)
+  // Wire up a Session* to this connection
+  // It doesn't go into a SessionMap instance until it sends an explicit
+  // request to open a session (initial state of Session is `closed`)
+  if (!s) {
+    s = new Session(con);
+    s->info.auth_name = con->get_peer_entity_name();
+    s->info.inst.addr = con->get_peer_addr();
+    s->info.inst.name = n;
+    dout(10) << " new session " << s << " for " << s->info.inst
+            << " con " << con << dendl;
+    con->set_priv(RefCountedPtr{s, false});
+    if (mds_rank) {
+      mds_rank->kick_waiters_for_any_client_connection();
     }
+  } else {
+    dout(10) << " existing session " << s << " for " << s->info.inst
+            << " existing con " << s->get_connection()
+            << ", new/authorizing con " << con << dendl;
+    con->set_priv(RefCountedPtr{s});
+
+    // Wait until we fully accept the connection before setting
+    // s->connection.  In particular, if there are multiple incoming
+    // connection attempts, they will all get their authorizer
+    // validated, but some of them may "lose the race" and get
+    // dropped.  We only want to consider the winner(s).  See
+    // ms_handle_accept().  This is important for Sessions we replay
+    // from the journal on recovery that don't have established
+    // messenger state; we want the con from only the winning
+    // connect attempt(s).  (Normal reconnects that don't follow MDS
+    // recovery are reconnected to the existing con by the
+    // messenger.)
+  }
 
-    if (caps_info.allow_all) {
-      // Flag for auth providers that don't provide cap strings
-      s->auth_caps.set_allow_all();
-    } else {
-      auto p = caps_info.caps.cbegin();
-      string auth_cap_str;
-      try {
-        decode(auth_cap_str, p);
-
-        dout(10) << __func__ << ": parsing auth_cap_str='" << auth_cap_str << "'" << dendl;
-        std::ostringstream errstr;
-        if (!s->auth_caps.parse(g_ceph_context, auth_cap_str, &errstr)) {
-          dout(1) << __func__ << ": auth cap parse error: " << errstr.str()
-                 << " parsing '" << auth_cap_str << "'" << dendl;
-         clog->warn() << name << " mds cap '" << auth_cap_str
-                      << "' does not parse: " << errstr.str();
-          is_valid = false;
-        }
-      } catch (buffer::error& e) {
-        // Assume legacy auth, defaults to:
-        //  * permit all filesystem ops
-        //  * permit no `tell` ops
-        dout(1) << __func__ << ": cannot decode auth caps bl of length " << caps_info.caps.length() << dendl;
-        is_valid = false;
+  AuthCapsInfo &caps_info = con->get_peer_caps_info();
+  if (caps_info.allow_all) {
+    // Flag for auth providers that don't provide cap strings
+    s->auth_caps.set_allow_all();
+  } else {
+    auto p = caps_info.caps.cbegin();
+    string auth_cap_str;
+    try {
+      decode(auth_cap_str, p);
+
+      dout(10) << __func__ << ": parsing auth_cap_str='" << auth_cap_str << "'"
+              << dendl;
+      std::ostringstream errstr;
+      if (!s->auth_caps.parse(g_ceph_context, auth_cap_str, &errstr)) {
+       dout(1) << __func__ << ": auth cap parse error: " << errstr.str()
+               << " parsing '" << auth_cap_str << "'" << dendl;
+       clog->warn() << name << " mds cap '" << auth_cap_str
+                    << "' does not parse: " << errstr.str();
+       ret = -EPERM;
+      } else {
+       ret = 1;
       }
+    } catch (buffer::error& e) {
+      // Assume legacy auth, defaults to:
+      //  * permit all filesystem ops
+      //  * permit no `tell` ops
+      dout(1) << __func__ << ": cannot decode auth caps bl of length "
+             << caps_info.caps.length() << dendl;
+      ret = -EPERM;
     }
   }
-
-  return true;  // we made a decision (see is_valid)
+  return ret;
 }
 
-
 void MDSDaemon::ms_handle_accept(Connection *con)
 {
   Mutex::Locker l(mds_lock);
index 745b4042816e1d5538a4e418cd175b4da50b66ea..bd8f89e619b997999eee212a7d4545d6de387be0 100644 (file)
@@ -115,6 +115,7 @@ class MDSDaemon : public Dispatcher, public md_config_obs_t {
                               int protocol, bufferlist& authorizer_data, bufferlist& authorizer_reply,
                            bool& isvalid, CryptoKey& session_key,
                            std::unique_ptr<AuthAuthorizerChallenge> *challenge) override;
+  int ms_handle_authentication(Connection *con) override;
   void ms_handle_accept(Connection *con) override;
   void ms_handle_connect(Connection *con) override;
   bool ms_handle_reset(Connection *con) override;