diff options
author | Spencer Jackson <spencer.jackson@mongodb.com> | 2018-12-12 13:05:57 -0500 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2019-01-10 18:59:20 -0500 |
commit | bc5ac036a39627b9b2637665e7ac38853d049754 (patch) | |
tree | ce789bbe14d8e4780ae4b231e85487ada3423953 | |
parent | c1bc93bc4e903fd1ea5eb035023d5054c6c86497 (diff) | |
download | mongo-bc5ac036a39627b9b2637665e7ac38853d049754.tar.gz |
SERVER-38483 Convert options in sasl_options.cpp to IDL
-rw-r--r-- | src/mongo/db/auth/SConscript | 20 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_options.cpp | 207 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_options.h | 40 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_options.idl | 88 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_options_init.cpp | 93 | ||||
-rw-r--r-- | src/mongo/db/mongod_options_init.cpp | 2 | ||||
-rw-r--r-- | src/mongo/dbtests/framework_options_init.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/mongos_options_init.cpp | 2 |
8 files changed, 250 insertions, 207 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index 60700235c12..4f505f5c88a 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -271,6 +271,7 @@ env.Library( 'saslauth', ], LIBDEPS_PRIVATE=[ + 'sasl_options_init', '$BUILD_DIR/mongo/client/sasl_client', '$BUILD_DIR/mongo/db/audit', '$BUILD_DIR/mongo/db/commands', @@ -301,13 +302,26 @@ env.Library( ], LIBDEPS=[ '$BUILD_DIR/mongo/base', - '$BUILD_DIR/mongo/db/server_parameters', - '$BUILD_DIR/mongo/util/net/network', - '$BUILD_DIR/mongo/util/options_parser/options_parser', + '$BUILD_DIR/mongo/idl/server_parameter', ], ) env.Library( + target='sasl_options_init', + source=[ + 'sasl_options_init.cpp', + env.Idlc('sasl_options.idl')[0], + ], + LIBDEPS=[ + 'sasl_options' + ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/util/options_parser/options_parser', + '$BUILD_DIR/mongo/util/net/network', + ], +) + +env.Library( target='saslauth', source=[ 'sasl_mechanism_registry.cpp', diff --git a/src/mongo/db/auth/sasl_options.cpp b/src/mongo/db/auth/sasl_options.cpp index ab6152d7556..703c7ac07d9 100644 --- a/src/mongo/db/auth/sasl_options.cpp +++ b/src/mongo/db/auth/sasl_options.cpp @@ -28,216 +28,23 @@ * it in the license file. */ -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kAccessControl - #include "mongo/db/auth/sasl_options.h" +#include "mongo/db/auth/sasl_options_gen.h" -#include "mongo/base/status.h" -#include "mongo/db/server_parameters.h" -#include "mongo/util/log.h" -#include "mongo/util/mongoutils/str.h" -#include "mongo/util/net/socket_utils.h" -#include "mongo/util/options_parser/startup_option_init.h" -#include "mongo/util/options_parser/startup_options.h" +#include "mongo/util/text.h" namespace mongo { +const std::vector<std::string> SASLGlobalParams::kDefaultAuthenticationMechanisms = + std::vector<std::string>{"MONGODB-X509", "SCRAM-SHA-1", "SCRAM-SHA-256"}; SASLGlobalParams saslGlobalParams; -// For backward compatability purposes, "scramIterationCount" refers to the SHA-1 variant. -// The SHA-256 variant, as well as all future parameters, will use their specific name. -constexpr auto scramSHA1IterationCountServerParameter = "scramIterationCount"_sd; -constexpr auto scramSHA256IterationCountServerParameter = "scramSHA256IterationCount"_sd; - -const int defaultScramSHA1IterationCount = 10000; -const int minimumScramSHA1IterationCount = 5000; - -const int defaultScramSHA256IterationCount = 15000; -const int minimumScramSHA256IterationCount = 5000; - SASLGlobalParams::SASLGlobalParams() { - // Authentication mechanisms supported by default. - authenticationMechanisms.push_back("MONGODB-X509"); - authenticationMechanisms.push_back("SCRAM-SHA-1"); - authenticationMechanisms.push_back("SCRAM-SHA-256"); - - // Default iteration count for SCRAM authentication. - scramSHA1IterationCount.store(defaultScramSHA1IterationCount); - scramSHA256IterationCount.store(defaultScramSHA256IterationCount); + scramSHA1IterationCount.store(kScramIterationCountDefault); + scramSHA256IterationCount.store(kScramSHA256IterationCountDefault); + authenticationMechanisms = kDefaultAuthenticationMechanisms; // Default value for auth failed delay authFailedDelay.store(0); } - -Status addSASLOptions(moe::OptionSection* options) { - moe::OptionSection saslOptions("SASL Options"); - - saslOptions - .addOptionChaining("security.authenticationMechanisms", - "", - moe::StringVector, - "List of supported authentication mechanisms. " - "Default is SCRAM-SHA-1 and MONGODB-X509.") - .setSources(moe::SourceYAMLConfig); - - saslOptions - .addOptionChaining( - "security.sasl.hostName", "", moe::String, "Fully qualified server domain name") - .setSources(moe::SourceYAMLConfig); - - saslOptions - .addOptionChaining("security.sasl.serviceName", - "", - moe::String, - "Registered name of the service using SASL") - .setSources(moe::SourceYAMLConfig); - - saslOptions - .addOptionChaining("security.sasl.saslauthdSocketPath", - "", - moe::String, - "Path to Unix domain socket file for saslauthd") - .setSources(moe::SourceYAMLConfig); - - Status ret = options->addSection(saslOptions); - if (!ret.isOK()) { - log() << "Failed to add sasl option section: " << ret.toString(); - return ret; - } - - return Status::OK(); -} - -Status storeSASLOptions(const moe::Environment& params) { - bool haveAuthenticationMechanisms = false; - bool haveHostName = false; - bool haveServiceName = false; - bool haveAuthdPath = false; - bool haveScramSHA1IterationCount = false; - bool haveScramSHA256IterationCount = false; - int scramSHA1IterationCount = defaultScramSHA1IterationCount; - - // Check our setParameter options first so that these values can be properly overridden via - // the command line even though the options have different names. - if (params.count("setParameter")) { - std::map<std::string, std::string> parameters = - params["setParameter"].as<std::map<std::string, std::string>>(); - for (std::map<std::string, std::string>::iterator parametersIt = parameters.begin(); - parametersIt != parameters.end(); - parametersIt++) { - if (parametersIt->first == "authenticationMechanisms") { - haveAuthenticationMechanisms = true; - } else if (parametersIt->first == "saslHostName") { - haveHostName = true; - } else if (parametersIt->first == "saslServiceName") { - haveServiceName = true; - } else if (parametersIt->first == "saslauthdPath") { - haveAuthdPath = true; - } else if (parametersIt->first == scramSHA1IterationCountServerParameter) { - haveScramSHA1IterationCount = true; - // If the value here is non-numeric, atoi() will fail to parse. - // We can ignore that error since the ExportedServerParameter - // will catch it for us. - scramSHA1IterationCount = atoi(parametersIt->second.c_str()); - } else if (parametersIt->first == scramSHA256IterationCountServerParameter) { - haveScramSHA256IterationCount = true; - } - } - } - - if (params.count("security.authenticationMechanisms") && !haveAuthenticationMechanisms) { - saslGlobalParams.authenticationMechanisms = - params["security.authenticationMechanisms"].as<std::vector<std::string>>(); - } - if (params.count("security.sasl.hostName") && !haveHostName) { - saslGlobalParams.hostName = params["security.sasl.hostName"].as<std::string>(); - } - if (params.count("security.sasl.serviceName") && !haveServiceName) { - saslGlobalParams.serviceName = params["security.sasl.serviceName"].as<std::string>(); - } - if (params.count("security.sasl.saslauthdSocketPath") && !haveAuthdPath) { - saslGlobalParams.authdPath = params["security.sasl.saslauthdSocketPath"].as<std::string>(); - } - if (params.count("security.sasl.scramIterationCount") && !haveScramSHA1IterationCount) { - scramSHA1IterationCount = params["security.sasl.scramIterationCount"].as<int>(); - saslGlobalParams.scramSHA1IterationCount.store(scramSHA1IterationCount); - } - if (!haveScramSHA256IterationCount) { - if (params.count("security.sasl.scramSHA256IterationCount")) { - saslGlobalParams.scramSHA256IterationCount.store( - params["security.sasl.scramSHA256IterationCount"].as<int>()); - } else { - // If scramSHA256IterationCount isn't provided explicitly, - // then fall back on scramIterationCount if it is greater than - // the default scramSHA256IterationCount. - saslGlobalParams.scramSHA256IterationCount.store( - std::max<int>(scramSHA1IterationCount, defaultScramSHA256IterationCount)); - } - } - - if (saslGlobalParams.hostName.empty()) - saslGlobalParams.hostName = getHostNameCached(); - if (saslGlobalParams.serviceName.empty()) - saslGlobalParams.serviceName = "mongodb"; - - return Status::OK(); -} - -MONGO_MODULE_STARTUP_OPTIONS_REGISTER(SASLOptions)(InitializerContext* context) { - return addSASLOptions(&moe::startupOptions); -} - -MONGO_STARTUP_OPTIONS_STORE(SASLOptions)(InitializerContext* context) { - return storeSASLOptions(moe::startupOptionsParsed); -} - -// SASL Startup Parameters, making them settable via setParameter on the command line or in the -// legacy INI config file. None of these parameters are modifiable at runtime. -ExportedServerParameter<std::vector<std::string>, ServerParameterType::kStartupOnly> - SASLAuthenticationMechanismsSetting(ServerParameterSet::getGlobal(), - "authenticationMechanisms", - &saslGlobalParams.authenticationMechanisms); - -ExportedServerParameter<std::string, ServerParameterType::kStartupOnly> SASLHostNameSetting( - ServerParameterSet::getGlobal(), "saslHostName", &saslGlobalParams.hostName); - -ExportedServerParameter<std::string, ServerParameterType::kStartupOnly> SASLServiceNameSetting( - ServerParameterSet::getGlobal(), "saslServiceName", &saslGlobalParams.serviceName); - -ExportedServerParameter<std::string, ServerParameterType::kStartupOnly> SASLAuthdPathSetting( - ServerParameterSet::getGlobal(), "saslauthdPath", &saslGlobalParams.authdPath); - -class ExportedScramIterationCountParameter - : public ExportedServerParameter<int, ServerParameterType::kStartupAndRuntime> { -public: - ExportedScramIterationCountParameter(StringData name, AtomicWord<int>* value, int minimum) - : ExportedServerParameter<int, ServerParameterType::kStartupAndRuntime>( - ServerParameterSet::getGlobal(), name.toString(), value), - _minimum(minimum) {} - - virtual Status validate(const int& newValue) { - if (newValue < _minimum) { - return Status( - ErrorCodes::BadValue, - mongoutils::str::stream() << "Invalid value for SCRAM iteration count: " << newValue - << " is less than the minimum SCRAM iteration count, " - << _minimum); - } - - return Status::OK(); - } - -private: - int _minimum; -}; - -ExportedScramIterationCountParameter scramSHA1IterationCountParam( - scramSHA1IterationCountServerParameter, - &saslGlobalParams.scramSHA1IterationCount, - minimumScramSHA1IterationCount); -ExportedScramIterationCountParameter scramSHA256IterationCountParam( - scramSHA256IterationCountServerParameter, - &saslGlobalParams.scramSHA256IterationCount, - minimumScramSHA256IterationCount); - } // namespace mongo diff --git a/src/mongo/db/auth/sasl_options.h b/src/mongo/db/auth/sasl_options.h index b9df88e04cf..d71859911b2 100644 --- a/src/mongo/db/auth/sasl_options.h +++ b/src/mongo/db/auth/sasl_options.h @@ -46,7 +46,11 @@ class Environment; namespace moe = optionenvironment; +struct SASLGlobalParams; +extern SASLGlobalParams saslGlobalParams; struct SASLGlobalParams { + static const std::vector<std::string> kDefaultAuthenticationMechanisms; + std::vector<std::string> authenticationMechanisms; std::string hostName; std::string serviceName; @@ -56,9 +60,41 @@ struct SASLGlobalParams { AtomicWord<int> authFailedDelay; SASLGlobalParams(); -}; -extern SASLGlobalParams saslGlobalParams; + static Status onSetAuthenticationMechanism(const std::vector<std::string>&) { + saslGlobalParams.numTimesAuthenticationMechanismsSet++; + return Status::OK(); + } + + static Status onSetHostName(const std::string&) { + saslGlobalParams.haveHostName = true; + return Status::OK(); + } + static Status onSetServiceName(const std::string&) { + saslGlobalParams.haveServiceName = true; + return Status::OK(); + } + static Status onSetAuthdPath(const std::string&) { + saslGlobalParams.haveAuthdPath = true; + return Status::OK(); + } + static Status onSetScramSHA1IterationCount(const int) { + saslGlobalParams.numTimesScramSHA1IterationCountSet++; + return Status::OK(); + } + static Status onSetScramSHA256IterationCount(const int) { + saslGlobalParams.numTimesScramSHA256IterationCountSet++; + return Status::OK(); + } + + + int numTimesAuthenticationMechanismsSet = 0; + bool haveHostName = false; + bool haveServiceName = false; + bool haveAuthdPath = false; + int numTimesScramSHA1IterationCountSet = 0; + int numTimesScramSHA256IterationCountSet = 0; +}; Status addSASLOptions(moe::OptionSection* options); diff --git a/src/mongo/db/auth/sasl_options.idl b/src/mongo/db/auth/sasl_options.idl new file mode 100644 index 00000000000..5c6070e9701 --- /dev/null +++ b/src/mongo/db/auth/sasl_options.idl @@ -0,0 +1,88 @@ +# 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. +# + +global: + cpp_namespace: "mongo" + cpp_includes: + - "mongo/db/auth/sasl_options.h" + configs: + section: "SASL Options" + source: [ yaml ] + +server_parameters: + authenticationMechanisms: + description: "The set of accepted authentication mechanisms" + set_at: startup + default: + expr: 'SASLGlobalParams::kDefaultAuthenticationMechanisms' + is_constexpr: false + on_update: "SASLGlobalParams::onSetAuthenticationMechanism" + cpp_varname: "saslGlobalParams.authenticationMechanisms" + saslHostName: + description: "Overrides the automatically detected hostname used in SASL authentication" + set_at: startup + on_update: "SASLGlobalParams::onSetHostName" + cpp_varname: "saslGlobalParams.hostName" + saslServiceName: + description: "Override the default service name used in Kerberos authentication" + set_at: startup + on_update: "SASLGlobalParams::onSetServiceName" + cpp_varname: "saslGlobalParams.serviceName" + saslauthdPath: + description: "The path to a saslauthd Unix domain socket" + set_at: startup + on_update: "SASLGlobalParams::onSetAuthdPath" + cpp_varname: "saslGlobalParams.authdPath" + scramIterationCount: + description: "The number of times passwords are iteratively hashed for SCRAM-SHA-1" + set_at: [startup, runtime] + on_update: "SASLGlobalParams::onSetScramSHA1IterationCount" + cpp_varname: "saslGlobalParams.scramSHA1IterationCount" + default: 10000 + validator: {gte: 5000} + scramSHA256IterationCount: + description: "The number of times passwords are iteratively hashed for SCRAM-SHA-256" + set_at: [startup, runtime] + on_update: "SASLGlobalParams::onSetScramSHA256IterationCount" + cpp_varname: "saslGlobalParams.scramSHA256IterationCount" + default: 15000 + validator: {gte: 5000} + +configs: + "security.authenticationMechanisms": + description: "List of supported authentication mechanisms. Default is SCRAM-SHA-1 and MONGODB-X509." + arg_vartype: StringVector + "security.sasl.hostName": + description: "Fully qualified server domain name" + arg_vartype: String + "security.sasl.serviceName": + description: "Registered name of the service using SASL" + arg_vartype: String + "security.sasl.saslauthdSocketPath": + description: "Path to Unix domain socket file for saslauthd" + arg_vartype: String diff --git a/src/mongo/db/auth/sasl_options_init.cpp b/src/mongo/db/auth/sasl_options_init.cpp new file mode 100644 index 00000000000..a66d88dac0e --- /dev/null +++ b/src/mongo/db/auth/sasl_options_init.cpp @@ -0,0 +1,93 @@ + +/** + * 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. + */ + +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kAccessControl + +#include "mongo/db/auth/sasl_options.h" +#include "mongo/db/auth/sasl_options_gen.h" + +#include "mongo/base/status.h" +#include "mongo/db/server_parameters.h" +#include "mongo/util/log.h" +#include "mongo/util/mongoutils/str.h" +#include "mongo/util/net/socket_utils.h" +#include "mongo/util/options_parser/startup_option_init.h" +#include "mongo/util/options_parser/startup_options.h" + +namespace mongo { + +Status storeSASLOptions(const moe::Environment& params) { + int scramSHA1IterationCount = saslGlobalParams.scramSHA1IterationCount.load(); + + if (params.count("security.authenticationMechanisms") && + saslGlobalParams.numTimesAuthenticationMechanismsSet <= 1) { + saslGlobalParams.authenticationMechanisms = + params["security.authenticationMechanisms"].as<std::vector<std::string>>(); + } + if (params.count("security.sasl.hostName") && !saslGlobalParams.haveHostName) { + saslGlobalParams.hostName = params["security.sasl.hostName"].as<std::string>(); + } + if (params.count("security.sasl.serviceName") && !saslGlobalParams.haveServiceName) { + saslGlobalParams.serviceName = params["security.sasl.serviceName"].as<std::string>(); + } + if (params.count("security.sasl.saslauthdSocketPath") && !saslGlobalParams.haveAuthdPath) { + saslGlobalParams.authdPath = params["security.sasl.saslauthdSocketPath"].as<std::string>(); + } + if (params.count("security.sasl.scramIterationCount") && + saslGlobalParams.numTimesScramSHA1IterationCountSet <= 1) { + scramSHA1IterationCount = params["security.sasl.scramIterationCount"].as<int>(); + saslGlobalParams.scramSHA1IterationCount.store(scramSHA1IterationCount); + } + if (saslGlobalParams.numTimesScramSHA256IterationCountSet <= 1) { + if (params.count("security.sasl.scramSHA256IterationCount")) { + saslGlobalParams.scramSHA256IterationCount.store( + params["security.sasl.scramSHA256IterationCount"].as<int>()); + } else { + // If scramSHA256IterationCount isn't provided explicitly, + // then fall back on scramIterationCount if it is greater than + // the default scramSHA256IterationCount. + saslGlobalParams.scramSHA256IterationCount.store( + std::max<int>(scramSHA1IterationCount, kScramSHA256IterationCountDefault)); + } + } + + if (saslGlobalParams.hostName.empty()) + saslGlobalParams.hostName = getHostNameCached(); + if (saslGlobalParams.serviceName.empty()) + saslGlobalParams.serviceName = "mongodb"; + + return Status::OK(); +} + +MONGO_INITIALIZER_GENERAL(StoreSASLOptions, ("CoreOptions_Store"), ("EndStartupOptionStorage")) +(InitializerContext* const context) { + return storeSASLOptions(moe::startupOptionsParsed); +} +} diff --git a/src/mongo/db/mongod_options_init.cpp b/src/mongo/db/mongod_options_init.cpp index e6c239e1856..183c5c19a7d 100644 --- a/src/mongo/db/mongod_options_init.cpp +++ b/src/mongo/db/mongod_options_init.cpp @@ -70,7 +70,7 @@ MONGO_INITIALIZER_GENERAL(MongodOptions, return Status::OK(); } -MONGO_INITIALIZER_GENERAL(MongodOptions_Store, +MONGO_INITIALIZER_GENERAL(CoreOptions_Store, ("BeginStartupOptionStorage"), ("EndStartupOptionStorage")) (InitializerContext* context) { diff --git a/src/mongo/dbtests/framework_options_init.cpp b/src/mongo/dbtests/framework_options_init.cpp index 39236e9712e..0738e210ee2 100644 --- a/src/mongo/dbtests/framework_options_init.cpp +++ b/src/mongo/dbtests/framework_options_init.cpp @@ -63,4 +63,9 @@ MONGO_STARTUP_OPTIONS_STORE(FrameworkOptions)(InitializerContext* context) { } return Status::OK(); } + +MONGO_INITIALIZER_GENERAL(CoreOptions_Store, MONGO_NO_PREREQUISITES, MONGO_NO_DEPENDENTS) +(InitializerContext* context) { + return Status::OK(); +} } diff --git a/src/mongo/s/mongos_options_init.cpp b/src/mongo/s/mongos_options_init.cpp index f459ab62fab..377fe76323a 100644 --- a/src/mongo/s/mongos_options_init.cpp +++ b/src/mongo/s/mongos_options_init.cpp @@ -72,7 +72,7 @@ MONGO_INITIALIZER_GENERAL(MongosOptions, return Status::OK(); } -MONGO_INITIALIZER_GENERAL(MongosOptions_Store, +MONGO_INITIALIZER_GENERAL(CoreOptions_Store, ("BeginStartupOptionStorage"), ("EndStartupOptionStorage")) (InitializerContext* context) { |