Status AuthzManagerExternalStateMongod::_getUserDocument( OperationContext* txn, const UserName& userName, BSONObj* userDoc) { Client::ReadContext ctx(txn, "admin"); int authzVersion; Status status = getStoredAuthorizationVersion(txn, &authzVersion); if (!status.isOK()) return status; switch (authzVersion) { case AuthorizationManager::schemaVersion26Upgrade: case AuthorizationManager::schemaVersion26Final: break; default: return Status(ErrorCodes::AuthSchemaIncompatible, mongoutils::str::stream() << "Unsupported schema version for getUserDescription(): " << authzVersion); } status = findOne( txn, (authzVersion == AuthorizationManager::schemaVersion26Final ? AuthorizationManager::usersCollectionNamespace : AuthorizationManager::usersAltCollectionNamespace), BSON(AuthorizationManager::USER_NAME_FIELD_NAME << userName.getUser() << AuthorizationManager::USER_DB_FIELD_NAME << userName.getDB()), userDoc); if (status == ErrorCodes::NoMatchingDocument) { status = Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "Could not find user " << userName.getFullName()); } return status; }
/* fetch a single object from collection ns that matches query set your db SavedContext first */ bool Helpers::findOne(const char *ns, const BSONObj &query, BSONObj& result, bool requireIndex) { DiskLoc loc = findOne( ns, query, requireIndex ); if ( loc.isNull() ) return false; result = loc.obj(); return true; }
void run() { const int expected = 100; drop(); addInserts(100); applyOplog(); ASSERT_EQUALS(expected, static_cast<int>(client()->count(ns()))); drop(); addVersionedInserts(100); applyOplog(); ASSERT_EQUALS(expected, static_cast<int>(client()->count(ns()))); drop(); addUpdates(); applyOplog(); BSONObj obj = findOne(); ASSERT_EQUALS(1334813340, obj["requests"]["1000001_2"]["timestamp"].number()); ASSERT_EQUALS(1334813368, obj["requests"]["1000002_2"]["timestamp"].number()); ASSERT_EQUALS(1334810820, obj["requests"]["100002_1"]["timestamp"].number()); drop(); }
void run() { const int expected = 100; drop(); addInserts(100); applyOplog(); ASSERT_EQUALS(expected, static_cast<int>(client()->count(ns()))); drop(); addVersionedInserts(100); applyOplog(); ASSERT_EQUALS(expected, static_cast<int>(client()->count(ns()))); drop(); addUpdates(); applyOplog(); BSONObj obj = findOne(); ASSERT_EQUALS(1334813340, obj["requests"]["1000001_2"]["timestamp"].number()); ASSERT_EQUALS(1334813368, obj["requests"]["1000002_2"]["timestamp"].number()); ASSERT_EQUALS(1334810820, obj["requests"]["100002_1"]["timestamp"].number()); drop(); // test converting updates to upserts but only for version 2.2.1 and greater, // which means oplog version 2 and greater. addConflictingUpdates(); applyOplog(); drop(); }
Status AuthzManagerExternalState::getPrivilegeDocumentV1(const StringData& dbname, const UserName& userName, BSONObj* result) { if (userName == internalSecurity.user->getName()) { return Status(ErrorCodes::InternalError, "Requested privilege document for the internal user"); } if (!NamespaceString::validDBName(dbname)) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << "Bad database name \"" << dbname << "\""); } const bool isUserFromTargetDB = (dbname == userName.getDB()); // Build the query needed to get the privilege document BSONObjBuilder queryBuilder; const NamespaceString usersNamespace(dbname, "system.users"); queryBuilder.append(AuthorizationManager::V1_USER_NAME_FIELD_NAME, userName.getUser()); if (isUserFromTargetDB) { queryBuilder.appendNull(AuthorizationManager::V1_USER_SOURCE_FIELD_NAME); } else { queryBuilder.append(AuthorizationManager::V1_USER_SOURCE_FIELD_NAME, userName.getDB()); } // Query for the privilege document BSONObj userBSONObj; Status found = findOne(usersNamespace, queryBuilder.done(), &userBSONObj); if (!found.isOK()) { if (found.code() == ErrorCodes::NoMatchingDocument) { // Return more detailed status that includes user name. return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "auth: couldn't find user " << userName.toString() << ", " << usersNamespace.ns(), 0); } else { return found; } } if (isUserFromTargetDB) { if (userBSONObj[AuthorizationManager::PASSWORD_FIELD_NAME].eoo()) { return Status(ErrorCodes::AuthSchemaIncompatible, mongoutils::str::stream() << "User documents with schema version " << AuthorizationManager::schemaVersion24 << " must have a \"" << AuthorizationManager::PASSWORD_FIELD_NAME << "\" field."); } } *result = userBSONObj.getOwned(); return Status::OK(); }
/* fetch a single object from collection ns that matches query set your db SavedContext first */ bool Helpers::findOne(Collection* collection, const BSONObj &query, BSONObj& result, bool requireIndex) { DiskLoc loc = findOne( collection, query, requireIndex ); if ( loc.isNull() ) return false; result = collection->docFor(loc); return true; }
Status AuthzManagerExternalStateMock::_findUser( const std::string& usersNamespace, const BSONObj& query, BSONObj* result) { if (!findOne(NamespaceString(usersNamespace), query, result).isOK()) { return Status(ErrorCodes::UserNotFound, "No matching user for query " + query.toString()); } return Status::OK(); }
/* fetch a single object from collection ns that matches query set your db SavedContext first */ RecordId Helpers::findOne(OperationContext* opCtx, Collection* collection, const BSONObj& query, bool requireIndex) { if (!collection) return RecordId(); auto qr = stdx::make_unique<QueryRequest>(collection->ns()); qr->setFilter(query); return findOne(opCtx, collection, std::move(qr), requireIndex); }
/* fetch a single object from collection ns that matches query set your db SavedContext first */ bool Helpers::findOne(OperationContext* txn, Collection* collection, const BSONObj &query, BSONObj& result, bool requireIndex) { RecordId loc = findOne( txn, collection, query, requireIndex ); if ( loc.isNull() ) return false; result = collection->docFor(txn, loc).value(); return true; }
QVariantMap TMongoQuery::findById(const QString &id, const QStringList &fields) { QVariantMap criteria; if (id.isEmpty()) { tSystemError("TMongoQuery::findById : ObjectId not found"); return QVariantMap(); } criteria[ObjectIdKey] = id; return findOne(criteria, fields); }
bool AuthzManagerExternalState::hasAnyPrivilegeDocuments() { BSONObj userBSONObj; Status status = findOne( AuthorizationManager::usersCollectionNamespace, BSONObj(), &userBSONObj); // If the status is NoMatchingDocument, there are no privilege documents. // If it's OK, there are. Otherwise, we were unable to complete the query, // so best to assume that there _are_ privilege documents. This might happen // if the node contaning the users collection becomes transiently unavailable. // See SERVER-12616, for example. return status != ErrorCodes::NoMatchingDocument; }
void run() { OpTime o(getNextGlobalOptime()); BSONObjBuilder b; b.appendTimestamp("ts", o.asLL()); b.append("op", "u"); b.append("o", BSON("$set" << BSON("x" << 456))); b.append("o2", BSON("_id" << 123)); b.append("ns", ns()); BSONObj obj = b.obj(); SyncTest2 sync2; std::vector<BSONObj> ops; ops.push_back(obj); sync2.insertOnRetry = true; // succeeds multiInitialSyncApply(ops, &sync2); BSONObj fin = findOne(); verify(fin["x"].Number() == 456); drop(); }
void run() { writelock lk(""); OpTime o1 = OpTime::now(); OpTime o2 = OpTime::now(); BSONObjBuilder b; b.appendTimestamp("ts", o2.asLL()); b.append("op", "u"); b.append("o", BSON("$set" << BSON("x" << 456))); b.append("o2", BSON("_id" << 123)); b.append("ns", ns()); BSONObj obj = b.obj(); SyncTest2 sync; ASSERT_THROWS(sync.applyOp(obj, o1), UserException); sync.insertOnRetry = true; // succeeds sync.applyOp(obj, o1); BSONObj fin = findOne(); assert(fin["x"].Number() == 456); }
Status AuthzManagerExternalStateLocal::getStoredAuthorizationVersion(int* outVersion) { BSONObj versionDoc; Status status = findOne(AuthorizationManager::versionCollectionNamespace, AuthorizationManager::versionDocumentQuery, &versionDoc); if (status.isOK()) { BSONElement versionElement = versionDoc[AuthorizationManager::schemaVersionFieldName]; if (versionElement.isNumber()) { *outVersion = versionElement.numberInt(); return Status::OK(); } else if (versionElement.eoo()) { return Status(ErrorCodes::NoSuchKey, mongoutils::str::stream() << "No " << AuthorizationManager::schemaVersionFieldName << " field in version document."); } else { return Status(ErrorCodes::TypeMismatch, mongoutils::str::stream() << "Bad (non-numeric) type " << versionElement.type() << "for " << AuthorizationManager::schemaVersionFieldName << " field in version document"); } } else if (status == ErrorCodes::NoMatchingDocument) { if (hasAnyPrivilegeDocuments()) { *outVersion = AuthorizationManager::schemaVersion24; } else { *outVersion = AuthorizationManager::schemaVersion26Final; } return Status::OK(); } else { return status; } }
void OplogReader::connectToSyncSource(OperationContext* txn, const OpTime& lastOpTimeFetched, const OpTime& requiredOpTime, ReplicationCoordinator* replCoord) { const Timestamp sentinelTimestamp(duration_cast<Seconds>(Date_t::now().toDurationSinceEpoch()), 0); const OpTime sentinel(sentinelTimestamp, std::numeric_limits<long long>::max()); OpTime oldestOpTimeSeen = sentinel; invariant(conn() == NULL); while (true) { HostAndPort candidate = replCoord->chooseNewSyncSource(lastOpTimeFetched); if (candidate.empty()) { if (oldestOpTimeSeen == sentinel) { // If, in this invocation of connectToSyncSource(), we did not successfully // connect to any node ahead of us, // we apparently have no sync sources to connect to. // This situation is common; e.g. if there are no writes to the primary at // the moment. return; } // Connected to at least one member, but in all cases we were too stale to use them // as a sync source. error() << "too stale to catch up -- entering maintenance mode"; log() << "our last optime : " << lastOpTimeFetched; log() << "oldest available is " << oldestOpTimeSeen; log() << "See http://dochub.mongodb.org/core/resyncingaverystalereplicasetmember"; auto status = replCoord->setMaintenanceMode(true); if (!status.isOK()) { warning() << "Failed to transition into maintenance mode: " << status; } bool worked = replCoord->setFollowerMode(MemberState::RS_RECOVERING); if (!worked) { warning() << "Failed to transition into " << MemberState(MemberState::RS_RECOVERING) << ". Current state: " << replCoord->getMemberState(); } return; } if (!connect(candidate)) { LOG(2) << "can't connect to " << candidate.toString() << " to read operations"; resetConnection(); replCoord->blacklistSyncSource(candidate, Date_t::now() + Seconds(10)); continue; } // Read the first (oldest) op and confirm that it's not newer than our last // fetched op. Otherwise, we have fallen off the back of that source's oplog. BSONObj remoteOldestOp(findOne(rsOplogName.c_str(), Query())); OpTime remoteOldOpTime = fassertStatusOK(28776, OpTime::parseFromOplogEntry(remoteOldestOp)); // remoteOldOpTime may come from a very old config, so we cannot compare their terms. if (!lastOpTimeFetched.isNull() && lastOpTimeFetched.getTimestamp() < remoteOldOpTime.getTimestamp()) { // We're too stale to use this sync source. resetConnection(); replCoord->blacklistSyncSource(candidate, Date_t::now() + Minutes(1)); if (oldestOpTimeSeen.getTimestamp() > remoteOldOpTime.getTimestamp()) { warning() << "we are too stale to use " << candidate.toString() << " as a sync source"; oldestOpTimeSeen = remoteOldOpTime; } continue; } // Check if sync source contains required optime. if (!requiredOpTime.isNull()) { // This query is structured so that it is executed on the sync source using the oplog // start hack (oplogReplay=true and $gt/$gte predicate over "ts"). auto ts = requiredOpTime.getTimestamp(); tailingQuery(rsOplogName.c_str(), BSON("ts" << BSON("$gte" << ts << "$lte" << ts))); auto status = _compareRequiredOpTimeWithQueryResponse(requiredOpTime); if (!status.isOK()) { const auto blacklistDuration = Seconds(60); const auto until = Date_t::now() + blacklistDuration; warning() << "We cannot use " << candidate.toString() << " as a sync source because it does not contain the necessary " "operations for us to reach a consistent state: " << status << " last fetched optime: " << lastOpTimeFetched << ". required optime: " << requiredOpTime << ". Blacklisting this sync source for " << blacklistDuration << " until: " << until; resetConnection(); replCoord->blacklistSyncSource(candidate, until); continue; } resetCursor(); } // TODO: If we were too stale (recovering with maintenance mode on), then turn it off, to // allow becoming secondary/etc. // Got a valid sync source. return; } // while (true) }
void OplogReader::connectToSyncSource(OperationContext* txn, const OpTime& lastOpTimeFetched, ReplicationCoordinator* replCoord) { const Timestamp sentinelTimestamp(duration_cast<Seconds>(Milliseconds(curTimeMillis64())), 0); const OpTime sentinel(sentinelTimestamp, std::numeric_limits<long long>::max()); OpTime oldestOpTimeSeen = sentinel; invariant(conn() == NULL); while (true) { HostAndPort candidate = replCoord->chooseNewSyncSource(lastOpTimeFetched.getTimestamp()); if (candidate.empty()) { if (oldestOpTimeSeen == sentinel) { // If, in this invocation of connectToSyncSource(), we did not successfully // connect to any node ahead of us, // we apparently have no sync sources to connect to. // This situation is common; e.g. if there are no writes to the primary at // the moment. return; } // Connected to at least one member, but in all cases we were too stale to use them // as a sync source. error() << "too stale to catch up"; log() << "our last optime : " << lastOpTimeFetched; log() << "oldest available is " << oldestOpTimeSeen; log() << "See http://dochub.mongodb.org/core/resyncingaverystalereplicasetmember"; setMinValid(txn, oldestOpTimeSeen); bool worked = replCoord->setFollowerMode(MemberState::RS_RECOVERING); if (!worked) { warning() << "Failed to transition into " << MemberState(MemberState::RS_RECOVERING) << ". Current state: " << replCoord->getMemberState(); } return; } if (!connect(candidate)) { LOG(2) << "can't connect to " << candidate.toString() << " to read operations"; resetConnection(); replCoord->blacklistSyncSource(candidate, Date_t::now() + Seconds(10)); continue; } // Read the first (oldest) op and confirm that it's not newer than our last // fetched op. Otherwise, we have fallen off the back of that source's oplog. BSONObj remoteOldestOp(findOne(rsOplogName.c_str(), Query())); OpTime remoteOldOpTime = fassertStatusOK(28776, OpTime::parseFromBSON(remoteOldestOp)); // remoteOldOpTime may come from a very old config, so we cannot compare their terms. if (!lastOpTimeFetched.isNull() && lastOpTimeFetched.getTimestamp() < remoteOldOpTime.getTimestamp()) { // We're too stale to use this sync source. resetConnection(); replCoord->blacklistSyncSource(candidate, Date_t::now() + Minutes(1)); if (oldestOpTimeSeen.getTimestamp() > remoteOldOpTime.getTimestamp()) { warning() << "we are too stale to use " << candidate.toString() << " as a sync source"; oldestOpTimeSeen = remoteOldOpTime; } continue; } // Got a valid sync source. return; } // while (true) }
inline bool DBClientWithCommands::runCommand(const string &dbname, const BSONObj& cmd, BSONObj &info) { string ns = dbname + ".$cmd"; info = findOne(ns, cmd); return isOk(info); }
void OplogReader::connectToSyncSource(OperationContext* txn, OpTime lastOpTimeFetched, ReplicationCoordinator* replCoord) { const OpTime sentinel(Milliseconds(curTimeMillis64()).total_seconds(), 0); OpTime oldestOpTimeSeen = sentinel; invariant(conn() == NULL); while (true) { HostAndPort candidate = replCoord->chooseNewSyncSource(lastOpTimeFetched); if (candidate.empty()) { if (oldestOpTimeSeen == sentinel) { // If, in this invocation of connectToSyncSource(), we did not successfully // connect to any node ahead of us, // we apparently have no sync sources to connect to. // This situation is common; e.g. if there are no writes to the primary at // the moment. return; } // Connected to at least one member, but in all cases we were too stale to use them // as a sync source. log() << "replSet error RS102 too stale to catch up"; log() << "replSet our last optime : " << lastOpTimeFetched.toStringLong(); log() << "replSet oldest available is " << oldestOpTimeSeen.toStringLong(); log() << "replSet " "See http://dochub.mongodb.org/core/resyncingaverystalereplicasetmember"; setMinValid(txn, oldestOpTimeSeen); bool worked = replCoord->setFollowerMode(MemberState::RS_RECOVERING); if (!worked) { warning() << "Failed to transition into " << MemberState(MemberState::RS_RECOVERING) << ". Current state: " << replCoord->getMemberState(); } return; } if (!connect(candidate)) { LOG(2) << "replSet can't connect to " << candidate.toString() << " to read operations"; resetConnection(); replCoord->blacklistSyncSource(candidate, Date_t(curTimeMillis64() + 10 * 1000)); continue; } // Read the first (oldest) op and confirm that it's not newer than our last // fetched op. Otherwise, we have fallen off the back of that source's oplog. BSONObj remoteOldestOp(findOne(rsoplog, Query())); BSONElement tsElem(remoteOldestOp["ts"]); if (tsElem.type() != Timestamp) { // This member's got a bad op in its oplog. warning() << "oplog invalid format on node " << candidate.toString(); resetConnection(); replCoord->blacklistSyncSource(candidate, Date_t(curTimeMillis64() + 600 * 1000)); continue; } OpTime remoteOldOpTime = tsElem._opTime(); if (!lastOpTimeFetched.isNull() && lastOpTimeFetched < remoteOldOpTime) { // We're too stale to use this sync source. resetConnection(); replCoord->blacklistSyncSource(candidate, Date_t(curTimeMillis64() + 600 * 1000)); if (oldestOpTimeSeen > remoteOldOpTime) { warning() << "we are too stale to use " << candidate.toString() << " as a sync source"; oldestOpTimeSeen = remoteOldOpTime; } continue; } // Got a valid sync source. return; } // while (true) }