summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth/authorization_session.cpp
diff options
context:
space:
mode:
authorKyle Suarez <kyle.suarez@mongodb.com>2016-12-16 13:51:23 -0500
committerKyle Suarez <kyle.suarez@mongodb.com>2017-01-03 16:07:14 -0500
commitf6daee8d3892e0b2c7c26afb9b1f1d4ba953ccf7 (patch)
tree1219a729e73bcfab4b8d93884b6c58dd458599b8 /src/mongo/db/auth/authorization_session.cpp
parentef1f1739d6cbff9fb4ddbcc77d467f183c0ab9f2 (diff)
downloadmongo-f6daee8d3892e0b2c7c26afb9b1f1d4ba953ccf7.tar.gz
SERVER-27420 explicitly parse first pipeline element in checkAuthForAggregate()
Diffstat (limited to 'src/mongo/db/auth/authorization_session.cpp')
-rw-r--r--src/mongo/db/auth/authorization_session.cpp49
1 files changed, 35 insertions, 14 deletions
diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp
index fe8e8be3f18..a91f350e24d 100644
--- a/src/mongo/db/auth/authorization_session.cpp
+++ b/src/mongo/db/auth/authorization_session.cpp
@@ -67,7 +67,7 @@ const std::string ADMIN_DBNAME = "admin";
Status checkAuthForCreateOrModifyView(AuthorizationSession* authzSession,
const NamespaceString& viewNs,
const NamespaceString& viewOnNs,
- const BSONObj& viewPipeline) {
+ const BSONArray& viewPipeline) {
// It's safe to allow a user to create or modify a view if they can't read it anyway.
if (!authzSession->isAuthorizedForActionsOnNamespace(viewNs, ActionType::find)) {
return Status::OK();
@@ -260,22 +260,43 @@ Status AuthorizationSession::checkAuthForAggregate(const NamespaceString& ns,
PrivilegeVector privileges;
- if (dps::extractElementAtPath(cmdObj, "pipeline.0.$indexStats")) {
- Privilege::addPrivilegeToPrivilegeVector(&privileges,
- Privilege(inputResource, ActionType::indexStats));
- } else if (dps::extractElementAtPath(cmdObj, "pipeline.0.$collStats")) {
- Privilege::addPrivilegeToPrivilegeVector(&privileges,
- Privilege(inputResource, ActionType::collStats));
- } else {
- // If no source requiring an alternative permission scheme is specified then default to
- // requiring find() privileges on the given namespace.
+ BSONElement pipelineElem = cmdObj["pipeline"];
+ if (pipelineElem.type() != BSONType::Array) {
+ return Status(ErrorCodes::TypeMismatch, "'pipeline' must be specified as an array");
+ }
+
+ BSONObj pipeline = pipelineElem.embeddedObject();
+ if (pipeline.isEmpty()) {
+ // The pipeline is empty, so we require only the find action.
Privilege::addPrivilegeToPrivilegeVector(&privileges,
Privilege(inputResource, ActionType::find));
- }
+ } else {
+ if (pipeline.firstElementType() != BSONType::Object) {
+ // The pipeline contains something that's not an object.
+ return Status(ErrorCodes::TypeMismatch,
+ "'pipeline' cannot contain non-object elements");
+ }
+
+ // We treat the first stage in the pipeline specially, as some aggregation stages that are
+ // valid initial sources have different auth requirements.
+ BSONObj firstPipelineStage = pipeline.firstElement().embeddedObject();
+ if (str::equals("$indexStats", firstPipelineStage.firstElementFieldName())) {
+ Privilege::addPrivilegeToPrivilegeVector(
+ &privileges, Privilege(inputResource, ActionType::indexStats));
+ } else if (str::equals("$collStats", firstPipelineStage.firstElementFieldName())) {
+ Privilege::addPrivilegeToPrivilegeVector(
+ &privileges, Privilege(inputResource, ActionType::collStats));
+ } else {
+ // If no source requiring an alternative permission scheme is specified then default to
+ // requiring find() privileges on the given namespace.
+ Privilege::addPrivilegeToPrivilegeVector(&privileges,
+ Privilege(inputResource, ActionType::find));
+ }
- BSONObj pipeline = cmdObj.getObjectField("pipeline");
- for (auto&& stageElem : pipeline) {
- _addPrivilegesForStage(db, cmdObj, &privileges, stageElem.embeddedObjectUserCheck());
+ // Add additional required privileges for each stage in the pipeline.
+ for (auto&& stageElem : pipeline) {
+ _addPrivilegesForStage(db, cmdObj, &privileges, stageElem.embeddedObjectUserCheck());
+ }
}
if (isAuthorizedForPrivileges(privileges))