void receivedGetMore(DbResponse& dbresponse, /*AbstractMessagingPort& dbMsgPort, */Message& m, stringstream& ss) { DbMessage d(m); const char *ns = d.getns(); ss << ns; setClient(ns); cc().top.setRead(); int ntoreturn = d.pullInt(); long long cursorid = d.pullInt64(); ss << " cid:" << cursorid; ss << " ntoreturn:" << ntoreturn; QueryResult* msgdata; try { AuthenticationInfo *ai = currentClient.get()->ai; uassert("unauthorized", ai->isAuthorized(cc().database()->name.c_str())); msgdata = getMore(ns, ntoreturn, cursorid, ss); } catch ( AssertionException& e ) { ss << " exception " + e.toString(); msgdata = emptyMoreResult(cursorid); } Message *resp = new Message(); resp->setData(msgdata, true); ss << " bytes:" << resp->data->dataLen(); ss << " nreturned:" << msgdata->nReturned; dbresponse.response = resp; dbresponse.responseTo = m.data->id; //dbMsgPort.reply(m, resp); }
void killOp( Message &m, DbResponse &dbresponse ) { BSONObj obj; AuthenticationInfo *ai = currentClient.get()->ai; if( !ai->isAuthorized("admin") ) { obj = fromjson("{\"err\":\"unauthorized\"}"); } else if( !dbMutexInfo.isLocked() ) obj = fromjson("{\"info\":\"no op in progress/not locked\"}"); else { killCurrentOp = 1; obj = fromjson("{\"info\":\"attempting to kill op\"}"); } replyToQuery(0, m, dbresponse, obj); }
bool run(const string& dbname , BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { AuthenticationInfo *ai = cc().getAuthenticationInfo(); uassert( 12598 , "$eval reads unauthorized", ai->isAuthorizedReads(dbname.c_str()) ); if ( cmdObj["nolock"].trueValue() ) { return dbEval(dbname, cmdObj, result, errmsg); } // write security will be enforced in DBDirectClient mongolock lk( ai->isAuthorized( dbname.c_str() ) ); Client::Context ctx( dbname ); return dbEval(dbname, cmdObj, result, errmsg); }
bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { AuthenticationInfo *ai = cc().getAuthenticationInfo(); uassert( 12598 , "$eval reads unauthorized", ai->isAuthorizedReads(dbname.c_str()) ); if ( cmdObj["nolock"].trueValue() ) { return dbEval(dbname, cmdObj, result, errmsg); } // write security will be enforced in DBDirectClient // TODO: should this be a db lock? scoped_ptr<Lock::ScopedLock> lk( ai->isAuthorized( dbname.c_str() ) ? static_cast<Lock::ScopedLock*>( new Lock::GlobalWrite() ) : static_cast<Lock::ScopedLock*>( new Lock::GlobalRead() ) ); Client::Context ctx( dbname ); return dbEval(dbname, cmdObj, result, errmsg); }
void inProgCmd( Message &m, DbResponse &dbresponse ) { BSONObjBuilder b; AuthenticationInfo *ai = cc().ai; if( !ai->isAuthorized("admin") ) { BSONObjBuilder b; b.append("err", "unauthorized"); } else { vector<BSONObj> vals; { boostlock bl(Client::clientsMutex); for( set<Client*>::iterator i = Client::clients.begin(); i != Client::clients.end(); i++ ) { Client *c = *i; CurOp& co = *(c->curop()); if( co.active ) vals.push_back( co.infoNoauth() ); } } b.append("inprog", vals); } replyToQuery(0, m, dbresponse, b.obj()); }
// Returns false when request includes 'end' bool assembleResponse( Message &m, DbResponse &dbresponse, const sockaddr_in &client ) { // before we lock... if ( m.data->operation() == dbQuery ) { const char *ns = m.data->_data + 4; if( strstr(ns, "$cmd.sys.") ) { if( strstr(ns, "$cmd.sys.inprog") ) { inProgCmd(m, dbresponse); return true; } if( strstr(ns, "$cmd.sys.killop") ) { killOp(m, dbresponse); return true; } } } if ( handlePossibleShardedMessage( m , dbresponse ) ){ /* important to do this before we lock so if a message has to be forwarded, doesn't block for that */ return true; } dblock lk; stringstream ss; char buf[64]; time_t now = time(0); CurOp& currentOp = *cc().curop(); currentOp.reset(now, client); time_t_to_String(now, buf); buf[20] = 0; // don't want the year ss << buf; Timer t; Client& c = cc(); c.clearns(); int logThreshold = 100; int ms; bool log = logLevel >= 1; c.curop()->op = m.data->operation(); #if 0 /* use this if you only want to process operations for a particular namespace. maybe add to cmd line parms or something fancier. */ DbMessage ddd(m); if ( strncmp(ddd.getns(), "clusterstock", 12) != 0 ) { static int q; if ( ++q < 20 ) out() << "TEMP skip " << ddd.getns() << endl; goto skip; } #endif if ( m.data->operation() == dbQuery ) { // receivedQuery() does its own authorization processing. receivedQuery(dbresponse, m, ss, true); } else if ( m.data->operation() == dbGetMore ) { // receivedQuery() does its own authorization processing. OPREAD; DEV log = true; ss << "getmore "; receivedGetMore(dbresponse, m, ss); } else if ( m.data->operation() == dbMsg ) { /* deprecated / rarely used. intended for connection diagnostics. */ ss << "msg "; char *p = m.data->_data; int len = strlen(p); if ( len > 400 ) out() << curTimeMillis() % 10000 << " long msg received, len:" << len << " ends with: " << p + len - 10 << endl; bool end = false; //strcmp("end", p) == 0; Message *resp = new Message(); resp->setData(opReply, "i am fine"); dbresponse.response = resp; dbresponse.responseTo = m.data->id; //dbMsgPort.reply(m, resp); if ( end ) return false; } else { const char *ns = m.data->_data + 4; char cl[256]; nsToClient(ns, cl); strncpy(currentOp.ns, ns, Namespace::MaxNsLen); AuthenticationInfo *ai = currentClient.get()->ai; if( !ai->isAuthorized(cl) ) { uassert_nothrow("unauthorized"); } else if ( m.data->operation() == dbInsert ) { OPWRITE; try { ss << "insert "; receivedInsert(m, ss); } catch ( AssertionException& e ) { LOGSOME problem() << " Caught Assertion insert, continuing\n"; ss << " exception " + e.toString(); } } else if ( m.data->operation() == dbUpdate ) { OPWRITE; try { ss << "update "; receivedUpdate(m, ss); } catch ( AssertionException& e ) { LOGSOME problem() << " Caught Assertion update, continuing" << endl; ss << " exception " + e.toString(); } } else if ( m.data->operation() == dbDelete ) { OPWRITE; try { ss << "remove "; receivedDelete(m, ss); } catch ( AssertionException& e ) { LOGSOME problem() << " Caught Assertion receivedDelete, continuing" << endl; ss << " exception " + e.toString(); } } else if ( m.data->operation() == dbKillCursors ) { OPREAD; try { logThreshold = 10; ss << "killcursors "; receivedKillCursors(m); } catch ( AssertionException& e ) { problem() << " Caught Assertion in kill cursors, continuing" << endl; ss << " exception " + e.toString(); } } else { out() << " operation isn't supported: " << m.data->operation() << endl; currentOp.active = false; assert(false); } } ms = t.millis(); log = log || (logLevel >= 2 && ++ctr % 512 == 0); DEV log = true; if ( log || ms > logThreshold ) { ss << ' ' << t.millis() << "ms"; out() << ss.str().c_str() << endl; } Database *database = cc().database(); if ( database && database->profile >= 1 ) { if ( database->profile >= 2 || ms >= 100 ) { // profile it profile(ss.str().c_str()+20/*skip ts*/, ms); } } currentOp.active = false; return true; }