diff options
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/auth/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/authentication_session.h | 9 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_commands.cpp | 74 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_commands.h | 42 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_options.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_options.idl | 2 | ||||
-rw-r--r-- | src/mongo/db/commands/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.cpp | 22 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.h | 5 | ||||
-rw-r--r-- | src/mongo/db/commands/server_status_servers.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/repl/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/replication_info.cpp | 27 | ||||
-rw-r--r-- | src/mongo/db/s/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/s/balancer/core_options_stub.cpp | 42 | ||||
-rw-r--r-- | src/mongo/db/stats/counters.cpp | 59 | ||||
-rw-r--r-- | src/mongo/db/stats/counters.h | 27 |
16 files changed, 320 insertions, 20 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index 6c579a188eb..a7cce5850bb 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -245,6 +245,7 @@ env.Library( '$BUILD_DIR/mongo/db/commands', '$BUILD_DIR/mongo/db/commands/authentication_commands', '$BUILD_DIR/mongo/db/commands/test_commands_enabled', + '$BUILD_DIR/mongo/db/stats/counters', 'sasl_options_init', ], ) @@ -271,6 +272,7 @@ env.Library( ], LIBDEPS=[ '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/stats/counters', '$BUILD_DIR/mongo/idl/server_parameter', ], ) diff --git a/src/mongo/db/auth/authentication_session.h b/src/mongo/db/auth/authentication_session.h index 5a26c46efd4..ff86ea7ca08 100644 --- a/src/mongo/db/auth/authentication_session.h +++ b/src/mongo/db/auth/authentication_session.h @@ -45,8 +45,8 @@ class AuthenticationSession { AuthenticationSession& operator=(const AuthenticationSession&) = delete; public: - explicit AuthenticationSession(std::unique_ptr<ServerMechanismBase> mech) - : _mech(std::move(mech)) {} + explicit AuthenticationSession(std::unique_ptr<ServerMechanismBase> mech, bool speculative) + : _mech(std::move(mech)), _speculative(speculative) {} /** * Sets the authentication session for the given "client" to "newSession". @@ -72,8 +72,13 @@ public: return _mech->setOptions(options); } + bool isSpeculative() const { + return _speculative; + } + private: std::unique_ptr<ServerMechanismBase> _mech; + bool _speculative{false}; }; } // namespace mongo diff --git a/src/mongo/db/auth/sasl_commands.cpp b/src/mongo/db/auth/sasl_commands.cpp index 1932b7e9a4e..a6276d3fec9 100644 --- a/src/mongo/db/auth/sasl_commands.cpp +++ b/src/mongo/db/auth/sasl_commands.cpp @@ -39,6 +39,7 @@ #include "mongo/bson/mutable/algorithm.h" #include "mongo/bson/mutable/document.h" #include "mongo/bson/util/bson_extract.h" +#include "mongo/client/authenticate.h" #include "mongo/client/sasl_client_authenticate.h" #include "mongo/db/audit.h" #include "mongo/db/auth/authentication_session.h" @@ -51,6 +52,7 @@ #include "mongo/db/commands.h" #include "mongo/db/commands/authentication_commands.h" #include "mongo/db/server_options.h" +#include "mongo/db/stats/counters.h" #include "mongo/util/base64.h" #include "mongo/util/log.h" #include "mongo/util/sequence_util.h" @@ -125,6 +127,7 @@ public: CmdSaslStart cmdSaslStart; CmdSaslContinue cmdSaslContinue; + Status buildResponse(const AuthenticationSession* session, const std::string& responsePayload, BSONType responsePayloadType, @@ -212,6 +215,9 @@ Status doSaslStep(OperationContext* opCtx, << " on " << mechanism.getAuthenticationDatabase() << " from client " << opCtx->getClient()->session()->remote(); } + if (session->isSpeculative()) { + authCounter.incSpeculativeAuthenticateSuccessful(mechanism.mechanismName().toString()); + } } return Status::OK(); } @@ -220,7 +226,8 @@ StatusWith<std::unique_ptr<AuthenticationSession>> doSaslStart(OperationContext* const std::string& db, const BSONObj& cmdObj, BSONObjBuilder* result, - std::string* principalName) { + std::string* principalName, + bool speculative) { bool autoAuthorize = false; Status status = bsonExtractBooleanFieldWithDefault( cmdObj, saslCommandAutoAuthorizeFieldName, autoAuthorizeDefault, &autoAuthorize); @@ -240,7 +247,16 @@ StatusWith<std::unique_ptr<AuthenticationSession>> doSaslStart(OperationContext* return swMech.getStatus(); } - auto session = std::make_unique<AuthenticationSession>(std::move(swMech.getValue())); + auto session = + std::make_unique<AuthenticationSession>(std::move(swMech.getValue()), speculative); + + if (speculative && + !session->getMechanism().properties().hasAllProperties( + SecurityPropertySet({SecurityProperty::kNoPlainText}))) { + return {ErrorCodes::BadValue, + "Plaintext mechanisms may not be used with speculativeSaslStart"}; + } + auto options = cmdObj["options"]; if (!options.eoo()) { if (options.type() != Object) { @@ -280,17 +296,11 @@ Status doSaslContinue(OperationContext* opCtx, return doSaslStep(opCtx, session, cmdObj, result); } -CmdSaslStart::CmdSaslStart() : BasicCommand(saslStartCommandName) {} -CmdSaslStart::~CmdSaslStart() {} - -std::string CmdSaslStart::help() const { - return "First step in a SASL authentication conversation."; -} - -bool CmdSaslStart::run(OperationContext* opCtx, - const std::string& db, - const BSONObj& cmdObj, - BSONObjBuilder& result) { +bool runSaslStart(OperationContext* opCtx, + const std::string& db, + const BSONObj& cmdObj, + BSONObjBuilder& result, + bool speculative) { opCtx->markKillOnClientDisconnect(); Client* client = opCtx->getClient(); AuthenticationSession::set(client, std::unique_ptr<AuthenticationSession>()); @@ -301,7 +311,7 @@ bool CmdSaslStart::run(OperationContext* opCtx, } std::string principalName; - auto swSession = doSaslStart(opCtx, db, cmdObj, &result, &principalName); + auto swSession = doSaslStart(opCtx, db, cmdObj, &result, &principalName, speculative); if (!swSession.isOK() || swSession.getValue()->getMechanism().isSuccess()) { audit::logAuthentication( @@ -315,6 +325,20 @@ bool CmdSaslStart::run(OperationContext* opCtx, return true; } +CmdSaslStart::CmdSaslStart() : BasicCommand(saslStartCommandName) {} +CmdSaslStart::~CmdSaslStart() {} + +std::string CmdSaslStart::help() const { + return "First step in a SASL authentication conversation."; +} + +bool CmdSaslStart::run(OperationContext* opCtx, + const std::string& db, + const BSONObj& cmdObj, + BSONObjBuilder& result) { + return runSaslStart(opCtx, db, cmdObj, result, false); +} + CmdSaslContinue::CmdSaslContinue() : BasicCommand(saslContinueCommandName) {} CmdSaslContinue::~CmdSaslContinue() {} @@ -371,4 +395,26 @@ MONGO_INITIALIZER(PreSaslCommands) } } // namespace + +void doSpeculativeSaslStart(OperationContext* opCtx, BSONObj cmdObj, BSONObjBuilder* result) try { + auto mechElem = cmdObj["mechanism"]; + if (mechElem.type() != String) { + return; + } + + authCounter.incSpeculativeAuthenticateReceived(mechElem.String()); + + auto dbElement = cmdObj["db"]; + if (dbElement.type() != String) { + return; + } + + BSONObjBuilder saslStartResult; + if (runSaslStart(opCtx, dbElement.String(), cmdObj, saslStartResult, true)) { + result->append(auth::kSpeculativeAuthenticate, saslStartResult.obj()); + } +} catch (...) { + // Treat failure like we never even got a speculative start. +} + } // namespace mongo diff --git a/src/mongo/db/auth/sasl_commands.h b/src/mongo/db/auth/sasl_commands.h new file mode 100644 index 00000000000..394e6034b0c --- /dev/null +++ b/src/mongo/db/auth/sasl_commands.h @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2018-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/bson/bsonobj.h" +#include "mongo/bson/bsonobjbuilder.h" + +namespace mongo { +class OperationContext; + +/** + * Handle isMaster: { speculativeAuthenticate: {...} } + */ +void doSpeculativeSaslStart(OperationContext* opCtx, BSONObj cmdObj, BSONObjBuilder* result); +} // namespace mongo diff --git a/src/mongo/db/auth/sasl_options.cpp b/src/mongo/db/auth/sasl_options.cpp index ac23ebf6618..d390ad99524 100644 --- a/src/mongo/db/auth/sasl_options.cpp +++ b/src/mongo/db/auth/sasl_options.cpp @@ -29,6 +29,7 @@ #include "mongo/db/auth/sasl_options.h" #include "mongo/db/auth/sasl_options_gen.h" +#include "mongo/db/stats/counters.h" #include "mongo/util/text.h" @@ -46,4 +47,13 @@ SASLGlobalParams::SASLGlobalParams() { // Default value for auth failed delay authFailedDelay.store(0); } + +namespace { +MONGO_INITIALIZER_WITH_PREREQUISITES(InitSpeculativeCounters, ("EndStartupOptionStorage")) +(InitializerContext*) { + authCounter.initializeMechanismMap(saslGlobalParams.authenticationMechanisms); + return Status::OK(); +} +} // namespace + } // namespace mongo diff --git a/src/mongo/db/auth/sasl_options.idl b/src/mongo/db/auth/sasl_options.idl index 5c6070e9701..c3753ff8d95 100644 --- a/src/mongo/db/auth/sasl_options.idl +++ b/src/mongo/db/auth/sasl_options.idl @@ -36,6 +36,8 @@ global: server_parameters: authenticationMechanisms: + # Note: mongo/db/stats/counter.cpp makes the assumption that this + # setting will never be changed at runtime. description: "The set of accepted authentication mechanisms" set_at: startup default: diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index 568e23c6272..679571a308f 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -192,6 +192,7 @@ env.Library( '$BUILD_DIR/mongo/db/auth/sasl_options', '$BUILD_DIR/mongo/db/auth/user_document_parser', '$BUILD_DIR/mongo/db/commands', + '$BUILD_DIR/mongo/db/stats/counters', '$BUILD_DIR/mongo/util/net/ssl_manager', ] ) diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index dd273d77faa..d51d9815d08 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -40,6 +40,7 @@ #include "mongo/base/status.h" #include "mongo/bson/mutable/algorithm.h" #include "mongo/bson/mutable/document.h" +#include "mongo/client/authenticate.h" #include "mongo/client/sasl_client_authenticate.h" #include "mongo/config.h" #include "mongo/db/audit.h" @@ -52,6 +53,7 @@ #include "mongo/db/commands.h" #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/operation_context.h" +#include "mongo/db/stats/counters.h" #include "mongo/platform/random.h" #include "mongo/rpc/metadata/client_metadata.h" #include "mongo/rpc/metadata/client_metadata_ismaster.h" @@ -360,4 +362,24 @@ void disableAuthMechanism(StringData authMechanism) { } } +void doSpeculativeAuthenticate(OperationContext* opCtx, + BSONObj cmdObj, + BSONObjBuilder* result) try { + auto mechElem = cmdObj["mechanism"]; + if (mechElem.type() != String) { + return; + } + + auto mechanism = mechElem.String(); + authCounter.incSpeculativeAuthenticateReceived(mechanism); + + BSONObjBuilder authResult; + if (cmdAuthenticate.run(opCtx, "$external", cmdObj, authResult)) { + authCounter.incSpeculativeAuthenticateSuccessful(mechanism); + result->append(auth::kSpeculativeAuthenticate, authResult.obj()); + } +} catch (...) { + // Treat failure like we never even got a speculative start. +} + } // namespace mongo diff --git a/src/mongo/db/commands/authentication_commands.h b/src/mongo/db/commands/authentication_commands.h index d6193a8f4ac..c211b799ef2 100644 --- a/src/mongo/db/commands/authentication_commands.h +++ b/src/mongo/db/commands/authentication_commands.h @@ -30,11 +30,16 @@ #pragma once #include "mongo/base/string_data.h" +#include "mongo/bson/bsonobj.h" +#include "mongo/bson/bsonobjbuilder.h" namespace mongo { +class OperationContext; constexpr StringData kX509AuthMechanism = "MONGODB-X509"_sd; void disableAuthMechanism(StringData authMechanism); +void doSpeculativeAuthenticate(OperationContext* opCtx, BSONObj isMaster, BSONObjBuilder* result); + } // namespace mongo diff --git a/src/mongo/db/commands/server_status_servers.cpp b/src/mongo/db/commands/server_status_servers.cpp index e85301b7b7a..a3d23061823 100644 --- a/src/mongo/db/commands/server_status_servers.cpp +++ b/src/mongo/db/commands/server_status_servers.cpp @@ -95,7 +95,6 @@ public: } network; -#ifdef MONGO_CONFIG_SSL class Security : public ServerStatusSection { public: Security() : ServerStatusSection("security") {} @@ -106,15 +105,23 @@ public: BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const override { - BSONObj result; + BSONObjBuilder result; + + BSONObjBuilder auth; + authCounter.append(&auth); + result.append("authentication", auth.obj()); + +#ifdef MONGO_CONFIG_SSL if (getSSLManager()) { - result = getSSLManager()->getSSLConfiguration().getServerStatusBSON(); + getSSLManager()->getSSLConfiguration().getServerStatusBSON(&result); } +#endif - return result; + return result.obj(); } } security; +#ifdef MONGO_CONFIG_SSL /** * Status section of which tls versions connected to MongoDB and completed an SSL handshake. * Note: Clients are only not counted if they try to connect to the server with a unsupported TLS diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript index 6efb849fc51..204e8042cd2 100644 --- a/src/mongo/db/repl/SConscript +++ b/src/mongo/db/repl/SConscript @@ -1128,6 +1128,8 @@ env.Library( 'replica_set_messages', ], LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/db/auth/authservercommon', + '$BUILD_DIR/mongo/db/commands/authentication_commands', '$BUILD_DIR/mongo/db/commands/server_status', '$BUILD_DIR/mongo/db/stats/counters', '$BUILD_DIR/mongo/transport/message_compressor', diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index 1f1d071e29a..6d65ffb2bd4 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -36,8 +36,11 @@ #include "mongo/bson/util/bson_extract.h" #include "mongo/client/connpool.h" #include "mongo/client/dbclient_connection.h" +#include "mongo/db/auth/sasl_command_constants.h" +#include "mongo/db/auth/sasl_commands.h" #include "mongo/db/auth/sasl_mechanism_registry.h" #include "mongo/db/client.h" +#include "mongo/db/commands/authentication_commands.h" #include "mongo/db/commands/server_status.h" #include "mongo/db/db_raii.h" #include "mongo/db/dbhelpers.h" @@ -516,6 +519,30 @@ public: } } + if (auto sae = cmdObj[auth::kSpeculativeAuthenticate]; !sae.eoo()) { + uassert(ErrorCodes::BadValue, + str::stream() << "isMaster." << auth::kSpeculativeAuthenticate + << " must be an Object", + sae.type() == Object); + auto specAuth = sae.Obj(); + + uassert(ErrorCodes::BadValue, + str::stream() << "isMaster." << auth::kSpeculativeAuthenticate + << " must be a non-empty Object", + !specAuth.isEmpty()); + auto specCmd = specAuth.firstElementFieldNameStringData(); + + if (specCmd == saslStartCommandName) { + doSpeculativeSaslStart(opCtx, specAuth, &result); + } else if (specCmd == auth::kAuthenticateCommand) { + doSpeculativeAuthenticate(opCtx, specAuth, &result); + } else { + uasserted(51769, + str::stream() << "isMaster." << auth::kSpeculativeAuthenticate + << " unknown command: " << specCmd); + } + } + return true; } } cmdismaster; diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 976282cf4c3..d7bf39ae0d9 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -352,6 +352,7 @@ env.CppUnitTest( 'balancer/balancer_chunk_selection_policy_test.cpp', 'balancer/balancer_policy_test.cpp', 'balancer/cluster_statistics_test.cpp', + 'balancer/core_options_stub.cpp', 'balancer/migration_manager_test.cpp', 'balancer/migration_test_fixture.cpp', 'balancer/scoped_migration_request_test.cpp', diff --git a/src/mongo/db/s/balancer/core_options_stub.cpp b/src/mongo/db/s/balancer/core_options_stub.cpp new file mode 100644 index 00000000000..2b9c5d8b837 --- /dev/null +++ b/src/mongo/db/s/balancer/core_options_stub.cpp @@ -0,0 +1,42 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/base/init.h" +#include "mongo/base/status.h" + +namespace mongo { +namespace { +MONGO_INITIALIZER_GENERAL(CoreOptions_Store, + ("BeginStartupOptionStorage"), + ("EndStartupOptionStorage")) +(InitializerContext* context) { + return Status::OK(); +} +} // namespace +} // namespace mongo diff --git a/src/mongo/db/stats/counters.cpp b/src/mongo/db/stats/counters.cpp index 6cc06589d78..8e4458db7a7 100644 --- a/src/mongo/db/stats/counters.cpp +++ b/src/mongo/db/stats/counters.cpp @@ -33,6 +33,7 @@ #include "mongo/db/stats/counters.h" +#include "mongo/client/authenticate.h" #include "mongo/db/jsobj.h" #include "mongo/util/log.h" @@ -168,7 +169,65 @@ void NetworkCounter::append(BSONObjBuilder& b) { b.append("tcpFastOpen", tfo.obj()); } +void AuthCounter::initializeMechanismMap(const std::vector<std::string>& mechanisms) { + invariant(_mechanisms.empty()); + + for (const auto& mech : mechanisms) { + _mechanisms.emplace( + std::piecewise_construct, std::forward_as_tuple(mech), std::forward_as_tuple()); + } +} + +void AuthCounter::incSpeculativeAuthenticateReceived(const std::string& mechanism) try { + _mechanisms.at(mechanism).speculativeAuthenticate.received.fetchAndAddRelaxed(1); +} catch (const std::out_of_range&) { + uasserted(51767, + str::stream() << "Received " << auth::kSpeculativeAuthenticate << " for mechanism " + << mechanism << " which is unknown or not enabled"); +} + +void AuthCounter::incSpeculativeAuthenticateSuccessful(const std::string& mechanism) try { + _mechanisms.at(mechanism).speculativeAuthenticate.successful.fetchAndAddRelaxed(1); +} catch (const std::out_of_range&) { + // Should never actually occur since it'd mean we succeeded at a mechanism + // we're not configured for. + uasserted(51768, + str::stream() << "Unexpectedly succeeded at " << auth::kSpeculativeAuthenticate + << " for " << mechanism << " which is not enabled"); +} + +/** + * authentication: { + * "mechanisms": { + * "SCRAM-SHA-256": { + * "speculativeAuthenticate": { received: ###, successful: ### }, + * }, + * "MONGODB-X509": { + * "speculativeAuthenticate": { received: ###, successful: ### }, + * }, + * }, + * } + */ +void AuthCounter::append(BSONObjBuilder* b) { + BSONObjBuilder mechsBuilder(b->subobjStart("mechanisms")); + + for (const auto& it : _mechanisms) { + const auto received = it.second.speculativeAuthenticate.received.load(); + const auto successful = it.second.speculativeAuthenticate.successful.load(); + + BSONObjBuilder mechBuilder(mechsBuilder.subobjStart(it.first)); + BSONObjBuilder specAuthBuilder(mechBuilder.subobjStart(auth::kSpeculativeAuthenticate)); + specAuthBuilder.append("received", received); + specAuthBuilder.append("successful", successful); + specAuthBuilder.done(); + mechBuilder.done(); + } + + mechsBuilder.done(); +} + OpCounters globalOpCounters; OpCounters replOpCounters; NetworkCounter networkCounter; +AuthCounter authCounter; } // namespace mongo diff --git a/src/mongo/db/stats/counters.h b/src/mongo/db/stats/counters.h index 0afb3c6756c..edc17eee2bd 100644 --- a/src/mongo/db/stats/counters.h +++ b/src/mongo/db/stats/counters.h @@ -29,6 +29,8 @@ #pragma once +#include <map> + #include "mongo/db/jsobj.h" #include "mongo/platform/atomic_word.h" #include "mongo/platform/basic.h" @@ -165,4 +167,29 @@ private: }; extern NetworkCounter networkCounter; + +class AuthCounter { +public: + void incSpeculativeAuthenticateReceived(const std::string& mechanism); + void incSpeculativeAuthenticateSuccessful(const std::string& mechanism); + + void append(BSONObjBuilder*); + + void initializeMechanismMap(const std::vector<std::string>&); + +private: + struct MechanismData { + struct { + AtomicWord<long long> received; + AtomicWord<long long> successful; + } speculativeAuthenticate; + }; + using MechanismMap = std::map<std::string, MechanismData>; + + // Mechanism maps are initialized at startup to contain all + // mechanisms known to authenticationMechanisms setParam. + // After that they are kept to a fixed size. + MechanismMap _mechanisms; +}; +extern AuthCounter authCounter; } // namespace mongo |