summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/auth/auth_options.idl6
-rw-r--r--src/mongo/db/commands/SConscript2
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp74
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp1
-rw-r--r--src/mongo/db/commands/user_management_commands.idl8
-rw-r--r--src/mongo/executor/network_interface_integration_fixture.cpp7
-rw-r--r--src/mongo/executor/network_interface_integration_fixture.h2
-rw-r--r--src/mongo/executor/network_interface_integration_test.cpp7
-rw-r--r--src/mongo/shell/shardingtest.js39
-rw-r--r--src/mongo/util/net/SConscript1
-rw-r--r--src/mongo/util/net/network_interface_ssl_test.cpp8
-rw-r--r--src/mongo/util/net/ssl_options_server.cpp7
12 files changed, 98 insertions, 64 deletions
diff --git a/src/mongo/db/auth/auth_options.idl b/src/mongo/db/auth/auth_options.idl
index 488e311ee75..a0d5139938a 100644
--- a/src/mongo/db/auth/auth_options.idl
+++ b/src/mongo/db/auth/auth_options.idl
@@ -42,3 +42,9 @@ server_parameters:
cpp_vartype: bool
cpp_varname: roleGraphInvalidationIsFatal
test_only: true
+ enforceUserClusterSeparation:
+ description: "Prevents creation of users whose names would be interpreted as cluster members"
+ set_at: startup
+ cpp_varname: "gEnforceUserClusterSeparation"
+ cpp_vartype: bool
+ default: true
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index a95cdedef92..ee9aeb89c8f 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -201,6 +201,7 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/bson/mutable/mutable_bson',
'$BUILD_DIR/mongo/db/auth/auth',
+ '$BUILD_DIR/mongo/db/auth/auth_options',
'$BUILD_DIR/mongo/db/auth/authentication_session',
'$BUILD_DIR/mongo/db/commands',
'$BUILD_DIR/mongo/rpc/client_metadata',
@@ -477,6 +478,7 @@ env.Library(
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/client/clientdriver_minimal',
'$BUILD_DIR/mongo/db/auth/auth',
+ '$BUILD_DIR/mongo/db/auth/auth_options',
'$BUILD_DIR/mongo/db/auth/authprivilege',
'$BUILD_DIR/mongo/db/auth/builtin_roles',
'$BUILD_DIR/mongo/db/auth/sasl_options',
diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp
index 2ed31e74055..0f5b5b7a546 100644
--- a/src/mongo/db/commands/authentication_commands.cpp
+++ b/src/mongo/db/commands/authentication_commands.cpp
@@ -43,6 +43,7 @@
#include "mongo/client/authenticate.h"
#include "mongo/client/sasl_client_authenticate.h"
#include "mongo/config.h"
+#include "mongo/db/auth/auth_options_gen.h"
#include "mongo/db/auth/authentication_session.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
@@ -52,6 +53,7 @@
#include "mongo/db/commands.h"
#include "mongo/db/commands/authentication_commands_gen.h"
#include "mongo/db/commands/test_commands_enabled.h"
+#include "mongo/db/commands/user_management_commands_gen.h"
#include "mongo/db/operation_context.h"
#include "mongo/logv2/log.h"
#include "mongo/platform/random.h"
@@ -223,10 +225,6 @@ void _authenticateX509(OperationContext* opCtx, AuthenticationSession* session)
"SSL support is required for the MONGODB-X509 mechanism.",
opCtx->getClient()->session()->getSSLManager());
- uassert(ErrorCodes::ProtocolError,
- "X.509 authentication must always use the $external database.",
- user.getDB() == "$external");
-
AuthorizationSession* authorizationSession = AuthorizationSession::get(client);
auto sslConfiguration = opCtx->getClient()->session()->getSSLConfiguration();
@@ -235,39 +233,51 @@ void _authenticateX509(OperationContext* opCtx, AuthenticationSession* session)
"Unable to verify x.509 certificate, as no CA has been provided.",
sslConfiguration->hasCA);
- // Handle internal cluster member auth, only applies to server-server connections
- if (sslConfiguration->isClusterMember(clientName)) {
- int clusterAuthMode = serverGlobalParams.clusterAuthMode.load();
-
- uassert(ErrorCodes::AuthenticationFailed,
- "The provided certificate "
- "can only be used for cluster authentication, not client "
- "authentication. The current configuration does not allow "
- "x.509 cluster authentication, check the --clusterAuthMode flag",
- clusterAuthMode != ServerGlobalParams::ClusterAuthMode_undefined &&
- clusterAuthMode != ServerGlobalParams::ClusterAuthMode_keyFile);
-
- if (auto clientMetadata = ClientMetadata::get(opCtx->getClient())) {
- auto clientMetadataDoc = clientMetadata->getDocument();
- auto driverName = clientMetadataDoc.getObjectField("driver"_sd)
- .getField("name"_sd)
- .checkAndGetStringData();
- if (!clientMetadata->getApplicationName().empty() ||
- (driverName != "MongoDB Internal Client" && driverName != "NetworkInterfaceTL")) {
- LOGV2_WARNING(20430,
- "Client isn't a mongod or mongos, but is connecting with a "
- "certificate with cluster membership");
- }
- }
+ uassert(ErrorCodes::ProtocolError,
+ "X.509 authentication must always use the $external database.",
+ user.getDB() == kExternalDB);
- session->setAsClusterMember();
- authorizationSession->grantInternalAuthorization(client);
- } else {
- // Handle normal client authentication, only applies to client-server connections
+ auto isInternalClient = [&]() -> bool {
+ return opCtx->getClient()->session()->getTags() & transport::Session::kInternalClient;
+ };
+
+ auto authorizeExternalUser = [&] {
uassert(ErrorCodes::BadValue,
kX509AuthenticationDisabledMessage,
!isX509AuthDisabled(opCtx->getServiceContext()));
uassertStatusOK(authorizationSession->addAndAuthorizeUser(opCtx, user));
+ };
+
+ if (sslConfiguration->isClusterMember(clientName)) {
+ // Handle internal cluster member auth, only applies to server-server connections
+ switch (serverGlobalParams.clusterAuthMode.load()) {
+ case ServerGlobalParams::ClusterAuthMode_undefined:
+ case ServerGlobalParams::ClusterAuthMode_keyFile: {
+ uassert(ErrorCodes::AuthenticationFailed,
+ "The provided certificate can only be used for cluster authentication, not "
+ "client authentication. The current configuration does not allow x.509 "
+ "cluster authentication, check the --clusterAuthMode flag",
+ !gEnforceUserClusterSeparation);
+
+ authorizeExternalUser();
+ } break;
+ case ServerGlobalParams::ClusterAuthMode_sendKeyFile:
+ case ServerGlobalParams::ClusterAuthMode_sendX509:
+ case ServerGlobalParams::ClusterAuthMode_x509: {
+ if (!isInternalClient()) {
+ LOGV2_WARNING(
+ 20430,
+ "Client isn't a mongod or mongos, but is connecting with a certificate "
+ "with cluster membership");
+ }
+
+ session->setAsClusterMember();
+ authorizationSession->grantInternalAuthorization(client);
+ } break;
+ };
+ } else {
+ // Handle normal client authentication, only applies to client-server connections
+ authorizeExternalUser();
}
}
#endif // MONGO_CONFIG_SSL
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index 5462ae4ccb0..3336a1787b3 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -46,6 +46,7 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/address_restriction.h"
+#include "mongo/db/auth/auth_options_gen.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege_parser.h"
diff --git a/src/mongo/db/commands/user_management_commands.idl b/src/mongo/db/commands/user_management_commands.idl
index d4dec18cb61..6c7b47ebf44 100644
--- a/src/mongo/db/commands/user_management_commands.idl
+++ b/src/mongo/db/commands/user_management_commands.idl
@@ -34,14 +34,6 @@ imports:
- "mongo/db/auth/address_restriction.idl"
- "mongo/db/auth/user_management_commands_parser.idl"
-server_parameters:
- enforceUserClusterSeparation:
- description: "Prevents creation of users whose names would be interpreted as cluster members"
- set_at: startup
- cpp_varname: "gEnforceUserClusterSeparation"
- cpp_vartype: bool
- default: true
-
structs:
dropAllUsersFromDatabaseReply:
description: "Response for dropAllUsersFromDatabase command"
diff --git a/src/mongo/executor/network_interface_integration_fixture.cpp b/src/mongo/executor/network_interface_integration_fixture.cpp
index 62e452e8c69..c3401173cc1 100644
--- a/src/mongo/executor/network_interface_integration_fixture.cpp
+++ b/src/mongo/executor/network_interface_integration_fixture.cpp
@@ -34,6 +34,7 @@
#include <memory>
#include "mongo/client/connection_string.h"
+#include "mongo/db/wire_version.h"
#include "mongo/executor/network_interface_factory.h"
#include "mongo/executor/network_interface_integration_fixture.h"
#include "mongo/executor/remote_command_response.h"
@@ -91,6 +92,12 @@ PseudoRandom* NetworkInterfaceIntegrationFixture::getRandomNumberGenerator() {
return _rng;
}
+void NetworkInterfaceIntegrationFixture::resetIsInternalClient(bool isInternalClient) {
+ WireSpec::Specification newSpec = *WireSpec::instance().get();
+ newSpec.isInternalClient = isInternalClient;
+ WireSpec::instance().reset(std::move(newSpec));
+}
+
void NetworkInterfaceIntegrationFixture::startCommand(const TaskExecutor::CallbackHandle& cbHandle,
RemoteCommandRequest& request,
StartCommandCB onFinish) {
diff --git a/src/mongo/executor/network_interface_integration_fixture.h b/src/mongo/executor/network_interface_integration_fixture.h
index 226bce34a5c..3fd1e58413d 100644
--- a/src/mongo/executor/network_interface_integration_fixture.h
+++ b/src/mongo/executor/network_interface_integration_fixture.h
@@ -75,6 +75,8 @@ public:
void setRandomNumberGenerator(PseudoRandom* generator);
+ void resetIsInternalClient(bool isInternalClient);
+
PseudoRandom* getRandomNumberGenerator();
void startCommand(const TaskExecutor::CallbackHandle& cbHandle,
diff --git a/src/mongo/executor/network_interface_integration_test.cpp b/src/mongo/executor/network_interface_integration_test.cpp
index 2496454d7c0..c5b23cd8a15 100644
--- a/src/mongo/executor/network_interface_integration_test.cpp
+++ b/src/mongo/executor/network_interface_integration_test.cpp
@@ -37,7 +37,6 @@
#include "mongo/base/status_with.h"
#include "mongo/client/connection_string.h"
-#include "mongo/db/wire_version.h"
#include "mongo/executor/connection_pool_stats.h"
#include "mongo/executor/network_connection_hook.h"
#include "mongo/executor/network_interface_integration_fixture.h"
@@ -151,12 +150,6 @@ public:
constexpr static Milliseconds kNoTimeout = RemoteCommandRequest::kNoTimeout;
constexpr static Milliseconds kMaxWait = Milliseconds(Minutes(1));
- void resetIsInternalClient(bool isInternalClient) {
- WireSpec::Specification newSpec = *WireSpec::instance().get();
- newSpec.isInternalClient = isInternalClient;
- WireSpec::instance().reset(std::move(newSpec));
- }
-
void assertNumOps(uint64_t canceled, uint64_t timedOut, uint64_t failed, uint64_t succeeded) {
auto counters = net().getCounters();
ASSERT_EQ(canceled, counters.canceled);
diff --git a/src/mongo/shell/shardingtest.js b/src/mongo/shell/shardingtest.js
index 2087653e897..d19ed6bdad9 100644
--- a/src/mongo/shell/shardingtest.js
+++ b/src/mongo/shell/shardingtest.js
@@ -393,6 +393,27 @@ var ShardingTest = function(params) {
}
};
+ this.stopAllConfigServers = function(opts) {
+ if (this.configRS) {
+ this.configRS.stopSet(undefined, undefined, opts);
+ } else {
+ // Old style config triplet
+ for (var i = 0; i < this._configServers.length; i++) {
+ this.stopConfigServer(i, opts);
+ }
+ }
+ };
+
+ this.stopAllShards = function(opts) {
+ for (var i = 0; i < this._connections.length; i++) {
+ if (this._rs[i]) {
+ this._rs[i].test.stopSet(15, undefined, opts);
+ } else {
+ this.stopMongod(i, opts);
+ }
+ }
+ };
+
this.stopAllMongos = function(opts) {
for (var i = 0; i < this._mongos.length; i++) {
this.stopMongos(i, opts);
@@ -415,25 +436,11 @@ var ShardingTest = function(params) {
this.stopAllMongos(opts);
let startTime = new Date(); // Measure the execution time of shutting down shards.
- for (var i = 0; i < this._connections.length; i++) {
- if (this._rs[i]) {
- this._rs[i].test.stopSet(15, undefined, opts);
- } else {
- this.stopMongod(i, opts);
- }
- }
+ this.stopAllShards(opts);
print("ShardingTest stopped all shards, took " + (new Date() - startTime) + "ms for " +
this._connections.length + " shards.");
- if (this.configRS) {
- this.configRS.stopSet(undefined, undefined, opts);
- } else {
- // Old style config triplet
- for (var i = 0; i < this._configServers.length; i++) {
- this.stopConfigServer(i, opts);
- }
- }
-
+ this.stopAllConfigServers(opts);
if (!opts.noCleanData) {
print("ShardingTest stop deleting all dbpaths");
for (var i = 0; i < _alldbpaths.length; i++) {
diff --git a/src/mongo/util/net/SConscript b/src/mongo/util/net/SConscript
index 1b027d1fe86..45deefd544c 100644
--- a/src/mongo/util/net/SConscript
+++ b/src/mongo/util/net/SConscript
@@ -68,6 +68,7 @@ env.Library(
'ssl_options',
],
LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/auth/auth_options',
'$BUILD_DIR/mongo/db/server_options_core',
'$BUILD_DIR/mongo/util/options_parser/options_parser',
]
diff --git a/src/mongo/util/net/network_interface_ssl_test.cpp b/src/mongo/util/net/network_interface_ssl_test.cpp
index afe6eeb6b18..2fe10c23884 100644
--- a/src/mongo/util/net/network_interface_ssl_test.cpp
+++ b/src/mongo/util/net/network_interface_ssl_test.cpp
@@ -54,6 +54,8 @@ std::string loadFile(const std::string& name) {
class NetworkInterfaceSSLFixture : public NetworkInterfaceIntegrationFixture {
public:
void setUp() final {
+ resetIsInternalClient(true);
+ NetworkInterfaceIntegrationFixture::setUp();
// Setup an internal user so that we can use it for external auth
UserHandle user(User(UserName("__system", "local")));
@@ -79,6 +81,11 @@ public:
createNet(nullptr, std::move(options));
net().startup();
}
+
+ void tearDown() override {
+ NetworkInterfaceIntegrationFixture::tearDown();
+ resetIsInternalClient(false);
+ }
};
TEST_F(NetworkInterfaceSSLFixture, Ping) {
@@ -86,7 +93,6 @@ TEST_F(NetworkInterfaceSSLFixture, Ping) {
"admin", BSON("ping" << 1), RemoteCommandRequest::kNoTimeout, transport::kEnableSSL);
}
-
} // namespace
} // namespace executor
} // namespace mongo
diff --git a/src/mongo/util/net/ssl_options_server.cpp b/src/mongo/util/net/ssl_options_server.cpp
index 0b0f0b4e955..809befe82d8 100644
--- a/src/mongo/util/net/ssl_options_server.cpp
+++ b/src/mongo/util/net/ssl_options_server.cpp
@@ -37,6 +37,7 @@
#include "mongo/base/status.h"
#include "mongo/config.h"
+#include "mongo/db/auth/auth_options_gen.h"
#include "mongo/db/server_options.h"
#include "mongo/logv2/log.h"
#include "mongo/util/options_parser/startup_option_init.h"
@@ -232,6 +233,12 @@ MONGO_STARTUP_OPTIONS_POST(SSLServerOptions)(InitializerContext*) {
if (sslGlobalParams.sslMode.load() == SSLParams::SSLMode_disabled) {
uasserted(ErrorCodes::BadValue, "need to enable TLS via the tlsMode flag");
}
+
+ if (!gEnforceUserClusterSeparation) {
+ uasserted(ErrorCodes::BadValue,
+ "cannot have have x.509 cluster authentication while not enforcing user "
+ "cluster separation");
+ }
}
if (sslGlobalParams.sslMode.load() == SSLParams::SSLMode_allowSSL) {