// Tests that a client may discover a user's supported SASL mechanisms via hello. // @tags: [requires_sharding] (function() { "use strict"; function runTest(conn) { const db = conn.getDB("admin"); const externalDB = conn.getDB("$external"); function getStatCounter() { const res = assert.commandWorked(db.runCommand({serverStatus: 1})); return res.security.authentication.saslSupportedMechsReceived; } function checkMechs(userid, mechs) { const lastCounterValue = getStatCounter(); const res = assert.commandWorked(db.runCommand({hello: 1, saslSupportedMechs: userid})); const counterValue = getStatCounter(); assert.eq(counterValue, lastCounterValue + 1); assert.eq(mechs.sort(), res.saslSupportedMechs.sort(), tojson(res)); } assert.commandWorked(db.runCommand({ createUser: "userAdmin", pwd: "userAdmin", roles: ["userAdminAnyDatabase", "clusterMonitor"] })); db.auth("userAdmin", "userAdmin"); // Check that unknown users do not interrupt hello let res = assert.commandWorked(db.runCommand({hello: 1, saslSupportedMechs: "test.bogus"})); assert.eq(undefined, res.saslSupportedMechs); // Check that invalid usernames produce the correct error code assert.commandFailedWithCode(db.runCommand({hello: 1, saslSupportedMechs: "bogus"}), ErrorCodes.BadValue); assert.commandWorked(db.runCommand({createUser: "user", pwd: "pwd", roles: []})); assert.commandWorked(externalDB.runCommand({createUser: "user", roles: []})); // Internal users should support scram methods. checkMechs("admin.user", ["SCRAM-SHA-256", "SCRAM-SHA-1"]); // External users on enterprise should support PLAIN, but not scram methods. if (assert.commandWorked(db.runCommand({buildInfo: 1})).modules.includes("enterprise")) { checkMechs("$external.user", ["PLAIN"]); } else { checkMechs("$external.user", []); } // Users with explicit mechs should only support those mechanisms assert.commandWorked(db.runCommand( {createUser: "256Only", pwd: "pwd", roles: [], mechanisms: ["SCRAM-SHA-256"]})); checkMechs("admin.256Only", ["SCRAM-SHA-256"]); assert.commandWorked( db.runCommand({createUser: "1Only", pwd: "pwd", roles: [], mechanisms: ["SCRAM-SHA-1"]})); checkMechs("admin.1Only", ["SCRAM-SHA-1"]); // Users with normalized and unnormalized names do not conflict assert.commandWorked(db.runCommand({createUser: "IX", pwd: "pwd", roles: []})); checkMechs("admin.IX", ["SCRAM-SHA-1", "SCRAM-SHA-256"]); assert.commandWorked(db.runCommand({createUser: "\u2168", pwd: "pwd", roles: []})); checkMechs("admin.\u2168", ["SCRAM-SHA-1", "SCRAM-SHA-256"]); // __system's mechanisms can be queried on local and admin if the server is in test mode checkMechs("local.__system", ["SCRAM-SHA-1", "SCRAM-SHA-256"]); checkMechs("admin.__system", ["SCRAM-SHA-1", "SCRAM-SHA-256"]); } // Test standalone. var m = MongoRunner.runMongod({ keyFile: 'jstests/libs/key1', setParameter: "authenticationMechanisms=SCRAM-SHA-1,SCRAM-SHA-256,PLAIN" }); runTest(m); MongoRunner.stopMongod(m); // Test mongos. var st = new ShardingTest({ keyFile: 'jstests/libs/key1', shards: 0, other: {mongosOptions: {setParameter: "authenticationMechanisms=PLAIN,SCRAM-SHA-256,SCRAM-SHA-1"}} }); runTest(st.s0); st.stop(); })();