summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2013-05-23 16:54:21 -0400
committerSpencer T Brody <spencer@10gen.com>2013-05-30 14:54:35 -0400
commit29112149f51cd3eaa0149ba9d4e16cc935d03b40 (patch)
treece4c6661b0669531387622ba023b7441e960cd2a
parent57a80ea1d0ae34124a5c408466834eda31e4578f (diff)
downloadmongo-29112149f51cd3eaa0149ba9d4e16cc935d03b40.tar.gz
Add AuthGlobalExternalState
-rw-r--r--src/mongo/db/auth/SConscript7
-rw-r--r--src/mongo/db/auth/auth_global_external_state.cpp94
-rw-r--r--src/mongo/db/auth/auth_global_external_state.h61
-rw-r--r--src/mongo/db/auth/auth_global_external_state_d.cpp37
-rw-r--r--src/mongo/db/auth/auth_global_external_state_d.h43
-rw-r--r--src/mongo/db/auth/auth_global_external_state_s.cpp54
-rw-r--r--src/mongo/db/auth/auth_global_external_state_s.h43
-rw-r--r--src/mongo/db/auth/auth_session_external_state.h10
-rw-r--r--src/mongo/db/auth/auth_session_external_state_d.h2
-rw-r--r--src/mongo/db/auth/auth_session_external_state_mock.h2
-rw-r--r--src/mongo/db/auth/auth_session_external_state_s.h2
-rw-r--r--src/mongo/db/auth/auth_session_external_state_server_common.h2
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);