diff options
-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 | 1 | ||||
-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 | 3 | ||||
-rw-r--r-- | src/mongo/s/security.cpp | 38 |
14 files changed, 132 insertions, 12 deletions
diff --git a/src/SConscript.client b/src/SConscript.client index 81055293af1..aded23f5b9b 100644 --- a/src/SConscript.client +++ b/src/SConscript.client @@ -27,7 +27,8 @@ clientSource = [ 'mongo/base/status.cpp', '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 ecfe672e74a..f5d9a803f70 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -126,7 +126,7 @@ commonFiles = [ "pch.cpp", "util/net/listen.cpp", "util/startup_test.cpp", "util/version.cpp", - "client/authentication_table.cpp", + "client/authentication_table_common.cpp", "client/connpool.cpp", "client/dbclient.cpp", "client/dbclient_rs.cpp", @@ -182,6 +182,7 @@ env.StaticLibrary('mongocommon', commonFiles, SYSLIBDEPS=commonSysLibdeps) env.StaticLibrary("coredb", [ + "client/authentication_table_server.cpp", "client/parallel.cpp", "db/commands.cpp", "db/commands/fail_point_cmd.cpp", @@ -564,7 +565,12 @@ mongos = env.Program( "mongodandmongos"] + env['MODULE_LIBDEPS_MONGOS']) 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 ddab123922d..75e7b3140b7 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 2fff7e4652b..dd5474aa9a2 100644 --- a/src/mongo/client/clientAndShell.cpp +++ b/src/mongo/client/clientAndShell.cpp @@ -82,4 +82,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 db9bd0b6665..a30370e7585 100644 --- a/src/mongo/db/client.cpp +++ b/src/mongo/db/client.cpp @@ -416,6 +416,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 dd719ccb1b9..86c8039103b 100644 --- a/src/mongo/db/client_common.h +++ b/src/mongo/db/client_common.h @@ -72,6 +72,7 @@ namespace mongo { AbstractMessagingPort * port() const { return _messagingPort; } static ClientBasic* getCurrent(); + static bool hasCurrent(); protected: ClientBasic(AbstractMessagingPort* messagingPort) : _messagingPort(messagingPort) {} diff --git a/src/mongo/db/security.cpp b/src/mongo/db/security.cpp index 0913bff6186..25a3d877a25 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 cab945d55d1..a7f01a98c5b 100755 --- a/src/mongo/db/security.h +++ b/src/mongo/db/security.h @@ -43,6 +43,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 59b5a89f602..9b1f96ceb7a 100644 --- a/src/mongo/s/client_info.cpp +++ b/src/mongo/s/client_info.cpp @@ -74,6 +74,7 @@ namespace mongo { _cur = _prev; _prev = temp; _cur->clear(); + _ai.startRequest(); } void ClientInfo::_setupAuth() { @@ -124,6 +125,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 8e0ed86f4f7..e71bc53e139 100644 --- a/src/mongo/s/client_info.h +++ b/src/mongo/s/client_info.h @@ -101,6 +101,9 @@ namespace mongo { void noAutoSplit() { _autoSplitOk = false; } + // Returns whether or not a ClientInfo for this thread has already been created and stored + // in _tlInfo. + static bool exists(); // Gets the ClientInfo object for this thread from _tlInfo. If no ClientInfo object exists // yet for this thread, it creates one. static ClientInfo * get(AbstractMessagingPort* messagingPort = NULL); diff --git a/src/mongo/s/security.cpp b/src/mongo/s/security.cpp index c1089867b76..e7ccbdee554 100644 --- a/src/mongo/s/security.cpp +++ b/src/mongo/s/security.cpp @@ -65,14 +65,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"; @@ -80,8 +94,15 @@ namespace mongo { DBConfigPtr config = grid.getDBConfig( adminNs ); Shard s = config->getShard( adminNs ); - ShardConnection conn( s, adminNs ); - BSONObj result = conn->findOne("admin.system.users", Query()); + // + // Note: The connection mechanism here is *not* ideal, and should not be used elsewhere. + // It is safe in this particular case because the admin database is always on the config + // server and does not move. + // + scoped_ptr<ScopedDbConnection> conn( + ScopedDbConnection::getInternalScopedDbConnection(s.getConnString(), 30.0)); + + BSONObj result = (*conn)->findOne("admin.system.users", Query()); if( result.isEmpty() ) { if( ! _warned ) { // you could get a few of these in a race, but that's ok @@ -91,13 +112,14 @@ namespace mongo { // Must return conn to pool // TODO: Check for errors during findOne(), or just let the conn die? - conn.done(); - return true; + conn->done(); + _isLocalHostAndLocalHostIsAuthorizedForAll = true; + return; } // Must return conn to pool - conn.done(); - return false; + conn->done(); + _isLocalHostAndLocalHostIsAuthorizedForAll = false; } bool CmdLogout::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { |