summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Cooper <adam.cooper@mongodb.com>2019-09-03 22:01:57 +0000
committerevergreen <evergreen@mongodb.com>2019-09-03 22:01:57 +0000
commit148c01077d4d8648a7c34125d2ec12d6e5a1056e (patch)
tree8d791b52bd84022bef6a1b0b11bd25ea3b8be55e
parent88df2558b0c3b39b86df2ab97814d701d701d704 (diff)
downloadmongo-148c01077d4d8648a7c34125d2ec12d6e5a1056e.tar.gz
SERVER-42652 Fix issue with rename collection
(cherry picked from commit cdde32442328fdd65bd1ae016164bcafff15fa92)
-rw-r--r--jstests/auth/authz_cache_on_system_modification.js68
-rw-r--r--jstests/auth/renameRestrictedCollections.js30
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.cpp11
3 files changed, 92 insertions, 17 deletions
diff --git a/jstests/auth/authz_cache_on_system_modification.js b/jstests/auth/authz_cache_on_system_modification.js
new file mode 100644
index 00000000000..bcf87e176d2
--- /dev/null
+++ b/jstests/auth/authz_cache_on_system_modification.js
@@ -0,0 +1,68 @@
+/**
+ * This tests that the user cache is invalidated after any changes are made to system collections
+ */
+
+(function() {
+ "use strict";
+
+ const conn = MongoRunner.runMongod({auth: ''});
+ let db = conn.getDB('admin');
+ const authzErrorCode = 13;
+
+ // creates a root user
+ assert.commandWorked(db.runCommand({createUser: 'root', pwd: 'pwd', roles: ['__system']}),
+ "Could not create user 'admin'");
+
+ db = (new Mongo(conn.host)).getDB('admin');
+ db.auth('root', 'pwd');
+
+ // creates a unique role, a user who has that role, and a collection upon which they can
+ // exercise
+ // that role
+ assert.commandWorked(db.createCollection("admin.test", {}),
+ "Could not create test collection in admin db");
+ assert.commandWorked(db.runCommand({
+ createRole: 'writeCustom',
+ roles: [],
+ privileges: [{resource: {db: "admin", collection: "admin.test"}, actions: ["insert"]}]
+ }),
+ "Could not create custom role");
+ assert.commandWorked(db.runCommand({createUser: 'custom', pwd: 'pwd', roles: ['writeCustom']}),
+ "Could not create new user with custom role");
+
+ // tests that a user does not retain their privileges after the system.roles collection is
+ // modified
+ (function testModifySystemRolesCollection() {
+ jsTestLog("Testing authz cache invalidation on system.roles collection modification");
+ assert(db.auth('custom', 'pwd'));
+ assert.commandWorked(db.runCommand({insert: "admin.test", documents: [{foo: "bar"}]}),
+ "Could not insert to test collection with 'custom' user");
+ assert(db.auth('root', 'pwd'));
+ assert.commandWorked(
+ db.runCommand({renameCollection: "admin.system.roles", to: "admin.wolez"}),
+ "Could not rename system.roles collection with root user");
+ assert(db.auth('custom', 'pwd'));
+ assert.commandFailedWithCode(
+ db.runCommand({insert: "admin.test", documents: [{woo: "mar"}]}),
+ authzErrorCode,
+ "Privileges retained after modification to system.roles collections");
+ })();
+
+ // tests that a user does not retain their privileges after the system.users colleciton is
+ // modified
+ (function testModifySystemUsersCollection() {
+ jsTestLog("Testing authz cache invalidation on system.users collection modification");
+ assert(db.auth('root', 'pwd'));
+ assert.commandWorked(db.createCollection("scratch", {}),
+ "Collection not created with root user");
+ assert.commandWorked(
+ db.runCommand({renameCollection: 'admin.system.users', to: 'admin.foo'}),
+ "System collection could not be renamed with root user");
+ assert.commandFailedWithCode(
+ db.runCommand({renameCollection: 'admin.scratch', to: 'admin.system.users'}),
+ authzErrorCode,
+ "User cache not invalidated after modification to system collection");
+ })();
+
+ MongoRunner.stopMongod(conn);
+})(); \ No newline at end of file
diff --git a/jstests/auth/renameRestrictedCollections.js b/jstests/auth/renameRestrictedCollections.js
index 27675fb06e9..2ada60e1421 100644
--- a/jstests/auth/renameRestrictedCollections.js
+++ b/jstests/auth/renameRestrictedCollections.js
@@ -70,6 +70,19 @@
assert.eq(null, adminDB.system.users.findOne({user: backdoorUserDoc.user}));
assert.neq(null, adminDB.system.users.findOne({user: 'userAdmin'}));
+ adminDB.auth('rootier', 'password');
+
+ // Test permissions against the configDB and localDB
+
+ // Start with test against inserting to and renaming collections in config and local
+ // as __system.
+ assert.commandWorked(configDB.test.insert({'a': 1}));
+ assert.commandWorked(configDB.test.renameCollection('test2'));
+
+ assert.commandWorked(localDB.test.insert({'a': 1}));
+ assert.commandWorked(localDB.test.renameCollection('test2'));
+ adminDB.logout();
+
// Test renaming collection in config with readWriteAnyDatabase
assert(adminDB.auth('readWriteAdmin', 'password'));
res = configDB.test2.insert({'b': 2});
@@ -85,25 +98,12 @@
assert.eq(0, res.ok);
assert.eq(CodeUnauthorized, res.code);
- adminDB.auth('rootier', 'password');
-
+ // Test renaming system.users collection with __system
+ assert(adminDB.auth('rootier', 'password'));
jsTestLog("Test that with __system you CAN rename to/from system.users");
res = adminDB.system.users.renameCollection("users", true);
assert.eq(1, res.ok, tojson(res));
-
- // Test permissions against the configDB and localDB
-
- // Start with test against inserting to and renaming collections in config and local
- // as userAdminAnyDatabase.
- assert.writeOK(configDB.test.insert({'a': 1}));
- assert.commandWorked(configDB.test.renameCollection('test2'));
-
- assert.writeOK(localDB.test.insert({'a': 1}));
- assert.commandWorked(localDB.test.renameCollection('test2'));
- adminDB.logout();
-
// At this point, all the user documents are gone, so further activity may be unauthorized,
// depending on cluster configuration. So, this is the end of the test.
MongoRunner.stopMongod(conn, {user: 'userAdmin', pwd: 'password'});
-
})(); \ No newline at end of file
diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp
index 9909657b06a..71a2d9ba071 100644
--- a/src/mongo/db/auth/authorization_manager_impl.cpp
+++ b/src/mongo/db/auth/authorization_manager_impl.cpp
@@ -643,8 +643,15 @@ bool loggedCommandOperatesOnAuthzData(const NamespaceString& nss, const BSONObj&
} else if (cmdName == "dropDatabase") {
return true;
} else if (cmdName == "renameCollection") {
- return isAuthzCollection(cmdObj.firstElement().str()) ||
- isAuthzCollection(cmdObj["to"].str());
+ const NamespaceString fromNamespace(cmdObj.firstElement().str());
+ const NamespaceString toNamespace(cmdObj["to"].str());
+ if (fromNamespace.db() == "admin" || toNamespace.db() == "admin") {
+ return isAuthzCollection(fromNamespace.coll().toString()) ||
+ isAuthzCollection(toNamespace.coll().toString());
+ } else {
+ return false;
+ }
+
} else if (cmdName == "dropIndexes" || cmdName == "deleteIndexes") {
return false;
} else if (cmdName == "create") {