Skip to content

Commit eacd9a5

Browse files
committed
[JAVA-269]: NullPointerException when authentication used with replica sets not logged correctly
1 parent ec5948e commit eacd9a5

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

src/main/com/mongodb/DB.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,14 +485,34 @@ private boolean _doauth( String username , byte[] hash ){
485485
* @param passwd
486486
*/
487487
public void addUser( String username , char[] passwd ){
488+
addUser(username, passwd, false);
489+
}
490+
491+
/**
492+
* Adds a new user for this db
493+
* @param username
494+
* @param passwd
495+
* @param readOnly if true, user will only be able to read
496+
*/
497+
public void addUser( String username , char[] passwd, boolean readOnly ){
488498
DBCollection c = getCollection( "system.users" );
489499
DBObject o = c.findOne( new BasicDBObject( "user" , username ) );
490500
if ( o == null )
491501
o = new BasicDBObject( "user" , username );
492502
o.put( "pwd" , _hash( username , passwd ) );
503+
o.put( "readOnly" , readOnly );
493504
c.save( o );
494505
}
495506

507+
/**
508+
* Removes a user for this db
509+
* @param username
510+
*/
511+
public void removeUser( String username ){
512+
DBCollection c = getCollection( "system.users" );
513+
c.remove(new BasicDBObject( "user" , username ));
514+
}
515+
496516
String _hash( String username , char[] passwd ){
497517
ByteArrayOutputStream bout = new ByteArrayOutputStream( username.length() + 20 + passwd.length );
498518
try {

src/main/com/mongodb/DBTCPConnector.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ class DBTCPConnector implements DBConnector {
3232

3333
public DBTCPConnector( Mongo m , ServerAddress addr )
3434
throws MongoException {
35+
_mongo = m;
3536
_portHolder = new DBPortPool.Holder( m._options );
3637
_checkAddress( addr );
3738

3839
_createLogger.info( addr.toString() );
3940

4041
if ( addr.isPaired() ){
4142
_allHosts = new ArrayList<ServerAddress>( addr.explode() );
42-
_rsStatus = new ReplicaSetStatus( _allHosts );
43+
_rsStatus = new ReplicaSetStatus( m, _allHosts );
4344
_createLogger.info( "switching to replica set mode : " + _allHosts + " -> " + _curMaster );
4445
}
4546
else {
@@ -61,7 +62,7 @@ public DBTCPConnector( Mongo m , List<ServerAddress> all )
6162
_checkAddress( all );
6263

6364
_allHosts = new ArrayList<ServerAddress>( all ); // make a copy so it can't be modified
64-
_rsStatus = new ReplicaSetStatus( _allHosts );
65+
_rsStatus = new ReplicaSetStatus( m, _allHosts );
6566

6667
_createLogger.info( all + " -> " + _curMaster );
6768
}
@@ -396,7 +397,7 @@ void testMaster()
396397
DBPort p = null;
397398
try {
398399
p = _masterPortPool.get();
399-
p.runCommand( "admin" , new BasicDBObject( "nonce" , 1 ) );
400+
p.runCommand( _mongo.getDB("admin") , new BasicDBObject( "nonce" , 1 ) );
400401
}
401402
finally {
402403
_masterPortPool.done( p );
@@ -434,6 +435,7 @@ public boolean isOpen(){
434435
return ! _closed;
435436
}
436437

438+
private Mongo _mongo;
437439
private ServerAddress _curMaster;
438440
private DBPortPool _masterPortPool;
439441
private DBPortPool.Holder _portHolder;

src/main/com/mongodb/ReplicaSetStatus.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
class ReplicaSetStatus {
2121

2222
static final Logger _rootLogger = Logger.getLogger( "com.mongodb.ReplicaSetStatus" );
23-
24-
ReplicaSetStatus( List<ServerAddress> initial ){
25-
23+
static final int UNAUTHENTICATED_ERROR_CODE = 10057;
24+
25+
ReplicaSetStatus( Mongo mongo, List<ServerAddress> initial ){
26+
_mongo = mongo;
2627
_all = Collections.synchronizedList( new ArrayList<Node>() );
2728
for ( ServerAddress addr : initial ){
2829
_all.add( new Node( addr ) );
@@ -120,7 +121,7 @@ synchronized void update(){
120121
synchronized void update(Set<Node> seenNodes){
121122
try {
122123
long start = System.currentTimeMillis();
123-
CommandResult res = _port.runCommand( "admin" , _isMasterCmd );
124+
CommandResult res = _port.runCommand( _mongo.getDB("admin") , _isMasterCmd );
124125
_lastCheck = System.currentTimeMillis();
125126
_pingTime = _lastCheck - start;
126127

@@ -168,13 +169,16 @@ synchronized void update(Set<Node> seenNodes){
168169
return;
169170

170171
try {
171-
DBObject config = _port.findOne( "local.system.replset" , new BasicDBObject() );
172+
DB db = _mongo.getDB("local");
173+
_port.checkAuth(db);
174+
DBObject config = _port.findOne( db, "system.replset" , new BasicDBObject() );
172175
if ( config == null ){
173-
// probbaly a replica pair
176+
// probably a replica pair
174177
// TODO: add this in when pairs are really gone
175178
//_logger.log( Level.SEVERE , "no replset config!" );
176-
}
177-
else {
179+
} else if (config.get("$err") != null && UNAUTHENTICATED_ERROR_CODE == (Integer)config.get("code")) {
180+
_logger.log( Level.WARNING , "Replica Set updater cannot get results, call authenticate on 'local' or 'admin' db");
181+
} else {
178182

179183
String setName = config.get( "_id" ).toString();
180184
if ( _setName == null ){
@@ -361,6 +365,7 @@ void close(){
361365

362366
final List<Node> _all;
363367
Updater _updater;
368+
Mongo _mongo;
364369
String _setName = null; // null until init
365370
Logger _logger = _rootLogger; // will get changed to use set name once its found
366371

@@ -385,7 +390,7 @@ public static void main( String args[] )
385390

386391
Mongo m = new Mongo( addrs );
387392

388-
ReplicaSetStatus status = new ReplicaSetStatus( addrs );
393+
ReplicaSetStatus status = new ReplicaSetStatus( m, addrs );
389394
System.out.println( status.ensureMaster()._addr );
390395

391396
while ( true ){

0 commit comments

Comments
 (0)