diff options
author | Hai-Kinh Hoang <haikinh.hoang@mongodb.com> | 2016-08-10 10:57:32 -0400 |
---|---|---|
committer | Hai-Kinh Hoang <haikinh.hoang@mongodb.com> | 2016-08-17 14:54:58 -0400 |
commit | c267c7ad3573c82e9b463cc6f918e76bb921b292 (patch) | |
tree | 845209245734ed585b90a97735ca9e6f3301c403 | |
parent | 7f05ff5fd7fab804d8d84397714b308adec6fe1a (diff) | |
download | mongo-c267c7ad3573c82e9b463cc6f918e76bb921b292.tar.gz |
SERVER-25082 Allow x509 authentication without user/subject field
-rw-r--r-- | jstests/ssl/x509_client.js | 8 | ||||
-rw-r--r-- | src/mongo/client/authenticate.cpp | 16 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.cpp | 18 | ||||
-rw-r--r-- | src/mongo/shell/dbshell.cpp | 10 |
4 files changed, 35 insertions, 17 deletions
diff --git a/jstests/ssl/x509_client.js b/jstests/ssl/x509_client.js index 7e38bd3a713..5bcc83edef9 100644 --- a/jstests/ssl/x509_client.js +++ b/jstests/ssl/x509_client.js @@ -70,9 +70,15 @@ function authAndTest(mongo) { "read without login"); assert(!external.auth({user: INVALID_CLIENT_USER, mechanism: 'MONGODB-X509'}), - "authentication with invalid user failed"); + "authentication with invalid user should fail"); assert(external.auth({user: CLIENT_USER, mechanism: 'MONGODB-X509'}), "authentication with valid user failed"); + assert(external.auth({mechanism: 'MONGODB-X509'}), + "authentication with valid client cert and no user field failed"); + assert(external.runCommand({authenticate: 1, mechanism: 'MONGODB-X509', user: CLIENT_USER}).ok, + "runCommand authentication with valid client cert and user field failed"); + assert(external.runCommand({authenticate: 1, mechanism: 'MONGODB-X509'}).ok, + "runCommand authentication with valid client cert and no user field failed"); // Check that we can add a user and read data test.createUser( diff --git a/src/mongo/client/authenticate.cpp b/src/mongo/client/authenticate.cpp index 7d45da9ef08..3f0320a2f4f 100644 --- a/src/mongo/client/authenticate.cpp +++ b/src/mongo/client/authenticate.cpp @@ -179,6 +179,11 @@ void authMongoCR(RunCommandHook runCommand, const BSONObj& params, AuthCompletio // AuthRequest createX509AuthCmd(const BSONObj& params, StringData clientName) { + if (clientName.empty()) { + return {ErrorCodes::AuthenticationFailed, + "Please enable SSL on the client-side to use the MONGODB-X509 authentication " + "mechanism."}; + } auto db = extractDBField(params); if (!db.isOK()) return std::move(db.getStatus()); @@ -187,16 +192,11 @@ AuthRequest createX509AuthCmd(const BSONObj& params, StringData clientName) { request.dbname = db.getValue(); std::string username; - auto response = bsonExtractStringField(params, saslCommandUserFieldName, &username); - if (!response.isOK()) + auto response = bsonExtractStringFieldWithDefault( + params, saslCommandUserFieldName, clientName.toString(), &username); + if (!response.isOK()) { return response; - - if (clientName.toString() == "") { - return {ErrorCodes::AuthenticationFailed, - "Please enable SSL on the client-side to use the MONGODB-X509 authentication " - "mechanism."}; } - if (username != clientName.toString()) { StringBuilder message; message << "Username \""; diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index a6a9a6f4508..f6fcc301b05 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -53,6 +53,7 @@ #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/jsobj.h" +#include "mongo/db/operation_context.h" #include "mongo/db/server_options.h" #include "mongo/platform/random.h" #include "mongo/stdx/memory.h" @@ -161,8 +162,19 @@ bool CmdAuthenticate::run(OperationContext* txn, redactForLogging(&cmdToLog); log() << " authenticate db: " << dbname << " " << cmdToLog; } + std::string mechanism = cmdObj.getStringField("mechanism"); + if (mechanism.empty()) { + mechanism = "MONGODB-CR"; + } + UserName user; + if (mechanism == "MONGODB-X509" && !cmdObj.hasField("user")) { + Client* client = txn->getClient(); + auto clientName = client->session()->getX509PeerInfo().subjectName; + user = UserName(clientName, dbname); + } else { + user = UserName(cmdObj.getStringField("user"), dbname); + } - UserName user(cmdObj.getStringField("user"), dbname); if (Command::testCommandsEnabled && user.getDB() == "admin" && user.getUser() == internalSecurity.user->getName().getUser()) { // Allows authenticating as the internal user against the admin database. This is to @@ -171,10 +183,6 @@ bool CmdAuthenticate::run(OperationContext* txn, user = internalSecurity.user->getName(); } - std::string mechanism = cmdObj.getStringField("mechanism"); - if (mechanism.empty()) { - mechanism = "MONGODB-CR"; - } Status status = _authenticate(txn, mechanism, user, cmdObj); audit::logAuthentication(Client::getCurrent(), mechanism, user, status.code()); if (!status.isOK()) { diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp index 97f80abeb5e..243bdd187ef 100644 --- a/src/mongo/shell/dbshell.cpp +++ b/src/mongo/shell/dbshell.cpp @@ -647,7 +647,8 @@ int _main(int argc, char* argv[], char** envp) { << escape(shellGlobalParams.gssapiServiceName) << "\";" << endl; } - if (!shellGlobalParams.nodb && shellGlobalParams.username.size()) { + if (!shellGlobalParams.nodb && (!shellGlobalParams.username.empty() || + shellGlobalParams.authenticationMechanism == "MONGODB-X509")) { authStringStream << "var username = \"" << escape(shellGlobalParams.username) << "\";" << endl; if (shellGlobalParams.usingPassword) { @@ -660,11 +661,14 @@ int _main(int argc, char* argv[], char** envp) { authStringStream << "var authDb = db.getSiblingDB(\"" << escape(shellGlobalParams.authenticationDatabase) << "\");" << endl; } - authStringStream << "authDb._authOrThrow({ " << saslCommandUserFieldName << ": username "; + + authStringStream << "authDb._authOrThrow({ "; + if (!shellGlobalParams.username.empty()) { + authStringStream << saslCommandUserFieldName << ": username "; + } if (shellGlobalParams.usingPassword) { authStringStream << ", " << saslCommandPasswordFieldName << ": password "; } - if (!shellGlobalParams.gssapiHostName.empty()) { authStringStream << ", " << saslCommandServiceHostnameFieldName << ": \"" << escape(shellGlobalParams.gssapiHostName) << '"' << endl; |