diff options
author | Andrew Schwerin <Andy Schwerin schwerin@10gen.com> | 2012-12-23 20:20:35 -0500 |
---|---|---|
committer | Andrew Schwerin <Andy Schwerin schwerin@10gen.com> | 2012-12-26 12:03:09 -0500 |
commit | 513470c4d1a2cef523f6423fdf57a550fa69cbc7 (patch) | |
tree | d1a89408288997873f1f8f07b5e66a831742e778 /src/mongo/db/auth | |
parent | 000ea9d49c4de0c68002809ad1b0b9558c1a5771 (diff) | |
download | mongo-513470c4d1a2cef523f6423fdf57a550fa69cbc7.tar.gz |
SERVER-7119 Make it possible to disable compatibility-form privilege documents via setParameter.
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r-- | src/mongo/db/auth/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/auth/auth_server_parameters.cpp | 33 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager.cpp | 31 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager.h | 4 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager_test.cpp | 27 |
5 files changed, 90 insertions, 6 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index c959c638ef1..e736fb3b665 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -22,6 +22,7 @@ env.StaticLibrary('authcore', ['action_set.cpp', env.StaticLibrary('authservercommon', ['auth_external_state_server_common.cpp', + 'auth_server_parameters.cpp', 'security_key.cpp'], LIBDEPS=['authcore']) diff --git a/src/mongo/db/auth/auth_server_parameters.cpp b/src/mongo/db/auth/auth_server_parameters.cpp new file mode 100644 index 00000000000..6c9dbf2abf3 --- /dev/null +++ b/src/mongo/db/auth/auth_server_parameters.cpp @@ -0,0 +1,33 @@ +/** +* 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/base/init.h" +#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/server_parameters.h" + +namespace mongo { +namespace { + + MONGO_EXPORT_SERVER_PARAMETER(supportCompatibilityFormPrivilegeDocuments, bool, true); + + MONGO_INITIALIZER(AuthSetPrivilegeDocumentCompatibilitySupport)(InitializerContext*) { + AuthorizationManager::setSupportOldStylePrivilegeDocuments( + supportCompatibilityFormPrivilegeDocuments); + return Status::OK(); + } + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp index d1131b55289..d36413c8f4b 100644 --- a/src/mongo/db/auth/authorization_manager.cpp +++ b/src/mongo/db/auth/authorization_manager.cpp @@ -51,6 +51,8 @@ namespace mongo { const std::string AuthorizationManager::USER_SOURCE_FIELD_NAME = "userSource"; const std::string AuthorizationManager::PASSWORD_FIELD_NAME = "pwd"; + bool AuthorizationManager::_doesSupportOldStylePrivileges = true; + namespace { const std::string ADMIN_DBNAME = "admin"; const std::string LOCAL_DBNAME = "local"; @@ -218,6 +220,16 @@ namespace { return Status::OK(); } + void AuthorizationManager::setSupportOldStylePrivilegeDocuments(bool enabled) { + _doesSupportOldStylePrivileges = enabled; + } + + static inline Status _oldPrivilegeFormatNotSupported() { + return Status(ErrorCodes::UnsupportedFormat, + "Support for compatibility-form privilege documents disabled; " + "All system.users entries must contain a 'roles' field"); + } + static inline Status _badValue(const char* reason, int location) { return Status(ErrorCodes::BadValue, reason, location); } @@ -232,7 +244,7 @@ namespace { static Status _checkRolesArray(const BSONElement& rolesElement) { if (rolesElement.type() != Array) { - return _badValue("Role fields must be an array when present in system.users entries", + return _badValue("Role fields must be an array when present in system.users entries", 0); } for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) { @@ -265,6 +277,10 @@ namespace { "field, but not both", 0); } + if (!_doesSupportOldStylePrivileges && rolesElement.eoo()) { + return _oldPrivilegeFormatNotSupported(); + } + // Cannot have both "roles" and "readOnly" elements. if (!rolesElement.eoo() && !readOnlyElement.eoo()) { return _badValue("system.users entry must not have both 'roles' and 'readOnly' fields", @@ -478,10 +494,15 @@ namespace { PrivilegeSet* result) { if (!privilegeDocument.hasField(ROLES_FIELD_NAME)) { // Old-style (v2.2 and prior) privilege document - return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname, - principal, - privilegeDocument, - result); + if (_doesSupportOldStylePrivileges) { + return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname, + principal, + privilegeDocument, + result); + } + else { + return _oldPrivilegeFormatNotSupported(); + } } else { return _buildPrivilegeSetFromExtendedPrivilegeDocument( diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h index b455cd72da9..e0924629828 100644 --- a/src/mongo/db/auth/authorization_manager.h +++ b/src/mongo/db/auth/authorization_manager.h @@ -63,6 +63,8 @@ namespace mongo { static const std::string USER_SOURCE_FIELD_NAME; static const std::string PASSWORD_FIELD_NAME; + static void setSupportOldStylePrivilegeDocuments(bool enabled); + // Checks to see if "doc" is a valid privilege document, assuming it is stored in the // "system.users" collection of database "dbname". // @@ -201,6 +203,8 @@ namespace mongo { // certain namespaces like system.users and system.profile. Privilege _modifyPrivilegeForSpecialCases(const Privilege& privilege); + static bool _doesSupportOldStylePrivileges; + scoped_ptr<AuthExternalState> _externalState; // All the privileges that have been acquired by the authenticated principals. diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp index 312995bfd5f..2d466f22a88 100644 --- a/src/mongo/db/auth/authorization_manager_test.cpp +++ b/src/mongo/db/auth/authorization_manager_test.cpp @@ -402,6 +402,32 @@ namespace { ASSERT_NOT_OK(check("test", BSON("user" << "" << "pwd" << "a"))); } + + class CompatibilityModeDisabler { + public: + CompatibilityModeDisabler() { + AuthorizationManager::setSupportOldStylePrivilegeDocuments(false); + } + ~CompatibilityModeDisabler() { + AuthorizationManager::setSupportOldStylePrivilegeDocuments(true); + } + }; + + TEST(AuthorizationManagerTest, DisableCompatibilityMode) { + Status (*check)(const StringData&, const BSONObj&) = + &AuthorizationManager::checkValidPrivilegeDocument; + + CompatibilityModeDisabler disabler; + + ASSERT_NOT_OK(check("test", BSON("user" << "andy" << "pwd" << "a"))); + ASSERT_NOT_OK(check("test", BSON("user" << "andy" << "pwd" << "a" << "readOnly" << 1))); + ASSERT_NOT_OK(check("test", BSON("user" << "andy" << "pwd" << "a" << "readOnly" << false))); + ASSERT_NOT_OK(check("test", BSON("user" << "andy" << "pwd" << "a" << "readOnly" << "yes"))); + + ASSERT_OK(check("test", BSON("user" << "andy" << "pwd" << "a" << + "roles" << BSON_ARRAY("dbAdmin" << "read")))); + } + TEST(AuthorizationManagerTest, DocumentValidationExtended) { Status (*check)(const StringData&, const BSONObj&) = &AuthorizationManager::checkValidPrivilegeDocument; @@ -472,7 +498,6 @@ namespace { "roles" << BSONArrayBuilder().arr()))); } - class AuthExternalStateImplictPriv : public AuthExternalStateMock { public: virtual bool _findUser(const string& usersNamespace, |