diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2022-03-31 19:23:39 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-01 05:00:23 +0000 |
commit | cbd9d61b6e44a560cb01b7412093502148327d56 (patch) | |
tree | 8c02bf0a3ba128aaad27ae5734502d1847c36dc0 /src/mongo/db/catalog/drop_collection.cpp | |
parent | 0b63ce894a4bed73014c0484f2bf811d99114d58 (diff) | |
download | mongo-cbd9d61b6e44a560cb01b7412093502148327d56.tar.gz |
SERVER-64914 warn if a user drops an encrypted collection before state collections
Diffstat (limited to 'src/mongo/db/catalog/drop_collection.cpp')
-rw-r--r-- | src/mongo/db/catalog/drop_collection.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/mongo/db/catalog/drop_collection.cpp b/src/mongo/db/catalog/drop_collection.cpp index 58b546bcbf5..54f861bafa3 100644 --- a/src/mongo/db/catalog/drop_collection.cpp +++ b/src/mongo/db/catalog/drop_collection.cpp @@ -43,6 +43,7 @@ #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" #include "mongo/db/index_builds_coordinator.h" +#include "mongo/db/operation_context.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/s/collection_sharding_state.h" #include "mongo/db/server_options.h" @@ -51,6 +52,7 @@ #include "mongo/util/fail_point.h" namespace mongo { +namespace { MONGO_FAIL_POINT_DEFINE(hangDropCollectionBeforeLockAcquisition); MONGO_FAIL_POINT_DEFINE(hangDuringDropCollection); @@ -69,6 +71,44 @@ Status _checkNssAndReplState(OperationContext* opCtx, const CollectionPtr& coll) return Status::OK(); } +void checkForCollection(std::shared_ptr<const CollectionCatalog> collectionCatalog, + OperationContext* opCtx, + const NamespaceString& baseNss, + boost::optional<StringData> collName, + std::vector<std::string>* pLeaked) { + + if (collName.has_value()) { + auto nss = NamespaceString(baseNss.db(), collName.value()); + + if (collectionCatalog->lookupCollectionByNamespace(opCtx, nss)) { + pLeaked->push_back(nss.toString()); + } + } +} + +void warnEncryptedCollectionsIfNeeded(OperationContext* opCtx, const CollectionPtr& coll) { + if (!coll->getCollectionOptions().encryptedFieldConfig.has_value()) { + return; + } + + auto catalog = CollectionCatalog::get(opCtx); + auto efc = coll->getCollectionOptions().encryptedFieldConfig.get(); + + std::vector<std::string> leaked; + + checkForCollection(catalog, opCtx, coll->ns(), efc.getEscCollection(), &leaked); + checkForCollection(catalog, opCtx, coll->ns(), efc.getEccCollection(), &leaked); + checkForCollection(catalog, opCtx, coll->ns(), efc.getEcocCollection(), &leaked); + + if (!leaked.empty()) { + LOGV2_WARNING( + 6491401, + "An encrypted collection was dropped before one or more of its state collections", + "name"_attr = coll->ns(), + "stateCollections"_attr = leaked); + } +} + Status _dropView(OperationContext* opCtx, Database* db, const NamespaceString& collectionName, @@ -317,7 +357,11 @@ Status _dropCollection(OperationContext* opCtx, return Status(ErrorCodes::NamespaceNotFound, "ns not found"); } - if (CollectionCatalog::get(opCtx)->lookupCollectionByNamespace(opCtx, collectionName)) { + auto collectionPtr = + CollectionCatalog::get(opCtx)->lookupCollectionByNamespace(opCtx, collectionName); + if (collectionPtr) { + warnEncryptedCollectionsIfNeeded(opCtx, collectionPtr); + return _abortIndexBuildsAndDrop( opCtx, std::move(autoDb), @@ -421,6 +465,7 @@ Status _dropCollection(OperationContext* opCtx, return Status(ErrorCodes::NamespaceNotFound, "ns not found"); } } +} // namespace Status dropCollection(OperationContext* opCtx, const NamespaceString& nss, |