summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2021-02-05 14:00:41 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-09 00:04:28 +0000
commit93bddb471583e84afc412b68c7e9c06871d42c43 (patch)
treea42ee943c596d6c0d203a4a4730980591f0b1189 /src/mongo/db/auth
parent3120087175678ec7a61a6d12cd9326ba8cfa2d45 (diff)
downloadmongo-93bddb471583e84afc412b68c7e9c06871d42c43.tar.gz
SERVER-54022 Simplify AuthorizationSession
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r--src/mongo/db/auth/SConscript34
-rw-r--r--src/mongo/db/auth/authorization_checks.cpp318
-rw-r--r--src/mongo/db/auth/authorization_checks.h104
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp1
-rw-r--r--src/mongo/db/auth/authorization_session.h79
-rw-r--r--src/mongo/db/auth/authorization_session_impl.cpp329
-rw-r--r--src/mongo/db/auth/authorization_session_impl.h47
-rw-r--r--src/mongo/db/auth/authorization_session_test.cpp132
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_local.cpp3
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_local.h4
-rw-r--r--src/mongo/db/auth/builtin_roles_test.cpp1
-rw-r--r--src/mongo/db/auth/sasl_authentication_session_test.cpp3
-rw-r--r--src/mongo/db/auth/sasl_commands.cpp2
13 files changed, 527 insertions, 530 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index e128915a769..5d1890e92d9 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -77,6 +77,9 @@ env.Library(
LIBDEPS=[
'auth_impl_internal',
],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/concurrency/lock_manager',
+ ]
)
env.Library(
@@ -86,7 +89,6 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
'auth',
'auth_options',
'authprivilege',
@@ -100,7 +102,6 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
'$BUILD_DIR/mongo/bson/util/bson_extract',
'auth',
'user',
@@ -134,14 +135,10 @@ env.Library(
LIBDEPS=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/base/secure_allocator',
- '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
'$BUILD_DIR/mongo/bson/util/bson_extract',
- '$BUILD_DIR/mongo/db/catalog/document_validation',
'$BUILD_DIR/mongo/db/common',
'$BUILD_DIR/mongo/db/global_settings',
'$BUILD_DIR/mongo/db/namespace_string',
- '$BUILD_DIR/mongo/db/pipeline/lite_parsed_document_source',
- '$BUILD_DIR/mongo/db/update/update_driver',
'$BUILD_DIR/mongo/util/concurrency/thread_pool',
'$BUILD_DIR/mongo/util/icu',
'$BUILD_DIR/mongo/util/net/ssl_manager',
@@ -165,6 +162,31 @@ env.Library(
)
env.Library(
+ target='auth_checks',
+ source=[
+ 'authorization_checks.cpp',
+ ],
+ LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/catalog/document_validation',
+ '$BUILD_DIR/mongo/db/common',
+ '$BUILD_DIR/mongo/db/namespace_string',
+ '$BUILD_DIR/mongo/db/pipeline/lite_parsed_document_source',
+ '$BUILD_DIR/mongo/db/update/update_driver',
+ 'auth',
+ 'authorization_manager_global',
+ 'authprivilege',
+ 'builtin_roles',
+ 'user',
+ 'user_document_parser',
+ ],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/audit',
+ '$BUILD_DIR/mongo/idl/server_parameter',
+ ],
+)
+
+env.Library(
target='authprivilege',
source=[
'action_set.cpp',
diff --git a/src/mongo/db/auth/authorization_checks.cpp b/src/mongo/db/auth/authorization_checks.cpp
new file mode 100644
index 00000000000..9877223dc89
--- /dev/null
+++ b/src/mongo/db/auth/authorization_checks.cpp
@@ -0,0 +1,318 @@
+/**
+ * Copyright (C) 2021-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/db/auth/authorization_checks.h"
+
+#include "mongo/db/catalog/document_validation.h"
+#include "mongo/db/pipeline/aggregation_request_helper.h"
+#include "mongo/db/pipeline/lite_parsed_pipeline.h"
+
+namespace mongo::auth {
+
+namespace {
+
+// Checks if this connection has the privileges necessary to create or modify the view 'viewNs'
+// to be a view on 'viewOnNs' with pipeline 'viewPipeline'. Call this function after verifying
+// that the user has the 'createCollection' or 'collMod' action, respectively.
+Status checkAuthForCreateOrModifyView(AuthorizationSession* authzSession,
+ const NamespaceString& viewNs,
+ const NamespaceString& viewOnNs,
+ const BSONArray& viewPipeline,
+ bool isMongos) {
+ // 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();
+ }
+
+ auto request = aggregation_request_helper::parseFromBSON(
+ viewNs,
+ BSON("aggregate" << viewOnNs.coll() << "pipeline" << viewPipeline << "cursor" << BSONObj()
+ << "$db" << viewOnNs.db()),
+ boost::none,
+ false);
+
+ auto statusWithPrivs = getPrivilegesForAggregate(authzSession, viewOnNs, request, isMongos);
+ PrivilegeVector privileges = uassertStatusOK(statusWithPrivs);
+ if (!authzSession->isAuthorizedForPrivileges(privileges)) {
+ return Status(ErrorCodes::Unauthorized, "unauthorized");
+ }
+ return Status::OK();
+}
+
+} // namespace
+
+
+Status checkAuthForFind(AuthorizationSession* authSession,
+ const NamespaceString& ns,
+ bool hasTerm) {
+ if (MONGO_unlikely(ns.isCommand())) {
+ return Status(ErrorCodes::InternalError,
+ str::stream() << "Checking query auth on command namespace " << ns.ns());
+ }
+ if (!authSession->isAuthorizedForActionsOnNamespace(ns, ActionType::find)) {
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized for query on " << ns.ns());
+ }
+
+ // Only internal clients (such as other nodes in a replica set) are allowed to use
+ // the 'term' field in a find operation. Use of this field could trigger changes
+ // in the receiving server's replication state and should be protected.
+ if (hasTerm &&
+ !authSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized for query with term on " << ns.ns());
+ }
+
+ return Status::OK();
+}
+
+Status checkAuthForGetMore(AuthorizationSession* authSession,
+ const NamespaceString& ns,
+ long long cursorID,
+ bool hasTerm) {
+ // Since users can only getMore their own cursors, we verify that a user either is authenticated
+ // or does not need to be.
+ if (!authSession->shouldIgnoreAuthChecks() && !authSession->isAuthenticated()) {
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized for getMore on " << ns.db());
+ }
+
+ // 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 &&
+ !authSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized for getMore with term on " << ns.ns());
+ }
+
+ return Status::OK();
+}
+
+Status checkAuthForInsert(AuthorizationSession* authSession,
+ OperationContext* opCtx,
+ const NamespaceString& ns) {
+ ActionSet required{ActionType::insert};
+ if (DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()) {
+ required.addAction(ActionType::bypassDocumentValidation);
+ }
+ if (!authSession->isAuthorizedForActionsOnNamespace(ns, required)) {
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized for insert on " << ns.ns());
+ }
+
+ return Status::OK();
+}
+
+Status checkAuthForUpdate(AuthorizationSession* authSession,
+ OperationContext* opCtx,
+ const NamespaceString& ns,
+ const BSONObj& query,
+ const write_ops::UpdateModification& update,
+ bool upsert) {
+ ActionSet required{ActionType::update};
+ StringData operationType = "update"_sd;
+
+ if (upsert) {
+ required.addAction(ActionType::insert);
+ operationType = "upsert"_sd;
+ }
+
+ if (DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()) {
+ required.addAction(ActionType::bypassDocumentValidation);
+ }
+
+ if (!authSession->isAuthorizedForActionsOnNamespace(ns, required)) {
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized for " << operationType << " on " << ns.ns());
+ }
+
+ return Status::OK();
+}
+
+Status checkAuthForDelete(AuthorizationSession* authSession,
+ OperationContext* opCtx,
+ const NamespaceString& ns,
+ const BSONObj& query) {
+ if (!authSession->isAuthorizedForActionsOnNamespace(ns, ActionType::remove)) {
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized to remove from " << ns.ns());
+ }
+ return Status::OK();
+}
+
+Status checkAuthForKillCursors(AuthorizationSession* authSession,
+ const NamespaceString& ns,
+ UserNameIterator cursorOwner) {
+ if (authSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::killAnyCursor)) {
+ return Status::OK();
+ }
+
+ if (authSession->isCoauthorizedWith(cursorOwner)) {
+ return Status::OK();
+ }
+
+ ResourcePattern target;
+ if (ns.isListCollectionsCursorNS()) {
+ target = ResourcePattern::forDatabaseName(ns.db());
+ } else {
+ target = ResourcePattern::forExactNamespace(ns);
+ }
+
+ if (authSession->isAuthorizedForActionsOnResource(target, ActionType::killAnyCursor)) {
+ return Status::OK();
+ }
+
+ return Status(ErrorCodes::Unauthorized,
+ str::stream() << "not authorized to kill cursor on " << ns.ns());
+}
+
+Status checkAuthForCreate(AuthorizationSession* authSession,
+ const CreateCommand& cmd,
+ bool isMongos) {
+ auto ns = cmd.getNamespace();
+
+ if (cmd.getCapped() &&
+ !authSession->isAuthorizedForActionsOnNamespace(ns, ActionType::convertToCapped)) {
+ return Status(ErrorCodes::Unauthorized, "unauthorized");
+ }
+
+ const bool hasCreateCollectionAction =
+ authSession->isAuthorizedForActionsOnNamespace(ns, ActionType::createCollection);
+
+ // If attempting to create a view, check for additional required privileges.
+ if (auto optViewOn = cmd.getViewOn()) {
+
+ // You need the createCollection action on this namespace; the insert action is not
+ // sufficient.
+ if (!hasCreateCollectionAction) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ // Parse the viewOn namespace and the pipeline. If no pipeline was specified, use the empty
+ // pipeline.
+ NamespaceString viewOnNs(ns.db(), optViewOn.get());
+ auto pipeline = cmd.getPipeline().get_value_or(std::vector<BSONObj>());
+ BSONArrayBuilder pipelineArray;
+ for (const auto& stage : pipeline) {
+ pipelineArray.append(stage);
+ }
+ return checkAuthForCreateOrModifyView(
+ authSession, ns, viewOnNs, pipelineArray.arr(), isMongos);
+ }
+
+ // To create a regular collection, ActionType::createCollection or ActionType::insert are
+ // both acceptable.
+ if (hasCreateCollectionAction ||
+ authSession->isAuthorizedForActionsOnNamespace(ns, ActionType::insert)) {
+ return Status::OK();
+ }
+
+ return Status(ErrorCodes::Unauthorized, "unauthorized");
+}
+
+Status checkAuthForCollMod(AuthorizationSession* authSession,
+ const NamespaceString& ns,
+ const BSONObj& cmdObj,
+ bool isMongos) {
+ if (!authSession->isAuthorizedForActionsOnNamespace(ns, ActionType::collMod)) {
+ return Status(ErrorCodes::Unauthorized, "unauthorized");
+ }
+
+ // Check for additional required privileges if attempting to modify a view. When auth is
+ // enabled, users must specify both "viewOn" and "pipeline" together. This prevents a user from
+ // exposing more information in the original underlying namespace by only changing "pipeline",
+ // or looking up more information via the original pipeline by only changing "viewOn".
+ const bool hasViewOn = cmdObj.hasField("viewOn");
+ const bool hasPipeline = cmdObj.hasField("pipeline");
+ if (hasViewOn != hasPipeline) {
+ return Status(
+ ErrorCodes::InvalidOptions,
+ "Must specify both 'viewOn' and 'pipeline' when modifying a view and auth is enabled");
+ }
+ if (hasViewOn) {
+ NamespaceString viewOnNs(ns.db(), cmdObj["viewOn"].checkAndGetStringData());
+ auto viewPipeline = BSONArray(cmdObj["pipeline"].Obj());
+ return checkAuthForCreateOrModifyView(authSession, ns, viewOnNs, viewPipeline, isMongos);
+ }
+
+ return Status::OK();
+}
+
+
+StatusWith<PrivilegeVector> getPrivilegesForAggregate(AuthorizationSession* authSession,
+ const NamespaceString& nss,
+ const AggregateCommand& request,
+ bool isMongos) {
+ if (!nss.isValid()) {
+ return Status(ErrorCodes::InvalidNamespace,
+ str::stream() << "Invalid input namespace, " << nss.ns());
+ }
+
+ PrivilegeVector privileges;
+
+ // If this connection does not need to be authenticated (for instance, if auth is disabled),
+ // returns an empty requirements set.
+ if (authSession->shouldIgnoreAuthChecks()) {
+ return privileges;
+ }
+
+ const auto& pipeline = request.getPipeline();
+
+ // If the aggregation pipeline is empty, confirm the user is authorized for find on 'nss'.
+ if (pipeline.empty()) {
+ Privilege currentPriv =
+ Privilege(ResourcePattern::forExactNamespace(nss), ActionType::find);
+ Privilege::addPrivilegeToPrivilegeVector(&privileges, currentPriv);
+ return privileges;
+ }
+
+ // If the first stage of the pipeline is not an initial source, the pipeline is implicitly
+ // reading documents from the underlying collection. The client must be authorized to do so.
+ auto liteParsedDocSource = LiteParsedDocumentSource::parse(nss, pipeline[0]);
+ if (!liteParsedDocSource->isInitialSource()) {
+ Privilege currentPriv =
+ Privilege(ResourcePattern::forExactNamespace(nss), ActionType::find);
+ Privilege::addPrivilegeToPrivilegeVector(&privileges, currentPriv);
+ }
+
+ // Confirm privileges for the pipeline.
+ for (auto&& pipelineStage : pipeline) {
+ liteParsedDocSource = LiteParsedDocumentSource::parse(nss, pipelineStage);
+ PrivilegeVector currentPrivs = liteParsedDocSource->requiredPrivileges(
+ isMongos, request.getBypassDocumentValidation().value_or(false));
+ Privilege::addPrivilegesToPrivilegeVector(&privileges, currentPrivs);
+ }
+ return privileges;
+}
+
+} // namespace mongo::auth
diff --git a/src/mongo/db/auth/authorization_checks.h b/src/mongo/db/auth/authorization_checks.h
new file mode 100644
index 00000000000..4dc13cf5fe7
--- /dev/null
+++ b/src/mongo/db/auth/authorization_checks.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2021-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the Server Side Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+
+#pragma once
+
+#include "mongo/base/status.h"
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/auth/user_set.h"
+#include "mongo/db/namespace_string.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/ops/write_ops_parsers.h"
+#include "mongo/db/pipeline/aggregate_command_gen.h"
+
+
+namespace mongo::auth {
+
+// Checks if this connection has the privileges necessary to perform a find operation
+// on the supplied namespace identifier.
+Status checkAuthForFind(AuthorizationSession* authSession, const NamespaceString& ns, bool hasTerm);
+
+// Checks if this connection has the privileges necessary to perform a getMore operation on
+// the identified cursor, supposing that cursor is associated with the supplied namespace
+// identifier.
+Status checkAuthForGetMore(AuthorizationSession* authSession,
+ const NamespaceString& ns,
+ long long cursorID,
+ bool hasTerm);
+
+// Checks if this connection has the privileges necessary to perform the given update on the
+// given namespace.
+Status checkAuthForUpdate(AuthorizationSession* authSession,
+ OperationContext* opCtx,
+ const NamespaceString& ns,
+ const BSONObj& query,
+ const write_ops::UpdateModification& update,
+ bool upsert);
+
+// Checks if this connection has the privileges necessary to insert to the given namespace.
+Status checkAuthForInsert(AuthorizationSession* authSession,
+ OperationContext* opCtx,
+ const NamespaceString& ns);
+
+// Checks if this connection has the privileges necessary to perform a delete on the given
+// namespace.
+Status checkAuthForDelete(AuthorizationSession* authSession,
+ OperationContext* opCtx,
+ const NamespaceString& ns,
+ const BSONObj& query);
+
+// Checks if this connection has the privileges necessary to perform a killCursor on
+// the identified cursor, supposing that cursor is associated with the supplied namespace
+// identifier.
+Status checkAuthForKillCursors(AuthorizationSession* authSession,
+ const NamespaceString& cursorNss,
+ UserNameIterator cursorOwner);
+
+// Attempts to get the privileges necessary to run the aggregation pipeline specified in
+// 'request' on the namespace 'ns' either directly on mongoD or via mongoS.
+StatusWith<PrivilegeVector> getPrivilegesForAggregate(AuthorizationSession* authSession,
+ const NamespaceString& ns,
+ const AggregateCommand& request,
+ bool isMongos);
+
+// Checks if this connection has the privileges necessary to create 'ns' with the options
+// supplied in 'cmdObj' either directly on mongoD or via mongoS.
+Status checkAuthForCreate(AuthorizationSession* authSession,
+ const CreateCommand& cmd,
+ bool isMongos);
+
+// Checks if this connection has the privileges necessary to modify 'ns' with the options
+// supplied in 'cmdObj' either directly on mongoD or via mongoS.
+Status checkAuthForCollMod(AuthorizationSession* authSession,
+ const NamespaceString& ns,
+ const BSONObj& cmdObj,
+ bool isMongos);
+
+} // namespace mongo::auth
diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp
index a64b4ed8fbf..23269084d1b 100644
--- a/src/mongo/db/auth/authorization_manager_test.cpp
+++ b/src/mongo/db/auth/authorization_manager_test.cpp
@@ -32,7 +32,6 @@
#include <memory>
#include "mongo/base/status.h"
-#include "mongo/bson/mutable/document.h"
#include "mongo/config.h"
#include "mongo/crypto/mechanism_scram.h"
#include "mongo/crypto/sha1_block.h"
diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h
index bd4a4f4c1f3..4f2084e5010 100644
--- a/src/mongo/db/auth/authorization_session.h
+++ b/src/mongo/db/auth/authorization_session.h
@@ -44,8 +44,6 @@
#include "mongo/db/commands/create_gen.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
-#include "mongo/db/ops/write_ops_parsers.h"
-#include "mongo/db/pipeline/aggregate_command_gen.h"
namespace mongo {
@@ -154,6 +152,9 @@ public:
// multiple users are authenticated, this method will throw an exception.
virtual User* getSingleUser() = 0;
+ // Is auth disabled? Returns true if auth is disabled.
+ virtual bool shouldIgnoreAuthChecks() = 0;
+
// Is authenticated as at least one user.
virtual bool isAuthenticated() = 0;
@@ -181,64 +182,6 @@ public:
// into a state where the first user can be created.
virtual PrivilegeVector getDefaultPrivileges() = 0;
- // Checks if this connection has the privileges necessary to perform a find operation
- // on the supplied namespace identifier.
- virtual Status checkAuthForFind(const NamespaceString& ns, bool hasTerm) = 0;
-
- // Checks if this connection has the privileges necessary to perform a getMore operation on
- // the identified cursor, supposing that cursor is associated with the supplied namespace
- // identifier.
- virtual Status checkAuthForGetMore(const NamespaceString& ns,
- long long cursorID,
- bool hasTerm) = 0;
-
- // Checks if this connection has the privileges necessary to perform the given update on the
- // given namespace.
- virtual Status checkAuthForUpdate(OperationContext* opCtx,
- const NamespaceString& ns,
- const BSONObj& query,
- const write_ops::UpdateModification& update,
- bool upsert) = 0;
-
- // Checks if this connection has the privileges necessary to insert to the given namespace.
- virtual Status checkAuthForInsert(OperationContext* opCtx, const NamespaceString& ns) = 0;
-
- // Checks if this connection has the privileges necessary to perform a delete on the given
- // namespace.
- virtual Status checkAuthForDelete(OperationContext* opCtx,
- const NamespaceString& ns,
- const BSONObj& query) = 0;
-
- // Checks if this connection has the privileges necessary to perform a killCursor on
- // the identified cursor, supposing that cursor is associated with the supplied namespace
- // identifier.
- virtual Status checkAuthForKillCursors(const NamespaceString& cursorNss,
- UserNameIterator cursorOwner) = 0;
-
- // Attempts to get the privileges necessary to run the aggregation pipeline specified in
- // 'request' on the namespace 'ns' either directly on mongoD or via mongoS.
- virtual StatusWith<PrivilegeVector> getPrivilegesForAggregate(const NamespaceString& ns,
- const AggregateCommand& request,
- bool isMongos) = 0;
-
- // Checks if this connection has the privileges necessary to create 'ns' with the options
- // supplied in 'cmdObj' either directly on mongoD or via mongoS.
- virtual Status checkAuthForCreate(const CreateCommand& cmd, bool isMongos) = 0;
-
- // Checks if this connection has the privileges necessary to modify 'ns' with the options
- // supplied in 'cmdObj' either directly on mongoD or via mongoS.
- virtual Status checkAuthForCollMod(const NamespaceString& ns,
- const BSONObj& cmdObj,
- bool isMongos) = 0;
-
- // Checks if this connection has the privileges necessary to grant the given privilege
- // to a role.
- virtual Status checkAuthorizedToGrantPrivilege(const Privilege& privilege) = 0;
-
- // Checks if this connection has the privileges necessary to revoke the given privilege
- // from a role.
- virtual Status checkAuthorizedToRevokePrivilege(const Privilege& privilege) = 0;
-
// Checks if the current session is authorized to list the collections in the given
// database. If it is, return a privilegeVector containing the privileges used to authorize
// this command.
@@ -259,26 +202,10 @@ public:
// Checks if this connection has the privileges necessary to create a new role
virtual bool isAuthorizedToCreateRole(const RoleName& roleName) = 0;
- // Utility function for isAuthorizedForActionsOnResource(
- // ResourcePattern::forDatabaseName(role.getDB()), ActionType::grantAnyRole)
- virtual bool isAuthorizedToGrantRole(const RoleName& role) = 0;
-
- // Utility function for isAuthorizedForActionsOnResource(
- // ResourcePattern::forDatabaseName(role.getDB()), ActionType::grantAnyRole)
- virtual bool isAuthorizedToRevokeRole(const RoleName& role) = 0;
-
// Utility function for isAuthorizedToChangeOwnPasswordAsUser and
// isAuthorizedToChangeOwnCustomDataAsUser
virtual bool isAuthorizedToChangeAsUser(const UserName& userName, ActionType actionType) = 0;
- // Returns true if the current session is authenticated as the given user and that user
- // is allowed to change his/her own password
- virtual bool isAuthorizedToChangeOwnPasswordAsUser(const UserName& userName) = 0;
-
- // Returns true if the current session is authenticated as the given user and that user
- // is allowed to change his/her own customData.
- virtual bool isAuthorizedToChangeOwnCustomDataAsUser(const UserName& userName) = 0;
-
// Returns true if any of the authenticated users on this session have the given role.
// NOTE: this does not refresh any of the users even if they are marked as invalid.
virtual bool isAuthenticatedAsUserWithRole(const RoleName& roleName) = 0;
diff --git a/src/mongo/db/auth/authorization_session_impl.cpp b/src/mongo/db/auth/authorization_session_impl.cpp
index 0f131648506..20ed5d956a6 100644
--- a/src/mongo/db/auth/authorization_session_impl.cpp
+++ b/src/mongo/db/auth/authorization_session_impl.cpp
@@ -33,6 +33,7 @@
#include "mongo/db/auth/authorization_session_impl.h"
+#include <array>
#include <string>
#include <vector>
@@ -43,17 +44,10 @@
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authz_session_external_state.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/auth/restriction_environment.h"
-#include "mongo/db/auth/security_key.h"
-#include "mongo/db/auth/user_management_commands_parser.h"
#include "mongo/db/bson/dotted_path_support.h"
-#include "mongo/db/catalog/document_validation.h"
#include "mongo/db/client.h"
-#include "mongo/db/jsobj.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
-#include "mongo/db/pipeline/aggregation_request_helper.h"
-#include "mongo/db/pipeline/lite_parsed_pipeline.h"
#include "mongo/logv2/log.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/str.h"
@@ -62,7 +56,6 @@ namespace mongo {
namespace dps = ::mongo::dotted_path_support;
using std::vector;
-
namespace {
std::unique_ptr<AuthorizationSession> authorizationSessionCreateImpl(
@@ -77,34 +70,6 @@ auto authorizationSessionCreateRegistration =
constexpr StringData ADMIN_DBNAME = "admin"_sd;
-// Checks if this connection has the privileges necessary to create or modify the view 'viewNs'
-// to be a view on 'viewOnNs' with pipeline 'viewPipeline'. Call this function after verifying
-// that the user has the 'createCollection' or 'collMod' action, respectively.
-Status checkAuthForCreateOrModifyView(AuthorizationSession* authzSession,
- const NamespaceString& viewNs,
- const NamespaceString& viewOnNs,
- const BSONArray& viewPipeline,
- bool isMongos) {
- // 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();
- }
-
- auto request = aggregation_request_helper::parseFromBSON(
- viewNs,
- BSON("aggregate" << viewOnNs.coll() << "pipeline" << viewPipeline << "cursor" << BSONObj()
- << "$db" << viewOnNs.db()),
- boost::none,
- false);
-
- auto statusWithPrivs = authzSession->getPrivilegesForAggregate(viewOnNs, request, isMongos);
- PrivilegeVector privileges = uassertStatusOK(statusWithPrivs);
- if (!authzSession->isAuthorizedForPrivileges(privileges)) {
- return Status(ErrorCodes::Unauthorized, "unauthorized");
- }
- return Status::OK();
-}
-
} // namespace
AuthorizationSessionImpl::AuthorizationSessionImpl(
@@ -267,274 +232,6 @@ PrivilegeVector AuthorizationSessionImpl::getDefaultPrivileges() {
return defaultPrivileges;
}
-StatusWith<PrivilegeVector> AuthorizationSessionImpl::getPrivilegesForAggregate(
- const NamespaceString& nss, const AggregateCommand& request, bool isMongos) {
- if (!nss.isValid()) {
- return Status(ErrorCodes::InvalidNamespace,
- str::stream() << "Invalid input namespace, " << nss.ns());
- }
-
- PrivilegeVector privileges;
-
- // If this connection does not need to be authenticated (for instance, if auth is disabled),
- // returns an empty requirements set.
- if (_externalState->shouldIgnoreAuthChecks()) {
- return privileges;
- }
-
- const auto& pipeline = request.getPipeline();
-
- // If the aggregation pipeline is empty, confirm the user is authorized for find on 'nss'.
- if (pipeline.empty()) {
- Privilege currentPriv =
- Privilege(ResourcePattern::forExactNamespace(nss), ActionType::find);
- Privilege::addPrivilegeToPrivilegeVector(&privileges, currentPriv);
- return privileges;
- }
-
- // If the first stage of the pipeline is not an initial source, the pipeline is implicitly
- // reading documents from the underlying collection. The client must be authorized to do so.
- auto liteParsedDocSource = LiteParsedDocumentSource::parse(nss, pipeline[0]);
- if (!liteParsedDocSource->isInitialSource()) {
- Privilege currentPriv =
- Privilege(ResourcePattern::forExactNamespace(nss), ActionType::find);
- Privilege::addPrivilegeToPrivilegeVector(&privileges, currentPriv);
- }
-
- // Confirm privileges for the pipeline.
- for (auto&& pipelineStage : pipeline) {
- liteParsedDocSource = LiteParsedDocumentSource::parse(nss, pipelineStage);
- PrivilegeVector currentPrivs = liteParsedDocSource->requiredPrivileges(
- isMongos, request.getBypassDocumentValidation().value_or(false));
- Privilege::addPrivilegesToPrivilegeVector(&privileges, currentPrivs);
- }
- return privileges;
-}
-
-Status AuthorizationSessionImpl::checkAuthForFind(const NamespaceString& ns, bool hasTerm) {
- if (MONGO_unlikely(ns.isCommand())) {
- return Status(ErrorCodes::InternalError,
- str::stream() << "Checking query auth on command namespace " << ns.ns());
- }
- if (!isAuthorizedForActionsOnNamespace(ns, ActionType::find)) {
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "not authorized for query on " << ns.ns());
- }
-
- // Only internal clients (such as other nodes in a replica set) are allowed to use
- // the 'term' field in a find 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 query with term on " << ns.ns());
- }
-
- return Status::OK();
-}
-
-Status AuthorizationSessionImpl::checkAuthForGetMore(const NamespaceString& ns,
- long long cursorID,
- bool hasTerm) {
- // Since users can only getMore their own cursors, we verify that a user either is authenticated
- // or does not need to be.
- if (!_externalState->shouldIgnoreAuthChecks() && !isAuthenticated()) {
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "not authorized for getMore on " << ns.db());
- }
-
- // 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();
-}
-
-Status AuthorizationSessionImpl::checkAuthForInsert(OperationContext* opCtx,
- const NamespaceString& ns) {
- ActionSet required{ActionType::insert};
- if (DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()) {
- required.addAction(ActionType::bypassDocumentValidation);
- }
- if (!isAuthorizedForActionsOnNamespace(ns, required)) {
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "not authorized for insert on " << ns.ns());
- }
-
- return Status::OK();
-}
-
-Status AuthorizationSessionImpl::checkAuthForUpdate(OperationContext* opCtx,
- const NamespaceString& ns,
- const BSONObj& query,
- const write_ops::UpdateModification& update,
- bool upsert) {
- ActionSet required{ActionType::update};
- StringData operationType = "update"_sd;
-
- if (upsert) {
- required.addAction(ActionType::insert);
- operationType = "upsert"_sd;
- }
-
- if (DocumentValidationSettings::get(opCtx).isSchemaValidationDisabled()) {
- required.addAction(ActionType::bypassDocumentValidation);
- }
-
- if (!isAuthorizedForActionsOnNamespace(ns, required)) {
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "not authorized for " << operationType << " on " << ns.ns());
- }
-
- return Status::OK();
-}
-
-Status AuthorizationSessionImpl::checkAuthForDelete(OperationContext* opCtx,
- const NamespaceString& ns,
- const BSONObj& query) {
- if (!isAuthorizedForActionsOnNamespace(ns, ActionType::remove)) {
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "not authorized to remove from " << ns.ns());
- }
- return Status::OK();
-}
-
-Status AuthorizationSessionImpl::checkAuthForKillCursors(const NamespaceString& ns,
- UserNameIterator cursorOwner) {
- if (isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
- ActionType::killAnyCursor)) {
- return Status::OK();
- }
-
- if (isCoauthorizedWith(cursorOwner)) {
- return Status::OK();
- }
-
- ResourcePattern target;
- if (ns.isListCollectionsCursorNS()) {
- target = ResourcePattern::forDatabaseName(ns.db());
- } else {
- target = ResourcePattern::forExactNamespace(ns);
- }
-
- if (isAuthorizedForActionsOnResource(target, ActionType::killAnyCursor)) {
- return Status::OK();
- }
-
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "not authorized to kill cursor on " << ns.ns());
-}
-
-Status AuthorizationSessionImpl::checkAuthForCreate(const CreateCommand& cmd, bool isMongos) {
- auto ns = cmd.getNamespace();
- if (cmd.getCapped() && !isAuthorizedForActionsOnNamespace(ns, ActionType::convertToCapped)) {
- return {ErrorCodes::Unauthorized, "unauthorized"};
- }
-
- const bool hasCreateCollectionAction =
- isAuthorizedForActionsOnNamespace(ns, ActionType::createCollection);
-
- // If attempting to create a view, check for additional required privileges.
- if (auto optViewOn = cmd.getViewOn()) {
- // You need the createCollection action on this namespace; the insert action is not
- // sufficient.
- if (!hasCreateCollectionAction) {
- return {ErrorCodes::Unauthorized, "unauthorized"};
- }
-
- // Parse the viewOn namespace and the pipeline. If no pipeline was specified, use the empty
- // pipeline.
- NamespaceString viewOnNs(ns.db(), optViewOn.get());
- auto pipeline = cmd.getPipeline().get_value_or(std::vector<BSONObj>());
- BSONArrayBuilder pipelineArray;
- for (const auto& stage : pipeline) {
- pipelineArray.append(stage);
- }
- return checkAuthForCreateOrModifyView(this, ns, viewOnNs, pipelineArray.arr(), isMongos);
- }
-
- // To create a regular collection, ActionType::createCollection or ActionType::insert are
- // both acceptable.
- if (hasCreateCollectionAction || isAuthorizedForActionsOnNamespace(ns, ActionType::insert)) {
- return Status::OK();
- }
-
- return {ErrorCodes::Unauthorized, "unauthorized"};
-}
-
-Status AuthorizationSessionImpl::checkAuthForCollMod(const NamespaceString& ns,
- const BSONObj& cmdObj,
- bool isMongos) {
- if (!isAuthorizedForActionsOnNamespace(ns, ActionType::collMod)) {
- return Status(ErrorCodes::Unauthorized, "unauthorized");
- }
-
- // Check for additional required privileges if attempting to modify a view. When auth is
- // enabled, users must specify both "viewOn" and "pipeline" together. This prevents a user from
- // exposing more information in the original underlying namespace by only changing "pipeline",
- // or looking up more information via the original pipeline by only changing "viewOn".
- const bool hasViewOn = cmdObj.hasField("viewOn");
- const bool hasPipeline = cmdObj.hasField("pipeline");
- if (hasViewOn != hasPipeline) {
- return Status(
- ErrorCodes::InvalidOptions,
- "Must specify both 'viewOn' and 'pipeline' when modifying a view and auth is enabled");
- }
- if (hasViewOn) {
- NamespaceString viewOnNs(ns.db(), cmdObj["viewOn"].checkAndGetStringData());
- auto viewPipeline = BSONArray(cmdObj["pipeline"].Obj());
- return checkAuthForCreateOrModifyView(this, ns, viewOnNs, viewPipeline, isMongos);
- }
-
- return Status::OK();
-}
-
-Status AuthorizationSessionImpl::checkAuthorizedToGrantPrivilege(const Privilege& privilege) {
- const ResourcePattern& resource = privilege.getResourcePattern();
- if (resource.isDatabasePattern() || resource.isExactNamespacePattern()) {
- if (!isAuthorizedForActionsOnResource(
- ResourcePattern::forDatabaseName(resource.databaseToMatch()),
- ActionType::grantRole)) {
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "Not authorized to grant privileges on the "
- << resource.databaseToMatch() << "database");
- }
- } else if (!isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName("admin"),
- ActionType::grantRole)) {
- return Status(ErrorCodes::Unauthorized,
- "To grant privileges affecting multiple databases or the cluster,"
- " must be authorized to grant roles from the admin database");
- }
- return Status::OK();
-}
-
-
-Status AuthorizationSessionImpl::checkAuthorizedToRevokePrivilege(const Privilege& privilege) {
- const ResourcePattern& resource = privilege.getResourcePattern();
- if (resource.isDatabasePattern() || resource.isExactNamespacePattern()) {
- if (!isAuthorizedForActionsOnResource(
- ResourcePattern::forDatabaseName(resource.databaseToMatch()),
- ActionType::revokeRole)) {
- return Status(ErrorCodes::Unauthorized,
- str::stream() << "Not authorized to revoke privileges on the "
- << resource.databaseToMatch() << "database");
- }
- } else if (!isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName("admin"),
- ActionType::revokeRole)) {
- return Status(ErrorCodes::Unauthorized,
- "To revoke privileges affecting multiple databases or the cluster,"
- " must be authorized to revoke roles from the admin database");
- }
- return Status::OK();
-}
-
bool AuthorizationSessionImpl::isAuthorizedToParseNamespaceElement(const BSONElement& element) {
const bool isUUID = element.type() == BinData && element.binDataType() == BinDataType::newUUID;
@@ -586,16 +283,6 @@ bool AuthorizationSessionImpl::isAuthorizedToCreateRole(const RoleName& roleName
return false;
}
-bool AuthorizationSessionImpl::isAuthorizedToGrantRole(const RoleName& role) {
- return isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(role.getDB()),
- ActionType::grantRole);
-}
-
-bool AuthorizationSessionImpl::isAuthorizedToRevokeRole(const RoleName& role) {
- return isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(role.getDB()),
- ActionType::revokeRole);
-}
-
bool AuthorizationSessionImpl::isAuthorizedForPrivilege(const Privilege& privilege) {
if (_externalState->shouldIgnoreAuthChecks())
return true;
@@ -717,16 +404,6 @@ bool AuthorizationSessionImpl::isAuthorizedToChangeAsUser(const UserName& userNa
return actions.contains(actionType);
}
-bool AuthorizationSessionImpl::isAuthorizedToChangeOwnPasswordAsUser(const UserName& userName) {
- return AuthorizationSessionImpl::isAuthorizedToChangeAsUser(userName,
- ActionType::changeOwnPassword);
-}
-
-bool AuthorizationSessionImpl::isAuthorizedToChangeOwnCustomDataAsUser(const UserName& userName) {
- return AuthorizationSessionImpl::isAuthorizedToChangeAsUser(userName,
- ActionType::changeOwnCustomData);
-}
-
StatusWith<PrivilegeVector> AuthorizationSessionImpl::checkAuthorizedToListCollections(
StringData dbname, const BSONObj& cmdObj) {
if (cmdObj["authorizedCollections"].trueValue() && cmdObj["nameOnly"].trueValue() &&
@@ -753,6 +430,10 @@ bool AuthorizationSessionImpl::isAuthenticatedAsUserWithRole(const RoleName& rol
return false;
}
+bool AuthorizationSessionImpl::shouldIgnoreAuthChecks() {
+ return _externalState->shouldIgnoreAuthChecks();
+}
+
bool AuthorizationSessionImpl::isAuthenticated() {
return _authenticatedUsers.begin() != _authenticatedUsers.end();
}
diff --git a/src/mongo/db/auth/authorization_session_impl.h b/src/mongo/db/auth/authorization_session_impl.h
index df74157aebc..598c05d5239 100644
--- a/src/mongo/db/auth/authorization_session_impl.h
+++ b/src/mongo/db/auth/authorization_session_impl.h
@@ -30,7 +30,6 @@
#pragma once
#include <memory>
-#include <string>
#include <vector>
#include "mongo/base/status.h"
@@ -42,7 +41,6 @@
#include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user_set.h"
#include "mongo/db/namespace_string.h"
-#include "mongo/db/pipeline/aggregate_command_gen.h"
namespace mongo {
@@ -80,6 +78,8 @@ public:
User* lookupUser(const UserName& name) override;
+ bool shouldIgnoreAuthChecks() override;
+
bool isAuthenticated() override;
User* getSingleUser() override;
@@ -96,44 +96,9 @@ public:
PrivilegeVector getDefaultPrivileges() override;
- Status checkAuthForFind(const NamespaceString& ns, bool hasTerm) override;
-
- Status checkAuthForGetMore(const NamespaceString& ns,
- long long cursorID,
- bool hasTerm) override;
-
- Status checkAuthForUpdate(OperationContext* opCtx,
- const NamespaceString& ns,
- const BSONObj& query,
- const write_ops::UpdateModification& update,
- bool upsert) override;
-
- Status checkAuthForInsert(OperationContext* opCtx, const NamespaceString& ns) override;
-
- Status checkAuthForDelete(OperationContext* opCtx,
- const NamespaceString& ns,
- const BSONObj& query) override;
-
- Status checkAuthForKillCursors(const NamespaceString& cursorNss,
- UserNameIterator cursorOwner) override;
-
- StatusWith<PrivilegeVector> getPrivilegesForAggregate(const NamespaceString& ns,
- const AggregateCommand& request,
- bool isMongos) override;
-
- Status checkAuthForCreate(const CreateCommand& cmd, bool isMongos) override;
-
- Status checkAuthForCollMod(const NamespaceString& ns,
- const BSONObj& cmdObj,
- bool isMongos) override;
-
StatusWith<PrivilegeVector> checkAuthorizedToListCollections(StringData dbname,
const BSONObj& cmdObj) override;
- Status checkAuthorizedToGrantPrivilege(const Privilege& privilege) override;
-
- Status checkAuthorizedToRevokePrivilege(const Privilege& privilege) override;
-
bool isUsingLocalhostBypass() override;
bool isAuthorizedToParseNamespaceElement(const BSONElement& elem) override;
@@ -142,16 +107,8 @@ public:
bool isAuthorizedToCreateRole(const RoleName& roleName) override;
- bool isAuthorizedToGrantRole(const RoleName& role) override;
-
- bool isAuthorizedToRevokeRole(const RoleName& role) override;
-
bool isAuthorizedToChangeAsUser(const UserName& userName, ActionType actionType) override;
- bool isAuthorizedToChangeOwnPasswordAsUser(const UserName& userName) override;
-
- bool isAuthorizedToChangeOwnCustomDataAsUser(const UserName& userName) override;
-
bool isAuthenticatedAsUserWithRole(const RoleName& roleName) override;
bool isAuthorizedForPrivilege(const Privilege& privilege) override;
diff --git a/src/mongo/db/auth/authorization_session_test.cpp b/src/mongo/db/auth/authorization_session_test.cpp
index 994c82850c0..517117dd298 100644
--- a/src/mongo/db/auth/authorization_session_test.cpp
+++ b/src/mongo/db/auth/authorization_session_test.cpp
@@ -37,6 +37,7 @@
#include "mongo/crypto/sha1_block.h"
#include "mongo/crypto/sha256_block.h"
#include "mongo/db/auth/action_type.h"
+#include "mongo/db/auth/authorization_checks.h"
#include "mongo/db/auth/authorization_manager_impl.h"
#include "mongo/db/auth/authorization_session_for_test.h"
#include "mongo/db/auth/authz_manager_external_state_mock.h"
@@ -599,8 +600,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateEmptyPipelineWithoutFindAction)
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << BSONArray() << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -611,8 +612,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateEmptyPipelineWithFindAction) {
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << BSONArray() << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -627,8 +628,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateWithoutFindActionIfFirstStageNot
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -641,8 +642,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateWithFindActionIfPipelineContains
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -654,8 +655,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateCollStatsWithoutCollStatsAction)
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -667,8 +668,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateCollStatsWithCollStatsAction) {
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -680,8 +681,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateIndexStatsWithoutIndexStatsActio
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -693,8 +694,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateIndexStatsWithIndexStatsAction) {
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -706,8 +707,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateCurrentOpAllUsersFalseWithoutInprog
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -719,8 +720,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateCurrentOpAllUsersFalseWithoutInp
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -740,8 +741,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateCurrentOpAllUsersFalseIfNotAuthe
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -753,8 +754,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateCurrentOpAllUsersTrueWithoutInpr
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -766,8 +767,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateCurrentOpAllUsersTrueWithoutInpr
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -780,8 +781,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateCurrentOpAllUsersTrueWithInprogActi
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -794,8 +795,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateCurrentOpAllUsersTrueWithInprogActi
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -808,8 +809,8 @@ TEST_F(AuthorizationSessionTest, CannotSpoofAllUsersTrueWithoutInprogActionOnMon
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -822,8 +823,8 @@ TEST_F(AuthorizationSessionTest, CannotSpoofAllUsersTrueWithoutInprogActionOnMon
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -836,9 +837,10 @@ TEST_F(AuthorizationSessionTest, AddPrivilegesForStageFailsIfOutNamespaceIsNotVa
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- ASSERT_THROWS_CODE(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false),
- AssertionException,
- ErrorCodes::InvalidNamespace);
+ ASSERT_THROWS_CODE(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false),
+ AssertionException,
+ ErrorCodes::InvalidNamespace);
}
TEST_F(AuthorizationSessionTest, CannotAggregateOutWithoutInsertAndRemoveOnTargetNamespace) {
@@ -850,8 +852,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateOutWithoutInsertAndRemoveOnTarge
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
// We have insert but not remove on the $out namespace.
@@ -875,8 +877,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateOutWithInsertAndRemoveOnTargetNames
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
auto aggNoBypassDocumentValidationReq =
@@ -886,8 +888,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateOutWithInsertAndRemoveOnTargetNames
<< "bypassDocumentValidation" << false << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- privileges = uassertStatusOK(authzSession->getPrivilegesForAggregate(
- testFooNss, aggNoBypassDocumentValidationReq, false));
+ privileges = uassertStatusOK(auth::getPrivilegesForAggregate(
+ authzSession.get(), testFooNss, aggNoBypassDocumentValidationReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -902,8 +904,8 @@ TEST_F(AuthorizationSessionTest,
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "bypassDocumentValidation" << true << "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -920,8 +922,8 @@ TEST_F(AuthorizationSessionTest,
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "bypassDocumentValidation" << true << "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -933,8 +935,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateLookupWithoutFindOnJoinedNamespa
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -947,8 +949,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateLookupWithFindOnJoinedNamespace) {
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -964,8 +966,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateLookupWithoutFindOnNestedJoinedN
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -981,8 +983,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateLookupWithFindOnNestedJoinedNamespa
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -1026,8 +1028,8 @@ TEST_F(AuthorizationSessionTest, CheckAuthForAggregateWithDeeplyNestedLookup) {
auto aggReq = uassertStatusOK(
aggregation_request_helper::parseFromBSONForTests(testFooNss, cmdBuilder.obj()));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -1040,8 +1042,8 @@ TEST_F(AuthorizationSessionTest, CannotAggregateGraphLookupWithoutFindOnJoinedNa
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -1054,8 +1056,8 @@ TEST_F(AuthorizationSessionTest, CanAggregateGraphLookupWithFindOnJoinedNamespac
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
@@ -1071,8 +1073,8 @@ TEST_F(AuthorizationSessionTest,
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, false));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, false));
ASSERT_FALSE(authzSession->isAuthorizedForPrivileges(privileges));
// We have find on the $lookup namespace but not on the $graphLookup namespace.
@@ -1100,8 +1102,8 @@ TEST_F(AuthorizationSessionTest,
testFooNss,
BSON("aggregate" << testFooNss.coll() << "pipeline" << pipeline << "cursor" << BSONObj()
<< "$db" << testFooNss.db())));
- PrivilegeVector privileges =
- uassertStatusOK(authzSession->getPrivilegesForAggregate(testFooNss, aggReq, true));
+ PrivilegeVector privileges = uassertStatusOK(
+ auth::getPrivilegesForAggregate(authzSession.get(), testFooNss, aggReq, true));
ASSERT_TRUE(authzSession->isAuthorizedForPrivileges(privileges));
}
diff --git a/src/mongo/db/auth/authz_manager_external_state_local.cpp b/src/mongo/db/auth/authz_manager_external_state_local.cpp
index 966a8271517..c471dffd63f 100644
--- a/src/mongo/db/auth/authz_manager_external_state_local.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_local.cpp
@@ -34,9 +34,6 @@
#include "mongo/db/auth/authz_manager_external_state_local.h"
#include "mongo/base/status.h"
-#include "mongo/bson/mutable/algorithm.h"
-#include "mongo/bson/mutable/document.h"
-#include "mongo/bson/mutable/element.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/db/auth/address_restriction.h"
#include "mongo/db/auth/auth_options_gen.h"
diff --git a/src/mongo/db/auth/authz_manager_external_state_local.h b/src/mongo/db/auth/authz_manager_external_state_local.h
index 68d24ebed79..629bdfe3340 100644
--- a/src/mongo/db/auth/authz_manager_external_state_local.h
+++ b/src/mongo/db/auth/authz_manager_external_state_local.h
@@ -42,10 +42,6 @@
namespace mongo {
-namespace mutablebson {
-class Document;
-} // namespace mutablebson
-
/**
* Common implementation of AuthzManagerExternalState for systems where role
* and user information are stored locally.
diff --git a/src/mongo/db/auth/builtin_roles_test.cpp b/src/mongo/db/auth/builtin_roles_test.cpp
index e58ca9b2bf6..283c7f57df7 100644
--- a/src/mongo/db/auth/builtin_roles_test.cpp
+++ b/src/mongo/db/auth/builtin_roles_test.cpp
@@ -33,7 +33,6 @@
#include <algorithm>
-#include "mongo/bson/mutable/document.h"
#include "mongo/db/auth/builtin_roles.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/sequence_util.h"
diff --git a/src/mongo/db/auth/sasl_authentication_session_test.cpp b/src/mongo/db/auth/sasl_authentication_session_test.cpp
index 7e4bd3766c8..d8df2909511 100644
--- a/src/mongo/db/auth/sasl_authentication_session_test.cpp
+++ b/src/mongo/db/auth/sasl_authentication_session_test.cpp
@@ -30,9 +30,6 @@
#include <string>
#include <vector>
-#include "mongo/bson/mutable/algorithm.h"
-#include "mongo/bson/mutable/document.h"
-#include "mongo/bson/mutable/element.h"
#include "mongo/client/sasl_client_session.h"
#include "mongo/crypto/mechanism_scram.h"
#include "mongo/db/auth/authorization_manager.h"
diff --git a/src/mongo/db/auth/sasl_commands.cpp b/src/mongo/db/auth/sasl_commands.cpp
index 30244aac85d..25f09916a51 100644
--- a/src/mongo/db/auth/sasl_commands.cpp
+++ b/src/mongo/db/auth/sasl_commands.cpp
@@ -36,8 +36,6 @@
#include "mongo/base/init.h"
#include "mongo/base/status.h"
#include "mongo/base/string_data.h"
-#include "mongo/bson/mutable/algorithm.h"
-#include "mongo/bson/mutable/document.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/client/authenticate.h"
#include "mongo/client/sasl_client_authenticate.h"