diff options
-rw-r--r-- | debian/mongo.1 | 2 | ||||
-rw-r--r-- | jstests/auth/adduser_helper.js | 64 | ||||
-rw-r--r-- | jstests/auth/repl.js | 2 | ||||
-rw-r--r-- | jstests/multiVersion/dumprestore_24_auth.js | 62 | ||||
-rw-r--r-- | jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js | 338 | ||||
-rw-r--r-- | src/mongo/shell/db.js | 155 | ||||
-rw-r--r-- | src/mongo/shell/dbshell.cpp | 7 |
7 files changed, 10 insertions, 620 deletions
diff --git a/debian/mongo.1 b/debian/mongo.1 index 87523a98768..651c521db64 100644 --- a/debian/mongo.1 +++ b/debian/mongo.1 @@ -333,7 +333,7 @@ file. .INDENT 3.5 \fBmongo\fP does not recorded interaction related to authentication in the history file, including -\fBauthenticate\fP and \fBdb.addUser()\fP\&. +\fBauthenticate\fP and \fBdb.createUser()\fP\&. .UNINDENT .UNINDENT .sp diff --git a/jstests/auth/adduser_helper.js b/jstests/auth/adduser_helper.js deleted file mode 100644 index ec4199e4f00..00000000000 --- a/jstests/auth/adduser_helper.js +++ /dev/null @@ -1,64 +0,0 @@ -// Test the db.addUser() shell helper. - -var passwordHash = function(username, password) { - return hex_md5(username + ":mongo:" + password); -} - -var conn = MongoRunner.runMongod({smallfiles: ""}); - -var db = conn.getDB('addUser'); -var admin = conn.getDB('admin'); -db.dropDatabase(); -admin.dropDatabase(); - -// Test that the deprecated (username,password,readonly) form of addUser still works -db.addUser('dbReadWrite', 'x'); -var userObj = db.getUser('dbReadWrite'); -assert.eq(1, userObj.roles.length); -assert.eq("dbOwner", userObj.roles[0].role); -assert.eq(db.getName(), userObj.roles[0].db); - -db.addUser('dbReadOnly', 'x', true); -userObj = db.getUser('dbReadOnly'); -assert.eq(1, userObj.roles.length); -assert.eq("read", userObj.roles[0].role); -assert.eq(db.getName(), userObj.roles[0].db); - -admin.addUser('adminReadWrite', 'x'); -userObj = admin.getUser('adminReadWrite'); -assert.eq(1, userObj.roles.length); -assert.eq("root", userObj.roles[0].role); -assert.eq("admin", userObj.roles[0].db); - -admin.addUser('adminReadOnly', 'x', true); -userObj = admin.getUser('adminReadOnly'); -assert.eq(1, userObj.roles.length); -assert.eq("readAnyDatabase", userObj.roles[0].role); -assert.eq("admin", userObj.roles[0].db); - -admin.dropDatabase(); - -// Create valid V2 format user -db.addUser({user:'andy', pwd:'password', roles:['read']}); -assert.eq(1, admin.system.users.count()); -userObj = admin.system.users.findOne({user:'andy'}); -assert.eq('andy', userObj['user']); -assert.eq(passwordHash('andy', 'password'), userObj['credentials']['MONGODB-CR']); - -// test changing password -db.changeUserPassword('andy', 'newpassword'); -assert.eq(1, admin.system.users.count()); -userObj = admin.system.users.findOne(); -assert.eq('andy', userObj['user']); -assert.eq(passwordHash('andy', 'newpassword'), userObj['credentials']['MONGODB-CR']); - -// Should fail because user already exists -assert.throws(function() {db.addUser({user:'andy', pwd:'password', roles:['read']});}); - -// Create valid extended form external user -db.getSiblingDB("$external").addUser({user:'spencer', roles:[{role: 'readWrite', db:'test'}]}); -assert.eq(2, admin.system.users.count()); -userObj = admin.system.users.findOne({user:'spencer', db:'$external'}); -assert.eq('spencer', userObj['user']); -assert.eq('$external', userObj['db']); -assert.eq(true, userObj['credentials']['external']); diff --git a/jstests/auth/repl.js b/jstests/auth/repl.js index 25129cfd821..404f3e23de7 100644 --- a/jstests/auth/repl.js +++ b/jstests/auth/repl.js @@ -22,7 +22,7 @@ var AuthReplTest = function(spec) { secondaryConn = spec.secondaryConn; adminPri = primaryConn.getDB("admin"); - adminPri.addUser({user: "super", pwd: "super", roles: ["__system"]}); + adminPri.createUser({user: "super", pwd: "super", roles: ["__system"]}); assert(adminPri.auth("super", "super"), "could not authenticate as superuser"); if (secondaryConn != null) { diff --git a/jstests/multiVersion/dumprestore_24_auth.js b/jstests/multiVersion/dumprestore_24_auth.js deleted file mode 100644 index 80dce2736bb..00000000000 --- a/jstests/multiVersion/dumprestore_24_auth.js +++ /dev/null @@ -1,62 +0,0 @@ -// Tests that you can dump user data from 2.4 and restore it to a clean 2.6 system, and that the -// current version of mongodump/mongorestore still support dumping/restoring to and from 2.4. - - -// The base name to use for various things in the test, including the dbpath and the database name -var testBaseName = "jstests_tool_dumprestore_24_to_26"; -var dumpDir = MongoRunner.getAndPrepareDumpDirectory(testBaseName); - -function multiVersionDumpRestoreTest(opts) { - resetDbpath(dumpDir); - var mongodSource = MongoRunner.runMongod({ binVersion : opts.mongodSourceVersion, - setParameter : "textSearchEnabled=true" }); - var mongodDest = MongoRunner.runMongod({ binVersion : opts.mongodDestVersion, - setParameter : "textSearchEnabled=true" }); - var sourceDB = mongodSource.getDB(testBaseName); - var sourceAdmin = mongodSource.getDB("admin"); - var destDB = mongodDest.getDB(testBaseName); - var destAdmin = mongodDest.getDB("admin"); - - sourceAdmin.addUser({user: 'adminUser', pwd: 'pwd', roles: ['userAdminAnyDatabase']}); - sourceDB.addUser({user: 'user', pwd: 'pwd', roles: ['readWrite']}); - - // Dump using the specified version of mongodump - MongoRunner.runMongoTool("mongodump", { out : dumpDir, binVersion : opts.mongoDumpVersion, - host : mongodSource.host }); - - // Drop the databases - sourceDB.dropDatabase(); - sourceAdmin.dropDatabase(); - - // Restore using the specified version of mongorestore - MongoRunner.runMongoTool("mongorestore", { dir : dumpDir, binVersion : opts.mongoRestoreVersion, - host : mongodDest.host }); - - // Wait until we actually have data or timeout - assert.soon(function() { return destAdmin.system.users.findOne(); }, "no data after sleep"); - assert.eq(1, destDB.system.users.count()); - assert.eq('user', destDB.system.users.findOne().user); - assert.eq(1, destAdmin.system.users.count()); - assert.eq('adminUser', destAdmin.system.users.findOne().user); - - if (opts.mongodDestVersion == "latest") { - var schemaVersion = - destAdmin.runCommand({getParameter: 1, authSchemaVersion: 1}).authSchemaVersion; - if (opts.mongodSourceVersion == "2.4") { - assert.eq(1, schemaVersion); - } else if (opts.mongodSourceVersion == "latest") { - assert.eq(3, schemaVersion); - } - } - - MongoRunner.stopMongod(mongodSource); - MongoRunner.stopMongod(mongodDest); -} - -multiVersionDumpRestoreTest({mongodSourceVersion: "2.4", - mongodDestVersion: "2.4", - mongoDumpVersion: "latest", - mongoRestoreVersion: "latest"}); - - -print("dumprestore_24_to_26 success!"); diff --git a/jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js b/jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js deleted file mode 100644 index 6196351445d..00000000000 --- a/jstests/multiVersion/mongos_rs_legacy_auth_shard_failure_tolerance.js +++ /dev/null @@ -1,338 +0,0 @@ -// -// Tests mongos's failure tolerance for authenticated replica set shards and slaveOk queries using -// legacy authentication -// -// TODO: Remove test post-2.6 -// -// Sets up a cluster with three shards, the first shard of which has an unsharded collection and -// half a sharded collection. The second shard has the second half of the sharded collection, and -// the third shard has nothing. Progressively shuts down the primary of each shard to see the -// impact on the cluster. -// -// Three different connection states are tested - active (connection is active through whole -// sequence), idle (connection is connected but not used before a shard change), and new -// (connection connected after shard change). -// - -var options = { separateConfig : true, - rs : true, - enableBalancer: true, - mongosOptions : { binVersion : "2.6" }, - rsOptions : { nodes : 2, binVersion : "2.4" }, - 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" ); -var shards = mongos.getDB( "config" ).shards.find().toArray(); - -assert.commandWorked( admin.runCommand({ setParameter : 1, traceExceptions : true }) ); - -var collSharded = mongos.getCollection( "fooSharded.barSharded" ); -var collUnsharded = mongos.getCollection( "fooUnsharded.barUnsharded" ); - -// Create the unsharded database with shard0 primary -collUnsharded.insert({ some : "doc" }); -assert.eq( null, collUnsharded.getDB().getLastError() ); -collUnsharded.remove({}); -assert.eq( null, collUnsharded.getDB().getLastError() ); -printjson( admin.runCommand({ movePrimary : collUnsharded.getDB().toString(), - to : shards[0]._id }) ); - -// Create the sharded database with shard1 primary -assert.commandWorked( admin.runCommand({ enableSharding : collSharded.getDB().toString() }) ); -printjson( admin.runCommand({ movePrimary : collSharded.getDB().toString(), to : shards[1]._id }) ); -assert.commandWorked( admin.runCommand({ shardCollection : collSharded.toString(), - key : { _id : 1 } }) ); -assert.commandWorked( admin.runCommand({ split : collSharded.toString(), middle : { _id : 0 } }) ); -assert.commandWorked( admin.runCommand({ moveChunk : collSharded.toString(), - find : { _id : -1 }, - to : shards[0]._id }) ); - -st.printShardingStatus(); - -var adminUser = "adminUser"; -var shardedDBUser = "shardedDBUser"; -var unshardedDBUser = "unshardedDBUser"; -var password = "password"; - -jsTest.log("Setting up (legacy) database users..."); - -// Create db users -collSharded.getDB()._addUserWithInsert({ user : shardedDBUser, - pwd : password, roles : [ "readWrite" ] }); -collUnsharded.getDB()._addUserWithInsert({ user : unshardedDBUser, - pwd : password, roles : [ "readWrite" ] }); - -jsTest.log("Setting up (legacy) admin user..."); - -// Create a user -admin._addUserWithInsert({ user : adminUser, pwd : password, roles: [ "userAdminAnyDatabase" ] }); -// There's an admin user now, so we need to login to do anything - -function authDBUsers( conn ) { - conn.getDB( collSharded.getDB().toString() ).auth(shardedDBUser, password); - conn.getDB( collUnsharded.getDB().toString() ).auth(unshardedDBUser, password); - return conn; -} - -function authUnshardedUser( conn ) { - conn.getDB( collUnsharded.getDB().toString() ).auth(unshardedDBUser, password); - return conn; -} - -// Needed b/c the GLE command itself can fail if the shard is down ("write result unknown") - we -// don't care if this happens in this test, we only care that we did not get "write succeeded". -// Depending on the connection pool state, we could get either. -function gleErrorOrThrow(database, msg) { - var gle; - try { - gle = database.getLastErrorObj(); - } - catch (ex) { - return; - } - if (!gle.err) doassert("getLastError is null: " + tojson(gle) + " :" + msg); - return; -}; - -// -// Setup is complete -// - -jsTest.log("Inserting initial data..."); - -var mongosConnActive = authDBUsers( new Mongo( mongos.host ) ); -authDBUsers(mongosConnActive); -var mongosConnIdle = null; -var mongosConnNew = null; - -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : -1 }); -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : 1 }); -assert.eq(null, mongosConnActive.getCollection( collSharded.toString() ).getDB().getLastError()); - -mongosConnActive.getCollection( collUnsharded.toString() ).insert({ _id : 1 }); -assert.eq(null, mongosConnActive.getCollection( collUnsharded.toString() ).getDB().getLastError()); - -jsTest.log("Stopping primary of third shard..."); - -mongosConnIdle = authDBUsers( new Mongo( mongos.host ) ); - -st.rs2.stop(st.rs2.getPrimary(), true ); // wait for stop - -jsTest.log("Testing active connection with third primary down..."); - -assert.neq(null, mongosConnActive.getCollection( collSharded.toString() ).findOne({ _id : -1 })); -assert.neq(null, mongosConnActive.getCollection( collSharded.toString() ).findOne({ _id : 1 })); -assert.neq(null, mongosConnActive.getCollection( collUnsharded.toString() ).findOne({ _id : 1 })); - -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : -2 }); -assert.gleSuccess(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : 2 }); -assert.gleSuccess(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collUnsharded.toString() ).insert({ _id : 2 }); -assert.gleSuccess(mongosConnActive.getCollection( collUnsharded.toString() ).getDB()); - -jsTest.log("Testing idle connection with third primary down..."); - -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : -3 }); -assert.gleSuccess(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : 3 }); -assert.gleSuccess(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collUnsharded.toString() ).insert({ _id : 3 }); -assert.gleSuccess(mongosConnIdle.getCollection( collUnsharded.toString() ).getDB()); - -assert.neq(null, mongosConnIdle.getCollection( collSharded.toString() ).findOne({ _id : -1 }) ); -assert.neq(null, mongosConnIdle.getCollection( collSharded.toString() ).findOne({ _id : 1 }) ); -assert.neq(null, mongosConnIdle.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -jsTest.log("Testing new connections with third primary down..."); - -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -assert.neq(null, mongosConnNew.getCollection( collSharded.toString() ).findOne({ _id : -1 }) ); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -assert.neq(null, mongosConnNew.getCollection( collSharded.toString() ).findOne({ _id : 1 }) ); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -assert.neq(null, mongosConnNew.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collSharded.toString() ).insert({ _id : -4 }); -assert.gleSuccess(mongosConnNew.getCollection( collSharded.toString() ).getDB()); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collSharded.toString() ).insert({ _id : 4 }); -assert.gleSuccess(mongosConnNew.getCollection( collSharded.toString() ).getDB()); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collUnsharded.toString() ).insert({ _id : 4 }); -assert.gleSuccess(mongosConnNew.getCollection( collUnsharded.toString() ).getDB()); - -gc(); // Clean up new connections - -jsTest.log("Stopping primary of second shard..."); - -mongosConnActive.setSlaveOk(); -mongosConnIdle = authDBUsers( new Mongo( mongos.host ) ); -mongosConnIdle.setSlaveOk(); - -// Need to save this node for later -var rs1Secondary = st.rs1.getSecondary(); - -st.rs1.stop(st.rs1.getPrimary(), true ); // wait for stop - -jsTest.log("Testing active connection with second primary down..."); - -assert.neq(null, mongosConnActive.getCollection( collSharded.toString() ).findOne({ _id : -1 })); -assert.neq(null, mongosConnActive.getCollection( collSharded.toString() ).findOne({ _id : 1 })); -assert.neq(null, mongosConnActive.getCollection( collUnsharded.toString() ).findOne({ _id : 1 })); - -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : -5 }); -assert.gleSuccess(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : 5 }); -gleErrorOrThrow(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collUnsharded.toString() ).insert({ _id : 5 }); -assert.gleSuccess(mongosConnActive.getCollection( collUnsharded.toString() ).getDB()); - -jsTest.log("Testing idle connection with second primary down..."); - -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : -6 }); -assert.gleSuccess(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : 6 }); -gleErrorOrThrow(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collUnsharded.toString() ).insert({ _id : 6 }); -assert.gleSuccess(mongosConnIdle.getCollection( collUnsharded.toString() ).getDB()); - -assert.neq(null, mongosConnIdle.getCollection( collSharded.toString() ).findOne({ _id : -1 }) ); -assert.neq(null, mongosConnIdle.getCollection( collSharded.toString() ).findOne({ _id : 1 }) ); -assert.neq(null, mongosConnIdle.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -jsTest.log("Testing new connections with second primary down..."); - -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.setSlaveOk(); -assert.neq(null, mongosConnNew.getCollection( collSharded.toString() ).findOne({ _id : -1 }) ); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.setSlaveOk(); -assert.neq(null, mongosConnNew.getCollection( collSharded.toString() ).findOne({ _id : 1 }) ); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.setSlaveOk(); -assert.neq(null, mongosConnNew.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collSharded.toString() ).insert({ _id : -7 }); -assert.gleSuccess(mongosConnNew.getCollection( collSharded.toString() ).getDB()); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collSharded.toString() ).insert({ _id : 7 }); -gleErrorOrThrow(mongosConnNew.getCollection( collSharded.toString() ).getDB()); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collUnsharded.toString() ).insert({ _id : 7 }); -assert.gleSuccess(mongosConnNew.getCollection( collUnsharded.toString() ).getDB()); - -gc(); // Clean up new connections - -jsTest.log("Stopping primary of first shard..."); - -mongosConnActive.setSlaveOk(); -mongosConnIdle = authDBUsers( new Mongo( mongos.host ) ); -mongosConnIdle.setSlaveOk(); - -st.rs0.stop(st.rs0.getPrimary(), true ); // wait for stop - -jsTest.log("Testing active connection with first primary down..."); - -assert.neq(null, mongosConnActive.getCollection( collSharded.toString() ).findOne({ _id : -1 })); -assert.neq(null, mongosConnActive.getCollection( collSharded.toString() ).findOne({ _id : 1 })); -assert.neq(null, mongosConnActive.getCollection( collUnsharded.toString() ).findOne({ _id : 1 })); - -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : -8 }); -gleErrorOrThrow(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : 8 }); -gleErrorOrThrow(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collUnsharded.toString() ).insert({ _id : 8 }); -gleErrorOrThrow(mongosConnActive.getCollection( collUnsharded.toString() ).getDB()); - -jsTest.log("Testing idle connection with first primary down..."); - -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : -9 }); -gleErrorOrThrow(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : 9 }); -gleErrorOrThrow(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collUnsharded.toString() ).insert({ _id : 9 }); -gleErrorOrThrow(mongosConnIdle.getCollection( collUnsharded.toString() ).getDB()); - -assert.neq(null, mongosConnIdle.getCollection( collSharded.toString() ).findOne({ _id : -1 }) ); -assert.neq(null, mongosConnIdle.getCollection( collSharded.toString() ).findOne({ _id : 1 }) ); -assert.neq(null, mongosConnIdle.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -jsTest.log("Testing new connections with first primary down..."); - -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.setSlaveOk(); -assert.neq(null, mongosConnNew.getCollection( collSharded.toString() ).findOne({ _id : -1 }) ); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.setSlaveOk(); -assert.neq(null, mongosConnNew.getCollection( collSharded.toString() ).findOne({ _id : 1 }) ); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.setSlaveOk(); -assert.neq(null, mongosConnNew.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collSharded.toString() ).insert({ _id : -10 }); -gleErrorOrThrow(mongosConnNew.getCollection( collSharded.toString() ).getDB()); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collSharded.toString() ).insert({ _id : 10 }); -gleErrorOrThrow(mongosConnNew.getCollection( collSharded.toString() ).getDB()); -mongosConnNew = authDBUsers( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collUnsharded.toString() ).insert({ _id : 10 }); -gleErrorOrThrow(mongosConnNew.getCollection( collUnsharded.toString() ).getDB()); - -gc(); // Clean up new connections - -jsTest.log("Stopping second shard..."); - -mongosConnActive.setSlaveOk(); -mongosConnIdle = authDBUsers( new Mongo( mongos.host ) ); -mongosConnIdle.setSlaveOk(); - -st.rs1.stop(rs1Secondary, true ); // wait for stop - -jsTest.log("Testing active connection with second shard down..."); - -assert.neq(null, mongosConnActive.getCollection( collSharded.toString() ).findOne({ _id : -1 })); -assert.neq(null, mongosConnActive.getCollection( collUnsharded.toString() ).findOne({ _id : 1 })); - -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : -11 }); -gleErrorOrThrow(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collSharded.toString() ).insert({ _id : 11 }); -gleErrorOrThrow(mongosConnActive.getCollection( collSharded.toString() ).getDB()); -mongosConnActive.getCollection( collUnsharded.toString() ).insert({ _id : 11 }); -gleErrorOrThrow(mongosConnActive.getCollection( collUnsharded.toString() ).getDB()); - -jsTest.log("Testing idle connection with second shard down..."); - -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : -12 }); -gleErrorOrThrow(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collSharded.toString() ).insert({ _id : 12 }); -gleErrorOrThrow(mongosConnIdle.getCollection( collSharded.toString() ).getDB()); -mongosConnIdle.getCollection( collUnsharded.toString() ).insert({ _id : 12 }); -gleErrorOrThrow(mongosConnIdle.getCollection( collUnsharded.toString() ).getDB()); - -assert.neq(null, mongosConnIdle.getCollection( collSharded.toString() ).findOne({ _id : -1 }) ); -assert.neq(null, mongosConnIdle.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -jsTest.log("Testing new connections with second shard down..."); - -// Note that this would fail for the sharded database with a primary on the second shard - -mongosConnNew = authUnshardedUser( new Mongo( mongos.host ) ); -mongosConnNew.setSlaveOk(); -assert.neq(null, mongosConnNew.getCollection( collUnsharded.toString() ).findOne({ _id : 1 }) ); - -mongosConnNew = authUnshardedUser( new Mongo( mongos.host ) ); -mongosConnNew.getCollection( collUnsharded.toString() ).insert({ _id : 13 }); -gleErrorOrThrow(mongosConnNew.getCollection( collUnsharded.toString() ).getDB()); - -gc(); // Clean up new connections - -jsTest.log("DONE!"); -st.stop(); diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js index 101663aff7e..c2d9ff4d869 100644 --- a/src/mongo/shell/db.js +++ b/src/mongo/shell/db.js @@ -893,98 +893,6 @@ function getUserObjString(userObj) { return toreturn; } -/** - * Used for creating users in systems with v1 style user information (ie MongoDB v2.4 and prior) - */ -DB.prototype._addUserWithInsert = function(userObj, replicatedTo, timeout) { - var c = this.getCollection( "system.users" ); - userObj = Object.extend({}, userObj); // Prevent modifications to userObj from getting to caller - if (userObj.pwd != null) { - userObj.pwd = _hashPassword(userObj.user, userObj.pwd); - } - - try { - c.save(userObj); - } catch (e) { - // SyncClusterConnections call GLE automatically after every write and will throw an - // exception if the insert failed. - if ( tojson(e).indexOf( "login" ) >= 0 ){ - // TODO: this check is a hack - print( "Creating user seems to have succeeded but threw an exception because we no " + - "longer have auth." ); - } else { - throw Error( "Could not insert into system.users: " + tojson(e) ); - } - } - print("Successfully added user: " + getUserObjString(userObj)); - - // - // When saving users to replica sets, the shell user will want to know if the user hasn't - // been fully replicated everywhere, since this will impact security. By default, replicate to - // majority of nodes with wtimeout 15 secs, though user can override - // - - replicatedTo = replicatedTo != undefined && replicatedTo != null ? replicatedTo : "majority" - - // in mongod version 2.1.0-, this worked - var le = {}; - try { - le = this.getLastErrorObj( replicatedTo, timeout || 30 * 1000 ); - // printjson( le ) - } - catch (e) { - errjson = tojson(e); - if ( errjson.indexOf( "login" ) >= 0 || errjson.indexOf( "unauthorized" ) >= 0 ) { - // TODO: this check is a hack - print( "addUser succeeded, but cannot wait for replication since we no longer have auth" ); - return ""; - } - print( "could not find getLastError object : " + tojson( e ) ) - } - - if (!le.err) { - return; - } - - // We can't detect replica set shards via mongos, so we'll sometimes get this error - // In this case though, we've already checked the local error before returning norepl, so - // the user has been written and we're happy - if (le.err == "norepl" || le.err == "noreplset") { - // nothing we can do - return; - } - - if (le.err == "timeout") { - throw Error( "timed out while waiting for user authentication to replicate - " + - "database will not be fully secured until replication finishes" ) - } - - if (le.err.startsWith("E11000 duplicate key error")) { - throw Error("User already exists with that username/userSource combination"); - } - - throw Error( "couldn't add user: " + le.err ); -} - -/** - * Helper method to convert "replicatedTo" and "timeout" fields into a writeConcern object - */ -DB.prototype._getWriteConcern = function(replicatedTo, timeout) { - return { w: replicatedTo != null ? replicatedTo : _defaultWriteConcern.w, - wtimeout: timeout || _defaultWriteConcern.wtimeout }; -} - -DB.prototype._addUser = function(userObj, replicatedTo, timeout) { - if (typeof replicatedTo == "object") { - throw Error("Cannot provide write concern object to addUser shell helper, " + - "use createUser instead"); - } - var commandExisted = this._createUser(userObj, this._getWriteConcern(replicatedTo, timeout)); - if (!commandExisted) { - this._addUserWithInsert(userObj, replicatedTo, timeout); - } -} - DB.prototype._modifyCommandToDigestPasswordIfNecessary = function(cmdObj, username) { if (!cmdObj["pwd"]) { return; @@ -1006,9 +914,7 @@ DB.prototype._modifyCommandToDigestPasswordIfNecessary = function(cmdObj, userna delete cmdObj["passwordDigestor"]; } -// Returns true if it worked, false if the createUser command wasn't found, and throws on all other -// failures -DB.prototype._createUser = function(userObj, writeConcern) { +DB.prototype.createUser = function(userObj, writeConcern) { var name = userObj["user"]; var cmdObj = {createUser:name}; cmdObj = Object.extend(cmdObj, userObj); @@ -1022,11 +928,12 @@ DB.prototype._createUser = function(userObj, writeConcern) { if (res.ok) { print("Successfully added user: " + getUserObjString(userObj)); - return true; + return; } if (res.errmsg == "no such cmd: createUser") { - return false; + throw Error("'createUser' command not found. This is most likely because you are " + + "talking to an old (pre v2.6) MongoDB server"); } if (res.errmsg == "timeout") { @@ -1045,60 +952,6 @@ function _hashPassword(username, password) { return hex_md5(username + ":mongo:" + password); } -// We need to continue to support the addUser(username, password, readOnly) form of addUser for at -// least one release, even though its behavior of creating a super-user by default is bad. -// TODO(spencer): remove this form from v2.8 -DB.prototype._addUserDeprecatedV22Version = function(username, pass, readOnly, replicatedTo, timeout) { - if ( pass == null || pass.length == 0 ) - throw Error("password can't be empty"); - - var userObjForCommand = { user: username, pwd: pass }; - if (this.getName() == "admin") { - if (readOnly) { - userObjForCommand["roles"] = ['readAnyDatabase']; - } else { - userObjForCommand["roles"] = ['root']; - } - } else { - if (readOnly) { - userObjForCommand["roles"] = ['read']; - } else { - userObjForCommand["roles"] = ['dbOwner']; - } - } - - var commandExisted = this._createUser(userObjForCommand, - this._getWriteConcern(replicatedTo, timeout)); - if (!commandExisted) { - var userObjForInsert = { user: username, pwd: pass, readOnly: readOnly || false }; - this._addUserWithInsert(userObjForInsert, replicatedTo, timeout); - } -} - -/** - * TODO(spencer): Remove this from 2.8, in favor of "createUser" - */ -DB.prototype.addUser = function() { - print("WARNING: The 'addUser' shell helper is DEPRECATED. Please use 'createUser' instead"); - - if (arguments.length == 0) { - throw Error("No arguments provided to addUser"); - } - - if (typeof arguments[0] == "object") { - this._addUser.apply(this, arguments); - } else { - this._addUserDeprecatedV22Version.apply(this, arguments); - } -} - -DB.prototype.createUser = function(userObj, writeConcern) { - var commandExisted = this._createUser(userObj, writeConcern); - if (!commandExisted) { - throw Error("'createUser' command not found. This is most likely because you are " + - "talking to an old (pre v2.6) MongoDB server"); - } -} /** * Used for updating users in systems with V1 style user information * (ie MongoDB v2.4 and prior) diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp index 2d1158ab263..d493ca7a351 100644 --- a/src/mongo/shell/dbshell.cpp +++ b/src/mongo/shell/dbshell.cpp @@ -142,11 +142,12 @@ void shellHistoryAdd( const char * line ) { return; lastLine = line; - // We don't want any .auth() or .addUser() shell helpers added, but we want to + // We don't want any .auth() or .createUser() shell helpers added, but we want to // be able to add things like `.author`, so be smart about how this is - // detected by using regular expresions. + // detected by using regular expresions. This is so we can avoid storing passwords + // in the history file in plaintext. static pcrecpp::RE hiddenHelpers( - "\\.\\s*(auth|addUser|createUser|updateUser|changeUserPassword)\\s*\\("); + "\\.\\s*(auth|createUser|updateUser|changeUserPassword)\\s*\\("); // Also don't want the raw user management commands to show in the shell when run directly // via runCommand. static pcrecpp::RE hiddenCommands( |