mirror of
https://github.com/ceph/ceph
synced 2025-01-29 22:43:40 +00:00
mds: move session setup into ms_handle_authentication
Signed-off-by: Sage Weil <sage@redhat.com>
This commit is contained in:
parent
67d2f3b901
commit
ecbd4a8aa8
@ -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,84 +1336,93 @@ bool MDSDaemon::ms_verify_authorizer(Connection *con, int peer_type,
|
||||
}
|
||||
|
||||
if (is_valid) {
|
||||
entity_name_t n(con->get_peer_type(), 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.)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
ms_handle_authentication(con);
|
||||
}
|
||||
|
||||
return true; // we made a decision (see is_valid)
|
||||
return true;
|
||||
}
|
||||
|
||||
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 = 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.)
|
||||
}
|
||||
|
||||
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 ret;
|
||||
}
|
||||
|
||||
void MDSDaemon::ms_handle_accept(Connection *con)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user