summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorADAM David Alan Martin <adam.martin@10gen.com>2017-08-30 16:53:25 -0400
committerADAM David Alan Martin <adam.martin@10gen.com>2017-08-30 18:10:54 -0400
commita561f9554d2caea44beb334c9c6e92742981f38d (patch)
tree42c3dcc1d440f4cb15cb92da6351da65850268f6
parentcef9cd4d98e15dd3ed2b94939e45578335c7876f (diff)
downloadmongo-a561f9554d2caea44beb334c9c6e92742981f38d.tar.gz
SERVER-28343 Session checks on GETMORE operations
Make `getMore` operations enforce that the cursor is correctly associated with the current session.
-rw-r--r--jstests/noPassthrough/logical_session_cursor_checks.js47
-rw-r--r--src/mongo/db/auth/authorization_session.cpp57
-rw-r--r--src/mongo/db/auth/authorization_session.h6
-rw-r--r--src/mongo/db/cursor_manager.cpp7
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.cpp9
-rw-r--r--src/mongo/s/query/cluster_cursor_manager_test.cpp58
6 files changed, 154 insertions, 30 deletions
diff --git a/jstests/noPassthrough/logical_session_cursor_checks.js b/jstests/noPassthrough/logical_session_cursor_checks.js
new file mode 100644
index 00000000000..d292e587c61
--- /dev/null
+++ b/jstests/noPassthrough/logical_session_cursor_checks.js
@@ -0,0 +1,47 @@
+(function() {
+ 'use strict';
+
+ var conn = MongoRunner.runMongod({auth: "", nojournal: ""});
+ var admin = conn.getDB("admin");
+ var data = conn.getDB("data_storage");
+
+ admin.createUser({user: 'admin', pwd: 'admin', roles: jsTest.adminUserRoles});
+ admin.auth("admin", "admin");
+ data.createUser({user: 'admin', pwd: 'admin', roles: jsTest.basicUserRoles});
+ data.createUser({user: 'user0', pwd: 'password', roles: jsTest.basicUserRoles});
+ admin.logout();
+
+ data.auth("user0", "password");
+ assert.writeOK(data.test.insert({name: "first", data: 1}));
+ assert.writeOK(data.test.insert({name: "second", data: 2}));
+
+ // Test that getMore works correctly on the same session.
+ {
+ var session1 = conn.startSession();
+ var session2 = conn.startSession();
+ var res = assert.commandWorked(
+ session1.getDatabase("data_storage").runCommand({find: "test", batchSize: 0}));
+ var cursorId = res.cursor.id;
+ assert.commandWorked(session1.getDatabase("data_storage")
+ .runCommand({getMore: cursorId, collection: "test"}));
+
+ session2.endSession();
+ session1.endSession();
+ }
+
+ // Test that getMore correctly gives an error, when using a cursor on a different session.
+ {
+ var session1 = conn.startSession();
+ var session2 = conn.startSession();
+ var res = assert.commandWorked(
+ session1.getDatabase("data_storage").runCommand({find: "test", batchSize: 0}));
+ var cursorId = res.cursor.id;
+ assert.commandFailed(session2.getDatabase("data_storage")
+ .runCommand({getMore: cursorId, collection: "test"}));
+
+ session2.endSession();
+ session1.endSession();
+ }
+
+ MongoRunner.stopMongod(conn);
+})();
diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp
index 409d5de9d8f..c5edacc96f7 100644
--- a/src/mongo/db/auth/authorization_session.cpp
+++ b/src/mongo/db/auth/authorization_session.cpp
@@ -975,3 +975,60 @@ bool AuthorizationSession::isImpersonating() const {
}
} // namespace mongo
+
+auto mongo::checkCursorSessionPrivilege(OperationContext* const opCtx,
+ const boost::optional<LogicalSessionId> cursorSessionId)
+ -> Status {
+ if (!AuthorizationSession::exists(opCtx->getClient())) {
+ return Status::OK();
+ }
+ auto* const authSession = AuthorizationSession::get(opCtx->getClient());
+
+ auto nobodyIsLoggedIn = [authSession] {
+ return !authSession->getAuthenticatedUserNames().more();
+ };
+
+ auto authHasImpersonatePrivilege = [authSession] {
+ return authSession->isAuthorizedForPrivilege(
+ Privilege(ResourcePattern::forClusterResource(), ActionType::impersonate));
+ };
+
+ auto authIsOn = [authSession] {
+ return authSession->getAuthorizationManager().isAuthEnabled();
+ };
+
+ auto sessionIdToStringOrNone =
+ [](const boost::optional<LogicalSessionId>& sessionId) -> std::string {
+ if (sessionId) {
+ return str::stream() << *sessionId;
+ }
+ return "none";
+ };
+
+ // If the cursor has a session then one of the following must be true:
+ // 1: context session id must match cursor session id.
+ // 2: user must be magic special (__system, or background task, etc).
+
+ // We do not check the user's ID against the cursor's notion of a user ID, since higher level
+ // auth checks will check that for us anyhow.
+ if (authIsOn() && // If the authorization is not on, then we permit anybody to do anything.
+ cursorSessionId && // If the cursor is not assigned to a session, it is okay to work with
+ // it from any session.
+ cursorSessionId != opCtx->getLogicalSessionId() && // If the cursor's session doesn't match
+ // the Operation Context's session, then
+ // we should forbid the operation
+ !nobodyIsLoggedIn() && // Unless, for some reason a user isn't actually using this
+ // Operation Context (which implies a background job
+ !authHasImpersonatePrivilege() // Or if the user has an impersonation privilege, in which
+ // case, the user gets to sidestep certain checks.
+ ) {
+ return Status{ErrorCodes::Unauthorized,
+ str::stream() << "Cursor session id ("
+ << sessionIdToStringOrNone(cursorSessionId)
+ << ") is not the same as the operation context's session id ("
+ << sessionIdToStringOrNone(opCtx->getLogicalSessionId())
+ << ")"};
+ }
+
+ return Status::OK();
+}
diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h
index edb838c1959..4bd1ebf1d11 100644
--- a/src/mongo/db/auth/authorization_session.h
+++ b/src/mongo/db/auth/authorization_session.h
@@ -343,4 +343,10 @@ private:
bool _impersonationFlag;
};
+// Returns a status encoding whether the current session in the specified `opCtx` has privilege to
+// access a cursor in the specified `cursorSessionId` parameter. Returns `Status::OK()`, when the
+// session is accessible. Returns a `mongo::Status` with information regarding the nature of
+// session inaccessibility when the session is not accessible.
+Status checkCursorSessionPrivilege(OperationContext* const opCtx,
+ const boost::optional<LogicalSessionId> cursorSessionId);
} // namespace mongo
diff --git a/src/mongo/db/cursor_manager.cpp b/src/mongo/db/cursor_manager.cpp
index e7192105867..a4b5712965f 100644
--- a/src/mongo/db/cursor_manager.cpp
+++ b/src/mongo/db/cursor_manager.cpp
@@ -512,6 +512,13 @@ StatusWith<ClientCursorPin> CursorManager::pinCursor(OperationContext* opCtx, Cu
delete cursor;
return error;
}
+
+ auto cursorPrivilegeStatus = checkCursorSessionPrivilege(opCtx, cursor->getSessionId());
+
+ if (!cursorPrivilegeStatus.isOK()) {
+ return cursorPrivilegeStatus;
+ }
+
cursor->_isPinned = true;
// We use pinning of a cursor as a proxy for active, user-initiated use of a cursor. Therefor,
diff --git a/src/mongo/s/query/cluster_cursor_manager.cpp b/src/mongo/s/query/cluster_cursor_manager.cpp
index 8585a6114d6..f5cde547cff 100644
--- a/src/mongo/s/query/cluster_cursor_manager.cpp
+++ b/src/mongo/s/query/cluster_cursor_manager.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/s/query/cluster_cursor_manager.h"
#include <set>
@@ -283,7 +284,13 @@ StatusWith<ClusterCursorManager::PinnedCursor> ClusterCursorManager::checkOutCur
return cursorInUseStatus(nss, cursorId);
}
- // We use pinning of a cursor as a proxy for active, user-initiated use of a cursor. Therefor,
+ const auto cursorPrivilegeStatus = checkCursorSessionPrivilege(opCtx, cursor->getLsid());
+
+ if (!cursorPrivilegeStatus.isOK()) {
+ return cursorPrivilegeStatus;
+ }
+
+ // We use pinning of a cursor as a proxy for active, user-initiated use of a cursor. Therefore,
// we pass down to the logical session cache and vivify the record (updating last use).
if (cursor->getLsid()) {
LogicalSessionCache::get(opCtx)->vivify(opCtx, cursor->getLsid().get());
diff --git a/src/mongo/s/query/cluster_cursor_manager_test.cpp b/src/mongo/s/query/cluster_cursor_manager_test.cpp
index 75695e1deb7..c49434619b9 100644
--- a/src/mongo/s/query/cluster_cursor_manager_test.cpp
+++ b/src/mongo/s/query/cluster_cursor_manager_test.cpp
@@ -140,7 +140,7 @@ TEST_F(ClusterCursorManagerTest, RegisterCursor) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
auto nextResult = pinnedCursor.getValue().next();
ASSERT_OK(nextResult.getStatus());
@@ -172,7 +172,7 @@ TEST_F(ClusterCursorManagerTest, CheckOutCursorBasic) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(checkedOutCursor.getStatus());
ASSERT_EQ(cursorId, checkedOutCursor.getValue().getCursorId());
auto nextResult = checkedOutCursor.getValue().next();
@@ -200,7 +200,7 @@ TEST_F(ClusterCursorManagerTest, CheckOutCursorMultipleCursors) {
ClusterCursorManager::CursorLifetime::Mortal));
}
for (int i = 0; i < numCursors; ++i) {
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorIds[i], nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorIds[i], _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
auto nextResult = pinnedCursor.getValue().next();
ASSERT_OK(nextResult.getStatus());
@@ -220,10 +220,10 @@ TEST_F(ClusterCursorManagerTest, CheckOutCursorPinned) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_EQ(ErrorCodes::CursorInUse,
- getManager()->checkOutCursor(nss, cursorId, nullptr).getStatus());
+ getManager()->checkOutCursor(nss, cursorId, _opCtx.get()).getStatus());
}
// Test that checking out a killed cursor returns an error with code ErrorCodes::CursorNotFound.
@@ -236,7 +236,7 @@ TEST_F(ClusterCursorManagerTest, CheckOutCursorKilled) {
ClusterCursorManager::CursorLifetime::Mortal));
ASSERT_OK(getManager()->killCursor(nss, cursorId));
ASSERT_EQ(ErrorCodes::CursorNotFound,
- getManager()->checkOutCursor(nss, cursorId, nullptr).getStatus());
+ getManager()->checkOutCursor(nss, cursorId, _opCtx.get()).getStatus());
}
// Test that checking out an unknown cursor returns an error with code ErrorCodes::CursorNotFound.
@@ -270,7 +270,7 @@ TEST_F(ClusterCursorManagerTest, CheckOutCursorWrongCursorId) {
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
ASSERT_EQ(ErrorCodes::CursorNotFound,
- getManager()->checkOutCursor(nss, cursorId + 1, nullptr).getStatus());
+ getManager()->checkOutCursor(nss, cursorId + 1, _opCtx.get()).getStatus());
}
// Test that checking out a cursor updates the 'last active' time associated with the cursor to the
@@ -284,7 +284,7 @@ TEST_F(ClusterCursorManagerTest, CheckOutCursorUpdateActiveTime) {
ClusterCursorManager::CursorLifetime::Mortal));
Date_t cursorRegistrationTime = getClockSource()->now();
getClockSource()->advance(Milliseconds(1));
- auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(checkedOutCursor.getStatus());
checkedOutCursor.getValue().returnCursor(ClusterCursorManager::CursorState::NotExhausted);
getManager()->killMortalCursorsInactiveSince(cursorRegistrationTime);
@@ -303,7 +303,7 @@ TEST_F(ClusterCursorManagerTest, ReturnCursorUpdateActiveTime) {
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
Date_t cursorCheckOutTime = getClockSource()->now();
- auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(checkedOutCursor.getStatus());
getClockSource()->advance(Milliseconds(1));
checkedOutCursor.getValue().returnCursor(ClusterCursorManager::CursorState::NotExhausted);
@@ -320,7 +320,7 @@ TEST_F(ClusterCursorManagerTest, KillCursorBasic) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_OK(getManager()->killCursor(nss, pinnedCursor.getValue().getCursorId()));
pinnedCursor.getValue().returnCursor(ClusterCursorManager::CursorState::NotExhausted);
@@ -436,7 +436,7 @@ TEST_F(ClusterCursorManagerTest, ShouldNotKillPinnedCursors) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pin = assertGet(getManager()->checkOutCursor(nss, cursorId, nullptr));
+ auto pin = assertGet(getManager()->checkOutCursor(nss, cursorId, _opCtx.get()));
getManager()->killMortalCursorsInactiveSince(getClockSource()->now());
ASSERT(!isMockCursorKilled(0));
getManager()->reapZombieCursors(nullptr);
@@ -523,7 +523,7 @@ TEST_F(ClusterCursorManagerTest, ReapZombieCursorsSkipPinned) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT(!isMockCursorKilled(0));
getManager()->reapZombieCursors(nullptr);
ASSERT(!isMockCursorKilled(0));
@@ -577,7 +577,7 @@ TEST_F(ClusterCursorManagerTest, StatsPinCursor) {
nss,
ClusterCursorManager::CursorType::MultiTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_EQ(1U, getManager()->stats().cursorsPinned);
}
@@ -640,7 +640,7 @@ TEST_F(ClusterCursorManagerTest, StatsKillPinnedCursor) {
nss,
ClusterCursorManager::CursorType::MultiTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_EQ(1U, getManager()->stats().cursorsPinned);
ASSERT_OK(getManager()->killCursor(nss, cursorId));
ASSERT_EQ(0U, getManager()->stats().cursorsPinned);
@@ -654,7 +654,7 @@ TEST_F(ClusterCursorManagerTest, StatsExhaustShardedCursor) {
nss,
ClusterCursorManager::CursorType::MultiTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_OK(pinnedCursor.getValue().next().getStatus());
ASSERT_EQ(1U, getManager()->stats().cursorsMultiTarget);
@@ -670,7 +670,7 @@ TEST_F(ClusterCursorManagerTest, StatsExhaustNotShardedCursor) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_OK(pinnedCursor.getValue().next().getStatus());
ASSERT_EQ(1U, getManager()->stats().cursorsSingleTarget);
@@ -687,7 +687,7 @@ TEST_F(ClusterCursorManagerTest, StatsExhaustPinnedCursor) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_OK(pinnedCursor.getValue().next().getStatus());
ASSERT_EQ(1U, getManager()->stats().cursorsPinned);
@@ -704,7 +704,7 @@ TEST_F(ClusterCursorManagerTest, StatsCheckInWithoutExhaustingPinnedCursor) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_OK(pinnedCursor.getValue().next().getStatus());
ASSERT_EQ(1U, getManager()->stats().cursorsPinned);
@@ -791,13 +791,13 @@ TEST_F(ClusterCursorManagerTest, PinnedCursorReturnCursorNotExhausted) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto registeredCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto registeredCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(registeredCursor.getStatus());
ASSERT_EQ(cursorId, registeredCursor.getValue().getCursorId());
ASSERT_NE(0, cursorId);
registeredCursor.getValue().returnCursor(ClusterCursorManager::CursorState::NotExhausted);
ASSERT_EQ(0, registeredCursor.getValue().getCursorId());
- auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto checkedOutCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(checkedOutCursor.getStatus());
}
@@ -810,7 +810,7 @@ TEST_F(ClusterCursorManagerTest, PinnedCursorReturnCursorExhausted) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto registeredCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto registeredCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(registeredCursor.getStatus());
ASSERT_EQ(cursorId, registeredCursor.getValue().getCursorId());
ASSERT_NE(0, cursorId);
@@ -821,7 +821,7 @@ TEST_F(ClusterCursorManagerTest, PinnedCursorReturnCursorExhausted) {
// Cursor should have been destroyed without ever being killed. To be sure that the cursor has
// not been marked kill pending but not yet destroyed (i.e. that the cursor is not a zombie), we
// reapZombieCursors() and check that the cursor still has not been killed.
- ASSERT_NOT_OK(getManager()->checkOutCursor(nss, cursorId, nullptr).getStatus());
+ ASSERT_NOT_OK(getManager()->checkOutCursor(nss, cursorId, _opCtx.get()).getStatus());
ASSERT(!isMockCursorKilled(0));
getManager()->reapZombieCursors(nullptr);
ASSERT(!isMockCursorKilled(0));
@@ -842,7 +842,7 @@ TEST_F(ClusterCursorManagerTest, PinnedCursorReturnCursorExhaustedWithNonExhaust
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto registeredCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto registeredCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(registeredCursor.getStatus());
ASSERT_EQ(cursorId, registeredCursor.getValue().getCursorId());
ASSERT_NE(0, cursorId);
@@ -851,7 +851,7 @@ TEST_F(ClusterCursorManagerTest, PinnedCursorReturnCursorExhaustedWithNonExhaust
ASSERT_EQ(0, registeredCursor.getValue().getCursorId());
// Cursor should be kill pending, so it will be killed during reaping.
- ASSERT_NOT_OK(getManager()->checkOutCursor(nss, cursorId, nullptr).getStatus());
+ ASSERT_NOT_OK(getManager()->checkOutCursor(nss, cursorId, _opCtx.get()).getStatus());
ASSERT(!isMockCursorKilled(0));
getManager()->reapZombieCursors(nullptr);
ASSERT(isMockCursorKilled(0));
@@ -866,7 +866,7 @@ TEST_F(ClusterCursorManagerTest, PinnedCursorMoveAssignmentKill) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
pinnedCursor = ClusterCursorManager::PinnedCursor();
ASSERT(!isMockCursorKilled(0));
getManager()->reapZombieCursors(nullptr);
@@ -882,7 +882,7 @@ TEST_F(ClusterCursorManagerTest, PinnedCursorDestructorKill) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
}
ASSERT(!isMockCursorKilled(0));
getManager()->reapZombieCursors(nullptr);
@@ -901,7 +901,7 @@ TEST_F(ClusterCursorManagerTest, RemotesExhausted) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_FALSE(pinnedCursor.getValue().remotesExhausted());
}
@@ -914,7 +914,7 @@ TEST_F(ClusterCursorManagerTest, DoNotReapKilledPinnedCursors) {
nss,
ClusterCursorManager::CursorType::SingleTarget,
ClusterCursorManager::CursorLifetime::Mortal));
- auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, nullptr);
+ auto pinnedCursor = getManager()->checkOutCursor(nss, cursorId, _opCtx.get());
ASSERT_OK(pinnedCursor.getStatus());
ASSERT_OK(getManager()->killCursor(nss, cursorId));
ASSERT(!isMockCursorKilled(0));
@@ -964,7 +964,7 @@ TEST_F(ClusterCursorManagerTest, CannotCheckoutCursorDuringShutdown) {
ASSERT(isMockCursorKilled(0));
ASSERT_EQUALS(ErrorCodes::ShutdownInProgress,
- getManager()->checkOutCursor(nss, cursorId, nullptr).getStatus());
+ getManager()->checkOutCursor(nss, cursorId, _opCtx.get()).getStatus());
}
/**