diff options
author | Spencer T Brody <spencer@10gen.com> | 2013-05-23 16:54:21 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2013-05-30 14:54:35 -0400 |
commit | 29112149f51cd3eaa0149ba9d4e16cc935d03b40 (patch) | |
tree | ce4c6661b0669531387622ba023b7441e960cd2a | |
parent | 57a80ea1d0ae34124a5c408466834eda31e4578f (diff) | |
download | mongo-29112149f51cd3eaa0149ba9d4e16cc935d03b40.tar.gz |
Add AuthGlobalExternalState
-rw-r--r-- | src/mongo/db/auth/SConscript | 7 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_global_external_state.cpp | 94 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_global_external_state.h | 61 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_global_external_state_d.cpp | 37 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_global_external_state_d.h | 43 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_global_external_state_s.cpp | 54 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_global_external_state_s.h | 43 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_session_external_state.h | 10 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_session_external_state_d.h | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_session_external_state_mock.h | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_session_external_state_s.h | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_session_external_state_server_common.h | 2 |
12 files changed, 347 insertions, 10 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index aa0979a7b7a..37f2ff4aea1 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -10,6 +10,7 @@ env.Command(['action_type.h', 'action_type.cpp'], ['generate_action_types.py', ' # Just the data structures used env.StaticLibrary('authcore', ['action_set.cpp', 'action_type.cpp', + 'auth_global_external_state.cpp', 'auth_session_external_state.cpp', 'authorization_manager.cpp', 'role_graph.cpp', @@ -32,12 +33,14 @@ env.StaticLibrary('authservercommon', LIBDEPS=['authcore']) env.StaticLibrary('authmongod', - ['auth_session_external_state_d.cpp', + ['auth_global_external_state_d.cpp', + 'auth_session_external_state_d.cpp', 'auth_index_d.cpp'], LIBDEPS=['authservercommon']) env.StaticLibrary('authmongos', - ['auth_session_external_state_s.cpp'], + ['auth_global_external_state_s.cpp', + 'auth_session_external_state_s.cpp'], LIBDEPS=['authservercommon']) env.CppUnitTest('action_set_test', 'action_set_test.cpp', LIBDEPS=['authcore']) diff --git a/src/mongo/db/auth/auth_global_external_state.cpp b/src/mongo/db/auth/auth_global_external_state.cpp new file mode 100644 index 00000000000..48731aece4b --- /dev/null +++ b/src/mongo/db/auth/auth_global_external_state.cpp @@ -0,0 +1,94 @@ +/** +* 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 "mongo/db/auth/auth_global_external_state.h" + +#include "mongo/base/status.h" +#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/jsobj.h" +#include "mongo/db/namespacestring.h" +#include "mongo/util/mongoutils/str.h" + +namespace mongo { + + AuthGlobalExternalState::AuthGlobalExternalState() {} + AuthGlobalExternalState::~AuthGlobalExternalState() {} + + Status AuthGlobalExternalState::getPrivilegeDocument(const std::string& dbname, + const UserName& userName, + BSONObj* result) { + + if (dbname == StringData("$external", StringData::LiteralTag()) || + dbname == AuthorizationManager::SERVER_RESOURCE_NAME || + dbname == AuthorizationManager::CLUSTER_RESOURCE_NAME) { + return Status(ErrorCodes::UserNotFound, + mongoutils::str::stream() << "No privilege documents stored in the " << + dbname << " user source."); + } + + if (!NamespaceString::validDBName(dbname)) { + return Status(ErrorCodes::BadValue, "Bad database name \"" + dbname + "\""); + } + + if (dbname == StringData("local", StringData::LiteralTag()) && + userName.getUser() == internalSecurity.user) { + + if (internalSecurity.pwd.empty()) { + return Status(ErrorCodes::UserNotFound, + "key file must be used to log in with internal user", + 15889); + } + *result = BSON(AuthorizationManager::USER_NAME_FIELD_NAME << + internalSecurity.user << + AuthorizationManager::PASSWORD_FIELD_NAME << + internalSecurity.pwd).getOwned(); + return Status::OK(); + } + + std::string usersNamespace = dbname + ".system.users"; + + BSONObj userBSONObj; + BSONObjBuilder queryBuilder; + queryBuilder.append(AuthorizationManager::USER_NAME_FIELD_NAME, userName.getUser()); + if (userName.getDB() == dbname) { + queryBuilder.appendNull(AuthorizationManager::USER_SOURCE_FIELD_NAME); + } + else { + queryBuilder.append(AuthorizationManager::USER_SOURCE_FIELD_NAME, + userName.getDB()); + } + + bool found = _findUser(usersNamespace, queryBuilder.obj(), &userBSONObj); + if (!found) { + return Status(ErrorCodes::UserNotFound, + mongoutils::str::stream() << "auth: couldn't find user " << + userName.toString() << ", " << usersNamespace, + 0); + } + + *result = userBSONObj.getOwned(); + return Status::OK(); + } + + bool AuthGlobalExternalState::_hasPrivilegeDocument(const std::string& dbname) const { + std::string usersNamespace = dbname + ".system.users"; + + BSONObj userBSONObj; + BSONObj query; + return _findUser(usersNamespace, query, &userBSONObj); + } + +} // namespace mongo diff --git a/src/mongo/db/auth/auth_global_external_state.h b/src/mongo/db/auth/auth_global_external_state.h new file mode 100644 index 00000000000..144193d0a30 --- /dev/null +++ b/src/mongo/db/auth/auth_global_external_state.h @@ -0,0 +1,61 @@ +/* +* 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/>. +*/ + +#pragma once + +#include <string> + +#include "mongo/base/disallow_copying.h" +#include "mongo/base/status.h" +#include "mongo/db/auth/user_name.h" +#include "mongo/db/jsobj.h" + +namespace mongo { + + /** + * Public interface for a class that encapsulates all the information related to system + * state not stored in AuthorizationManager. This is primarily to make AuthorizationManager + * easier to test as well as to allow different implementations for mongos and mongod. + */ + class AuthGlobalExternalState { + MONGO_DISALLOW_COPYING(AuthGlobalExternalState); + + public: + + virtual ~AuthGlobalExternalState(); + + // Gets the privilege information document for "userName" on "dbname". + // + // On success, returns Status::OK() and stores a shared-ownership copy of the document into + // "result". + Status getPrivilegeDocument(const std::string& dbname, + const UserName& userName, + BSONObj* result); + + protected: + AuthGlobalExternalState(); // This class should never be instantiated directly. + + // Queries the userNamespace with the given query and returns the privilegeDocument found + // in *result. Returns true if it finds a document matching the query, or false if not. + virtual bool _findUser(const std::string& usersNamespace, + const BSONObj& query, + BSONObj* result) const = 0; + + // Returns true if there exists at least one privilege document in the given database. + bool _hasPrivilegeDocument(const std::string& dbname) const; + }; + +} // namespace mongo diff --git a/src/mongo/db/auth/auth_global_external_state_d.cpp b/src/mongo/db/auth/auth_global_external_state_d.cpp new file mode 100644 index 00000000000..9af0d3e626a --- /dev/null +++ b/src/mongo/db/auth/auth_global_external_state_d.cpp @@ -0,0 +1,37 @@ +/** +* 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 "mongo/db/auth/auth_global_external_state_d.h" + +#include "mongo/db/client.h" +#include "mongo/db/dbhelpers.h" +#include "mongo/db/jsobj.h" + +namespace mongo { + + AuthGlobalExternalStateMongod::AuthGlobalExternalStateMongod() {} + AuthGlobalExternalStateMongod::~AuthGlobalExternalStateMongod() {} + + bool AuthGlobalExternalStateMongod::_findUser(const string& usersNamespace, + const BSONObj& query, + BSONObj* result) const { + Client::GodScope gs; + Client::ReadContext ctx(usersNamespace); + + return Helpers::findOne(usersNamespace, query, *result); + } + +} // namespace mongo diff --git a/src/mongo/db/auth/auth_global_external_state_d.h b/src/mongo/db/auth/auth_global_external_state_d.h new file mode 100644 index 00000000000..afa079c852d --- /dev/null +++ b/src/mongo/db/auth/auth_global_external_state_d.h @@ -0,0 +1,43 @@ +/** +* 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/>. +*/ + +#pragma once + +#include <string> + +#include "mongo/base/disallow_copying.h" +#include "mongo/base/status.h" +#include "mongo/db/auth/auth_global_external_state.h" + +namespace mongo { + + /** + * The implementation of AuthGlobalExternalState functionality for mongod. + */ + class AuthGlobalExternalStateMongod : public AuthGlobalExternalState { + MONGO_DISALLOW_COPYING(AuthGlobalExternalStateMongod); + + public: + AuthGlobalExternalStateMongod(); + virtual ~AuthGlobalExternalStateMongod(); + + protected: + virtual bool _findUser(const string& usersNamespace, + const BSONObj& query, + BSONObj* result) const; + }; + +} // namespace mongo diff --git a/src/mongo/db/auth/auth_global_external_state_s.cpp b/src/mongo/db/auth/auth_global_external_state_s.cpp new file mode 100644 index 00000000000..8083a235c29 --- /dev/null +++ b/src/mongo/db/auth/auth_global_external_state_s.cpp @@ -0,0 +1,54 @@ +/** +* 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 "mongo/db/auth/auth_global_external_state_s.h" + +#include <string> + +#include "mongo/client/dbclientinterface.h" +#include "mongo/db/jsobj.h" +#include "mongo/s/grid.h" + +namespace mongo { + + AuthGlobalExternalStateMongos::AuthGlobalExternalStateMongos() {} + AuthGlobalExternalStateMongos::~AuthGlobalExternalStateMongos() {} + + namespace { + ScopedDbConnection* getConnectionForUsersCollection(const std::string& ns) { + // + // Note: The connection mechanism here is *not* ideal, and should not be used elsewhere. + // If the primary for the collection moves, this approach may throw rather than handle + // version exceptions. + // + + DBConfigPtr config = grid.getDBConfig(ns); + Shard s = config->getShard(ns); + + return new ScopedDbConnection(s.getConnString(), 30.0); + } + } + + bool AuthGlobalExternalStateMongos::_findUser(const string& usersNamespace, + const BSONObj& query, + BSONObj* result) const { + scoped_ptr<ScopedDbConnection> conn(getConnectionForUsersCollection(usersNamespace)); + *result = conn->get()->findOne(usersNamespace, query).getOwned(); + conn->done(); + return !result->isEmpty(); + } + +} // namespace mongo diff --git a/src/mongo/db/auth/auth_global_external_state_s.h b/src/mongo/db/auth/auth_global_external_state_s.h new file mode 100644 index 00000000000..5cd6a4f05e3 --- /dev/null +++ b/src/mongo/db/auth/auth_global_external_state_s.h @@ -0,0 +1,43 @@ +/** +* 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/>. +*/ + +#pragma once + +#include <string> + +#include "mongo/base/disallow_copying.h" +#include "mongo/base/status.h" +#include "mongo/db/auth/auth_global_external_state.h" + +namespace mongo { + + /** + * The implementation of AuthGlobalExternalState functionality for mongos. + */ + class AuthGlobalExternalStateMongos : public AuthGlobalExternalState{ + MONGO_DISALLOW_COPYING(AuthGlobalExternalStateMongos); + + public: + AuthGlobalExternalStateMongos(); + virtual ~AuthGlobalExternalStateMongos(); + + protected: + virtual bool _findUser(const string& usersNamespace, + const BSONObj& query, + BSONObj* result) const; + }; + +} // namespace mongo diff --git a/src/mongo/db/auth/auth_session_external_state.h b/src/mongo/db/auth/auth_session_external_state.h index 2a5330ed8d6..4701cb3cbdb 100644 --- a/src/mongo/db/auth/auth_session_external_state.h +++ b/src/mongo/db/auth/auth_session_external_state.h @@ -28,10 +28,9 @@ namespace mongo { class Principal; /** - * Public interface for a class that encapsulates all the information related to system state - * not stored in AuthorizationManager. This is primarily to make AuthorizationManager easier - * to test. There are two classes that implement this interface, AuthExternalStateImpl, which - * is what's used for the actual system, and AuthExternalStateMock, which is used in the tests. + * Public interface for a class that encapsulates all the session information related to system + * state not stored in AuthorizationasSession. This is primarily to make AuthorizationSession + * easier to test as well as to allow different implementations in mongos and mongod. */ class AuthSessionExternalState { MONGO_DISALLOW_COPYING(AuthSessionExternalState); @@ -56,6 +55,7 @@ namespace mongo { // // On success, returns Status::OK() and stores a shared-ownership copy of the document into // "result". + // TODO: remove this in favor of using the AuthGlobalExternalState Status getPrivilegeDocument(const std::string& dbname, const UserName& userName, BSONObj* result); @@ -73,11 +73,13 @@ namespace mongo { // Queries the userNamespace with the given query and returns the privilegeDocument found // in *result. Returns true if it finds a document matching the query, or false if not. + // TODO: remove this in favor of using the AuthGlobalExternalState virtual bool _findUser(const std::string& usersNamespace, const BSONObj& query, BSONObj* result) const = 0; // Returns true if there exists at least one privilege document in the given database. + // TODO: remove this in favor of using the AuthGlobalExternalState bool _hasPrivilegeDocument(const std::string& dbname) const; }; diff --git a/src/mongo/db/auth/auth_session_external_state_d.h b/src/mongo/db/auth/auth_session_external_state_d.h index 54f9f94eeab..af97192a48d 100644 --- a/src/mongo/db/auth/auth_session_external_state_d.h +++ b/src/mongo/db/auth/auth_session_external_state_d.h @@ -23,7 +23,7 @@ namespace mongo { /** - * The implementation of AuthExternalState functionality for mongod. + * The implementation of AuthSessionExternalState functionality for mongod. */ class AuthSessionExternalStateMongod : public AuthSessionExternalStateServerCommon { MONGO_DISALLOW_COPYING(AuthSessionExternalStateMongod); diff --git a/src/mongo/db/auth/auth_session_external_state_mock.h b/src/mongo/db/auth/auth_session_external_state_mock.h index ff156ac457a..09678567ebd 100644 --- a/src/mongo/db/auth/auth_session_external_state_mock.h +++ b/src/mongo/db/auth/auth_session_external_state_mock.h @@ -23,7 +23,7 @@ namespace mongo { /** - * Mock of the AuthExternalState class used only for testing. + * Mock of the AuthSessionExternalState class used only for testing. */ class AuthSessionExternalStateMock : public AuthSessionExternalState { MONGO_DISALLOW_COPYING(AuthSessionExternalStateMock); diff --git a/src/mongo/db/auth/auth_session_external_state_s.h b/src/mongo/db/auth/auth_session_external_state_s.h index 94702472cb3..b8d8d03290a 100644 --- a/src/mongo/db/auth/auth_session_external_state_s.h +++ b/src/mongo/db/auth/auth_session_external_state_s.h @@ -23,7 +23,7 @@ namespace mongo { /** - * The implementation of AuthExternalState functionality for mongos. + * The implementation of AuthSessionExternalState functionality for mongos. */ class AuthSessionExternalStateMongos : public AuthSessionExternalStateServerCommon { MONGO_DISALLOW_COPYING(AuthSessionExternalStateMongos); diff --git a/src/mongo/db/auth/auth_session_external_state_server_common.h b/src/mongo/db/auth/auth_session_external_state_server_common.h index 8620a2112aa..3d1375c9517 100644 --- a/src/mongo/db/auth/auth_session_external_state_server_common.h +++ b/src/mongo/db/auth/auth_session_external_state_server_common.h @@ -23,7 +23,7 @@ namespace mongo { /** - * The implementation of AuthExternalState functionality common to mongod and mongos. + * The implementation of AuthSessionExternalState functionality common to mongod and mongos. */ class AuthSessionExternalStateServerCommon : public AuthSessionExternalState { MONGO_DISALLOW_COPYING(AuthSessionExternalStateServerCommon); |