bool CmdAuthenticate::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { log() << " authenticate db: " << dbname << " " << cmdObj << endl; string user = cmdObj.getStringField("user"); string key = cmdObj.getStringField("key"); string received_nonce = cmdObj.getStringField("nonce"); if( user.empty() || key.empty() || received_nonce.empty() ) { log() << "field missing/wrong type in received authenticate command " << dbname << endl; errmsg = "auth fails"; sleepmillis(10); return false; } stringstream digestBuilder; { bool reject = false; ClientBasic *client = ClientBasic::getCurrent(); AuthenticationSession *session = client->getAuthenticationSession(); if (!session || session->getType() != AuthenticationSession::SESSION_TYPE_MONGO) { reject = true; LOG(1) << "auth: No pending nonce" << endl; } else { nonce64 nonce = static_cast<MongoAuthenticationSession*>(session)->getNonce(); digestBuilder << hex << nonce; reject = digestBuilder.str() != received_nonce; if ( reject ) { LOG(1) << "auth: Authentication failed for " << dbname << '$' << user << endl; } } client->resetAuthenticationSession(NULL); if ( reject ) { log() << "auth: bad nonce received or getnonce not called. could be a driver bug or a security attack. db:" << dbname << endl; errmsg = "auth fails"; sleepmillis(30); return false; } } BSONObj userObj; string pwd; if (!getUserObj(dbname, user, userObj, pwd)) { errmsg = "auth fails"; return false; } md5digest d; { digestBuilder << user << pwd; string done = digestBuilder.str(); md5_state_t st; md5_init(&st); md5_append(&st, (const md5_byte_t *) done.c_str(), done.size()); md5_finish(&st, d); } string computed = digestToString( d ); if ( key != computed ) { log() << "auth: key mismatch " << user << ", ns:" << dbname << endl; errmsg = "auth fails"; return false; } bool readOnly = userObj["readOnly"].trueValue(); authenticate(dbname, user, readOnly ); result.append( "dbname" , dbname ); result.append( "user" , user ); result.appendBool( "readOnly" , readOnly ); return true; }
bool CmdAuthenticate::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { if (!_areNonceAuthenticateCommandsEnabled) { errmsg = _nonceAuthenticateCommandsDisabledMessage; return false; } log() << " authenticate db: " << dbname << " " << cmdObj << endl; string user = cmdObj.getStringField("user"); string key = cmdObj.getStringField("key"); string received_nonce = cmdObj.getStringField("nonce"); if( user.empty() || key.empty() || received_nonce.empty() ) { log() << "field missing/wrong type in received authenticate command " << dbname << endl; errmsg = "auth fails"; sleepmillis(10); return false; } stringstream digestBuilder; { bool reject = false; ClientBasic *client = ClientBasic::getCurrent(); AuthenticationSession *session = client->getAuthenticationSession(); if (!session || session->getType() != AuthenticationSession::SESSION_TYPE_MONGO) { reject = true; LOG(1) << "auth: No pending nonce" << endl; } else { nonce64 nonce = static_cast<MongoAuthenticationSession*>(session)->getNonce(); digestBuilder << hex << nonce; reject = digestBuilder.str() != received_nonce; if ( reject ) { LOG(1) << "auth: Authentication failed for " << dbname << '$' << user << endl; } } client->resetAuthenticationSession(NULL); if ( reject ) { log() << "auth: bad nonce received or getnonce not called. could be a driver bug or a security attack. db:" << dbname << endl; errmsg = "auth fails"; sleepmillis(30); return false; } } BSONObj userObj; string pwd; Status status = ClientBasic::getCurrent()->getAuthorizationManager()->getPrivilegeDocument( dbname, user, &userObj); if (!status.isOK()) { log() << status.reason() << std::endl; errmsg = status.reason(); return false; } pwd = userObj["pwd"].String(); md5digest d; { digestBuilder << user << pwd; string done = digestBuilder.str(); md5_state_t st; md5_init(&st); md5_append(&st, (const md5_byte_t *) done.c_str(), done.size()); md5_finish(&st, d); } string computed = digestToString( d ); if ( key != computed ) { log() << "auth: key mismatch " << user << ", ns:" << dbname << endl; errmsg = "auth fails"; return false; } status = authenticateAndAuthorizePrincipal(user, dbname, userObj); uassert(16500, mongoutils::str::stream() << "Problem acquiring privileges for principal \"" << user << "\": " << status.reason(), status == Status::OK()); bool readOnly = userObj["readOnly"].trueValue(); // TODO: remove this once all auth checking goes through AuthorizationManager instead of // AuthenticationInfo authenticate(dbname, user, readOnly ); result.append( "dbname" , dbname ); result.append( "user" , user ); result.appendBool( "readOnly" , readOnly ); return true; }
bool CmdAuthenticate::authenticateCR(const string& dbname, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result) { string user = cmdObj.getStringField("user"); if (!_areNonceAuthenticateCommandsEnabled) { // SERVER-8461, MONGODB-CR must be enabled for authenticating the internal user, so that // cluster members may communicate with each other. if (dbname != StringData("local", StringData::LiteralTag()) || user != internalSecurity.user) { errmsg = _nonceAuthenticateCommandsDisabledMessage; result.append(saslCommandCodeFieldName, ErrorCodes::AuthenticationFailed); return false; } } string key = cmdObj.getStringField("key"); string received_nonce = cmdObj.getStringField("nonce"); if( user.empty() || key.empty() || received_nonce.empty() ) { log() << "field missing/wrong type in received authenticate command " << dbname << endl; errmsg = "auth fails"; sleepmillis(10); result.append(saslCommandCodeFieldName, ErrorCodes::AuthenticationFailed); return false; } stringstream digestBuilder; { bool reject = false; ClientBasic *client = ClientBasic::getCurrent(); AuthenticationSession *session = client->getAuthenticationSession(); if (!session || session->getType() != AuthenticationSession::SESSION_TYPE_MONGO) { reject = true; LOG(1) << "auth: No pending nonce" << endl; } else { nonce64 nonce = static_cast<MongoAuthenticationSession*>(session)->getNonce(); digestBuilder << hex << nonce; reject = digestBuilder.str() != received_nonce; if ( reject ) { LOG(1) << "auth: Authentication failed for " << dbname << '$' << user << endl; } } client->resetAuthenticationSession(NULL); if ( reject ) { log() << "auth: bad nonce received or getnonce not called. could be a driver bug or a security attack. db:" << dbname << endl; errmsg = "auth fails"; sleepmillis(30); result.append(saslCommandCodeFieldName, ErrorCodes::AuthenticationFailed); return false; } } BSONObj userObj; string pwd; Status status = getGlobalAuthorizationManager()->getPrivilegeDocument( dbname, UserName(user, dbname), &userObj); if (!status.isOK()) { log() << status.reason() << std::endl; errmsg = "auth fails"; result.append(saslCommandCodeFieldName, ErrorCodes::AuthenticationFailed); return false; } pwd = userObj["pwd"].String(); md5digest d; { digestBuilder << user << pwd; string done = digestBuilder.str(); md5_state_t st; md5_init(&st); md5_append(&st, (const md5_byte_t *) done.c_str(), done.size()); md5_finish(&st, d); } string computed = digestToString( d ); if ( key != computed ) { log() << "auth: key mismatch " << user << ", ns:" << dbname << endl; errmsg = "auth fails"; result.append(saslCommandCodeFieldName, ErrorCodes::AuthenticationFailed); return false; } AuthorizationSession* authorizationSession = ClientBasic::getCurrent()->getAuthorizationSession(); Principal* principal = new Principal(UserName(user, dbname)); principal->setImplicitPrivilegeAcquisition(true); authorizationSession->addAuthorizedPrincipal(principal); result.append( "dbname" , dbname ); result.append( "user" , user ); return true; }