summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/auth/auth1.js10
-rw-r--r--jstests/auth/auth2.js24
-rw-r--r--jstests/auth/auth_helpers.js9
-rw-r--r--jstests/auth/auth_options.js1
-rw-r--r--jstests/auth/basic_role_auth.js11
-rw-r--r--jstests/auth/copyauth.js21
-rw-r--r--jstests/auth/copyauth2.js16
-rw-r--r--jstests/auth/disable_localhost_bypass.js21
-rw-r--r--jstests/auth/lib/commands_lib.js1
-rw-r--r--jstests/auth/localhostAuthBypass.js2
-rw-r--r--jstests/auth/mongos_cache_invalidation.js10
-rw-r--r--jstests/auth/readIndex.js8
-rw-r--r--jstests/auth/repl.js7
-rw-r--r--jstests/auth/resource_pattern_matching.js7
-rw-r--r--jstests/auth/role_management_commands.js5
-rw-r--r--jstests/libs/command_line/test_parsed_options.js12
-rw-r--r--jstests/multiVersion/auth_schema_upgrade_26.js13
-rw-r--r--jstests/multiVersion/auth_schema_upgrade_26_repl_version_mismatch.js9
-rw-r--r--jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js1
-rw-r--r--jstests/replsets/auth3.js3
-rw-r--r--jstests/replsets/localhostAuthBypass.js2
-rw-r--r--jstests/replsets/rollback_auth.js7
-rw-r--r--jstests/sharding/auth.js25
-rw-r--r--jstests/sharding/auth2.js4
-rw-r--r--jstests/sharding/authCommands.js13
-rw-r--r--jstests/sharding/auth_add_shard.js17
-rw-r--r--jstests/sharding/auth_config_down.js7
-rw-r--r--jstests/sharding/auth_repl.js20
-rw-r--r--jstests/sharding/localhostAuthBypass.js25
-rw-r--r--jstests/sharding/mongos_rs_auth_shard_failure_tolerance.js25
-rw-r--r--jstests/sharding/sharding_with_keyfile_auth.js25
-rw-r--r--jstests/ssl/initial_sync1_x509.js64
-rw-r--r--jstests/ssl/libs/ssl_helpers.js9
-rw-r--r--jstests/ssl/set_parameter_ssl.js10
-rw-r--r--jstests/ssl/sharding_with_x509.js4
-rw-r--r--jstests/ssl/upgrade_to_x509_ssl.js17
-rw-r--r--jstests/ssl/x509_client.js4
-rw-r--r--jstests/sslSpecial/upgrade_to_x509_ssl_nossl.js21
-rw-r--r--jstests/tool/dumpauth.js7
-rw-r--r--jstests/tool/stat1.js6
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/db/auth/authorization_session.cpp52
-rw-r--r--src/mongo/db/auth/authorization_session.h7
-rw-r--r--src/mongo/db/auth/authz_session_external_state.h12
-rw-r--r--src/mongo/db/auth/authz_session_external_state_mock.h18
-rw-r--r--src/mongo/db/auth/authz_session_external_state_server_common.cpp11
-rw-r--r--src/mongo/db/auth/authz_session_external_state_server_common.h1
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp8
-rw-r--r--src/mongo/scripting/engine.cpp2
-rw-r--r--src/mongo/shell/createCPPfromJavaScriptFiles.js1
-rw-r--r--src/mongo/shell/replsettest.js88
-rw-r--r--src/mongo/shell/shardingtest.js22
-rw-r--r--src/mongo/shell/utils_auth.js (renamed from jstests/multiVersion/libs/auth_support.js)52
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]);
- });
- };
- }());
-}());
+ }());