summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth
diff options
context:
space:
mode:
authorAndrew Schwerin <Andy Schwerin schwerin@10gen.com>2012-12-23 20:20:35 -0500
committerAndrew Schwerin <Andy Schwerin schwerin@10gen.com>2012-12-26 12:03:09 -0500
commit513470c4d1a2cef523f6423fdf57a550fa69cbc7 (patch)
treed1a89408288997873f1f8f07b5e66a831742e778 /src/mongo/db/auth
parent000ea9d49c4de0c68002809ad1b0b9558c1a5771 (diff)
downloadmongo-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/SConscript1
-rw-r--r--src/mongo/db/auth/auth_server_parameters.cpp33
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp31
-rw-r--r--src/mongo/db/auth/authorization_manager.h4
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp27
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,