diff options
53 files changed, 510 insertions, 268 deletions
diff --git a/jstests/auth/auth1.js b/jstests/auth/auth1.js index f5e9a877ad4..4098c6bfbef 100644 --- a/jstests/auth/auth1.js +++ b/jstests/auth/auth1.js @@ -8,15 +8,19 @@ baseName = "jstests_auth_auth1"; m = startMongod( "--auth", "--port", port, "--dbpath", MongoRunner.dataPath + baseName, "--nohttpinterface", "--bind_ip", "127.0.0.1" ); db = m.getDB( "test" ); -t = db[ baseName ]; -t.drop(); - // these are used by read-only user mro = new Mongo(m.host); dbRO = mro.getDB( "test" ); tRO = dbRO[ baseName ]; +db.getSisterDB("admin").createUser({user: "root", pwd: "root", roles: ["root"]}); +db.getSisterDB("admin").auth("root", "root"); + +t = db[ baseName ]; +t.drop(); + db.dropAllUsers(); +db.logout(); db.getSisterDB( "admin" ).createUser({user: "super", pwd: "super", roles: ["__system"] }); db.getSisterDB("admin").auth("super", "super"); diff --git a/jstests/auth/auth2.js b/jstests/auth/auth2.js index 84b7a0c7fd2..3cb9838682a 100644 --- a/jstests/auth/auth2.js +++ b/jstests/auth/auth2.js @@ -3,21 +3,25 @@ port = allocatePorts( 1 )[ 0 ]; baseName = "jstests_auth_auth2"; -m = startMongod( "--auth", "--port", port, "--dbpath", MongoRunner.dataPath + baseName, "--nohttpinterface", "--bind_ip", "127.0.0.1" , "--nojournal" , "--smallfiles" ); +m = startMongod( "--auth", "--port", port, "--dbpath", MongoRunner.dataPath + baseName, "--nohttpinterface", "--bind_ip", "127.0.0.1", "--nojournal", "--smallfiles" ); db = m.getDB( "admin" ); -t = db[ baseName ]; -t.drop(); +// These statements throw because the localhost exception does not allow +// these operations: it only allows the creation of the first admin user +// and necessary setup operations. +assert.throws( function(){ db.users.count(); } ); +assert.throws( function() { db.shutdownServer(); } ); -users = db.getCollection( "system.users" ); -assert.eq( 0 , users.count() ); - -db.createUser({user: "eliot" , pwd: "eliot", roles: jsTest.adminUserRoles}); +db.createUser( { user: "eliot", pwd: "eliot", roles: [ "root" ] } ); -assert.throws( function(){ db.users.count(); } ) +// These statements throw because we have a user but have not authenticated +// as that user. +assert.throws( function(){ db.users.count(); } ); +assert.throws( function() { db.shutdownServer(); } ); -assert.throws( function() { db.shutdownServer(); } ) +db.auth( "eliot", "eliot" ); -db.auth( "eliot" , "eliot" ) +users = db.getCollection( "system.users" ); +assert.eq( 1, users.count() ); db.shutdownServer(); diff --git a/jstests/auth/auth_helpers.js b/jstests/auth/auth_helpers.js index d97e37e2d2f..3db73977811 100644 --- a/jstests/auth/auth_helpers.js +++ b/jstests/auth/auth_helpers.js @@ -4,6 +4,10 @@ var conn = MongoRunner.runMongod({ smallfiles: "", auth: "" }); var mechanisms, hasMongoCR, hasCramMd5; +var admin = conn.getDB('admin'); +admin.createUser({user:'andy', pwd: 'a', roles: jsTest.adminUserRoles}); +admin.auth({user: 'andy', pwd: 'a'}); + // Find out if this build supports the authenticationMechanisms startup parameter. If it does, // restart with MONGODB-CR and CRAM-MD5 mechanisms enabled. var cmdOut = conn.getDB('admin').runCommand({getParameter: 1, authenticationMechanisms: 1}) @@ -23,12 +27,9 @@ else { print("test info: Using only default authentication mechanism, MONGODB-CR."); } -var admin = conn.getDB('admin'); - +admin = conn.getDB('admin'); var testedSomething = false; -admin.createUser({user:'andy', pwd: 'a', roles: jsTest.adminUserRoles}); - // If the server supports them MONGODB-CR, try all the ways to call db.auth that use MONGODB-CR. if (hasMongoCR) { testedSomething = true; diff --git a/jstests/auth/auth_options.js b/jstests/auth/auth_options.js index 4f5dc27fb78..1a38821fa03 100644 --- a/jstests/auth/auth_options.js +++ b/jstests/auth/auth_options.js @@ -10,6 +10,7 @@ var expectedResult = { } } }; + testGetCmdLineOptsMongod({ auth : "" }, expectedResult); jsTest.log("Testing \"noauth\" command line option"); diff --git a/jstests/auth/basic_role_auth.js b/jstests/auth/basic_role_auth.js index 801a5d64ecd..c1ea6626506 100644 --- a/jstests/auth/basic_role_auth.js +++ b/jstests/auth/basic_role_auth.js @@ -477,15 +477,15 @@ var runTests = function(conn) { var testDB = conn.getDB('test'); var adminDB = conn.getDB('admin'); + adminDB.createUser({ user: 'root', pwd: AUTH_INFO.admin.root.pwd, + roles: AUTH_INFO.admin.root.roles }); + adminDB.auth('root', AUTH_INFO.admin.root.pwd); + for (var x = 0; x < 10; x++) { testDB.kill_cursor.insert({ x: x }); adminDB.kill_cursor.insert({ x: x }); } - adminDB.createUser({ user: 'root', pwd: AUTH_INFO.admin.root.pwd, - roles: AUTH_INFO.admin.root.roles }); - adminDB.auth('root', AUTH_INFO.admin.root.pwd); - for (var dbName in AUTH_INFO) { var dbObj = AUTH_INFO[dbName]; @@ -526,6 +526,8 @@ var runTests = function(conn) { } }); + teardown(); + if (failures.length > 0) { var list = ''; failures.forEach(function(test) { list += (test + '\n'); }); @@ -542,3 +544,4 @@ var st = new ShardingTest({ shards: 1, keyFile: 'jstests/libs/key1' }); runTests(st.s); st.stop(); +print('SUCCESS! Completed basic_role_auth.js'); diff --git a/jstests/auth/copyauth.js b/jstests/auth/copyauth.js index 3378039047a..1148b31104e 100644 --- a/jstests/auth/copyauth.js +++ b/jstests/auth/copyauth.js @@ -52,7 +52,14 @@ function ClusterSpawnHelper(clusterType, startWithAuth) { var replSetTest = new ReplSetTest(replSetTestConfig); replSetTest.startSet(); replSetTest.initiate(); - replSetTest.awaitReplication(); + if (startWithAuth) { + authutil.asCluster(replSetTest.nodes, + replSetTestConfig.nodeOptions.keyFile, + function() { replSetTest.awaitReplication(); }); + } + else { + replSetTest.awaitReplication(); + } this.conn = replSetTest.getMaster(); this.connString = replSetTest.getURL(); } @@ -116,16 +123,16 @@ function copydbBetweenClustersTest(configObj) { // 1. Get a connection to the source database, insert data and setup auth if applicable source = new ClusterSpawnHelper(configObj.sourceClusterType, configObj.isSourceUsingAuth); - source.conn.getDB(baseName)[baseName].save({i:1}); - assert.eq(1, source.conn.getDB(baseName)[baseName].count()); - assert.eq(1, source.conn.getDB(baseName)[baseName].findOne().i); - if (configObj.isSourceUsingAuth) { // Create a super user so we can create a regular user and not be locked out afterwards source.conn.getDB("admin").createUser({ user: "sourceSuperUser", pwd: "sourceSuperUser", roles: [ "root" ] }); source.conn.getDB("admin").auth("sourceSuperUser", "sourceSuperUser"); + source.conn.getDB(baseName)[baseName].save({i:1}); + assert.eq(1, source.conn.getDB(baseName)[baseName].count()); + assert.eq(1, source.conn.getDB(baseName)[baseName].findOne().i); + // Insert a document and create a regular user that we will use for the target // authenticating with the source source.conn.getDB(baseName).createUser({ user: "foo", pwd: "bar", @@ -133,6 +140,10 @@ function copydbBetweenClustersTest(configObj) { source.conn.getDB("admin").logout(); assert.throws(function() { source.conn.getDB(baseName)[baseName].findOne(); }); + } else { + source.conn.getDB(baseName)[baseName].save({i:1}); + assert.eq(1, source.conn.getDB(baseName)[baseName].count()); + assert.eq(1, source.conn.getDB(baseName)[baseName].findOne().i); } diff --git a/jstests/auth/copyauth2.js b/jstests/auth/copyauth2.js index 1707711238b..852ba40e641 100644 --- a/jstests/auth/copyauth2.js +++ b/jstests/auth/copyauth2.js @@ -1,9 +1,11 @@ // Basic test that copydb works with auth enabled when copying within the same cluster function runTest(a, b) { + a.createUser({user: "chevy", pwd: "chase", roles: ["read", {role:'readWrite', db: b._name}]}); a.foo.insert({a:1}); - a.createUser({user: "chevy" , pwd: "chase", roles: ["read", {role:'readWrite', db: b._name}]}); - a.auth('chevy', 'chase'); + b.getSiblingDB( "admin").logout(); + + a.auth("chevy", "chase"); assert.eq( 1 , a.foo.count() , "A" ); assert.eq( 0 , b.foo.count() , "B" ); @@ -14,14 +16,17 @@ function runTest(a, b) { } - // run all tests standalone var conn = MongoRunner.runMongod({auth:""}); var a = conn.getDB( "copydb2-test-a" ); var b = conn.getDB( "copydb2-test-b" ); +var adminDB = conn.getDB( "admin" ); +adminDB.createUser({user: "root", pwd: "root", roles: ["root"]}); +adminDB.auth("root", "root"); runTest(a, b); MongoRunner.stopMongod(conn); +/** Doesn't work in a sharded setup due to SERVER-13080 // run all tests sharded var st = new ShardingTest({ shards: 2, @@ -30,5 +35,10 @@ var st = new ShardingTest({ }); var a = st.s.getDB( "copydb2-test-a" ); var b = st.s.getDB( "copydb2-test-b" ); +st.s.getDB( "admin" ).createUser({user: "root", pwd: "root", roles: ["root"]}); +st.s.getDB( "admin" ).auth("root", "root"); runTest(a, b); st.stop(); +*/ + +print("Successfully completed copyauth2.js test."); diff --git a/jstests/auth/disable_localhost_bypass.js b/jstests/auth/disable_localhost_bypass.js index 01f3c13e88f..9d29f5ae9fe 100644 --- a/jstests/auth/disable_localhost_bypass.js +++ b/jstests/auth/disable_localhost_bypass.js @@ -5,9 +5,24 @@ var conn2 = MongoRunner.runMongod({ auth: "", smallfiles: "", setParameter: "enableLocalhostAuthBypass=false"}); -// Should succeed because of localhost exception +// Should fail because of localhost exception narrowed (SERVER-12621). +assert.writeError(conn1.getDB("test").foo.insert({a:1})); +assert.throws(function() { conn2.getDB("test").foo.findOne(); }); + +// Should succeed due to localhost exception. +conn1.getDB("admin").createUser({user: "root", pwd: "pass", roles: ["root"]}); + +conn1.getDB("admin").auth("root", "pass"); conn1.getDB("test").foo.insert({a:1}); -assert.eq(1, conn1.getDB("test").foo.findOne().a); + +conn1.getDB("admin").dropAllUsers(); +conn1.getDB("admin").logout(); + +assert.throws(function() { conn2.getDB("test").foo.findOne(); }); // Should fail since localhost exception is disabled -assert.throws(function() { conn2.getDB("test").foo.findOne(); });
\ No newline at end of file +assert.throws(function() { + conn2.getDB("admin").createUser({user: "root", pwd: "pass", roles: ["root"]}); +}); + +print("SUCCESS Completed disable_localhost_bypass.js"); diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js index 8a00aaa4ae5..752e4a6b3cf 100644 --- a/jstests/auth/lib/commands_lib.js +++ b/jstests/auth/lib/commands_lib.js @@ -623,6 +623,7 @@ var authCommandsLib = { { testname: "copydb", command: {copydb: 1, fromdb: firstDbName, todb: secondDbName}, + skipSharded: true, // Does not work sharded due to SERVER-13080 testcases: [ { runOnDb: adminDbName, diff --git a/jstests/auth/localhostAuthBypass.js b/jstests/auth/localhostAuthBypass.js index ecd16268aa2..cb34eea6438 100644 --- a/jstests/auth/localhostAuthBypass.js +++ b/jstests/auth/localhostAuthBypass.js @@ -72,7 +72,7 @@ var runTest = function(useHostName) { var mongo = new Mongo(host); - assertCanRunCommands(mongo); + assertCannotRunCommands(mongo); createUser(mongo); diff --git a/jstests/auth/mongos_cache_invalidation.js b/jstests/auth/mongos_cache_invalidation.js index 94bb42d3f3f..652899d3287 100644 --- a/jstests/auth/mongos_cache_invalidation.js +++ b/jstests/auth/mongos_cache_invalidation.js @@ -16,6 +16,9 @@ var st = new ShardingTest({ shards: 2, {setParameter: "userCacheInvalidationIntervalSecs=600"}], keyFile: 'jstests/libs/key1' }); +st.s1.getDB('admin').createUser({user: 'root', pwd: 'pwd', roles: ['root']}); +st.s1.getDB('admin').auth('root', 'pwd'); + var res = st.s1.getDB('admin').runCommand({setParameter: 1, userCacheInvalidationIntervalSecs: 0}); assert.commandFailed(res, "Setting the invalidation interval to an disallowed value should fail"); @@ -25,9 +28,10 @@ assert.commandFailed(res, "Setting the invalidation interval to an disallowed va res = st.s1.getDB('admin').runCommand({getParameter: 1, userCacheInvalidationIntervalSecs: 1}); assert.eq(5, res.userCacheInvalidationIntervalSecs); -st.s0.getDB('test').foo.insert({a:1}); // initial data +st.s1.getDB('test').foo.insert({a:1}); // initial data +st.s1.getDB('admin').createUser({user: 'admin', pwd: 'pwd', roles: ['userAdminAnyDatabase']}); +st.s1.getDB('admin').logout(); -st.s0.getDB('admin').createUser({user: 'admin', pwd: 'pwd', roles: ['userAdminAnyDatabase']}); st.s0.getDB('admin').auth('admin', 'pwd'); st.s0.getDB('admin').createRole({role: 'myRole', roles: [], @@ -191,3 +195,5 @@ db3.auth('spencer', 'pwd'); })(); st.stop(); + +print("SUCCESS Completed mongos_cache_invalidation.js"); diff --git a/jstests/auth/readIndex.js b/jstests/auth/readIndex.js index 8ef52d1b5e1..945fabe84a9 100644 --- a/jstests/auth/readIndex.js +++ b/jstests/auth/readIndex.js @@ -4,11 +4,11 @@ var conn = MongoRunner.runMongod({auth : ""}); var adminDB = conn.getDB("admin"); var testDB = conn.getDB("testdb"); +adminDB.createUser({user:'root', pwd:'password', roles:['root']}); +adminDB.auth('root', 'password'); testDB.foo.insert({a:1}); - -testDB.createUser({user:'dbAdmin', - pwd:'password', - roles:['dbAdmin']}); +testDB.createUser({user:'dbAdmin', pwd:'password', roles:['dbAdmin']}); +adminDB.logout(); testDB.auth('dbAdmin', 'password'); testDB.foo.ensureIndex({a:1}); diff --git a/jstests/auth/repl.js b/jstests/auth/repl.js index 3dfd01df6f5..25129cfd821 100644 --- a/jstests/auth/repl.js +++ b/jstests/auth/repl.js @@ -183,7 +183,7 @@ jsTest.log("1 test replica sets"); var rs = new ReplSetTest({name: rsName, nodes: 2}); var nodes = rs.startSet(mongoOptions); rs.initiate(); -rs.awaitReplication(); +authutil.asCluster(nodes, "jstests/libs/key1", function() { rs.awaitReplication(); }); var primary = rs.getPrimary(); var secondary = rs.getSecondary(); @@ -200,7 +200,7 @@ jsTest.log("2 test initial sync"); rs = new ReplSetTest({name: rsName, nodes: 1, nodeOptions: mongoOptions}); nodes = rs.startSet(); rs.initiate(); -rs.awaitReplication(); +authutil.asCluster(nodes, "jstests/libs/key1", function() { rs.awaitReplication(); }); primary = rs.getPrimary(); @@ -235,6 +235,9 @@ master = rt.start(true, mongoOptions, true); slave = rt.start(false, mongoOptions, true); var masterDB = master.getDB("admin"); +masterDB.createUser({user: "root", pwd: "pass", roles: ["root"]}); +masterDB.auth("root", "pass"); + // ensure that master/slave replication is up and running masterDB.foo.save({}, { writeConcern: { w: 2, wtimeout: 5000 }}); masterDB.foo.drop(); diff --git a/jstests/auth/resource_pattern_matching.js b/jstests/auth/resource_pattern_matching.js index 232146a807c..74583f6c270 100644 --- a/jstests/auth/resource_pattern_matching.js +++ b/jstests/auth/resource_pattern_matching.js @@ -249,10 +249,11 @@ print('--- sharding test ---') var st = new ShardingTest({ mongos: 2, shard: 1, + keyFile: keyfile, other: { - mongosOptions: { 'auth': null, 'httpinterface': null, 'keyFile': keyfile }, - configOptions: { 'auth': null, 'httpinterface': null, 'keyFile': keyfile }, - shardOptions: { 'auth': null, 'httpinterface': null, 'keyFile': keyfile } + mongosOptions: { 'auth': null, 'httpinterface': null }, + configOptions: { 'auth': null, 'httpinterface': null }, + shardOptions: { 'auth': null, 'httpinterface': null } } }) run_tests(st.s0.getDB('admin'), st.s1.getDB('admin')); diff --git a/jstests/auth/role_management_commands.js b/jstests/auth/role_management_commands.js index ef445615b6f..d5eeff86f42 100644 --- a/jstests/auth/role_management_commands.js +++ b/jstests/auth/role_management_commands.js @@ -13,10 +13,7 @@ function runTest(conn) { var userAdminConn = new Mongo(conn.host); var testUserAdmin = userAdminConn.getDB('test'); var adminUserAdmin = userAdminConn.getDB('admin'); - adminUserAdmin.createRole({role: 'myUserAdminRole', - roles: ['userAdminAnyDatabase'], - privileges: []}); - adminUserAdmin.createUser({user: 'userAdmin', pwd: 'pwd', roles: ['myUserAdminRole']}); + adminUserAdmin.createUser({user: 'userAdmin', pwd: 'pwd', roles: ['userAdminAnyDatabase']}); adminUserAdmin.auth('userAdmin', 'pwd'); testUserAdmin.createUser({user: 'testUser', pwd: 'pwd', roles:[]}); var db = conn.getDB('test'); diff --git a/jstests/libs/command_line/test_parsed_options.js b/jstests/libs/command_line/test_parsed_options.js index d7813953b8b..f194b73ce7f 100644 --- a/jstests/libs/command_line/test_parsed_options.js +++ b/jstests/libs/command_line/test_parsed_options.js @@ -89,6 +89,17 @@ function testGetCmdLineOptsMongod(mongoRunnerConfig, expectedResult) { // Start mongod with options var mongod = MongoRunner.runMongod(mongoRunnerConfig); + // Create and authenticate high-privilege user in case mongod is running with authorization. + // Try/catch is necessary in case this is being run on an uninitiated replset, by a test + // such as repl_options.js for example. + var ex; + try { + mongod.getDB("admin").createUser({user: "root", pwd: "pass", roles: ["root"]}); + mongod.getDB("admin").auth("root", "pass"); + } + catch (ex) { + } + // Get the parsed options var getCmdLineOptsResult = mongod.adminCommand("getCmdLineOpts"); @@ -109,6 +120,7 @@ function testGetCmdLineOptsMongod(mongoRunnerConfig, expectedResult) { assert.docEq(getCmdLineOptsResult.parsed, expectedResult.parsed); // Cleanup + mongod.getDB("admin").logout(); MongoRunner.stopMongod(mongod.port); } diff --git a/jstests/multiVersion/auth_schema_upgrade_26.js b/jstests/multiVersion/auth_schema_upgrade_26.js index 76050b05752..d77bb09d03e 100644 --- a/jstests/multiVersion/auth_schema_upgrade_26.js +++ b/jstests/multiVersion/auth_schema_upgrade_26.js @@ -8,7 +8,6 @@ * Finally, verifies that all users are available where expected. */ -load('jstests/multiVersion/libs/auth_support.js'); load('jstests/multiVersion/libs/multi_cluster.js'); load('jstests/multiVersion/libs/multi_rs.js'); @@ -18,12 +17,12 @@ load('jstests/multiVersion/libs/multi_rs.js'); var newVersion = '2.6'; var keyfile = 'jstests/libs/key1'; - var logout = AuthSupport.logout; - var assertAuthenticate = AuthSupport.assertAuthenticate; - var assertAuthenticateFails = AuthSupport.assertAuthenticateFails; + var logout = authutil.logout; + var assertAuthenticate = authutil.assertAuthenticate; + var assertAuthenticateFails = authutil.assertAuthenticateFails; function asCluster(conn, action) { - return AuthSupport.asCluster(conn, keyfile, action); + return authutil.asCluster(conn, keyfile, action); } /** @@ -120,8 +119,12 @@ load('jstests/multiVersion/libs/multi_rs.js'); assertAuthenticate(s0AdminConn, 't2', { user: 't2-user', pwd: 'a' }); } + // enableBalancer is true because otherwise, the attempt in ShardingTest to turn off + // the balancer by authenticating as the system user fails, because the mongos auth-logout + // hacks aren't present in old versions. var initialOptions = { name: 'auth_schema_upgrade_normal', + enableBalancer: true, rs: { nodes: 3 }, mongosOptions: { binVersion: oldVersion }, configOptions: { binVersion: oldVersion }, diff --git a/jstests/multiVersion/auth_schema_upgrade_26_repl_version_mismatch.js b/jstests/multiVersion/auth_schema_upgrade_26_repl_version_mismatch.js index 84967d15a21..86419c5e39a 100644 --- a/jstests/multiVersion/auth_schema_upgrade_26_repl_version_mismatch.js +++ b/jstests/multiVersion/auth_schema_upgrade_26_repl_version_mismatch.js @@ -3,7 +3,6 @@ * a binary version that is too old, but will proceed if that member is down. */ -load('jstests/multiVersion/libs/auth_support.js'); load('jstests/multiVersion/libs/multi_rs.js'); (function () { @@ -12,12 +11,12 @@ load('jstests/multiVersion/libs/multi_rs.js'); var newVersion = '2.6'; var keyfile = 'jstests/libs/key1'; - var logout = AuthSupport.logout; - var assertAuthenticate = AuthSupport.assertAuthenticate; - var assertAuthenticateFails = AuthSupport.assertAuthenticateFails; + var logout = authutil.logout; + var assertAuthenticate = authutil.assertAuthenticate; + var assertAuthenticateFails = authutil.assertAuthenticateFails; function asCluster(conn, action) { - return AuthSupport.asCluster(conn, keyfile, action); + return authutil.asCluster(conn, keyfile, action); } var rst = new ReplSetTest({ diff --git a/jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js b/jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js index 43e47547c1f..6196351445d 100644 --- a/jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js +++ b/jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js @@ -16,6 +16,7 @@ var options = { separateConfig : true, rs : true, + enableBalancer: true, mongosOptions : { binVersion : "2.6" }, rsOptions : { nodes : 2, binVersion : "2.4" }, keyFile : "jstests/libs/key1" }; diff --git a/jstests/replsets/auth3.js b/jstests/replsets/auth3.js index 846debb626c..8218dc12e60 100644 --- a/jstests/replsets/auth3.js +++ b/jstests/replsets/auth3.js @@ -41,12 +41,13 @@ assert.soon(function() { print("make common point"); safeInsert(); -rs.awaitReplication(); +authutil.asCluster(rs.nodes, 'jstests/libs/key1', function() { rs.awaitReplication(); }); print("write stuff to 0&2") rs.stop(1); master = rs.getMaster(); +master.getDB("admin").auth("foo", "bar"); master.getDB("foo").bar.drop(); print("last op: "+tojson(master.getDB("local").oplog.rs.find().sort({$natural:-1}).limit(1).next())); diff --git a/jstests/replsets/localhostAuthBypass.js b/jstests/replsets/localhostAuthBypass.js index 720c77b4b00..261538ee6a1 100644 --- a/jstests/replsets/localhostAuthBypass.js +++ b/jstests/replsets/localhostAuthBypass.js @@ -84,7 +84,7 @@ var runTest = function(useHostName) { var mongo = new Mongo(host); - assertCanRunCommands(mongo); + assertCannotRunCommands(mongo); createUser(mongo); diff --git a/jstests/replsets/rollback_auth.js b/jstests/replsets/rollback_auth.js index bc12268d95b..9d919e2e24b 100644 --- a/jstests/replsets/rollback_auth.js +++ b/jstests/replsets/rollback_auth.js @@ -138,6 +138,7 @@ replTest.waitForState(a_conn, replTest.PRIMARY, 60000); jsTestLog("Doing writes that should persist after the rollback"); // Modify the user and role in a way that will persist. +A.auth('userAdmin', 'pwd'); a.grantPrivilegesToRole('myRole', [{resource: {db: 'test', collection: 'baz'}, actions: ['collStats']}], {}); // Default write concern will wait for majority, which will time out. @@ -148,6 +149,8 @@ a.createRole({role: 'persistentRole', a.grantRolesToUser('spencer', ['persistentRole'], {}); // Default write concern will wait for majority, which will time out. +A.logout(); +a.auth('spencer', 'pwd'); // A has the data we just wrote, but not what B wrote before assert.commandWorked(a.runCommand({dbStats: 1})); @@ -171,7 +174,9 @@ jsTestLog("Triggering rollback"); B.runCommand({ replSetTest: 1, blind: false }); reconnect(a); reconnect(b); -replTest.awaitReplication(); +authutil.asCluster(replTest.nodes, + 'jstests/libs/key1', + function() { replTest.awaitReplication(); }); replTest.waitForState(a_conn, replTest.PRIMARY, 60000); replTest.waitForState(b_conn, replTest.SECONDARY, 60000); diff --git a/jstests/sharding/auth.js b/jstests/sharding/auth.js index 122f768427a..9a4afd2d60f 100644 --- a/jstests/sharding/auth.js +++ b/jstests/sharding/auth.js @@ -48,20 +48,10 @@ var s = new ShardingTest( "auth1", 0 , 0 , 1 , enableBalancer:true } ); -print("logging in first, if there was an unclean shutdown the user might already exist"); -login(adminUser); - -var user = s.getDB("admin").system.users.findOne(); -if (user) { - print("user already exists"); - printjson(user); -} -else { - print("adding user"); - s.getDB(adminUser.db).createUser({user: adminUser.username, - pwd: adminUser.password, - roles: jsTest.adminUserRoles}); -} +print("adding user"); +s.getDB(adminUser.db).createUser({user: adminUser.username, + pwd: adminUser.password, + roles: jsTest.adminUserRoles}); login(adminUser); assert.writeOK(s.getDB( "config" ).settings.update({ _id: "chunksize" }, @@ -81,7 +71,9 @@ d1.startSet({keyFile : "jstests/libs/key2", verbose : 0}); d1.initiate(); print("initiated"); -var shardName = getShardName(d1); +var shardName = authutil.asCluster(d1.nodes, + "jstests/libs/key2", + function() { return getShardName(d1); }); print("adding shard w/out auth "+shardName); logout(adminUser); @@ -155,7 +147,8 @@ d2.startSet({keyFile : "jstests/libs/key1", verbose : 0}); d2.initiate(); d2.awaitSecondaryNodes(); -shardName = getShardName(d2); +shardName = authutil.asCluster(d2.nodes, "jstests/libs/key1", + function() { return getShardName(d2); }); print("adding shard "+shardName); login(adminUser); diff --git a/jstests/sharding/auth2.js b/jstests/sharding/auth2.js index 5dd8618ee26..51c2d9baa8d 100644 --- a/jstests/sharding/auth2.js +++ b/jstests/sharding/auth2.js @@ -2,8 +2,6 @@ var st = new ShardingTest({ keyFile : 'jstests/libs/key1', shards : 2, chunksize other : { nopreallocj : 1, verbose : 2, useHostname : true, configOptions : { verbose : 2 }}}); -st.printShardingStatus(); - var mongos = st.s; var adminDB = mongos.getDB('admin'); var db = mongos.getDB('test') @@ -19,4 +17,4 @@ for ( var i = 0; i < 100; i++ ) { assert( adminDB.auth('admin', 'password'), "Auth failed on attempt #: " + i ); } -st.stop();
\ No newline at end of file +st.stop(); diff --git a/jstests/sharding/authCommands.js b/jstests/sharding/authCommands.js index a3e5a712416..9624da7d34f 100644 --- a/jstests/sharding/authCommands.js +++ b/jstests/sharding/authCommands.js @@ -14,13 +14,6 @@ var adminDB = mongos.getDB( 'admin' ); var configDB = mongos.getDB( 'config' ); var testDB = mongos.getDB( 'test' ); -// Secondaries should be up here, since we awaitReplication in the ShardingTest, but we *don't* -// wait for the mongos to explicitly detect them. -ReplSetTest.awaitRSClientHosts( mongos, st.rs0.getSecondaries(), { ok : true, secondary : true }); -ReplSetTest.awaitRSClientHosts( mongos, st.rs1.getSecondaries(), { ok : true, secondary : true }); - -st.printShardingStatus(); - jsTestLog('Setting up initial users'); var rwUser = 'rwUser'; var roUser = 'roUser'; @@ -29,6 +22,12 @@ var password = 'password'; adminDB.createUser({user: rwUser, pwd: password, roles: jsTest.adminUserRoles}); assert( adminDB.auth( rwUser, password ) ); + +// Secondaries should be up here, since we awaitReplication in the ShardingTest, but we *don't* +// wait for the mongos to explicitly detect them. +ReplSetTest.awaitRSClientHosts( mongos, st.rs0.getSecondaries(), { ok : true, secondary : true }); +ReplSetTest.awaitRSClientHosts( mongos, st.rs1.getSecondaries(), { ok : true, secondary : true }); + testDB.createUser({user: rwUser, pwd: password, roles: jsTest.basicUserRoles}); testDB.createUser({user: roUser, pwd: password, roles: jsTest.readOnlyUserRoles}); diff --git a/jstests/sharding/auth_add_shard.js b/jstests/sharding/auth_add_shard.js index 5d8edee49ec..48661a22fe0 100644 --- a/jstests/sharding/auth_add_shard.js +++ b/jstests/sharding/auth_add_shard.js @@ -16,29 +16,22 @@ adminUser = { db : "admin", username : "foo", password : "bar" }; //set up a 2 shard cluster with keyfile var st = new ShardingTest( { name : "auth_add_shard1", shards : 1, mongos : 1, verbose : 1, keyFile : "jstests/libs/key1" } ) -st.stopBalancer(); var mongos = st.s0 var admin = mongos.getDB("admin") -assert.eq( 1, st.config.shards.count() , "initial server count wrong" ); - print("1 shard system setup"); //add the admin user -var user = admin.system.users.findOne(); -if (user) { - print("user already exists"); - printjson(user); -} -else { - print("adding user"); - mongos.getDB(adminUser.db).createUser({user: adminUser.username, pwd: adminUser.password, roles: jsTest.adminUserRoles}); -} +print("adding user"); +mongos.getDB(adminUser.db).createUser({user: adminUser.username, pwd: adminUser.password, roles: jsTest.adminUserRoles}); //login as admin user login(adminUser); +st.stopBalancer(); +assert.eq( 1, st.config.shards.count() , "initial server count wrong" ); + //start a mongod with NO keyfile var conn = MongoRunner.runMongod({}); print (conn); diff --git a/jstests/sharding/auth_config_down.js b/jstests/sharding/auth_config_down.js index 6f97051a864..fc5d4bab82d 100644 --- a/jstests/sharding/auth_config_down.js +++ b/jstests/sharding/auth_config_down.js @@ -12,8 +12,9 @@ var mongos = st.s0 var configs = st._configServers printjson( configs ) -st.printShardingStatus() +mongos.getDB("admin").createUser({user: "root", pwd: "pass", roles: ["root"]}); +mongos.getDB("admin").auth("root", "pass"); assert.writeOK(mongos.getCollection( "foo.bar" ).insert({ hello : "world" })); var stopOrder = [ 1, 0 ] @@ -31,16 +32,17 @@ for( var i = 0; i < stopOrder.length; i++ ){ var mongosWithAuth = MongoRunner.runMongos({ keyFile : "jstests/libs/key1", configdb : mongos.savedOptions.configdb }) var foodb = mongosWithAuth.getDB('foo'); + mongosWithAuth.getDB("admin").auth("root", "pass"); var res = foodb.bar.findOne(); assert.neq(null, res, "Test FAILED: unable to find document using mongos with auth"); assert.eq("world", res.hello); + mongosWithAuth.getDB("admin").logout(); assert.throws( function() { foodb.createUser({user:'user' + i, pwd: 'pwd', roles: []}); } ); } // Restart the config servers and make sure everything is consistent for (var i = 0; i < stopOrder.length; i++ ) { - var configToStart = configs[ stopOrder[i] ]; jsTest.log( "Starting config server " + stopOrder[i] + " : " + configToStop ); @@ -51,6 +53,7 @@ for (var i = 0; i < stopOrder.length; i++ ) { assert.eq(0, mongos.getDB('foo').getUsers().length); for (var i = 0; i < configs.length; i++) { + configs[i].getDB("admin").auth("root", "pass"); assert.eq(0, configs[i].getDB('foo').getUsers().length); } diff --git a/jstests/sharding/auth_repl.js b/jstests/sharding/auth_repl.js index c07719843b1..eb4fc36677a 100644 --- a/jstests/sharding/auth_repl.js +++ b/jstests/sharding/auth_repl.js @@ -9,25 +9,21 @@ var primary = replTest.getPrimary(); // Setup the database using replSet connection before setting the authentication var conn = new Mongo(replTest.getURL()); var testDB = conn.getDB('test'); +var adminDB = conn.getDB('admin'); var testColl = testDB.user; -assert.writeOK(testColl.insert({ x: 1 }, { writeConcern: { w: nodeCount }})); - // Setup the cached connection for primary and secondary in DBClientReplicaSet // before setting up authentication -var doc = testColl.findOne(); -assert(doc != null); +assert.commandWorked(adminDB.runCommand({replSetGetStatus: 1})); conn.setSlaveOk(); - -doc = testColl.findOne(); -assert(doc != null); +assert.commandWorked(adminDB.runCommand({replSetGetStatus: 1})); // Add admin user using direct connection to primary to simulate connection from remote host -var adminDB = primary.getDB('admin'); -adminDB.createUser({user: 'user', pwd: 'user', roles: jsTest.adminUserRoles}, - {w: nodeCount, wtimeout: 30000}); -adminDB.auth('user', 'user'); +var priAdminDB = primary.getDB('admin'); +priAdminDB.createUser({user: 'user', pwd: 'user', roles: jsTest.adminUserRoles}, + {w: nodeCount, wtimeout: 30000}); +priAdminDB.auth('user', 'user'); var priTestDB = primary.getDB('test'); priTestDB.createUser({user: 'a', pwd: 'a', roles: jsTest.basicUserRoles}, @@ -37,6 +33,8 @@ priTestDB.createUser({user: 'a', pwd: 'a', roles: jsTest.basicUserRoles}, assert.eq(1, testDB.auth('a', 'a')); jsTest.log('Sending an authorized query that should be ok'); +assert.writeOK(testColl.insert({ x: 1 })); + conn.setSlaveOk(true); doc = testColl.findOne(); assert(doc != null); diff --git a/jstests/sharding/localhostAuthBypass.js b/jstests/sharding/localhostAuthBypass.js index 33b4d167361..f363fc8dd20 100644 --- a/jstests/sharding/localhostAuthBypass.js +++ b/jstests/sharding/localhostAuthBypass.js @@ -59,14 +59,12 @@ var assertCannotRunCommands = function(mongo, st) { mongo.getDB("config").shards.findOne(); }); - var to = findEmptyShard(st, "test.foo"); - var res = mongo.getDB("admin").runCommand({ moveChunk: "test.foo", find: {_id: 1}, - to: to + to: "shard0000" // Arbitrary shard. }); - assert.commandFailed(res); + assert.commandFailedWithCode(res, 13 /* Authz code */); }; var assertCanRunCommands = function(mongo, st) { @@ -179,23 +177,14 @@ var runTest = function(useHostName) { var mongo = new Mongo(host); - setupSharding(mongo); - - assertCanRunCommands(mongo, st); - - addUsersToEachShard(st); - - assertCanRunCommands(mongo, st); - - createUser(mongo); - - // now that we have a user, we need to make sure - // helper functions on st work for the rest of the script. - authenticate(st.s); - assertCannotRunCommands(mongo, st); + createUser(mongo); authenticate(mongo); + setupSharding(mongo); + + addUsersToEachShard(st); + authenticate(st.s); assertCanRunCommands(mongo, st); diff --git a/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js b/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js index 5b8f930f8bd..42295415580 100644 --- a/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js +++ b/jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js @@ -17,10 +17,21 @@ var options = { separateConfig : true, keyFile : "jstests/libs/key1" }; var st = new ShardingTest({shards : 3, mongos : 1, other : options}); -st.stopBalancer(); var mongos = st.s0; var admin = mongos.getDB( "admin" ); + +jsTest.log("Setting up initial admin user..."); +var adminUser = "adminUser"; +var password = "password"; + +// Create a user +admin.createUser({ user : adminUser, pwd : password, roles: [ "root" ] }); +// There's an admin user now, so we need to login to do anything +// Login as admin user +admin.auth(adminUser, password); + +st.stopBalancer(); var shards = mongos.getDB( "config" ).shards.find().toArray(); assert.commandWorked( admin.runCommand({ setParameter : 1, traceExceptions : true }) ); @@ -45,20 +56,8 @@ assert.commandWorked( admin.runCommand({ moveChunk : collSharded.toString(), to : shards[0]._id }) ); st.printShardingStatus(); - -var adminUser = "adminUser"; var shardedDBUser = "shardedDBUser"; var unshardedDBUser = "unshardedDBUser"; -var password = "password"; - -jsTest.log("Setting up initial admin user..."); - -// Create a user -admin.createUser({ user : adminUser, pwd : password, roles: [ "userAdminAnyDatabase" ] }); -// There's an admin user now, so we need to login to do anything - -// Login as admin user -admin.auth(adminUser, password); jsTest.log("Setting up database users..."); diff --git a/jstests/sharding/sharding_with_keyfile_auth.js b/jstests/sharding/sharding_with_keyfile_auth.js index 2fe594544d8..6f4c02dbcbf 100644 --- a/jstests/sharding/sharding_with_keyfile_auth.js +++ b/jstests/sharding/sharding_with_keyfile_auth.js @@ -13,28 +13,29 @@ var st = new ShardingTest({ name : myTestName , // Make sure all our instances got the key var configs = st._configServers -var shards = st._connections var mongoses = st._mongos +mongoses[0].getDB( "admin" ).createUser({ user: "root", pwd: "pass", roles: ["root"] }); + for( var i = 0; i < configs.length; i++ ){ - printjson( new Mongo( "localhost:" + configs[i].port ).getDB("admin").runCommand({ getCmdLineOpts : 1 }) ) - assert.eq( new Mongo( "localhost:" + configs[i].port ).getDB("admin").runCommand({ getCmdLineOpts : 1 }).parsed.security.keyFile, keyFile ) + var confAdmin = configs[i].getDB( "admin" ); + confAdmin.auth( "root", "pass" ); + printjson( confAdmin.runCommand({ getCmdLineOpts : 1 }) ) + assert.eq( confAdmin.runCommand({ getCmdLineOpts : 1 }).parsed.security.keyFile, keyFile ) } -for( var i = 0; i < shards.length; i++ ){ - printjson( new Mongo( "localhost:" + shards[i].port ).getDB("admin").runCommand({ getCmdLineOpts : 1 }) ) - assert.eq( new Mongo( "localhost:" + shards[i].port ).getDB("admin").runCommand({ getCmdLineOpts : 1 }).parsed.security.keyFile, keyFile ) -} - for( var i = 0; i < mongoses.length; i++ ){ - printjson( new Mongo( "localhost:" + mongoses[i].port ).getDB("admin").runCommand({ getCmdLineOpts : 1 }) ) - assert.eq( new Mongo( "localhost:" + mongoses[i].port ).getDB("admin").runCommand({ getCmdLineOpts : 1 }).parsed.security.keyFile, keyFile ) + var monsAdmin = mongoses[i].getDB( "admin" ); + monsAdmin.auth( "root", "pass" ); + printjson( monsAdmin.runCommand({ getCmdLineOpts : 1 }) ) + assert.eq( monsAdmin.runCommand({ getCmdLineOpts : 1 }).parsed.security.keyFile, keyFile ) } var mongos = new Mongo( "localhost:" + st.s0.port ) -var coll = mongos.getCollection( "test.foo" ) +var coll = mongos.getDB( "test" ).foo; -st.shardColl( coll, { _id : 1 }, false ) +mongos.getDB( "admin" ).auth( "root", "pass" ); +mongos.getDB( "admin" ).runCommand({shardCollection : coll, key : {_id : 1}}); // Create an index so we can find by num later coll.ensureIndex({ insert : 1 }) diff --git a/jstests/ssl/initial_sync1_x509.js b/jstests/ssl/initial_sync1_x509.js index 410fc2ba827..0d70bd17cf7 100644 --- a/jstests/ssl/initial_sync1_x509.js +++ b/jstests/ssl/initial_sync1_x509.js @@ -1,15 +1,65 @@ -// Basic tests for cluster authentication using x509 -// This test is launching replsets/initial_sync1.js with different -// values for clusterAuthMode to emulate an upgrade process. +// Basic tests for cluster authentication using x509. var common_options = {keyFile : "jstests/libs/key1"}; +function runInitialSyncTest() { + load("jstests/replsets/rslib.js"); + + print("1. Bring up set"); + var replTest = new ReplSetTest({name: "jstests_initsync1_x509", + nodes : {node0 : x509_options1, node1 : x509_options2}}); + + var conns = replTest.startSet(); + replTest.initiate(); + + var master = replTest.getMaster(); + var foo = master.getDB("foo"); + var admin = master.getDB("admin"); + + var slave1 = replTest.liveNodes.slaves[0]; + var admin_s1 = slave1.getDB("admin"); + + print("2. Create a root user."); + admin.createUser({ user: "root", pwd: "pass", roles: ["root"]}); + admin.auth("root", "pass"); + admin_s1.auth("root", "pass"); + + print("3. Insert some data"); + var bulk = foo.bar.initializeUnorderedBulkOp(); + for (var i = 0; i < 100; i++) { + bulk.insert({ date: new Date(), x: i, str: "all the talk on the market" }); + } + assert.writeOK(bulk.execute()); + print("total in foo: "+foo.bar.count()); + + print("4. Make sure synced"); + replTest.awaitReplication(); + + print("5. Insert some stuff"); + master = replTest.getMaster(); + bulk = foo.bar.initializeUnorderedBulkOp(); + for (var i = 0; i < 100; i++) { + bulk.insert({ date: new Date(), x: i, str: "all the talk on the market" }); + } + assert.writeOK(bulk.execute()); + + print("6. Everyone happy eventually"); + replTest.awaitReplication(300000); + + print("7. Check hbmsg"); + master.getDB("admin").runCommand({replSetTest:1, sethbmsg:"foo bar baz"}); + var status = master.getDB("admin").runCommand({replSetGetStatus:1}); + printjson(status); + assert.eq(status.members[0].infoMessage, "foo bar baz"); + replTest.stopSet(); +} + // Standard case, clusterAuthMode: x509 -x509_options1 = Object.merge(common_options, +var x509_options1 = Object.merge(common_options, {sslClusterFile: "jstests/libs/cluster-cert.pem", clusterAuthMode: "x509"}); var x509_options2 = x509_options1; -load("jstests/replsets/initial_sync1.js"); +runInitialSyncTest(); // Mixed clusterAuthMode: sendX509 and sendKeyFile and try adding --auth x509_options1 = Object.merge(common_options, @@ -17,12 +67,12 @@ x509_options1 = Object.merge(common_options, clusterAuthMode: "sendX509", auth: ""}); x509_options2 = Object.merge(common_options, {clusterAuthMode: "sendKeyFile"}); -load("jstests/replsets/initial_sync1.js"); +runInitialSyncTest(); // Mixed clusterAuthMode: x509 and sendX509, use the PEMKeyFile for outgoing connections x509_options1 = Object.merge(common_options, {clusterAuthMode: "x509"}); x509_options2 = Object.merge(common_options, {clusterAuthMode: "sendX509"}); -load("jstests/replsets/initial_sync1.js"); +runInitialSyncTest(); // verify that replset initiate fails if using a self-signed cert x509_options1 = Object.merge(common_options, {clusterAuthMode: "x509"}); diff --git a/jstests/ssl/libs/ssl_helpers.js b/jstests/ssl/libs/ssl_helpers.js index c4a0f97968e..5ff3c9f1ba9 100644 --- a/jstests/ssl/libs/ssl_helpers.js +++ b/jstests/ssl/libs/ssl_helpers.js @@ -102,7 +102,7 @@ function mixedShardTest(options1, options2, shouldSucceed) { // TODO: merge this with that file and add to utils? // -ReplSetTest.prototype.upgradeSet = function( options ){ +ReplSetTest.prototype.upgradeSet = function( options, user, pwd ){ options = options || {} var nodes = this.nodes @@ -130,15 +130,18 @@ ReplSetTest.prototype.upgradeSet = function( options ){ this.nodeOptions[nodeName] = Object.merge(this.nodeOptions[nodeName], options); } printjson(this.nodeOptions); - this.upgradeNode( node, options, true ) + this.upgradeNode( node, options, true, user, pwd ) if( noDowntimePossible ) assert.eq( this.getNodeId( primary ), prevPrimaryId ) } } -ReplSetTest.prototype.upgradeNode = function( node, opts, waitForState ){ +ReplSetTest.prototype.upgradeNode = function( node, opts, waitForState, user, pwd ){ var node = this.restart( node, opts ) + if (user != undefined) { + node.getDB("admin").auth(user, pwd); + } // By default, wait for primary or secondary state if( waitForState == undefined ) waitForState = true if( waitForState == true ) waitForState = [ ReplSetTest.State.PRIMARY, diff --git a/jstests/ssl/set_parameter_ssl.js b/jstests/ssl/set_parameter_ssl.js index 2460c8041ae..34a5c101087 100644 --- a/jstests/ssl/set_parameter_ssl.js +++ b/jstests/ssl/set_parameter_ssl.js @@ -8,11 +8,13 @@ port = allocatePorts(1)[0]; function testSSLTransition(oldMode, newMode, shouldSucceed) { var conn = MongoRunner.runMongod({port: port, - sslMode: oldMode, + sslMode: oldMode, sslPEMKeyFile: SERVER_CERT, sslCAFile: CA_CERT}); - var adminDB = conn.getDB("admin"); + var adminDB = conn.getDB("admin"); + adminDB.createUser({user: "root", pwd: "pwd", roles: ['root']}); + adminDB.auth("root", "pwd"); var res = adminDB.runCommand({ "setParameter" : 1, "sslMode" : newMode }); @@ -27,7 +29,9 @@ function testAuthModeTransition(oldMode, newMode, shouldSucceed) { sslCAFile: CA_CERT, clusterAuthMode: oldMode}); - var adminDB = conn.getDB("admin"); + var adminDB = conn.getDB("admin"); + adminDB.createUser({user: "root", pwd: "pwd", roles: ['root']}); + adminDB.auth("root", "pwd"); var res = adminDB.runCommand({ "setParameter" : 1, "clusterAuthMode" : newMode }); diff --git a/jstests/ssl/sharding_with_x509.js b/jstests/ssl/sharding_with_x509.js index 559fb325c7f..f27b30c7b71 100644 --- a/jstests/ssl/sharding_with_x509.js +++ b/jstests/ssl/sharding_with_x509.js @@ -7,10 +7,14 @@ var x509_options = {sslMode : "requireSSL", sslClusterFile: "jstests/libs/cluster-cert.pem", clusterAuthMode: "x509"}; +// Start ShardingTest with enableBalancer because ShardingTest attempts to turn +// off the balancer otherwise, which it will not be authorized to do. Once SERVER-14017 +// is fixed the "enableBalancer" line could be removed. var st = new ShardingTest({ name : "sharding_with_x509" , shards : 2, mongos : 1, other: { + enableBalancer: true, configOptions : x509_options, mongosOptions : x509_options, rsOptions : x509_options, diff --git a/jstests/ssl/upgrade_to_x509_ssl.js b/jstests/ssl/upgrade_to_x509_ssl.js index 89696eb864c..b89a5753535 100644 --- a/jstests/ssl/upgrade_to_x509_ssl.js +++ b/jstests/ssl/upgrade_to_x509_ssl.js @@ -22,15 +22,25 @@ rst.initiate(); // Connect to master and do some basic operations var rstConn1 = rst.getMaster(); +print("Performing basic operations on master."); +rstConn1.getDB("admin").createUser({user:"root", pwd:"pwd", roles:["root"]}); +rstConn1.getDB("admin").auth("root", "pwd"); rstConn1.getDB("test").a.insert({a:1, str:"TESTTESTTEST"}); rstConn1.getDB("test").a.insert({a:1, str:"WOOPWOOPWOOPWOOPWOOP"}); assert.eq(2, rstConn1.getDB("test").a.count(), "Error interacting with replSet"); print("===== UPGRADE allowSSL,sendKeyfile -> preferSSL,sendX509 ====="); +for (var n = 0; n < rst.nodes.length; n++) { + rst.nodes[n].getDB("admin").auth("root", "pwd"); +} rst.upgradeSet({sslMode:"preferSSL", sslPEMKeyFile: SERVER_CERT, sslAllowInvalidCertificates: "", clusterAuthMode:"sendX509", keyFile: KEYFILE, - sslCAFile: CA_CERT}); + sslCAFile: CA_CERT}, "root", "pwd"); +// The upgradeSet call restarts the nodes so we need to reauthenticate. +for (var n = 0; n < rst.nodes.length; n++) { + rst.nodes[n].getDB("admin").auth("root", "pwd"); +} rst.awaitReplication(); var rstConn3 = rst.getMaster(); rstConn3.getDB("test").a.insert({a:3, str:"TESTTESTTEST"}); @@ -44,7 +54,10 @@ print("===== UPGRADE preferSSL,sendX509 -> requireSSL,x509 ====="); rst.upgradeSet({sslMode:"requireSSL", sslPEMKeyFile: SERVER_CERT, sslAllowInvalidCertificates: "", clusterAuthMode:"x509", keyFile: KEYFILE, - sslCAFile: CA_CERT}); + sslCAFile: CA_CERT}, "root", "pwd"); +for (var n = 0; n < rst.nodes.length; n++) { + rst.nodes[n].getDB("admin").auth("root", "pwd"); +} rst.awaitReplication(); var rstConn4 = rst.getMaster(); rstConn4.getDB("test").a.insert({a:4, str:"TESTTESTTEST"}); diff --git a/jstests/ssl/x509_client.js b/jstests/ssl/x509_client.js index f4589e91bdd..b049d428383 100644 --- a/jstests/ssl/x509_client.js +++ b/jstests/ssl/x509_client.js @@ -5,10 +5,14 @@ TestData.useX509 = false; // Check if this build supports the authenticationMechanisms startup parameter. var conn = MongoRunner.runMongod({ smallfiles: "", auth: "" }); +conn.getDB('admin').createUser({user: "root", pwd: "pass", roles: ["root"]}); +conn.getDB('admin').auth("root", "pass"); var cmdOut = conn.getDB('admin').runCommand({getParameter: 1, authenticationMechanisms: 1}) if (cmdOut.ok) { TestData.authMechanism = "MONGODB-X509"; // SERVER-10353 } +conn.getDB('admin').dropAllUsers(); +conn.getDB('admin').logout(); MongoRunner.stopMongod(conn); var SERVER_CERT = "jstests/libs/server.pem" diff --git a/jstests/sslSpecial/upgrade_to_x509_ssl_nossl.js b/jstests/sslSpecial/upgrade_to_x509_ssl_nossl.js index 481532c22de..ab70a6460f0 100644 --- a/jstests/sslSpecial/upgrade_to_x509_ssl_nossl.js +++ b/jstests/sslSpecial/upgrade_to_x509_ssl_nossl.js @@ -16,14 +16,22 @@ rst.initiate(); // Connect to master and do some basic operations var rstConn1 = rst.getMaster(); +rstConn1.getDB("admin").createUser({user: "root", pwd: "pwd", roles: ["root"]}); +rstConn1.getDB("admin").auth("root", "pwd"); rstConn1.getDB("test").a.insert({a:1, str:"TESTTESTTEST"}); assert.eq(1, rstConn1.getDB("test").a.count(), "Error interacting with replSet"); print("===== UPGRADE disabled,keyFile -> allowSSL,sendKeyfile ====="); +for (var n = 0; n < rst.nodes.length; n++) { + rst.nodes[n].getDB("admin").auth("root", "pwd"); +} rst.upgradeSet({sslMode:"allowSSL", sslPEMKeyFile: SERVER_CERT, sslAllowInvalidCertificates:"", clusterAuthMode:"sendKeyFile", keyFile: KEYFILE, - sslCAFile: CA_CERT}); + sslCAFile: CA_CERT}, "root", "pwd"); +for (var n = 0; n < rst.nodes.length; n++) { + rst.nodes[n].getDB("admin").auth("root", "pwd"); +} rst.awaitReplication(); var rstConn2 = rst.getMaster(); @@ -34,8 +42,12 @@ print("===== UPGRADE allowSSL,sendKeyfile -> preferSSL,sendX509 ====="); rst.upgradeSet({sslMode:"preferSSL", sslPEMKeyFile: SERVER_CERT, sslAllowInvalidCertificates:"", clusterAuthMode:"sendX509", keyFile: KEYFILE, - sslCAFile: CA_CERT}); + sslCAFile: CA_CERT}, "root", "pwd"); +for (var n = 0; n < rst.nodes.length; n++) { + rst.nodes[n].getDB("admin").auth("root", "pwd"); +} rst.awaitReplication(); + var rstConn3 = rst.getMaster(); rstConn3.getDB("test").a.insert({a:3, str:"PEASandCARROTS"}); assert.eq(3, rstConn3.getDB("test").a.count(), "Error interacting with replSet"); @@ -49,7 +61,10 @@ print("===== UPGRADE preferSSL,sendX509 -> preferSSL,x509 ====="); rst.upgradeSet({sslMode:"preferSSL", sslPEMKeyFile: SERVER_CERT, sslAllowInvalidCertificates:"", clusterAuthMode:"x509", keyFile: KEYFILE, - sslCAFile: CA_CERT}); + sslCAFile: CA_CERT}, "root", "pwd"); +for (var n = 0; n < rst.nodes.length; n++) { + rst.nodes[n].getDB("admin").auth("root", "pwd"); +} rst.awaitReplication(); var rstConn4 = rst.getMaster(); rstConn4.getDB("test").a.insert({a:4, str:"BEEP BOOP"}); diff --git a/jstests/tool/dumpauth.js b/jstests/tool/dumpauth.js index 2fcd32a9157..7ae165f5ce1 100644 --- a/jstests/tool/dumpauth.js +++ b/jstests/tool/dumpauth.js @@ -6,6 +6,9 @@ baseName = "tool_dumpauth"; m = startMongod( "--auth", "--port", port, "--dbpath", MongoRunner.dataPath + baseName, "--nohttpinterface", "--bind_ip", "127.0.0.1" ); db = m.getDB( "admin" ); +db.createUser({user: "testuser" , pwd: "testuser", roles: jsTest.adminUserRoles}); +assert( db.auth( "testuser" , "testuser" ) , "auth failed" ); + t = db[ baseName ]; t.drop(); @@ -13,10 +16,6 @@ for(var i = 0; i < 100; i++) { t["testcol"].save({ "x": i }); } -db.createUser({user: "testuser" , pwd: "testuser", roles: jsTest.adminUserRoles}); - -assert( db.auth( "testuser" , "testuser" ) , "auth failed" ); - x = runMongoProgram( "mongodump", "--db", baseName, "--authenticationDatabase=admin", diff --git a/jstests/tool/stat1.js b/jstests/tool/stat1.js index 96211f7d3f2..4c6d718a522 100644 --- a/jstests/tool/stat1.js +++ b/jstests/tool/stat1.js @@ -6,13 +6,7 @@ baseName = "tool_stat1"; m = startMongod( "--auth", "--port", port, "--dbpath", MongoRunner.dataPath + baseName, "--nohttpinterface", "--bind_ip", "127.0.0.1" ); db = m.getDB( "admin" ); -t = db[ baseName ]; -t.drop(); - -db.dropAllUsers(); - db.createUser({user: "eliot" , pwd: "eliot", roles: jsTest.adminUserRoles}); - assert( db.auth( "eliot" , "eliot" ) , "auth failed" ); x = runMongoProgram( "mongostat", "--host", "127.0.0.1:"+port, "--username", "eliot", "--password", "eliot", "--rowcount", "1" ); diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 66d0d77762a..0178094175a 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -1108,6 +1108,7 @@ env.JSHeader("shell/mongo.cpp", "shell/upgrade_check.js", "shell/utils.js", "shell/utils_sh.js", + "shell/utils_auth.js", ]) # if you add a file here, you need to add it in shell/shell_utils.cpp and shell/createCPPfromJavaScriptFiles.js as well diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp index 6c932ab6375..a934ee3aae6 100644 --- a/src/mongo/db/auth/authorization_session.cpp +++ b/src/mongo/db/auth/authorization_session.cpp @@ -124,6 +124,42 @@ namespace { _authenticatedUsers.add(internalSecurity.user); } + PrivilegeVector AuthorizationSession::getDefaultPrivileges() { + PrivilegeVector defaultPrivileges; + + // If localhost exception is active (and no users exist), + // return a vector of the minimum privileges required to bootstrap + // a system and add the first user. + if (_externalState->shouldAllowLocalhost()) { + ResourcePattern adminDBResource = ResourcePattern::forDatabaseName(ADMIN_DBNAME); + ActionSet setupAdminUserActionSet; + setupAdminUserActionSet.addAction(ActionType::createUser); + setupAdminUserActionSet.addAction(ActionType::grantRole); + Privilege setupAdminUserPrivilege = + Privilege(adminDBResource, setupAdminUserActionSet); + + ResourcePattern externalDBResource = ResourcePattern::forDatabaseName("$external"); + Privilege setupExternalUserPrivilege = + Privilege(externalDBResource, ActionType::createUser); + + ActionSet setupServerConfigActionSet; + setupServerConfigActionSet.addAction(ActionType::addShard); + setupServerConfigActionSet.addAction(ActionType::replSetConfigure); + setupServerConfigActionSet.addAction(ActionType::replSetGetStatus); + Privilege setupServerConfigPrivilege = + Privilege(ResourcePattern::forClusterResource(), setupServerConfigActionSet); + + Privilege::addPrivilegeToPrivilegeVector(&defaultPrivileges, setupAdminUserPrivilege); + Privilege::addPrivilegeToPrivilegeVector(&defaultPrivileges, + setupExternalUserPrivilege); + Privilege::addPrivilegeToPrivilegeVector(&defaultPrivileges, + setupServerConfigPrivilege); + return defaultPrivileges; + } + + return defaultPrivileges; + } + Status AuthorizationSession::checkAuthForQuery(const NamespaceString& ns, const BSONObj& query) { if (MONGO_unlikely(ns.isCommand())) { @@ -435,6 +471,22 @@ namespace { ActionSet unmetRequirements = privilege.getActions(); + PrivilegeVector defaultPrivileges = getDefaultPrivileges(); + for (PrivilegeVector::iterator it = defaultPrivileges.begin(); + it != defaultPrivileges.end(); ++it) { + + for (int i = 0; i < resourceSearchListLength; ++i) { + if (!(it->getResourcePattern() == resourceSearchList[i])) + continue; + + ActionSet userActions = it->getActions(); + unmetRequirements.removeAllActionsFromSet(userActions); + + if (unmetRequirements.empty()) + return true; + } + } + for (UserSet::iterator it = _authenticatedUsers.begin(); it != _authenticatedUsers.end(); ++it) { User* user = *it; diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h index 92e4e6f6552..1a12a0719e0 100644 --- a/src/mongo/db/auth/authorization_session.h +++ b/src/mongo/db/auth/authorization_session.h @@ -100,6 +100,13 @@ namespace mongo { // Used to grant internal threads full access. void grantInternalAuthorization(); + // Generates a vector of default privileges that are granted to any user, + // regardless of which roles that user does or does not possess. + // If localhost exception is active, the permissions include the ability to create + // the first user and the ability to run the commands needed to bootstrap the system + // into a state where the first user can be created. + PrivilegeVector getDefaultPrivileges(); + // Checks if this connection has the privileges necessary to perform the given query on the // given namespace. Status checkAuthForQuery(const NamespaceString& ns, const BSONObj& query); diff --git a/src/mongo/db/auth/authz_session_external_state.h b/src/mongo/db/auth/authz_session_external_state.h index 2f8b4d097c5..dbd838cb68f 100644 --- a/src/mongo/db/auth/authz_session_external_state.h +++ b/src/mongo/db/auth/authz_session_external_state.h @@ -56,12 +56,16 @@ namespace mongo { // Returns true if this connection should be treated as if it has full access to do // anything, regardless of the current auth state. Currently the reasons why this could be - // are that auth isn't enabled, the connection is from localhost and there are no admin - // users, or the connection is a "god" connection. - // NOTE: _checkShouldAllowLocalhost MUST be called at least once before any call to - // shouldIgnoreAuthChecks or we could ignore auth checks incorrectly. + // are that auth isn't enabled or the connection is a "god" connection. virtual bool shouldIgnoreAuthChecks() const = 0; + // Returns true if this connection should be treated as a localhost connection with no + // admin authentication users created. This condition is used to allow the creation of + // the first user on a server with authorization enabled. + // NOTE: _checkShouldAllowLocalhost MUST be called at least once before any call to + // shouldAllowLocalhost or we could ignore auth checks incorrectly. + virtual bool shouldAllowLocalhost() const = 0; + // Should be called at the beginning of every new request. This performs the checks // necessary to determine if localhost connections should be given full access. virtual void startRequest() = 0; diff --git a/src/mongo/db/auth/authz_session_external_state_mock.h b/src/mongo/db/auth/authz_session_external_state_mock.h index 3db4df17de6..c884654ac91 100644 --- a/src/mongo/db/auth/authz_session_external_state_mock.h +++ b/src/mongo/db/auth/authz_session_external_state_mock.h @@ -43,20 +43,30 @@ namespace mongo { public: AuthzSessionExternalStateMock(AuthorizationManager* authzManager) : - AuthzSessionExternalState(authzManager), _returnValue(false) {} + AuthzSessionExternalState(authzManager), _ignoreAuthChecksReturnValue(false), + _allowLocalhostReturnValue(false) {} virtual bool shouldIgnoreAuthChecks() const { - return _returnValue; + return _ignoreAuthChecksReturnValue; + } + + virtual bool shouldAllowLocalhost() const { + return _allowLocalhostReturnValue; } void setReturnValueForShouldIgnoreAuthChecks(bool returnValue) { - _returnValue = returnValue; + _ignoreAuthChecksReturnValue = returnValue; + } + + void setReturnValueForShouldAllowLocalhost(bool returnValue) { + _allowLocalhostReturnValue = returnValue; } virtual void startRequest() {} private: - bool _returnValue; + bool _ignoreAuthChecksReturnValue; + bool _allowLocalhostReturnValue; }; } // namespace mongo diff --git a/src/mongo/db/auth/authz_session_external_state_server_common.cpp b/src/mongo/db/auth/authz_session_external_state_server_common.cpp index 80f24004533..b5c6f6a4bc3 100644 --- a/src/mongo/db/auth/authz_session_external_state_server_common.cpp +++ b/src/mongo/db/auth/authz_session_external_state_server_common.cpp @@ -41,7 +41,7 @@ namespace { } // namespace // NOTE: we default _allowLocalhost to true under the assumption that _checkShouldAllowLocalhost - // will always be called before any calls to shouldIgnoreAuthChecks. If this is not the case, + // will always be called before any calls to shouldAllowLocalhost. If this is not the case, // it could cause a security hole. AuthzSessionExternalStateServerCommon::AuthzSessionExternalStateServerCommon( AuthorizationManager* authzManager) : @@ -70,10 +70,13 @@ namespace { } } - bool AuthzSessionExternalStateServerCommon::shouldIgnoreAuthChecks() const { + bool AuthzSessionExternalStateServerCommon::shouldAllowLocalhost() const { ClientBasic* client = ClientBasic::getCurrent(); - return !_authzManager->isAuthEnabled() || - (_allowLocalhost && client->getIsLocalHostConnection()); + return _allowLocalhost && client->getIsLocalHostConnection(); + } + + bool AuthzSessionExternalStateServerCommon::shouldIgnoreAuthChecks() const { + return !_authzManager->isAuthEnabled(); } } // namespace mongo diff --git a/src/mongo/db/auth/authz_session_external_state_server_common.h b/src/mongo/db/auth/authz_session_external_state_server_common.h index a621fc1f651..f6e1a97f4a9 100644 --- a/src/mongo/db/auth/authz_session_external_state_server_common.h +++ b/src/mongo/db/auth/authz_session_external_state_server_common.h @@ -44,6 +44,7 @@ namespace mongo { public: virtual ~AuthzSessionExternalStateServerCommon(); + virtual bool shouldAllowLocalhost() const; virtual bool shouldIgnoreAuthChecks() const; protected: diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index ac10481084e..651ecb6cca9 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -387,6 +387,14 @@ namespace mongo { AuthorizationSession* authSession = ClientBasic::getCurrent()->getAuthorizationSession(); authSession->logoutDatabase(dbname); + if (Command::testCommandsEnabled && dbname == "admin") { + // Allows logging out as the internal user against the admin database, however + // this actually logs out of the local database as well. This is to + // support the auth passthrough test framework on mongos (since you can't use the + // local database on a mongos, so you can't logout as the internal user + // without this). + authSession->logoutDatabase("local"); + } return true; } } cmdLogout; diff --git a/src/mongo/scripting/engine.cpp b/src/mongo/scripting/engine.cpp index 6f24e26c2c0..5a7789be8b3 100644 --- a/src/mongo/scripting/engine.cpp +++ b/src/mongo/scripting/engine.cpp @@ -262,12 +262,14 @@ namespace mongo { extern const JSFile upgrade_check; extern const JSFile utils; extern const JSFile utils_sh; + extern const JSFile utils_auth; extern const JSFile bulk_api; } void Scope::execCoreFiles() { execSetup(JSFiles::utils); execSetup(JSFiles::utils_sh); + execSetup(JSFiles::utils_auth); execSetup(JSFiles::db); execSetup(JSFiles::mongo); execSetup(JSFiles::mr); diff --git a/src/mongo/shell/createCPPfromJavaScriptFiles.js b/src/mongo/shell/createCPPfromJavaScriptFiles.js index 42880e7bfe7..e81495083a4 100644 --- a/src/mongo/shell/createCPPfromJavaScriptFiles.js +++ b/src/mongo/shell/createCPPfromJavaScriptFiles.js @@ -106,6 +106,7 @@ shell.CurrentDirectory = WScript.Arguments.Unnamed.Item( 0 ); var fso = new ActiveXObject( "Scripting.FileSystemObject" ); rebuildIfNeeded(fso, "shell/mongo.cpp", ["shell/assert.js", "shell/types.js", "shell/utils.js", "shell/utils_sh.js", + "shell/utils_auth.js", "shell/db.js", "shell/mongo.js", "shell/mr.js", "shell/query.js", "shell/collection.js", "shell/upgrade_check.js", diff --git a/src/mongo/shell/replsettest.js b/src/mongo/shell/replsettest.js index ead6d712105..a95999704c1 100644 --- a/src/mongo/shell/replsettest.js +++ b/src/mongo/shell/replsettest.js @@ -895,45 +895,67 @@ ReplSetTest.prototype.waitForIndicator = function( node, states, ind, timeout ){ var status = undefined var self = this; - assert.soon(function() { - - try { - status = self.status(); - } - catch ( ex ) { - print( "ReplSetTest waitForIndicator could not get status: " + tojson( ex ) ); - return false; - } - - var printStatus = false - if( lastTime == null || ( currTime = new Date().getTime() ) - (1000 * 5) > lastTime ){ - if( lastTime == null ) print( "ReplSetTest waitForIndicator Initial status ( timeout : " + timeout + " ) :" ) - printjson( status ) - lastTime = new Date().getTime() - printStatus = true - } + var checkStatusWaitForIndicator = function() { + assert.soon(function() { - if (typeof status.members == 'undefined') { - return false; - } + try { + status = self.status(); + } + catch ( ex ) { + print( "ReplSetTest waitForIndicator could not get status: " + tojson( ex ) ); + return false; + } - for( var i = 0; i < status.members.length; i++ ){ - if( printStatus ) print( "Status for : " + status.members[i].name + ", checking " + node.host + "/" + node.name ) - if( status.members[i].name == node.host || status.members[i].name == node.name ){ - for( var j = 0; j < states.length; j++ ){ - if( printStatus ) print( "Status " + " : " + status.members[i][ind] + " target state : " + states[j] ) - if( status.members[i][ind] == states[j] ) return true; + var printStatus = false + if( lastTime == null || ( currTime = new Date().getTime() ) - (1000 * 5) > lastTime ) { + if( lastTime == null ) { + print( "ReplSetTest waitForIndicator Initial status ( timeout : " + + timeout + " ) :" ); } + printjson( status ); + lastTime = new Date().getTime(); + printStatus = true; } - } - - return false - - }, "waiting for state indicator " + ind + " for " + timeout + "ms", timeout); - + + if (typeof status.members == 'undefined') { + return false; + } + + for( var i = 0; i < status.members.length; i++ ) { + if( printStatus ) { + print( "Status for : " + status.members[i].name + ", checking " + + node.host + "/" + node.name ); + } + if( status.members[i].name == node.host || status.members[i].name == node.name ) { + for( var j = 0; j < states.length; j++ ) { + if( printStatus ) { + print( "Status " + " : " + status.members[i][ind] + + " target state : " + states[j] ); + } + if( status.members[i][ind] == states[j] ) { + return true; + } + } + } + } + + return false; + + }, "waiting for state indicator " + ind + " for " + timeout + "ms", timeout); + }; + + if (self.keyFile) { + // Authenticate connections to the replica set members using the keyfile, + // if applicable, before attempting to perform operations. + authutil.asCluster(self.getMaster(), self.keyFile, checkStatusWaitForIndicator); + } + else { + // No keyfile, so no authenication necessary. + checkStatusWaitForIndicator(); + } + print( "ReplSetTest waitForIndicator final status:" ) printjson( status ) - } ReplSetTest.Health = {} diff --git a/src/mongo/shell/shardingtest.js b/src/mongo/shell/shardingtest.js index 6f74762856e..ebd6121f966 100644 --- a/src/mongo/shell/shardingtest.js +++ b/src/mongo/shell/shardingtest.js @@ -274,7 +274,9 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other var rs = this._rs[i].test; rs.getMaster().getDB( "admin" ).foo.save( { x : 1 } ) - rs.awaitReplication(); + if (keyFile) { + authutil.asCluster(rs.nodes, keyFile, function() { rs.awaitReplication(); }); + } rs.awaitSecondaryNodes(); var rsConn = new Mongo( rs.getURL() ); @@ -381,7 +383,23 @@ ShardingTest = function( testName , numShards , verboseLevel , numMongos , other // Disable the balancer unless it is explicitly turned on if ( !otherParams.enableBalancer ) { - this.stopBalancer(); + if (keyFile) { + authutil.assertAuthenticate(this._mongos, 'admin', { + user: '__system', + mechanism: 'MONGODB-CR', + pwd: cat(keyFile).replace(/[ \n]/g, '') + }); + + try { + this.stopBalancer(); + } + finally { + authutil.logout(this._mongos, 'admin'); + } + } + else { + this.stopBalancer(); + } } if ( ! otherParams.manualAddShard ){ diff --git a/jstests/multiVersion/libs/auth_support.js b/src/mongo/shell/utils_auth.js index 1554c4abf49..67e44d192dc 100644 --- a/jstests/multiVersion/libs/auth_support.js +++ b/src/mongo/shell/utils_auth.js @@ -1,14 +1,13 @@ -var AuthSupport; +var authutil; -(function () { - - assert(!AuthSupport, "Double-load of auth_support.js detected!"); - AuthSupport = {}; +(function() { + assert(!authutil); + authutil = {}; /** * Logs out all connections "conn" from database "dbname". */ - var logout = function AuthSupport_logout(conn, dbname) { + authutil.logout = function(conn, dbname) { var i; if (null == conn.length) { conn = [ conn ]; @@ -17,7 +16,6 @@ var AuthSupport; conn[i].getDB(dbname).logout(); } }; - AuthSupport.logout = logout; /** * Authenticates all connections in "conns" using "authParams" on database "dbName". @@ -25,8 +23,7 @@ var AuthSupport; * Raises an exception if any authentication fails, and tries to leave all connnections * in "conns" in the logged-out-of-dbName state. */ - var assertAuthenticate = function AuthSupport_assertAuthenticate(conns, dbName, authParams) { - + authutil.assertAuthenticate = function(conns, dbName, authParams) { var conn, i, ex, ex2; if (conns.length == null) conns = [ conns ]; @@ -41,22 +38,19 @@ var AuthSupport; } catch (ex) { try { - logout(conns, dbName); + authutil.logout(conns, dbName); } catch (ex2) { } throw ex; } }; - AuthSupport.assertAuthenticate = assertAuthenticate; - /** + /** * Authenticates all connections in "conns" using "authParams" on database "dbName". * Raises in exception if any of the authentications succeed. */ - var assertAuthenticateFails = function AuthSupport_assertAuthenticateFails( - conns, dbName, authParams) { - + authutil.assertAuthenticateFails = function(conns, dbName, authParams) { var conn, i; if (conns.length == null) conns = [ conns ]; @@ -68,47 +62,29 @@ var AuthSupport; tojson(authParams)); } }; - AuthSupport.assertAuthenticateFails = assertAuthenticateFails; /** * Executes action() after authenticating the keyfile user on "conn", then logs out the keyfile * user. */ - var asCluster = function AuthSupport_asCluster(conn, keyfile, action) { + authutil.asCluster = function(conn, keyfile, action) { var ex; - assertAuthenticate(conn, 'local', { + authutil.assertAuthenticate(conn, 'local', { user: '__system', mechanism: 'MONGODB-CR', pwd: cat(keyfile).replace(/[ \n]/g, '') }); try { - action(); + return action(); } finally { try { - logout(conn, 'local'); + authutil.logout(conn, 'local'); } catch (ex) { } } }; - AuthSupport.asCluster = asCluster; - - // Update ReplSetTest.prototype.waitForIndicator to authenticate connections to the - // replica set members using the keyfile, before attempting to perform operations. - (function updateReplsetTestPrototypes() { - var originalWaitForIndicator = ReplSetTest.prototype.waitForIndicator; - ReplSetTest.prototype.waitForIndicator = function newRSTestWaitForIndicator( - node, states, ind, timeout) { - - var self = this; - if (node.length) - return originalWaitForIndicator.apply(self, [node, states, ind, timeout]); - asCluster(self.getMaster(), self.keyFile, function () { - originalWaitForIndicator.apply(self, [node, states, ind, timeout]); - }); - }; - }()); -}()); + }()); |