summaryrefslogtreecommitdiff
path: root/src/mongo/s/query/cluster_cursor_manager.h
diff options
context:
space:
mode:
authorIan Boros <ian.boros@10gen.com>2018-01-29 14:28:05 -0500
committerIan Boros <ian.boros@10gen.com>2018-02-07 13:09:43 -0500
commit8630f685156c7515c59ce071e59d9d6ec200f2e4 (patch)
treef13e93429738ae997a93adc3a4d717ac44bc15be /src/mongo/s/query/cluster_cursor_manager.h
parent5f86a8e4ca87f169dc708b15b13a26c2bb514762 (diff)
downloadmongo-8630f685156c7515c59ce071e59d9d6ec200f2e4.tar.gz
SERVER-32395 Make killCursors work against pinned cursors on mongos when auth is enabled
Diffstat (limited to 'src/mongo/s/query/cluster_cursor_manager.h')
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.h71
1 files changed, 54 insertions, 17 deletions
diff --git a/src/mongo/s/query/cluster_cursor_manager.h b/src/mongo/s/query/cluster_cursor_manager.h
index 8357117099f..923e6914953 100644
--- a/src/mongo/s/query/cluster_cursor_manager.h
+++ b/src/mongo/s/query/cluster_cursor_manager.h
@@ -115,6 +115,11 @@ public:
size_t cursorsPinned = 0;
};
+ // Represents a function that may be passed into a ClusterCursorManager method which checks
+ // whether the current client is authorized to perform the operation in question. The function
+ // will be passed the list of users authorized to use the cursor.
+ using AuthzCheckFn = std::function<Status(UserNameIterator)>;
+
/**
* PinnedCursor is a moveable, non-copyable class representing ownership of a cursor that has
* been leased from a ClusterCursorManager.
@@ -186,12 +191,6 @@ public:
bool isTailableAndAwaitData() const;
/**
- * Returns the set of authenticated users when this cursor was created. Cannot be called
- * after returnCursor() is called. A cursor must be owned.
- */
- UserNameIterator getAuthenticatedUsers() const;
-
- /**
* Transfers ownership of the underlying cursor back to the manager. A cursor must be
* owned, and a cursor will no longer be owned after this method completes.
*
@@ -299,7 +298,8 @@ public:
std::unique_ptr<ClusterClientCursor> cursor,
const NamespaceString& nss,
CursorType cursorType,
- CursorLifetime cursorLifetime);
+ CursorLifetime cursorLifetime,
+ UserNameIterator authenticatedUsers);
/**
* Moves the given cursor to the 'pinned' state, and transfers ownership of the cursor to the
@@ -310,6 +310,10 @@ public:
* returns an error Status with code CursorInUse. If the given cursor is not registered or has
* a pending kill, returns an error Status with code CursorNotFound.
*
+ * 'authChecker' is function that will be called with the list of users authorized to use this
+ * cursor. This function should check whether the current client is also authorized to use this
+ * cursor, and if not, return an error status, which will cause checkOutCursor to fail.
+ *
* This method updates the 'last active' time associated with the cursor to the current time.
*
* Does not block.
@@ -318,9 +322,20 @@ public:
StatusWith<PinnedCursor> checkOutCursor(const NamespaceString& nss,
CursorId cursorId,
OperationContext* opCtx,
+ AuthzCheckFn authChecker,
AuthCheck checkSessionAuth = kCheckSession);
/**
+ * This method will find the given cursor, and if it exists, call 'authChecker', passing the
+ * list of users authorized to use the cursor. Will propagate the return value of authChecker.
+ */
+ Status checkAuthForKillCursors(OperationContext* opCtx,
+ const NamespaceString& nss,
+ CursorId cursorId,
+ AuthzCheckFn authChecker);
+
+
+ /**
* Informs the manager that the given cursor should be killed. The cursor need not necessarily
* be in the 'idle' state, and the lifetime type of the cursor is ignored.
*
@@ -462,12 +477,15 @@ private:
CursorEntry(std::unique_ptr<ClusterClientCursor> cursor,
CursorType cursorType,
CursorLifetime cursorLifetime,
- Date_t lastActive)
+ Date_t lastActive,
+ UserNameIterator authenticatedUsersIter)
: _cursor(std::move(cursor)),
_cursorType(cursorType),
_cursorLifetime(cursorLifetime),
_lastActive(lastActive),
- _lsid(_cursor->getLsid()) {
+ _lsid(_cursor->getLsid()),
+ _authenticatedUsers(
+ userNameIteratorToContainer<std::vector<UserName>>(authenticatedUsersIter)) {
invariant(_cursor);
}
@@ -494,29 +512,38 @@ private:
return _lastActive;
}
- bool isCursorOwned() const {
- return static_cast<bool>(_cursor);
- }
-
boost::optional<LogicalSessionId> getLsid() const {
return _lsid;
}
/**
- * Releases the cursor from this entry. If the cursor has already been released, returns
- * null.
+ * Returns the cursor owned by this CursorEntry for an operation to use. Only one operation
+ * may use the cursor at a time, so callers should check that getOperationUsingCursor()
+ * returns null before using this function. Callers may pass nullptr, but only if the
+ * released cursor is going to be deleted.
*/
- std::unique_ptr<ClusterClientCursor> releaseCursor() {
+ std::unique_ptr<ClusterClientCursor> releaseCursor(OperationContext* opCtx) {
+ invariant(!_operationUsingCursor);
+ invariant(_cursor);
+ _operationUsingCursor = opCtx;
return std::move(_cursor);
}
+ OperationContext* getOperationUsingCursor() const {
+ return _operationUsingCursor;
+ }
+
/**
- * Transfers ownership of the given released cursor back to this entry.
+ * Indicate that the cursor is no longer in use by an operation. Once this is called,
+ * another operation may check the cursor out.
*/
void returnCursor(std::unique_ptr<ClusterClientCursor> cursor) {
invariant(cursor);
invariant(!_cursor);
+ invariant(_operationUsingCursor);
+
_cursor = std::move(cursor);
+ _operationUsingCursor = nullptr;
}
void setKillPending() {
@@ -531,6 +558,10 @@ private:
_lastActive = lastActive;
}
+ UserNameIterator getAuthenticatedUsers() const {
+ return makeUserNameIterator(_authenticatedUsers.begin(), _authenticatedUsers.end());
+ }
+
private:
std::unique_ptr<ClusterClientCursor> _cursor;
bool _killPending = false;
@@ -539,6 +570,12 @@ private:
CursorLifetime _cursorLifetime = CursorLifetime::Mortal;
Date_t _lastActive;
boost::optional<LogicalSessionId> _lsid;
+
+ // Current operation using the cursor. Non-null if the cursor is checked out.
+ OperationContext* _operationUsingCursor = nullptr;
+
+ // The set of users authorized to use this cursor.
+ const std::vector<UserName> _authenticatedUsers;
};
/**