예제 #1
0
파일: instance.cpp 프로젝트: fizx/mongo
 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);
 }
예제 #2
0
 bool CmdLogout::run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
     AuthenticationInfo *ai = ClientInfo::get()->getAuthenticationInfo();
     AuthorizationManager* authManager = ClientInfo::get()->getAuthorizationManager();
     ai->logout(dbname);
     authManager->logoutDatabase(dbname);
     return true;
 }
예제 #3
0
 bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
     // database->name is the one we are logging out...
     AuthenticationInfo *ai = authInfo.get();
     assert( ai ); 
     ai->logout(database->name.c_str());
     return true;
 }
예제 #4
0
파일: security.cpp 프로젝트: DumaGit/mongo
    void CmdAuthenticate::authenticate(const string& dbname, const string& user, const bool readOnly) {
        AuthenticationInfo *ai = ClientInfo::get()->getAuthenticationInfo();

        if ( readOnly ) {
            ai->authorizeReadOnly( dbname , user );
        }
        else {
            ai->authorize( dbname , user );
        }
    }
예제 #5
0
    void CmdAuthenticate::authenticate(const string& dbname, const string& user, const bool readOnly) {
        ClientBasic* c = ClientBasic::getCurrent();
        assert(c);
        AuthenticationInfo *ai = c->getAuthenticationInfo();

        if ( readOnly ) {
            ai->authorizeReadOnly( dbname , user );
        }
        else {
            ai->authorize( dbname , user );
        }
    }
예제 #6
0
파일: instance.cpp 프로젝트: fizx/mongo
 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);
 }
예제 #7
0
파일: dbeval.cpp 프로젝트: BendustiK/mongo
        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);
        }
예제 #8
0
파일: dbeval.cpp 프로젝트: JeremyOT/mongo
        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);
        }
예제 #9
0
파일: instance.cpp 프로젝트: fizx/mongo
    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());
    }
예제 #10
0
파일: instance.cpp 프로젝트: fizx/mongo
    // 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;
    }
예제 #11
0
 bool run(const string& dbname , BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
     AuthenticationInfo *ai = cc().getAuthenticationInfo();
     ai->logout(dbname);
     return true;
 }
예제 #12
0
        bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            log(1) << " authenticate: " << 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 " << database->name << '\n';                log() << "field missing/wrong type in received authenticate command " << database->name << '\n';
                errmsg = "auth fails";
                sleepmillis(10);
                return false;
            }
            
            stringstream digestBuilder;

            {
                nonce *ln = lastNonce.release();
                digestBuilder << hex << *ln;
                
                if( ln == 0 || digestBuilder.str() != received_nonce ) {
                    log() << "auth: bad nonce received. could be a driver bug or a security attack. db:" << database->name << '\n';                log() << "field missing/wr " << database->name << '\n';
                    errmsg = "auth fails";
                    sleepmillis(30);
                    return false;
                }
            }

            static BSONObj userPattern = fromjson("{\"user\":1}");
            string systemUsers = database->name + ".system.users";
            OCCASIONALLY Helpers::ensureIndex(systemUsers.c_str(), userPattern, "user_1");

            BSONObj userObj;
            {
                BSONObjBuilder b;
                b << "user" << user;
                BSONObj query = b.done();
                if( !Helpers::findOne(systemUsers.c_str(), query, userObj) ) { 
                    log() << "auth: couldn't find user " << user << ", " << systemUsers << '\n';
                    errmsg = "auth fails";
                    return false;
                }
            }
            
            md5digest d;
            {
                
                string pwd = userObj.getStringField("pwd");
                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:" << ns << '\n';
                errmsg = "auth fails";
                return false;
            }

            AuthenticationInfo *ai = authInfo.get();
            assert( ai );
            ai->authorize(database->name.c_str());
            return true;
        }
예제 #13
0
파일: s_only.cpp 프로젝트: LeeShuni/mongo
    void Command::execCommandClientBasic(Command * c ,
                                         ClientBasic& client,
                                         int queryOptions,
                                         const char *ns,
                                         BSONObj& cmdObj,
                                         BSONObjBuilder& result,
                                         bool fromRepl ) {
        verify(c);

        AuthenticationInfo *ai = client.getAuthenticationInfo();

        std::string dbname = nsToDatabase(ns);

        // Access control checks
        if (!noauth) {
            std::vector<Privilege> privileges;
            c->addRequiredPrivileges(dbname, cmdObj, &privileges);
            AuthorizationManager* authManager = client.getAuthorizationManager();
            if (c->requiresAuth() && (!authManager->checkAuthForPrivileges(privileges).isOK()
                            || !ai->isAuthorizedForLock(dbname, c->locktype()))) {
                result.append("note", str::stream() << "not authorized for command: " <<
                                    c->name << " on database " << dbname);
                appendCommandStatus(result, false, "unauthorized");
                return;
            }
        }
        if (c->adminOnly() && c->localHostOnlyIfNoAuth(cmdObj) && noauth && !ai->isLocalHost()) {
            log() << "command denied: " << cmdObj.toString() << endl;
            appendCommandStatus(result,
                               false,
                               "unauthorized: this command must run from localhost when running db "
                               "without auth");
            return;
        }
        if (c->adminOnly() && !startsWith(ns, "admin.")) {
            log() << "command denied: " << cmdObj.toString() << endl;
            appendCommandStatus(result, false, "access denied - use admin db");
            return;
        }
        // End of access control checks

        if (cmdObj.getBoolField("help")) {
            stringstream help;
            help << "help for: " << c->name << " ";
            c->help( help );
            result.append( "help" , help.str() );
            result.append( "lockType" , c->locktype() );
            appendCommandStatus(result, true, "");
            return;
        }
        std::string errmsg;
        bool ok;
        try {
            ok = c->run( dbname , cmdObj, queryOptions, errmsg, result, false );
        }
        catch (DBException& e) {
            ok = false;
            int code = e.getCode();
            if (code == RecvStaleConfigCode) { // code for StaleConfigException
                throw;
            }

            stringstream ss;
            ss << "exception: " << e.what();
            errmsg = ss.str();
            result.append( "code" , code );
        }

        appendCommandStatus(result, ok, errmsg);
    }
예제 #14
0
파일: security.cpp 프로젝트: DumaGit/mongo
 bool CmdLogout::run(const string& dbname , BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
     AuthenticationInfo *ai = ClientInfo::get()->getAuthenticationInfo();
     ai->logout(dbname);
     return true;
 }
예제 #15
0
 bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
     // database->name is the one we are logging out...
     AuthenticationInfo *ai = cc().getAuthenticationInfo();
     ai->logout(nsToDatabase(ns));
     return true;
 }
예제 #16
0
        bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            log(1) << " authenticate: " << 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 " 
                    << cc().database()->name
                    << endl;               
                errmsg = "auth fails";
                sleepmillis(10);
                return false;
            }
            
            stringstream digestBuilder;

            {
                bool reject = false;
                nonce *ln = lastNonce.release();
                if ( ln == 0 ) {
                    reject = true;
                } else {
                    digestBuilder << hex << *ln;
                    reject = digestBuilder.str() != received_nonce;
                }
                    
                if ( reject ) {
                    log() << "auth: bad nonce received or getnonce not called. could be a driver bug or a security attack. db:" << cc().database()->name << endl;
                    errmsg = "auth fails";
                    sleepmillis(30);
                    return false;
                }
            }

            static BSONObj userPattern = fromjson("{\"user\":1}");
            string systemUsers = cc().database()->name + ".system.users";
            OCCASIONALLY Helpers::ensureIndex(systemUsers.c_str(), userPattern, false, "user_1");

            BSONObj userObj;
            {
                BSONObjBuilder b;
                b << "user" << user;
                BSONObj query = b.done();
                if( !Helpers::findOne(systemUsers.c_str(), query, userObj) ) { 
                    log() << "auth: couldn't find user " << user << ", " << systemUsers << endl;
                    errmsg = "auth fails";
                    return false;
                }
            }
            
            md5digest d;
            {
                
                string pwd = userObj.getStringField("pwd");
                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:" << ns << endl;
                errmsg = "auth fails";
                return false;
            }

            AuthenticationInfo *ai = cc().getAuthenticationInfo();
            
            if ( userObj[ "readOnly" ].isBoolean() && userObj[ "readOnly" ].boolean() ) {
                if ( readLockSupported() ){
                    ai->authorizeReadOnly( cc().database()->name.c_str() );
                }
                else {
                    log() << "warning: old version of boost, read-only users not supported" << endl;
                    ai->authorize( cc().database()->name.c_str() );
                }
            } else {
                ai->authorize( cc().database()->name.c_str() );
            }
            return true;
        }
예제 #17
0
//
// Test local authentication
//
void testLocalAuthSuccess()
{
    String authHeader;

    AuthenticationManager  authManager;

    AuthenticationInfo* authInfo = new AuthenticationInfo(true);

    // Test valid header
    authHeader.append(localHeader);
    authHeader.append("\"");
    authHeader.append(testUser);
    authHeader.append("\"");

    String respHeader =
        authManager.getPegasusAuthResponseHeader(authHeader, authInfo);

    if (verbose) cout << "RespHeader: " << respHeader << endl;

    Uint32 startQuote = respHeader.find(0, '"');
    PEGASUS_TEST_ASSERT(startQuote != PEG_NOT_FOUND);

    Uint32 endQuote = respHeader.find(startQuote + 1, '"');
    PEGASUS_TEST_ASSERT(endQuote != PEG_NOT_FOUND);

    String filePath = respHeader.subString(
        startQuote + 1, (endQuote - startQuote - 1));
    PEGASUS_TEST_ASSERT(filePath.size() != 0);

    authHeader.clear();
    authHeader.append(localHeader);
    authHeader.append("\"");
    authHeader.append(testUser);
    authHeader.append(":");
    authHeader.append(filePath);
    authHeader.append(":");
    authHeader.append(authInfo->getLocalAuthSecret());
    authHeader.append("\"");

    if (verbose) cout << "Local Resp AuthHeader: " << authHeader << endl;

    Boolean authenticated;
    // test case looks for success, initialize with failure
    AuthenticationStatus authStatus(AUTHSC_UNAUTHORIZED);


    authStatus = authManager.performPegasusAuthentication(authHeader, authInfo);
    authenticated = authStatus.isSuccess();

    //
    // remove the auth file created for this user request
    //
    if (FileSystem::exists(filePath))
    {
        FileSystem::removeFile(filePath);
    }
    if (verbose)
    {
        cout << "Local Authentication of User " + testUser + " returned with: ";
        cout << authenticated << endl;
    }

    delete authInfo;

    PEGASUS_TEST_ASSERT(authenticated);
}