diff options
author | Adam Cooper <adam.cooper@mongodb.com> | 2019-09-03 22:01:57 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-09-03 22:01:57 +0000 |
commit | 148c01077d4d8648a7c34125d2ec12d6e5a1056e (patch) | |
tree | 8d791b52bd84022bef6a1b0b11bd25ea3b8be55e | |
parent | 88df2558b0c3b39b86df2ab97814d701d701d704 (diff) | |
download | mongo-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.js | 68 | ||||
-rw-r--r-- | jstests/auth/renameRestrictedCollections.js | 30 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager_impl.cpp | 11 |
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") { |