Status AuthorizationSession::checkAuthForKillCursors(const NamespaceString& ns, long long cursorID) { // See implementation comments in checkAuthForGetMore(). This method looks very similar. if (ns.isListCollectionsCursorNS()) { if (!isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()), ActionType::killCursors)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized to kill listCollections cursor on " << ns.ns()); } } else if (ns.isListIndexesCursorNS()) { NamespaceString targetNS = ns.getTargetNSForListIndexes(); if (!isAuthorizedForActionsOnNamespace(targetNS, ActionType::killCursors)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized to kill listIndexes cursor on " << ns.ns()); } } else { if (!isAuthorizedForActionsOnNamespace(ns, ActionType::killCursors)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized to kill cursor on " << ns.ns()); } } return Status::OK(); }
Status AuthorizationSession::checkAuthForKillCursors(const NamespaceString& ns, long long cursorID) { // See implementation comments in checkAuthForGetMore(). This method looks very similar. // 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) || isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()), ActionType::listCollections))) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized to kill listCollections cursor on " << ns.ns()); } } else if (ns.isListIndexesCursorNS()) { 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()); } } else { if (!(isAuthorizedForActionsOnNamespace(ns, ActionType::killCursors) || isAuthorizedForActionsOnNamespace(ns, ActionType::find))) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized to kill cursor on " << ns.ns()); } } return Status::OK(); }
Status AuthorizationSession::checkAuthForGetMore(const NamespaceString& ns, long long cursorID) { // "ns" can be in one of three formats: "listCollections" format, "listIndexes" format, and // normal format. if (ns.isListCollectionsCursorNS()) { // "ns" is of the form "<db>.$cmd.listCollections". Check if we can perform the // listCollections action on the database resource for "<db>". if (!isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()), ActionType::listCollections)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized for listCollections getMore on " << ns.ns()); } } else if (ns.isListIndexesCursorNS()) { // "ns" is of the form "<db>.$cmd.listIndexes.<coll>". Check if we can perform the // listIndexes action on the "<db>.<coll>" namespace. NamespaceString targetNS = ns.getTargetNSForListIndexes(); if (!isAuthorizedForActionsOnNamespace(targetNS, ActionType::listIndexes)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized for listIndexes getMore on " << ns.ns()); } } else { // "ns" is a regular namespace string. Check if we can perform the find action on it. if (!isAuthorizedForActionsOnNamespace(ns, ActionType::find)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized for getMore on " << ns.ns()); } } return Status::OK(); }
Status AuthorizationSession::checkAuthForGetMore(const NamespaceString& ns, long long cursorID, bool hasTerm) { // "ns" can be in one of three formats: "listCollections" format, "listIndexes" format, and // normal format. if (ns.isListCollectionsCursorNS()) { // "ns" is of the form "<db>.$cmd.listCollections". Check if we can perform the // listCollections action on the database resource for "<db>". if (!isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()), ActionType::listCollections)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized for listCollections getMore on " << ns.ns()); } } else if (ns.isListIndexesCursorNS()) { // "ns" is of the form "<db>.$cmd.listIndexes.<coll>". Check if we can perform the // listIndexes action on the "<db>.<coll>" namespace. NamespaceString targetNS = ns.getTargetNSForListIndexes(); if (!isAuthorizedForActionsOnNamespace(targetNS, ActionType::listIndexes)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized for listIndexes getMore on " << ns.ns()); } } else { // "ns" is a regular namespace string. Check if we can perform the find action on it. if (!isAuthorizedForActionsOnNamespace(ns, ActionType::find)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized for getMore on " << ns.ns()); } } // Only internal clients (such as other nodes in a replica set) are allowed to use // the 'term' field in a getMore operation. Use of this field could trigger changes // in the receiving server's replication state and should be protected. if (hasTerm && !isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), ActionType::internal)) { return Status(ErrorCodes::Unauthorized, str::stream() << "not authorized for getMore with term on " << ns.ns()); } return Status::OK(); }