Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

SERVER-7119 Make it possible to disable compatibility-form privilege …

…documents via setParameter.
  • Loading branch information...
commit 513470c4d1a2cef523f6423fdf57a550fa69cbc7 1 parent 000ea9d
Andrew Schwerin authored
View
24 jstests/auth/disable_compatibility_privileges.js
@@ -0,0 +1,24 @@
+// Test disabling old-style privilege documents at server startup.
+
+function assertGLEOK(status) {
+ assert(status.ok && status.err === null,
+ "Expected OK status object; found " + tojson(status));
+}
+
+function assertGLENotOK(status) {
+ assert(status.ok && status.err !== null,
+ "Expected not-OK status object; found " + tojson(status));
+}
+
+var conn = MongoRunner.runMongod({ auth: "",
+ smallfiles: "",
+ setParameter: "supportCompatibilityFormPrivilegeDocuments=false"
+ });
+var test = conn.getDB("test");
+
+// Valid compatibility document shoudl fail.
+test.system.users.insert({ user: "spencer", pwd: hex_md5("spencer:mongo:a"), readOnly: true });
+assertGLENotOK(test.getLastErrorObj());
+
+test.system.users.insert({ user: "spencer", userSource: "test2", roles: ["dbAdmin"] });
+assertGLEOK(test.getLastErrorObj());
View
1  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'])
View
33 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
View
31 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(
View
4 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.
View
27 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,
Please sign in to comment.
Something went wrong with that request. Please try again.