Skip to content

Commit

Permalink
SERVER-6117 SlaveOk Query fails with auth error even after logging in
Browse files Browse the repository at this point in the history
  • Loading branch information
renctan committed Jul 9, 2012
1 parent a056a5d commit 02b30c6
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
51 changes: 51 additions & 0 deletions jstests/sharding/auth_repl.js
@@ -0,0 +1,51 @@
var replTest = new ReplSetTest({ nodes: 3 });
replTest.startSet({ oplogSize: 10, keyFile: 'jstests/libs/key1' });
replTest.initiate();
replTest.awaitSecondaryNodes();

var nodeCount = replTest.nodes.length;
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 testColl = testDB.user;

testColl.insert({ x: 1 });
testDB.runCommand({ getLastError: 1, w: nodeCount });

// Setup the cached connection for primary and secondary in DBClientReplicaSet
// before setting up authentication
var doc = testColl.findOne();
assert(doc != null);

conn.setSlaveOk();

doc = testColl.findOne();
assert(doc != null);

// Add admin user using direct connection to primary to simulate connection from remote host
var adminDB = primary.getDB('admin');
adminDB.addUser('user', 'user', false, nodeCount);
adminDB.auth('user', 'user');

var priTestDB = primary.getDB('test');
priTestDB.addUser('a', 'a', false, nodeCount);

// Authenticate the replSet connection
assert.eq(1, testDB.auth('a', 'a'));

jsTest.log('Sending an authorized query that should be ok');
conn.setSlaveOk(true);
doc = testColl.findOne();
assert(doc != null);

doc = testColl.find().readPref('secondary').next();
assert(doc != null);

conn.setSlaveOk(false);
doc = testColl.findOne();
assert(doc != null);

replTest.stopSet();

17 changes: 16 additions & 1 deletion src/mongo/client/dbclient_rs.cpp
Expand Up @@ -1328,6 +1328,22 @@ namespace mongo {
if( ! m->auth(dbname, username, pwd, errmsg, digestPassword, level ) )
return false;

/* Also authenticate the cached secondary connection. Note that this is only
* needed when we actually have something cached and is last known to be
* working.
*/
if (_lastSlaveOkConn.get() != NULL && !_lastSlaveOkConn->isFailed()) {
try {
_lastSlaveOkConn->auth(dbname, username, pwd, errmsg, digestPassword, level);
}
catch (const DBException& ex) {
/* Swallow exception. _lastSlaveOkConn is now in failed state.
* The next time we create a new secondary connection it will
* be authenticated with the credentials from _auths.
*/
}
}

// now that it does, we should save so that for a new node we can auth
_auths.push_back( AuthInfo( dbname , username , pwd , digestPassword ) );
return true;
Expand Down Expand Up @@ -1472,7 +1488,6 @@ namespace mongo {
DBClientConnection* DBClientReplicaSet::selectNodeUsingTags(ReadPreference preference,
TagSet* tags) {
if (checkLastHost(preference, tags)) {
// TODO: SERVER-5082, slave auth credentials may have changed
return _lastSlaveOkConn.get();
}

Expand Down

0 comments on commit 02b30c6

Please sign in to comment.