diff options
author | Spencer T Brody <spencer@10gen.com> | 2012-12-23 14:52:47 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2012-12-23 20:31:30 -0500 |
commit | 13bde295415c1e5ea9afd6b7faed3f2a425e33fa (patch) | |
tree | f4d66387a608a2747696e217fb7030cd9f14f445 /src | |
parent | a615d7dd1e3201e03d8fc8ed2f6a31d73e192cc1 (diff) | |
download | mongo-13bde295415c1e5ea9afd6b7faed3f2a425e33fa.tar.gz |
SERVER-7572 Remove AuthenticationInfo
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/SConscript | 5 | ||||
-rw-r--r-- | src/mongo/client/authentication_table.h | 69 | ||||
-rw-r--r-- | src/mongo/client/authentication_table_client.cpp | 27 | ||||
-rw-r--r-- | src/mongo/client/authentication_table_common.cpp | 105 | ||||
-rw-r--r-- | src/mongo/client/authentication_table_server.cpp | 30 | ||||
-rw-r--r-- | src/mongo/client/dbclientinterface.h | 1 | ||||
-rw-r--r-- | src/mongo/db/client.h | 3 | ||||
-rw-r--r-- | src/mongo/db/client_basic.h | 2 | ||||
-rw-r--r-- | src/mongo/db/dbwebserver.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/pipeline/pipeline.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/security.cpp | 92 | ||||
-rw-r--r-- | src/mongo/db/security.h | 105 | ||||
-rw-r--r-- | src/mongo/db/security_commands.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/security_common.cpp | 38 | ||||
-rw-r--r-- | src/mongo/db/security_common.h | 1 | ||||
-rw-r--r-- | src/mongo/dbtests/authtests.cpp | 137 | ||||
-rw-r--r-- | src/mongo/s/client_info.cpp | 1 | ||||
-rw-r--r-- | src/mongo/s/client_info.h | 3 | ||||
-rw-r--r-- | src/mongo/s/security.cpp | 61 |
19 files changed, 1 insertions, 697 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 94a6b39d5a1..a922ae71406 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -146,7 +146,6 @@ commonFiles = [ "pch.cpp", "util/net/listen.cpp", "util/startup_test.cpp", "util/version.cpp", - "client/authentication_table_common.cpp", "client/connpool.cpp", "client/dbclient.cpp", "client/dbclient_rs.cpp", @@ -212,7 +211,6 @@ env.StaticLibrary('mongocommon', commonFiles, SYSLIBDEPS=commonSysLibdeps) env.StaticLibrary("coredb", [ - "client/authentication_table_server.cpp", "client/parallel.cpp", "db/commands.cpp", "db/commands/connection_status.cpp", @@ -610,8 +608,7 @@ mongos = env.Program( "mongodandmongos", "s/upgrade"] + env['MODULE_LIBDEPS_MONGOS']) env.Install( '#/', mongos ) -env.Library("clientandshell", ["client/authentication_table_client.cpp", - "client/clientAndShell.cpp"], +env.Library("clientandshell", ["client/clientAndShell.cpp"], LIBDEPS=["mongocommon", "defaultversion", "gridfs", diff --git a/src/mongo/client/authentication_table.h b/src/mongo/client/authentication_table.h deleted file mode 100644 index 75e7b3140b7..00000000000 --- a/src/mongo/client/authentication_table.h +++ /dev/null @@ -1,69 +0,0 @@ -// authentication_table.h - -/* 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. - */ - -#pragma once - -#include <string> - -#include "mongo/client/authlevel.h" -#include "mongo/db/jsobj.h" - -namespace mongo { - - /** - * An AuthenticationTable object is present within every AuthenticationInfo object and - * contains the map of dbname to auth level for the current client. - * All syncronization to this class is done through its encompassing AuthenticationInfo. - */ - class AuthenticationTable { - public: - AuthenticationTable() {} - ~AuthenticationTable() {} - - void addAuth( const std::string& dbname, - const std::string& user, - const Auth::Level& level ); - - void addAuth( const std::string& dbname , const Auth& auth ); - - void removeAuth( const std::string& dbname ); - - void clearAuth(); - - Auth getAuthForDb( const std::string& dbname ) const; - - // Takes the authentication state from the given BSONObj, replacing whatever state it had. - void setFromBSON( const BSONObj& obj ); - - BSONObj toBSON() const; - - BSONObj copyCommandObjAddingAuth( const BSONObj& cmdObj ) const; - - static const AuthenticationTable& getInternalSecurityAuthenticationTable(); - // Only used once at startup to setup the authentication table. - static AuthenticationTable& getMutableInternalSecurityAuthenticationTable(); - - 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 deleted file mode 100644 index 32bd99ba573..00000000000 --- a/src/mongo/client/authentication_table_client.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* 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_basic.h" -#include "mongo/db/security.h" - -namespace mongo { - - bool AuthenticationTable::_shouldSendInternalSecurityTable() const { - return false; - } - -} diff --git a/src/mongo/client/authentication_table_common.cpp b/src/mongo/client/authentication_table_common.cpp deleted file mode 100644 index ca6eda1a26f..00000000000 --- a/src/mongo/client/authentication_table_common.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// authentication_table.cpp - -/* 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/util/map_util.h" -#include "mongo/util/mongoutils/str.h" - -namespace mongo { - - AuthenticationTable internalSecurityAuthenticationTable; - const string AuthenticationTable::fieldName = "$auth"; - - const AuthenticationTable& AuthenticationTable::getInternalSecurityAuthenticationTable() { - return internalSecurityAuthenticationTable; - } - - AuthenticationTable& AuthenticationTable::getMutableInternalSecurityAuthenticationTable() { - return internalSecurityAuthenticationTable; - } - - void AuthenticationTable::addAuth(const std::string& dbname , const std::string& user, - const Auth::Level& level ) { - Auth auth; - auth.level = level; - auth.user = user; - addAuth( dbname, auth ); - } - - void AuthenticationTable::addAuth(const std::string& dbname , const Auth& auth) { - _dbs[dbname] = auth; - } - - void AuthenticationTable::removeAuth(const std::string& dbname ) { - _dbs.erase(dbname); - } - - void AuthenticationTable::clearAuth() { - _dbs.clear(); - } - - Auth AuthenticationTable::getAuthForDb( const std::string& dbname ) const { - return mapFindWithDefault( _dbs, dbname, Auth() ); - } - - // Takes the authentication state from the given BSONObj - void AuthenticationTable::setFromBSON( const BSONObj& obj ) { - _dbs.clear(); - - BSONObjIterator it( obj ); - while ( it.more() ) { - BSONElement dbInfo = it.next(); - BSONElement subObj = dbInfo.Obj().firstElement(); - Auth auth; - auth.user = subObj.fieldName(); - auth.level = static_cast<Auth::Level>(subObj.Int()); - _dbs[dbInfo.fieldName()] = auth; - } - } - - BSONObj AuthenticationTable::toBSON() const { - BSONObjBuilder b; - for ( DBAuthMap::const_iterator i = _dbs.begin(); i != _dbs.end(); ++i ) { - BSONObjBuilder temp( b.subobjStart( i->first ) ); - temp.append( i->second.user, i->second.level ); - temp.done(); - } - return b.obj(); - } - - BSONObj AuthenticationTable::copyCommandObjAddingAuth( const BSONObj& cmdObj ) const { - BSONObjBuilder cmdWithAuth; - - // Copy all elements of the original command object, but don't take user-provided $auth. - BSONObjIterator it(cmdObj); - while ( it.more() ) { - BSONElement e = it.next(); - if ( mongoutils::str::equals( e.fieldName(), fieldName.c_str() ) ) continue; - cmdWithAuth.append(e); - } - - 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 deleted file mode 100644 index b2f88a2f66a..00000000000 --- a/src/mongo/client/authentication_table_server.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* 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_basic.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/dbclientinterface.h b/src/mongo/client/dbclientinterface.h index 9b91ec8aa54..8e8155fcbe2 100644 --- a/src/mongo/client/dbclientinterface.h +++ b/src/mongo/client/dbclientinterface.h @@ -23,7 +23,6 @@ #include "mongo/pch.h" #include "mongo/client/authlevel.h" -#include "mongo/client/authentication_table.h" #include "mongo/db/jsobj.h" #include "mongo/platform/atomic_word.h" #include "mongo/util/net/message.h" diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h index 3b19b11762c..c6cd74d65c2 100644 --- a/src/mongo/db/client.h +++ b/src/mongo/db/client.h @@ -81,8 +81,6 @@ namespace mongo { bool shutdown(); string clientAddress(bool includePort=false) const; - const AuthenticationInfo * getAuthenticationInfo() const { return &_ai; } - AuthenticationInfo * getAuthenticationInfo() { return &_ai; } CurOp* curop() const { return _curOp; } Context* getContext() const { return _context; } Database* database() const { return _context ? _context->db() : 0; } @@ -125,7 +123,6 @@ namespace mongo { bool _shutdown; // to track if Client::shutdown() gets called std::string _desc; bool _god; - AuthenticationInfo _ai; OpTime _lastOp; BSONObj _handshake; BSONObj _remoteId; diff --git a/src/mongo/db/client_basic.h b/src/mongo/db/client_basic.h index a8cb1f26277..703263e18f7 100644 --- a/src/mongo/db/client_basic.h +++ b/src/mongo/db/client_basic.h @@ -37,8 +37,6 @@ namespace mongo { class ClientBasic : boost::noncopyable { public: virtual ~ClientBasic(); - virtual const AuthenticationInfo * getAuthenticationInfo() const = 0; - virtual AuthenticationInfo * getAuthenticationInfo() = 0; AuthenticationSession* getAuthenticationSession(); void resetAuthenticationSession(AuthenticationSession* newSession); void swapAuthenticationSession(boost::scoped_ptr<AuthenticationSession>& other); diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp index 19f987281c3..1c6ae0d5923 100644 --- a/src/mongo/db/dbwebserver.cpp +++ b/src/mongo/db/dbwebserver.cpp @@ -89,10 +89,6 @@ namespace mongo { bool allowed( const char * rq , vector<string>& headers, const SockAddr &from ) { if ( from.isLocalHost() || !_webUsers->haveAdminUsers() ) { _authorizePrincipal("RestUser", false); - - // TODO: remove this once all auth checking goes through the AuthorizationManager - // instead of AuthenticationInfo - cmdAuthenticate.authenticate( "admin", "RestUser", false ); return true; } @@ -135,10 +131,6 @@ namespace mongo { user[ "readOnly" ].boolean(); _authorizePrincipal(principalName, readOnly); - - // TODO: remove this once all auth checking goes through the - // AuthorizationManager instead of AuthenticationInfo - cmdAuthenticate.authenticate("admin", principalName, readOnly); return true; } } diff --git a/src/mongo/db/pipeline/pipeline.cpp b/src/mongo/db/pipeline/pipeline.cpp index 1523ffd3fc9..6ec1771d2e6 100644 --- a/src/mongo/db/pipeline/pipeline.cpp +++ b/src/mongo/db/pipeline/pipeline.cpp @@ -17,7 +17,6 @@ #include "pch.h" #include "db/pipeline/pipeline.h" -#include "mongo/client/authentication_table.h" #include "db/jsobj.h" #include "db/pipeline/accumulator.h" #include "db/pipeline/document.h" diff --git a/src/mongo/db/security.cpp b/src/mongo/db/security.cpp index 9918a3e0bb2..17325def651 100644 --- a/src/mongo/db/security.cpp +++ b/src/mongo/db/security.cpp @@ -32,100 +32,8 @@ namespace mongo { - bool AuthenticationInfo::_warned = false; - - void AuthenticationInfo::setTemporaryAuthorization( BSONObj& obj ) { - fassert( 16232, !_usingTempAuth ); - scoped_spinlock lk( _lock ); - LOG(5) << "Setting temporary authorization to: " << obj << endl; - _tempAuthTable.setFromBSON( obj ); - _usingTempAuth = true; - } - - void AuthenticationInfo::clearTemporaryAuthorization() { - scoped_spinlock lk( _lock ); - _usingTempAuth = false; - _tempAuthTable.clearAuth(); - } - - bool AuthenticationInfo::hasTemporaryAuthorization() { - scoped_spinlock lk( _lock ); - return _usingTempAuth; - } - - bool AuthenticationInfo::usingInternalUser() { - return getUser("local") == internalSecurity.user || - getUser("admin") == internalSecurity.user; - } - - string AuthenticationInfo::getUser( const string& dbname ) const { - scoped_spinlock lk(_lock); - return _authTable.getAuthForDb( dbname ).user; - } - - bool AuthenticationInfo::_isAuthorizedSpecialChecks( const string& dbname ) const { - if ( cc().isGod() ) - return true; - return _isLocalHostAndLocalHostIsAuthorizedForAll; - } - - void AuthenticationInfo::setIsALocalHostConnectionWithSpecialAuthPowers() { - verify(!_isLocalHost); - _isLocalHost = true; - _isLocalHostAndLocalHostIsAuthorizedForAll = true; - _checkLocalHostSpecialAdmin(); - } - - bool AuthenticationInfo::isSpecialLocalhostAdmin() const { - return _isLocalHostAndLocalHostIsAuthorizedForAll; - } - - void AuthenticationInfo::_checkLocalHostSpecialAdmin() { - if ( ! _isLocalHost ) - return; - - if ( ! _isLocalHostAndLocalHostIsAuthorizedForAll ) - return; - - if ( ! noauth ) { - Client::GodScope gs; - Client::ReadContext ctx("admin.system.users"); - BSONObj result; - if( Helpers::getSingleton("admin.system.users", result) ) { - _isLocalHostAndLocalHostIsAuthorizedForAll = false; - } - else if ( ! _warned ) { - // you could get a few of these in a race, but that's ok - _warned = true; - log() << "note: no users configured in admin.system.users, allowing localhost access" << endl; - } - } - - - } - - void AuthenticationInfo::startRequest() { - if ( ! Lock::isLocked() ) { - _checkLocalHostSpecialAdmin(); - } - } - - AuthenticationInfo::TemporaryAuthReleaser::TemporaryAuthReleaser ( AuthenticationInfo* ai ) : - _ai (ai), _hadTempAuthFromStart( ai->hasTemporaryAuthorization() ) {} - - AuthenticationInfo::TemporaryAuthReleaser::~TemporaryAuthReleaser() { - // Some commands can run other commands using the DBDirectClient, which leads to the - // temporary auth already being set when the inner command runs. If that's the case, we - // shouldn't clear the temporary auth set by a command higher up in the call stack. - if ( !_hadTempAuthFromStart ) { - _ai->clearTemporaryAuthorization(); - } - } - bool CmdLogout::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { - AuthenticationInfo *ai = cc().getAuthenticationInfo(); AuthorizationManager* authManager = cc().getAuthorizationManager(); - ai->logout(dbname); authManager->logoutDatabase(dbname); return true; } diff --git a/src/mongo/db/security.h b/src/mongo/db/security.h index e5c5cd07ea7..4134e5ed1f9 100644 --- a/src/mongo/db/security.h +++ b/src/mongo/db/security.h @@ -21,7 +21,6 @@ #include <string> #include "mongo/db/security_common.h" -#include "mongo/client/authentication_table.h" #include "mongo/client/authlevel.h" #include "mongo/util/concurrency/spin_lock.h" @@ -29,108 +28,4 @@ namespace mongo { - /** An AuthenticationInfo object is present within every mongo::Client object */ - class AuthenticationInfo : boost::noncopyable { - bool _isLocalHost; - bool _isLocalHostAndLocalHostIsAuthorizedForAll; - public: - void startRequest(); // need to call at the beginning of each request - void setIsALocalHostConnectionWithSpecialAuthPowers(); // called, if localhost, when conneciton established. - AuthenticationInfo() { - _isLocalHost = false; - _isLocalHostAndLocalHostIsAuthorizedForAll = false; - _usingTempAuth = false; - } - ~AuthenticationInfo() {} - bool isLocalHost() const { return _isLocalHost; } // why are you calling this? makes no sense to be externalized - bool isSpecialLocalhostAdmin() const; - - // -- modifiers ---- - - void logout(const std::string& dbname ) { - scoped_spinlock lk(_lock); - _authTable.removeAuth( dbname ); - } - void authorize(const std::string& dbname , const std::string& user ) { - scoped_spinlock lk(_lock); - _authTable.addAuth( dbname, user, Auth::WRITE ); - } - void authorizeReadOnly(const std::string& dbname , const std::string& user ) { - scoped_spinlock lk(_lock); - _authTable.addAuth( dbname, user, Auth::READ ); - } - - // -- accessors --- - - bool isAuthorized(const std::string& dbname) const { - return _isAuthorized( dbname, Auth::WRITE ); - } - - bool isAuthorizedReads(const std::string& dbname) const { - return _isAuthorized( dbname, Auth::READ ); - } - - /** - * @param lockType - this is from dbmutex 1 is write, 0 is read - */ - bool isAuthorizedForLock(const std::string& dbname, int lockType ) const { - return _isAuthorized( dbname , lockType > 0 ? Auth::WRITE : Auth::READ ); - } - - std::string getUser( const std::string& dbname ) const; - - void print() const; - - BSONObj toBSON() const; - - void setTemporaryAuthorization( BSONObj& obj ); - void clearTemporaryAuthorization(); - bool hasTemporaryAuthorization(); - - // Returns true if this AuthenticationInfo has been auth'd to use the internal user - bool usingInternalUser(); - - // When TemporaryAuthReleaser goes out of scope it clears the temporary authentication set - // in its AuthenticationInfo object, unless that AuthenticationInfo already had temporary - // auth set at the time that the TemporaryAuthReleaser was initialized. - class TemporaryAuthReleaser : boost::noncopyable { - public: - TemporaryAuthReleaser ( AuthenticationInfo* ai ); - ~TemporaryAuthReleaser(); - private: - AuthenticationInfo* _ai; - bool _hadTempAuthFromStart; - }; - - private: - void _checkLocalHostSpecialAdmin(); - - /** takes a lock */ - bool _isAuthorized(const std::string& dbname, Auth::Level level) const; - - // Must be in _lock - bool _isAuthorizedSingle_inlock(const std::string& dbname, Auth::Level level) const; - - /** cannot call this locked */ - bool _isAuthorizedSpecialChecks( const std::string& dbname ) const ; - - // Must be in _lock - void _addTempAuth_inlock( const std::string& dbname, const std::string& user, - Auth::Level level); - - private: - // while most access to _authTable is from our thread (the TLS thread), currentOp() - // inspects it too thus we need this. - // This protects _authTable, _tempAuthTable, and _usingTempAuth. - mutable SpinLock _lock; - - // todo: caching should not last forever - AuthenticationTable _authTable; - // when _usingTempAuth is true, this is used for all auth checks instead of _authTable - AuthenticationTable _tempAuthTable; - - bool _usingTempAuth; - static bool _warned; - }; - } // namespace mongo diff --git a/src/mongo/db/security_commands.cpp b/src/mongo/db/security_commands.cpp index ad5bdbda664..c7575cb0116 100644 --- a/src/mongo/db/security_commands.cpp +++ b/src/mongo/db/security_commands.cpp @@ -180,17 +180,8 @@ namespace mongo { principal->setImplicitPrivilegeAcquisition(true); authorizationManager->addAuthorizedPrincipal(principal); - bool readOnly = userObj["readOnly"].trueValue(); - // TODO: remove this once all auth checking goes through AuthorizationManager instead of - // AuthenticationInfo - authenticate(dbname, user, readOnly ); - - result.append( "dbname" , dbname ); result.append( "user" , user ); - result.appendBool( "readOnly" , readOnly ); - - return true; } diff --git a/src/mongo/db/security_common.cpp b/src/mongo/db/security_common.cpp index 59cb2d503d3..053faef70d6 100644 --- a/src/mongo/db/security_common.cpp +++ b/src/mongo/db/security_common.cpp @@ -117,42 +117,4 @@ namespace mongo { return true; } - void CmdAuthenticate::authenticate(const string& dbname, const string& user, const bool readOnly) { - ClientBasic* c = ClientBasic::getCurrent(); - verify(c); - AuthenticationInfo *ai = c->getAuthenticationInfo(); - - if ( readOnly ) { - ai->authorizeReadOnly( dbname , user ); - } - else { - ai->authorize( dbname , user ); - } - } - - - bool AuthenticationInfo::_isAuthorized(const string& dbname, Auth::Level level) const { - if ( noauth ) { - return true; - } - { - scoped_spinlock lk(_lock); - - if ( _isAuthorizedSingle_inlock( dbname , level ) ) - return true; - - if ( _isAuthorizedSingle_inlock( "admin" , level ) ) - return true; - - if ( _isAuthorizedSingle_inlock( "local" , level ) ) - return true; - } - return _isAuthorizedSpecialChecks( dbname ); - } - - bool AuthenticationInfo::_isAuthorizedSingle_inlock(const string& dbname, Auth::Level level) const { - const AuthenticationTable& authTable = _usingTempAuth ? _tempAuthTable : _authTable; - return authTable.getAuthForDb( dbname ).level >= level; - } - } // namespace mongo diff --git a/src/mongo/db/security_common.h b/src/mongo/db/security_common.h index e521bcc7aef..450fc5da68d 100644 --- a/src/mongo/db/security_common.h +++ b/src/mongo/db/security_common.h @@ -53,7 +53,6 @@ namespace mongo { std::vector<Privilege>* out) {} // No auth required CmdAuthenticate() : Command("authenticate") {} bool run(const string& dbname , BSONObj& cmdObj, int options, string& errmsg, BSONObjBuilder& result, bool fromRepl); - void authenticate(const string& dbname, const string& user, const bool readOnly); }; extern CmdAuthenticate cmdAuthenticate; diff --git a/src/mongo/dbtests/authtests.cpp b/src/mongo/dbtests/authtests.cpp deleted file mode 100644 index 08f4ff71e35..00000000000 --- a/src/mongo/dbtests/authtests.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// authtests.cpp : unit tests relating to authentication. -// - -/** - * Copyright (C) 2012 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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 - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "../db/security.h" -#include "dbtests.h" - -namespace AuthTests { - - /** Simple test for AuthenticationInfo::setTemporaryAuthorization. */ - class TempAuth { - public: - void run() { - bool authEnabled = mongo::noauth; - mongo::noauth = false; // Enable authentication. - AuthenticationInfo ai; - - ASSERT( ! ai.isAuthorized( "test" ) ); - ASSERT( ! ai.isAuthorized( "admin" ) ); - ASSERT( ! ai.isAuthorizedReads( "test" ) ); - ASSERT( ! ai.isAuthorizedReads( "admin" ) ); - - ai.authorizeReadOnly( "admin", "adminRO" ); - ASSERT( ! ai.isAuthorized( "test" ) ); - ASSERT( ! ai.isAuthorized( "admin" ) ); - ASSERT( ai.isAuthorizedReads( "test" ) ); - ASSERT( ai.isAuthorizedReads( "admin" ) ); - - { - AuthenticationInfo::TemporaryAuthReleaser authRelease( &ai ); - BSONObj input = BSON( - "admin" << BSON( "adminRO" << 1 ) << - "test" << BSON( "testRW" << 2 ) - ); - ai.setTemporaryAuthorization( input ); - ASSERT( ai.isAuthorized( "test" ) ); - ASSERT( ! ai.isAuthorized( "admin" ) ); - ASSERT( ! ai.isAuthorized( "test2" ) ); - ASSERT( ai.isAuthorizedReads( "test" ) ); - ASSERT( ai.isAuthorizedReads( "admin" ) ); - ASSERT( ai.isAuthorizedReads( "test2" ) ); - - { - // This shouldn't actually clear the temporary auth when it goes out of scope - // because there is already temporary auth set at this point. - AuthenticationInfo::TemporaryAuthReleaser authRelease( &ai ); - } - - // Auth should be the same as before the second TemporaryAuthReleaser - ASSERT( ai.isAuthorized( "test" ) ); - ASSERT( ! ai.isAuthorized( "admin" ) ); - ASSERT( ! ai.isAuthorized( "test2" ) ); - ASSERT( ai.isAuthorizedReads( "test" ) ); - ASSERT( ai.isAuthorizedReads( "admin" ) ); - ASSERT( ai.isAuthorizedReads( "test2" ) ); - } - - ASSERT( ! ai.isAuthorized( "test" ) ); - ASSERT( ! ai.isAuthorized( "admin" ) ); - ASSERT( ai.isAuthorizedReads( "test" ) ); - ASSERT( ai.isAuthorizedReads( "admin" ) ); - mongo::noauth = authEnabled; // Restore authentication. - } - }; - - /** Simple test for AuthenticationTable::toBSON. */ - class ToBSON { - public: - void run() { - AuthenticationTable at; - at.addAuth("admin", "adminUser", Auth::WRITE); - at.addAuth("test", "testUser", Auth::WRITE); - at.addAuth("local", "localUser", Auth::READ); - - BSONObj expected = BSON( - "admin" << BSON( "adminUser" << 2 ) << - "test" << BSON( "testUser" << 2 ) << - "local" << BSON( "localUser" << 1 ) - ); - - ASSERT( bson2set(expected) == bson2set(at.toBSON()) ); - } - }; - - /** Simple test for AuthenticationTable::copyCommandObjAddingAuth. */ - class AddAuth { - public: - void run() { - AuthenticationTable at; - at.addAuth("test", "testUser", Auth::WRITE); - - BSONObj cmd = BSON( "commandName" << "commandValue" ); - BSONObj cmdWithAuth = at.copyCommandObjAddingAuth( cmd ); - BSONObj expected = BSON( - "commandName" << "commandValue" << - "$auth" << BSON( "test" << BSON( "testUser" << 2 ) ) - ); - - // Make sure a malicious user can't set their own $auth - BSONObj bogusAuthCmd = BSON( - "commandName" << "commandValue" << - "$auth" << BSON( "admin" << BSON( "adminUser" << 2 ) ) - ); - BSONObj bogusAuthCmdWithAuth = at.copyCommandObjAddingAuth( bogusAuthCmd ); - log() << "bogusAuthCmd: " << bogusAuthCmd << endl; - log() << "bogusAuthCmdWithAuth: " << bogusAuthCmdWithAuth << endl; - ASSERT( bson2set(expected) == bson2set(bogusAuthCmdWithAuth) ); - } - }; - - class All : public Suite { - public: - All() : Suite( "auth" ) { - } - void setupTests() { - add<TempAuth>(); - add<ToBSON>(); - add<AddAuth>(); - } - } myall; - -} // namespace AuthTests diff --git a/src/mongo/s/client_info.cpp b/src/mongo/s/client_info.cpp index e07a00eacaa..0447b1917ab 100644 --- a/src/mongo/s/client_info.cpp +++ b/src/mongo/s/client_info.cpp @@ -72,7 +72,6 @@ namespace mongo { _cur = _prev; _prev = temp; _cur->clear(); - _ai.startRequest(); getAuthorizationManager()->startRequest(); } diff --git a/src/mongo/s/client_info.h b/src/mongo/s/client_info.h index 16fef1a800a..ccd0a3d8b71 100644 --- a/src/mongo/s/client_info.h +++ b/src/mongo/s/client_info.h @@ -109,11 +109,8 @@ namespace mongo { static ClientInfo * get(AbstractMessagingPort* messagingPort = NULL); // Creates a ClientInfo and stores it in _tlInfo static ClientInfo* create(AbstractMessagingPort* messagingPort); - const AuthenticationInfo* getAuthenticationInfo() const { return (AuthenticationInfo*)&_ai; } - AuthenticationInfo* getAuthenticationInfo() { return (AuthenticationInfo*)&_ai; } private: - AuthenticationInfo _ai; struct WBInfo { WBInfo( const WriteBackListener::ConnectionIdent& c, OID o, bool fromLastOperation ) : ident( c ), id( o ), fromLastOperation( fromLastOperation ) {} diff --git a/src/mongo/s/security.cpp b/src/mongo/s/security.cpp index f9b7f1e9149..eed1ea72508 100644 --- a/src/mongo/s/security.cpp +++ b/src/mongo/s/security.cpp @@ -30,69 +30,8 @@ namespace mongo { - bool AuthenticationInfo::_warned; - - void AuthenticationInfo::startRequest() { - _checkLocalHostSpecialAdmin(); - } - - void AuthenticationInfo::setIsALocalHostConnectionWithSpecialAuthPowers() { - verify(!_isLocalHost); - _isLocalHost = true; - _isLocalHostAndLocalHostIsAuthorizedForAll = true; - _checkLocalHostSpecialAdmin(); - } - - bool AuthenticationInfo::_isAuthorizedSpecialChecks( const string& dbname ) const { - return isSpecialLocalhostAdmin(); - } - - bool AuthenticationInfo::isSpecialLocalhostAdmin() const { - return _isLocalHostAndLocalHostIsAuthorizedForAll; - } - - void AuthenticationInfo::_checkLocalHostSpecialAdmin() { - if (noauth || !_isLocalHost || !_isLocalHostAndLocalHostIsAuthorizedForAll) { - return; - } - - string adminNs = "admin.system.users"; - - DBConfigPtr config = grid.getDBConfig( adminNs ); - Shard s = config->getShard( adminNs ); - - // - // 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 - _warned = true; - log() << "note: no users configured in admin.system.users, allowing localhost access" << endl; - } - - // Must return conn to pool - // TODO: Check for errors during findOne(), or just let the conn die? - conn->done(); - _isLocalHostAndLocalHostIsAuthorizedForAll = true; - return; - } - - // Must return conn to pool - conn->done(); - _isLocalHostAndLocalHostIsAuthorizedForAll = false; - } - bool CmdLogout::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { - AuthenticationInfo *ai = ClientInfo::get()->getAuthenticationInfo(); AuthorizationManager* authManager = ClientInfo::get()->getAuthorizationManager(); - ai->logout(dbname); authManager->logoutDatabase(dbname); return true; } |