/** * This tests that the proper access control is enforced around modifications to user and role data. * @tags: [requires_sharding] */ function runTest(conn) { var authzErrorCode = 13; conn.getDB('admin').createUser( {user: 'userAdmin', pwd: 'pwd', roles: ['userAdminAnyDatabase']}); var userAdminConn = new Mongo(conn.host); userAdminConn.getDB('admin').auth('userAdmin', 'pwd'); var testUserAdmin = userAdminConn.getDB('test'); var adminUserAdmin = userAdminConn.getDB('admin'); testUserAdmin.createRole({role: 'testRole', roles: [], privileges: []}); adminUserAdmin.createRole({role: 'adminRole', roles: [], privileges: []}); testUserAdmin.createUser( {user: 'spencer', pwd: 'pwd', roles: ['testRole', {role: 'adminRole', db: 'admin'}]}); adminUserAdmin.createUser({user: 'otherUser', pwd: 'pwd', roles: []}); var db = conn.getDB('test'); db.auth('spencer', 'pwd'); var admindb = conn.getDB('admin'); // "adminUserAdmin" and "testUserAdmin" are handles to the "admin" and "test" dbs, respectively. // Both are on the same connection, which has been auth'd as a user with 'userAdminAnyDatabase'. // "db" and "admindb" are also handles to the "test" and "admin" dbs, but on a connection that // has been auth'd as the user spencer@test. "testUserAdmin" and "adminUserAdmin" will be used // to control what privileges spencer@test has (and thus are usable by "db" and "admindb"), // while "db" and "admindb" will be used for the actual permission checks that are being tested. (function testCreateUser() { jsTestLog("Testing user creation"); var res = db.runCommand({createUser: 'andy', pwd: 'pwd', roles: []}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['createUser']}]); assert.commandWorked(db.runCommand({createUser: 'andy', pwd: 'pwd', roles: []})); res = admindb.runCommand({createUser: 'andy', pwd: 'pwd', roles: []}); assert.commandFailedWithCode(res, authzErrorCode); })(); (function testCreateRole() { jsTestLog("Testing role creation"); var res = db.runCommand({createRole: 'testRole2', roles: [], privileges: []}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['createRole']}]); assert.commandWorked(db.runCommand({createRole: 'testRole2', roles: [], privileges: []})); res = admindb.runCommand({createRole: 'testRole2', roles: [], privileges: []}); assert.commandFailedWithCode(res, authzErrorCode); })(); (function() { jsTestLog("Testing role creation, of user-defined roles with same name as built-in roles"); var cmdObj = {createRole: "readWrite", roles: [], privileges: []}; var res = adminUserAdmin.runCommand(cmdObj); assert.commandFailed(res, tojson(cmdObj)); var roleObj = adminUserAdmin.system.roles.findOne({role: "readWrite", db: "admin"}); // double check that no role object named "readWrite" has been created assert(!roleObj, "user-defined \"readWrite\" role was created: " + tojson(roleObj)); })(); (function testViewUser() { jsTestLog("Testing viewing user information"); var res = db.runCommand({usersInfo: 'andy'}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['viewUser']}]); assert.commandWorked(db.runCommand({usersInfo: 'andy'})); res = admindb.runCommand({usersInfo: 'andy'}); assert.commandFailedWithCode(res, authzErrorCode); })(); (function testViewRole() { jsTestLog("Testing viewing role information"); var res = db.runCommand({rolesInfo: 'testRole2'}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['viewRole']}]); assert.commandWorked(db.runCommand({rolesInfo: 'testRole2'})); res = admindb.runCommand({rolesInfo: 'testRole2'}); assert.commandFailedWithCode(res, authzErrorCode); })(); (function testDropUser() { jsTestLog("Testing dropping user"); var res = db.runCommand({dropUser: 'andy'}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['dropUser']}]); assert.commandWorked(db.runCommand({dropUser: 'andy'})); res = admindb.runCommand({dropUser: 'andy'}); assert.commandFailedWithCode(res, authzErrorCode); })(); (function testDropRole() { jsTestLog("Testing dropping role"); var res = db.runCommand({dropRole: 'testRole2'}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['dropRole']}]); assert.commandWorked(db.runCommand({dropRole: 'testRole2'})); res = admindb.runCommand({dropRole: 'testRole2'}); assert.commandFailedWithCode(res, authzErrorCode); })(); (function testGrantRole() { jsTestLog("Testing granting roles"); var res = db.runCommand({createUser: 'andy', pwd: 'pwd', roles: ['read']}); assert.commandFailedWithCode(res, authzErrorCode); res = db.runCommand({grantRolesToUser: 'spencer', roles: ['read']}); assert.commandFailedWithCode(res, authzErrorCode); res = db.runCommand({grantRolesToRole: 'testRole', roles: ['read']}); assert.commandFailedWithCode(res, authzErrorCode); res = admindb.runCommand( {grantRolesToUser: 'otherUser', roles: [{role: 'read', db: 'test'}]}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['grantRole']}]); assert.commandWorked(db.runCommand({createUser: 'andy', pwd: 'pwd', roles: ['read']})); assert.commandWorked(db.runCommand({grantRolesToUser: 'spencer', roles: ['read']})); assert.commandWorked(db.runCommand({grantRolesToRole: 'testRole', roles: ['read']})); // Granting roles from other dbs should fail res = db.runCommand({grantRolesToUser: 'spencer', roles: [{role: 'read', db: 'other'}]}); assert.commandFailedWithCode(res, authzErrorCode); // Granting roles from this db to users in another db, however, should work res = admindb.runCommand( {grantRolesToUser: 'otherUser', roles: [{role: 'read', db: 'test'}]}); assert.commandWorked(res); })(); (function testRevokeRole() { jsTestLog("Testing revoking roles"); var res = db.runCommand({revokeRolesFromUser: 'spencer', roles: ['read']}); assert.commandFailedWithCode(res, authzErrorCode); res = db.runCommand({revokeRolesFromRole: 'testRole', roles: ['read']}); assert.commandFailedWithCode(res, authzErrorCode); res = admindb.runCommand( {revokeRolesFromUser: 'otherUser', roles: [{role: 'read', db: 'test'}]}); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['revokeRole']}]); assert.commandWorked(db.runCommand({revokeRolesFromUser: 'spencer', roles: ['read']})); assert.commandWorked(db.runCommand({revokeRolesFromRole: 'testRole', roles: ['read']})); // Revoking roles from other dbs should fail res = db.runCommand({revokeRolesFromUser: 'spencer', roles: [{role: 'read', db: 'other'}]}); assert.commandFailedWithCode(res, authzErrorCode); // Revoking roles from this db from users in another db, however, should work res = admindb.runCommand( {revokeRolesFromUser: 'otherUser', roles: [{role: 'read', db: 'test'}]}); assert.commandWorked(res); })(); (function testGrantPrivileges() { jsTestLog("Testing granting privileges"); testUserAdmin.revokePrivilegesFromRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['grantRole']}]); var res = db.runCommand({ createRole: 'testRole2', roles: [], privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandFailedWithCode(res, authzErrorCode); res = db.runCommand({ grantPrivilegesToRole: 'testRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandFailedWithCode(res, authzErrorCode); res = admindb.runCommand({ grantPrivilegesToRole: 'adminRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['grantRole']}]); res = db.runCommand({ createRole: 'testRole2', roles: [], privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandWorked(res); res = db.runCommand({ grantPrivilegesToRole: 'testRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandWorked(res); // Granting privileges from other dbs should fail res = db.runCommand({ grantPrivilegesToRole: 'testRole', privileges: [{resource: {db: 'other', collection: ''}, actions: ['find']}] }); assert.commandFailedWithCode(res, authzErrorCode); // Granting privileges from this db to users in another db, however, should work res = admindb.runCommand({ grantPrivilegesToRole: 'adminRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandWorked(res); })(); (function testRevokePrivileges() { jsTestLog("Testing revoking privileges"); testUserAdmin.revokePrivilegesFromRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['revokeRole']}]); var res = db.runCommand({ revokePrivilegesFromRole: 'testRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandFailedWithCode(res, authzErrorCode); res = admindb.runCommand({ revokePrivilegesFromRole: 'adminRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandFailedWithCode(res, authzErrorCode); testUserAdmin.grantPrivilegesToRole( 'testRole', [{resource: {db: 'test', collection: ''}, actions: ['revokeRole']}]); res = db.runCommand({ revokePrivilegesFromRole: 'testRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandWorked(res); // Revoking privileges from other dbs should fail res = db.runCommand({ revokePrivilegesFromRole: 'testRole', privileges: [{resource: {db: 'other', collection: ''}, actions: ['find']}] }); assert.commandFailedWithCode(res, authzErrorCode); // Granting privileges from this db to users in another db, however, should work res = admindb.runCommand({ revokePrivilegesFromRole: 'adminRole', privileges: [{resource: {db: 'test', collection: ''}, actions: ['find']}] }); assert.commandWorked(res); })(); } jsTest.log('Test standalone'); var conn = MongoRunner.runMongod({auth: ''}); runTest(conn); MongoRunner.stopMongod(conn); jsTest.log('Test sharding'); var st = new ShardingTest({shards: 2, config: 3, keyFile: 'jstests/libs/key1'}); runTest(st.s); st.stop();