diff options
author | Spencer T Brody <spencer@10gen.com> | 2012-11-16 20:44:21 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2013-02-27 13:45:25 -0500 |
commit | b4e33ce1ba54c6bfa4ff9ae0bd144d674e11c883 (patch) | |
tree | b3901a5820ab63e0c1fe38776f0ae1f4fe71d711 | |
parent | 37c3df43f01a57c3698db6e371f71371a0ddd6a4 (diff) | |
download | mongo-b4e33ce1ba54c6bfa4ff9ae0bd144d674e11c883.tar.gz |
SERVER-6591 Fix localhost auth exception in sharded systems
-rw-r--r-- | src/SConscript.client | 3 | ||||
-rw-r--r-- | src/mongo/SConscript | 10 | ||||
-rw-r--r-- | src/mongo/client/authentication_table.h | 3 | ||||
-rw-r--r-- | src/mongo/client/authentication_table_client.cpp | 27 | ||||
-rw-r--r-- | src/mongo/client/authentication_table_common.cpp (renamed from src/mongo/client/authentication_table.cpp) | 7 | ||||
-rw-r--r-- | src/mongo/client/authentication_table_server.cpp | 30 | ||||
-rw-r--r-- | src/mongo/client/clientAndShell.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/client.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/client_common.h | 2 | ||||
-rw-r--r-- | src/mongo/db/security.cpp | 4 | ||||
-rwxr-xr-x | src/mongo/db/security.h | 1 | ||||
-rw-r--r-- | src/mongo/s/client_info.cpp | 9 | ||||
-rw-r--r-- | src/mongo/s/client_info.h | 5 | ||||
-rw-r--r-- | src/mongo/s/security.cpp | 23 |
14 files changed, 124 insertions, 8 deletions
diff --git a/src/SConscript.client b/src/SConscript.client index 7a6bdc9d8ea..7308518c5ed 100644 --- a/src/SConscript.client +++ b/src/SConscript.client @@ -8,7 +8,8 @@ Import('env clientEnv') clientSource = [ 'mongo/bson/oid.cpp', 'mongo/buildinfo.cpp', - "mongo/client/authentication_table.cpp", + "mongo/client/authentication_table_common.cpp", + "mongo/client/authentication_table_client.cpp", 'mongo/client/clientAndShell.cpp', 'mongo/client/clientOnly.cpp', 'mongo/client/connection_factory.cpp', diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 0cfbedcc8a4..787f423124d 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -81,7 +81,7 @@ commonFiles = [ "pch.cpp", "util/net/message_port.cpp", "util/net/listen.cpp", "util/startup_test.cpp", - "client/authentication_table.cpp", + "client/authentication_table_common.cpp", "client/connpool.cpp", "client/dbclient.cpp", "client/dbclient_rs.cpp", @@ -102,6 +102,7 @@ env.StaticLibrary('mongocommon', commonFiles, '$BUILD_DIR/third_party/shim_boost'],) env.StaticLibrary("coredb", [ + "client/authentication_table_server.cpp", "client/parallel.cpp", "db/commands.cpp", "db/commands/hashcmd.cpp", @@ -443,7 +444,12 @@ mongos = env.Program( "mongodandmongos"]) env.Install( '#/', mongos ) -env.Library("clientandshell", ["client/clientAndShell.cpp"], LIBDEPS=["mongocommon", "defaultversion", "gridfs", "notmongodormongos"]) +env.Library("clientandshell", ["client/authentication_table_client.cpp", + "client/clientAndShell.cpp"], + LIBDEPS=["mongocommon", + "defaultversion", + "gridfs", + "notmongodormongos"]) env.Library("allclient", "client/clientOnly.cpp", LIBDEPS=["clientandshell"]) if has_option( "sharedclient" ): diff --git a/src/mongo/client/authentication_table.h b/src/mongo/client/authentication_table.h index 20cb8c4fdba..c0476b92984 100644 --- a/src/mongo/client/authentication_table.h +++ b/src/mongo/client/authentication_table.h @@ -59,6 +59,9 @@ namespace mongo { static const string fieldName; private: + + bool _shouldSendInternalSecurityTable() const; + typedef map<std::string,Auth> DBAuthMap; DBAuthMap _dbs; // dbname -> auth }; diff --git a/src/mongo/client/authentication_table_client.cpp b/src/mongo/client/authentication_table_client.cpp new file mode 100644 index 00000000000..593d44616e6 --- /dev/null +++ b/src/mongo/client/authentication_table_client.cpp @@ -0,0 +1,27 @@ +/* Copyright 2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "mongo/client/authentication_table.h" +#include "mongo/db/client_common.h" +#include "mongo/db/security.h" + +namespace mongo { + + bool AuthenticationTable::_shouldSendInternalSecurityTable() const { + return false; + } + +} diff --git a/src/mongo/client/authentication_table.cpp b/src/mongo/client/authentication_table_common.cpp index 9af6de4f5c7..ca6eda1a26f 100644 --- a/src/mongo/client/authentication_table.cpp +++ b/src/mongo/client/authentication_table_common.cpp @@ -93,7 +93,12 @@ namespace mongo { cmdWithAuth.append(e); } - cmdWithAuth.append( fieldName, toBSON() ); + if (_shouldSendInternalSecurityTable()) { + cmdWithAuth.append(fieldName, internalSecurityAuthenticationTable.toBSON()); + } + else { + cmdWithAuth.append(fieldName, toBSON()); + } return cmdWithAuth.obj(); } diff --git a/src/mongo/client/authentication_table_server.cpp b/src/mongo/client/authentication_table_server.cpp new file mode 100644 index 00000000000..dc69a5629ea --- /dev/null +++ b/src/mongo/client/authentication_table_server.cpp @@ -0,0 +1,30 @@ +/* Copyright 2012 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "mongo/client/authentication_table.h" +#include "mongo/db/client_common.h" +#include "mongo/db/security.h" + +namespace mongo { + + bool AuthenticationTable::_shouldSendInternalSecurityTable() const { + if (!ClientBasic::hasCurrent() || !ClientBasic::getCurrent()->getAuthenticationInfo()) { + return false; + } + return ClientBasic::getCurrent()->getAuthenticationInfo()->isSpecialLocalhostAdmin(); + } + +} diff --git a/src/mongo/client/clientAndShell.cpp b/src/mongo/client/clientAndShell.cpp index 6c4e3be311d..d02a153c615 100644 --- a/src/mongo/client/clientAndShell.cpp +++ b/src/mongo/client/clientAndShell.cpp @@ -87,4 +87,8 @@ namespace mongo { ClientBasic* ClientBasic::getCurrent() { return 0; } + + bool ClientBasic::hasCurrent() { + return false; + } } diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp index 11216632fa1..aa35f645345 100644 --- a/src/mongo/db/client.cpp +++ b/src/mongo/db/client.cpp @@ -445,6 +445,10 @@ namespace mongo { } } + bool ClientBasic::hasCurrent() { + return currentClient.get(); + } + ClientBasic* ClientBasic::getCurrent() { return currentClient.get(); } diff --git a/src/mongo/db/client_common.h b/src/mongo/db/client_common.h index 1d61f81b575..5bacd8a932c 100644 --- a/src/mongo/db/client_common.h +++ b/src/mongo/db/client_common.h @@ -43,5 +43,7 @@ namespace mongo { virtual HostAndPort getRemote() const = 0; static ClientBasic* getCurrent(); + static bool hasCurrent(); + }; } diff --git a/src/mongo/db/security.cpp b/src/mongo/db/security.cpp index 06ef0bf86dd..0326f6d65c7 100644 --- a/src/mongo/db/security.cpp +++ b/src/mongo/db/security.cpp @@ -73,6 +73,10 @@ namespace mongo { _checkLocalHostSpecialAdmin(); } + bool AuthenticationInfo::isSpecialLocalhostAdmin() const { + return _isLocalHostAndLocalHostIsAuthorizedForAll; + } + void AuthenticationInfo::_checkLocalHostSpecialAdmin() { if ( ! _isLocalHost ) return; diff --git a/src/mongo/db/security.h b/src/mongo/db/security.h index 791f38947c6..0b152296afc 100755 --- a/src/mongo/db/security.h +++ b/src/mongo/db/security.h @@ -44,6 +44,7 @@ namespace mongo { } ~AuthenticationInfo() {} bool isLocalHost() const { return _isLocalHost; } // why are you calling this? makes no sense to be externalized + bool isSpecialLocalhostAdmin() const; // -- modifiers ---- diff --git a/src/mongo/s/client_info.cpp b/src/mongo/s/client_info.cpp index d304e5eb25d..0cbcfe22156 100644 --- a/src/mongo/s/client_info.cpp +++ b/src/mongo/s/client_info.cpp @@ -70,6 +70,7 @@ namespace mongo { _cur = _prev; _prev = temp; _cur->clear(); + _ai.startRequest(); } ClientInfo * ClientInfo::get() { @@ -82,6 +83,14 @@ namespace mongo { return info; } + bool ClientInfo::exists() { + return _tlInfo.get(); + } + + bool ClientBasic::hasCurrent() { + return ClientInfo::exists(); + } + ClientBasic* ClientBasic::getCurrent() { return ClientInfo::get(); } diff --git a/src/mongo/s/client_info.h b/src/mongo/s/client_info.h index 504ac0e3a68..180fc049322 100644 --- a/src/mongo/s/client_info.h +++ b/src/mongo/s/client_info.h @@ -100,6 +100,11 @@ namespace mongo { void noAutoSplit() { _autoSplitOk = false; } static ClientInfo * get(); + + // Returns whether or not a ClientInfo for this thread has already been created and stored + // in _tlInfo. + static bool exists(); + const AuthenticationInfo* getAuthenticationInfo() const { return (AuthenticationInfo*)&_ai; } AuthenticationInfo* getAuthenticationInfo() { return (AuthenticationInfo*)&_ai; } bool isAdmin() { return _ai.isAuthorized( "admin" ); } diff --git a/src/mongo/s/security.cpp b/src/mongo/s/security.cpp index f309369c20d..090f3afe80e 100644 --- a/src/mongo/s/security.cpp +++ b/src/mongo/s/security.cpp @@ -64,14 +64,28 @@ namespace mongo { return true; } + void AuthenticationInfo::startRequest() { + _checkLocalHostSpecialAdmin(); + } + void AuthenticationInfo::setIsALocalHostConnectionWithSpecialAuthPowers() { verify(!_isLocalHost); _isLocalHost = true; + _isLocalHostAndLocalHostIsAuthorizedForAll = true; + _checkLocalHostSpecialAdmin(); } bool AuthenticationInfo::_isAuthorizedSpecialChecks( const string& dbname ) const { - if ( !_isLocalHost ) { - return false; + return isSpecialLocalhostAdmin(); + } + + bool AuthenticationInfo::isSpecialLocalhostAdmin() const { + return _isLocalHostAndLocalHostIsAuthorizedForAll; + } + + void AuthenticationInfo::_checkLocalHostSpecialAdmin() { + if (!_isLocalHost || !_isLocalHostAndLocalHostIsAuthorizedForAll) { + return; } string adminNs = "admin.system.users"; @@ -93,12 +107,13 @@ namespace mongo { // Must return conn to pool // TODO: Check for errors during findOne(), or just let the conn die? conn.done(); - return true; + _isLocalHostAndLocalHostIsAuthorizedForAll = true; + return; } // Must return conn to pool conn.done(); - return false; + _isLocalHostAndLocalHostIsAuthorizedForAll = false; } bool CmdLogout::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { |