diff options
author | Spencer Jackson <spencer.jackson@mongodb.com> | 2017-05-23 17:25:40 -0400 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2017-06-20 09:54:38 -0400 |
commit | 14f18168d8a9ab8a62256db7ad8f7983d3bbfd8f (patch) | |
tree | b1815e3d47c3b5bfda7fb8342592be9dc164fe29 | |
parent | 0c8f38a70e1ddfd657bec265749c49c4df97dc1e (diff) | |
download | mongo-14f18168d8a9ab8a62256db7ad8f7983d3bbfd8f.tar.gz |
SERVER-28344: Implement the admin.system.sessions collection
-rw-r--r-- | jstests/noPassthrough/system_indexes.js (renamed from jstests/auth/system_authorization_indexes.js) | 13 | ||||
-rw-r--r-- | src/mongo/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/SConscript | 12 | ||||
-rw-r--r-- | src/mongo/db/auth/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/database_holder_impl.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/catalog/database_impl.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/db.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/ops/insert.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/system_index.cpp (renamed from src/mongo/db/auth/auth_index_d.cpp) | 51 | ||||
-rw-r--r-- | src/mongo/db/system_index.h (renamed from src/mongo/db/auth/auth_index_d.h) | 16 |
11 files changed, 82 insertions, 26 deletions
diff --git a/jstests/auth/system_authorization_indexes.js b/jstests/noPassthrough/system_indexes.js index 75c7b098916..0ef6a362f40 100644 --- a/jstests/auth/system_authorization_indexes.js +++ b/jstests/noPassthrough/system_indexes.js @@ -60,4 +60,17 @@ conn = MongoRunner.runMongod({restart: conn, cleanData: false}); db = conn.getDB("admin"); assert.eq(2, db.system.roles.getIndexes().length); + + // TEST: Inserting to the sessions collection creates indexes + assert.eq(0, db.system.sessions.getIndexes().length); + db.system.sessions.insert({lastUse: new Date()}); + assert.eq(2, db.system.sessions.getIndexes().length); + + // TEST: Destroying admin.system.sessions index and restarting will recreate it + assert.commandWorked(db.system.sessions.dropIndexes()); + MongoRunner.stopMongod(conn); + conn = MongoRunner.runMongod({restart: conn, cleanData: false}); + db = conn.getDB("admin"); + assert.eq(2, db.system.sessions.getIndexes().length); + })(); diff --git a/src/mongo/SConscript b/src/mongo/SConscript index e0a230e17fb..e223758ada8 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -302,6 +302,7 @@ mongod = env.Program( 'db/serveronly', 'db/service_context_d', 'db/startup_warnings_mongod', + 'db/system_index', 'db/ttl_d', 'executor/network_interface_factory', 'rpc/rpc', diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index 584b675859d..8ae073e544d 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -564,6 +564,18 @@ env.Library( ) env.Library( + target='system_index', + source=[ + 'system_index.cpp', + ], + LIBDEPS=[ + 'db_raii', + 'catalog/index_key_validate', + 'logical_session_cache', + ], +) + +env.Library( target="service_context_d", source=[ "service_context_d.cpp", diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index c4329719357..968771fb8d2 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -170,12 +170,10 @@ env.Library('saslauth', env.Library('authmongod', ['authz_manager_external_state_d.cpp', 'authz_session_external_state_d.cpp', - 'auth_index_d.cpp', 'impersonation_session.cpp' ], LIBDEPS=[ 'authservercommon', - '$BUILD_DIR/mongo/db/catalog/index_key_validate', '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/dbdirectclient', '$BUILD_DIR/mongo/db/dbhelpers', diff --git a/src/mongo/db/catalog/SConscript b/src/mongo/db/catalog/SConscript index 4dc1f6a66cc..96796d1ff23 100644 --- a/src/mongo/db/catalog/SConscript +++ b/src/mongo/db/catalog/SConscript @@ -171,7 +171,6 @@ env.Library( 'index_create', 'index_key_validate', '$BUILD_DIR/mongo/base', - '$BUILD_DIR/mongo/db/auth/authmongod', '$BUILD_DIR/mongo/db/clientcursor', '$BUILD_DIR/mongo/db/concurrency/lock_manager', '$BUILD_DIR/mongo/db/curop', @@ -181,6 +180,7 @@ env.Library( '$BUILD_DIR/mongo/db/service_context', '$BUILD_DIR/mongo/db/storage/mmap_v1/storage_mmapv1', '$BUILD_DIR/mongo/db/storage/key_string', + '$BUILD_DIR/mongo/db/system_index', '$BUILD_DIR/mongo/db/ttl_collection_cache', '$BUILD_DIR/mongo/db/collection_index_usage_tracker', '$BUILD_DIR/mongo/db/background', diff --git a/src/mongo/db/catalog/database_holder_impl.cpp b/src/mongo/db/catalog/database_holder_impl.cpp index 4649fca4aa6..dcb4e4bca5d 100644 --- a/src/mongo/db/catalog/database_holder_impl.cpp +++ b/src/mongo/db/catalog/database_holder_impl.cpp @@ -34,7 +34,6 @@ #include "mongo/base/init.h" #include "mongo/db/audit.h" -#include "mongo/db/auth/auth_index_d.h" #include "mongo/db/background.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_catalog_entry.h" diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp index 9a4e826d8c7..387d96cf98b 100644 --- a/src/mongo/db/catalog/database_impl.cpp +++ b/src/mongo/db/catalog/database_impl.cpp @@ -38,7 +38,6 @@ #include "mongo/base/init.h" #include "mongo/db/audit.h" -#include "mongo/db/auth/auth_index_d.h" #include "mongo/db/background.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_catalog_entry.h" @@ -63,6 +62,7 @@ #include "mongo/db/storage/recovery_unit.h" #include "mongo/db/storage/storage_engine.h" #include "mongo/db/storage/storage_options.h" +#include "mongo/db/system_index.h" #include "mongo/db/views/view_catalog.h" #include "mongo/util/assert_util.h" #include "mongo/util/log.h" @@ -727,7 +727,7 @@ Collection* DatabaseImpl::createCollection(OperationContext* opCtx, } if (nss.isSystem()) { - authindex::createSystemIndexes(opCtx, collection); + createSystemIndexes(opCtx, collection); } } diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index a5d87bfbf55..5949ade69ad 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -45,7 +45,6 @@ #include "mongo/client/replica_set_monitor.h" #include "mongo/config.h" #include "mongo/db/audit.h" -#include "mongo/db/auth/auth_index_d.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_manager_global.h" #include "mongo/db/catalog/collection.h" @@ -109,6 +108,7 @@ #include "mongo/db/storage/mmap_v1/mmap_v1_options.h" #include "mongo/db/storage/storage_engine.h" #include "mongo/db/storage/storage_options.h" +#include "mongo/db/system_index.h" #include "mongo/db/ttl.h" #include "mongo/db/wire_version.h" #include "mongo/executor/network_connection_hook.h" @@ -594,7 +594,7 @@ ExitCode _initAndListen(int listenPort) { AuthorizationManager* globalAuthzManager = getGlobalAuthorizationManager(); if (globalAuthzManager->shouldValidateAuthSchemaOnStartup()) { - Status status = authindex::verifySystemIndexes(startupOpCtx.get()); + Status status = verifySystemIndexes(startupOpCtx.get()); if (!status.isOK()) { log() << redact(status); if (status.code() == ErrorCodes::AuthSchemaIncompatible) { diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp index c448126eca7..245734cffce 100644 --- a/src/mongo/db/ops/insert.cpp +++ b/src/mongo/db/ops/insert.cpp @@ -235,6 +235,8 @@ Status userAllowedCreateNS(StringData db, StringData coll) { if (db == "admin") { if (coll == "system.version") return Status::OK(); + if (coll == "system.sessions") + return Status::OK(); if (coll == "system.roles") return Status::OK(); if (coll == "system.new_users") diff --git a/src/mongo/db/auth/auth_index_d.cpp b/src/mongo/db/system_index.cpp index ff12e9f4f6d..a46b1bf45eb 100644 --- a/src/mongo/db/auth/auth_index_d.cpp +++ b/src/mongo/db/system_index.cpp @@ -1,5 +1,5 @@ /** -* Copyright (C) 2012 10gen Inc. +* Copyright (C) 2017 MongoDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, @@ -26,11 +26,11 @@ * it in the license file. */ -#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kAccessControl +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kStorage #include "mongo/platform/basic.h" -#include "mongo/db/auth/auth_index_d.h" +#include "mongo/db/system_index.h" #include "mongo/base/init.h" #include "mongo/base/status.h" @@ -47,23 +47,27 @@ #include "mongo/db/db_raii.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/jsobj.h" +#include "mongo/db/logical_session_cache.h" #include "mongo/util/assert_util.h" #include "mongo/util/log.h" -namespace mongo { - -using std::endl; +using namespace std::chrono_literals; -namespace authindex { +namespace mongo { namespace { BSONObj v1SystemUsersKeyPattern; BSONObj v3SystemUsersKeyPattern; BSONObj v3SystemRolesKeyPattern; +BSONObj v1SystemSessionsKeyPattern; std::string v3SystemUsersIndexName; std::string v3SystemRolesIndexName; +std::string v1SystemSessionsIndexName; IndexSpec v3SystemUsersIndexSpec; IndexSpec v3SystemRolesIndexSpec; +IndexSpec v1SystemSessionsIndexSpec; + +const NamespaceString sessionCollectionNamespace("admin.system.sessions"); MONGO_INITIALIZER(AuthIndexKeyPatterns)(InitializerContext*) { v1SystemUsersKeyPattern = BSON("user" << 1 << "userSource" << 1); @@ -73,6 +77,7 @@ MONGO_INITIALIZER(AuthIndexKeyPatterns)(InitializerContext*) { v3SystemRolesKeyPattern = BSON( AuthorizationManager::ROLE_NAME_FIELD_NAME << 1 << AuthorizationManager::ROLE_DB_FIELD_NAME << 1); + v1SystemSessionsKeyPattern = BSON("lastUse" << 1); v3SystemUsersIndexName = std::string(str::stream() << AuthorizationManager::USER_NAME_FIELD_NAME << "_1_" << AuthorizationManager::USER_DB_FIELD_NAME @@ -81,6 +86,7 @@ MONGO_INITIALIZER(AuthIndexKeyPatterns)(InitializerContext*) { std::string(str::stream() << AuthorizationManager::ROLE_NAME_FIELD_NAME << "_1_" << AuthorizationManager::ROLE_DB_FIELD_NAME << "_1"); + v1SystemSessionsIndexName = "lastUse_1"; v3SystemUsersIndexSpec.addKeys(v3SystemUsersKeyPattern); v3SystemUsersIndexSpec.unique(); @@ -90,6 +96,11 @@ MONGO_INITIALIZER(AuthIndexKeyPatterns)(InitializerContext*) { v3SystemRolesIndexSpec.unique(); v3SystemRolesIndexSpec.name(v3SystemRolesIndexName); + v1SystemSessionsIndexSpec.addKeys(v1SystemSessionsKeyPattern); + v1SystemSessionsIndexSpec.expireAfterSeconds( + durationCount<Seconds>(Minutes(localLogicalSessionTimeoutMinutes))); + v1SystemSessionsIndexSpec.name(v1SystemSessionsIndexName); + return Status::OK(); } @@ -188,6 +199,23 @@ Status verifySystemIndexes(OperationContext* opCtx) { } } + // Ensure that system indexes exist for the sessions collection, if it exists. + collection = autoDb.getDb()->getCollection(opCtx, sessionCollectionNamespace); + if (collection) { + IndexCatalog* indexCatalog = collection->getIndexCatalog(); + invariant(indexCatalog); + + std::vector<IndexDescriptor*> indexes; + indexCatalog->findIndexesByKeyPattern(opCtx, v1SystemSessionsKeyPattern, false, &indexes); + if (indexes.empty()) { + try { + generateSystemIndexForExistingCollection( + opCtx, collection, sessionCollectionNamespace, v1SystemSessionsIndexSpec); + } catch (...) { + return exceptionToStatus(); + } + } + } return Status::OK(); } @@ -211,8 +239,15 @@ void createSystemIndexes(OperationContext* opCtx, Collection* collection) { fassertStatusOK( 40458, collection->getIndexCatalog()->createIndexOnEmptyCollection(opCtx, indexSpec)); + } else if (ns == sessionCollectionNamespace) { + auto indexSpec = fassertStatusOK( + 40493, + index_key_validate::validateIndexSpec( + v1SystemSessionsIndexSpec.toBSON(), ns, serverGlobalParams.featureCompatibility)); + + fassertStatusOK( + 40494, collection->getIndexCatalog()->createIndexOnEmptyCollection(opCtx, indexSpec)); } } -} // namespace authindex } // namespace mongo diff --git a/src/mongo/db/auth/auth_index_d.h b/src/mongo/db/system_index.h index 6b2be592489..bb0c1c23d81 100644 --- a/src/mongo/db/auth/auth_index_d.h +++ b/src/mongo/db/system_index.h @@ -1,5 +1,5 @@ /** -* Copyright (C) 2012 10gen Inc. +* Copyright (C) 2017 MongoDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, @@ -28,26 +28,22 @@ #pragma once -#include "mongo/db/namespace_string.h" - namespace mongo { class Collection; class OperationContext; - -namespace authindex { +class Status; /** - * Creates the appropriate indexes on _new_ system collections supporting authentication and - * authorization. + * Creates the appropriate indexes on _new_ system collections for authentication, + * authorization, and sessions. */ void createSystemIndexes(OperationContext* opCtx, Collection* collection); /** - * Verifies that only the appropriate indexes to support authentication and authorization - * are present in the admin database + * Verifies that only the appropriate indexes to support authentication, authorization, and + * sessions are present in the admin database. Will create new indexes, if they are missing. */ Status verifySystemIndexes(OperationContext* opCtx); -} // namespace authindex } // namespace mongo |