diff options
Diffstat (limited to 'src/mongo/db/auth/authorization_session.cpp')
-rw-r--r-- | src/mongo/db/auth/authorization_session.cpp | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp index 15ee3480a88..8d990765552 100644 --- a/src/mongo/db/auth/authorization_session.cpp +++ b/src/mongo/db/auth/authorization_session.cpp @@ -466,35 +466,57 @@ Status AuthorizationSession::checkAuthForDelete(OperationContext* opCtx, } Status AuthorizationSession::checkAuthForKillCursors(const NamespaceString& ns, - long long cursorID) { - // See implementation comments in checkAuthForGetMore(). This method looks very similar. + UserNameIterator cursorOwner) { + if (isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::killAnyCursor)) { + return Status::OK(); + } - // SERVER-20364 Check for find or killCursor privileges until we have a way of associating - // a cursor with an owner. if (ns.isListCollectionsCursorNS()) { - if (!(isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()), - ActionType::killCursors) || - isAuthorizedToListCollections(ns.db()))) { - return Status(ErrorCodes::Unauthorized, - str::stream() << "not authorized to kill listCollections cursor on " - << ns.ns()); + // listCollections: Target the database being enumerated. + if (isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()), + ActionType::killAnyCursor)) { + return Status::OK(); + } + const bool canKill = + isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()), + ActionType::killCursors) || + isAuthorizedToListCollections(ns.db()); + if (canKill && isCoauthorizedWith(cursorOwner)) { + return Status::OK(); } + return Status(ErrorCodes::Unauthorized, + str::stream() << "not authorized to kill listCollections cursor on " + << ns.ns()); } else if (ns.isListIndexesCursorNS()) { + + // listIndexes: Target the underlying collection. NamespaceString targetNS = ns.getTargetNSForListIndexes(); - if (!(isAuthorizedForActionsOnNamespace(targetNS, ActionType::killCursors) || - isAuthorizedForActionsOnNamespace(targetNS, ActionType::listIndexes))) { - return Status(ErrorCodes::Unauthorized, - str::stream() << "not authorized to kill listIndexes cursor on " - << ns.ns()); + if (isAuthorizedForActionsOnNamespace(targetNS, ActionType::killAnyCursor)) { + return Status::OK(); + } + const bool canKill = isAuthorizedForActionsOnNamespace(targetNS, ActionType::killCursors) || + isAuthorizedForActionsOnNamespace(targetNS, ActionType::listIndexes); + if (canKill && isCoauthorizedWith(cursorOwner)) { + return Status::OK(); } + + return Status(ErrorCodes::Unauthorized, + str::stream() << "not authorized to kill listIndexes cursor on " << ns.ns()); } else { - if (!(isAuthorizedForActionsOnNamespace(ns, ActionType::killCursors) || - isAuthorizedForActionsOnNamespace(ns, ActionType::find))) { - return Status(ErrorCodes::Unauthorized, - str::stream() << "not authorized to kill cursor on " << ns.ns()); + + // Otherwise: Target the collection as named. + if (isAuthorizedForActionsOnNamespace(ns, ActionType::killAnyCursor)) { + return Status::OK(); } + const bool canKill = isAuthorizedForActionsOnNamespace(ns, ActionType::killCursors) || + isAuthorizedForActionsOnNamespace(ns, ActionType::find); + if (canKill && isCoauthorizedWith(cursorOwner)) { + return Status::OK(); + } + return Status(ErrorCodes::Unauthorized, + str::stream() << "not authorized to kill cursor on " << ns.ns()); } - return Status::OK(); } Status AuthorizationSession::checkAuthForCreate(const NamespaceString& ns, |