From ab7ceed2108a7d19518490929b03fa6f4a13257c Mon Sep 17 00:00:00 2001 From: Ian Whalen Date: Fri, 22 Sep 2017 16:10:50 -0400 Subject: Revert "SERVER-31174 Move the sessions collection to config.system.sessions" This reverts commit ba1704f7cbc0b9a03a181df145f75f433a59b7df. --- jstests/auth/lib/commands_lib.js | 6 +- jstests/auth/list_all_sessions.js | 9 +- jstests/auth/list_sessions.js | 11 +- jstests/core/list_all_sessions.js | 3 +- jstests/core/list_sessions.js | 5 +- .../refresh_logical_session_cache_now.js | 9 +- jstests/noPassthrough/refresh_sessions_command.js | 15 +-- jstests/noPassthrough/system_indexes.js | 16 ++- .../noPassthrough/verify_session_cache_updates.js | 4 +- jstests/replsets/refresh_sessions_rs.js | 2 +- jstests/sharding/refresh_sessions.js | 2 +- src/mongo/db/namespace_string.cpp | 3 +- src/mongo/db/ops/insert.cpp | 6 +- .../db/pipeline/document_source_list_sessions.h | 2 +- src/mongo/db/sessions_collection.h | 4 +- src/mongo/db/system_index.cpp | 128 ++++++++++----------- src/mongo/dbtests/logical_sessions_tests.cpp | 2 +- 17 files changed, 101 insertions(+), 126 deletions(-) diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js index 6717e17e64d..90b8d1051f8 100644 --- a/jstests/auth/lib/commands_lib.js +++ b/jstests/auth/lib/commands_lib.js @@ -664,7 +664,7 @@ var authCommandsLib = { testname: "aggregate_listLocalSessions_allUsers_true", command: {aggregate: 1, pipeline: [{$listLocalSessions: {allUsers: true}}], cursor: {}}, testcases: [{ - runOnDb: "config", + runOnDb: adminDbName, roles: {clusterAdmin: 1, clusterMonitor: 1, clusterManager: 1, root: 1, __system: 1} }], @@ -684,7 +684,7 @@ var authCommandsLib = { cursor: {} }, testcases: [{ - runOnDb: "config", + runOnDb: adminDbName, roles: {clusterAdmin: 1, clusterMonitor: 1, clusterManager: 1, root: 1, __system: 1} }] @@ -696,7 +696,7 @@ var authCommandsLib = { pipeline: [{$listSessions: {allUsers: false}}], cursor: {} }, - testcases: [{runOnDb: "config", roles: roles_all}] + testcases: [{runOnDb: adminDbName, roles: roles_all}] }, { testname: "aggregate_lookup", diff --git a/jstests/auth/list_all_sessions.js b/jstests/auth/list_all_sessions.js index 2fd47476ee9..68053722323 100644 --- a/jstests/auth/list_all_sessions.js +++ b/jstests/auth/list_all_sessions.js @@ -7,11 +7,10 @@ function runListAllSessionsTest(mongod) { assert(mongod); const admin = mongod.getDB("admin"); - const config = mongod.getDB("config"); const pipeline = [{'$listSessions': {allUsers: true}}]; function listSessions() { - return config.system.sessions.aggregate(pipeline); + return admin.system.sessions.aggregate(pipeline); } admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles}); @@ -20,7 +19,7 @@ admin.logout(); // Fail if we're not logged in. - assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized); + assertErrorCode(admin.system.sessions, pipeline, ErrorCodes.Unauthorized); // Start a new session and capture its sessionId. assert(admin.auth('user1', 'pass')); @@ -29,11 +28,11 @@ assert.commandWorked(admin.runCommand({refreshLogicalSessionCacheNow: 1})); // Ensure that a normal user can NOT listSessions{allUsers:true} to view their session. - assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized); + assertErrorCode(admin.system.sessions, pipeline, ErrorCodes.Unauthorized); // Ensure that a normal user can NOT listSessions to view others' sessions. const viewAdminPipeline = [{'$listSessions': {users: [{user: 'admin', db: 'admin'}]}}]; - assertErrorCode(config.system.sessions, viewAdminPipeline, ErrorCodes.Unauthorized); + assertErrorCode(admin.system.sessions, viewAdminPipeline, ErrorCodes.Unauthorized); // Ensure that the cache now contains the session and is visible by admin assert(admin.auth('admin', 'pass')); diff --git a/jstests/auth/list_sessions.js b/jstests/auth/list_sessions.js index b130999a3ef..4647f6d75c7 100644 --- a/jstests/auth/list_sessions.js +++ b/jstests/auth/list_sessions.js @@ -7,11 +7,10 @@ function runListSessionsTest(mongod) { assert(mongod); const admin = mongod.getDB('admin'); - const config = mongod.getDB('config'); const pipeline = [{'$listSessions': {}}]; function listSessions() { - return config.system.sessions.aggregate(pipeline); + return admin.system.sessions.aggregate(pipeline); } admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles}); @@ -22,7 +21,7 @@ admin.logout(); // Fail when not logged in. - assertErrorCode(config.system.sessions, pipeline, ErrorCodes.Unauthorized); + assertErrorCode(admin.system.sessions, pipeline, ErrorCodes.Unauthorized); // Start a new session and capture its sessionId. assert(admin.auth('user1', 'pass')); @@ -40,7 +39,7 @@ // Ask again using explicit UID. const user1Pipeline = [{'$listSessions': {users: [{user: "user1", db: "admin"}]}}]; function listUser1Sessions() { - return config.system.sessions.aggregate(user1Pipeline); + return admin.system.sessions.aggregate(user1Pipeline); } const resultArrayMine = listUser1Sessions().toArray(); assert.eq(bsonWoCompare(resultArray, resultArrayMine), 0); @@ -53,14 +52,14 @@ assert.eq(listSessions().toArray().length, 0); // Ensure users can't view either other's sessions. - assertErrorCode(config.system.sessions, user1Pipeline, ErrorCodes.Unauthorized); + assertErrorCode(admin.system.sessions, user1Pipeline, ErrorCodes.Unauthorized); if (true) { // TODO SERVER-29141: Support forcing pipelines to run on mongos return; } function listLocalSessions() { - return config.aggregate([{'$listLocalSessions': {}}]); + return admin.aggregate([{'$listLocalSessions': {}}]); } assert.eq(listLocalSessions().toArray().length, 0); } diff --git a/jstests/core/list_all_sessions.js b/jstests/core/list_all_sessions.js index cf36f1187dd..aef0ae33109 100644 --- a/jstests/core/list_all_sessions.js +++ b/jstests/core/list_all_sessions.js @@ -5,10 +5,9 @@ load('jstests/aggregation/extras/utils.js'); const admin = db.getSiblingDB("admin"); - const config = db.getSiblingDB("config"); const pipeline = [{'$listSessions': {allUsers: true}}]; function listSessions() { - return config.system.sessions.aggregate(pipeline); + return admin.system.sessions.aggregate(pipeline); } // Start a new session and capture its sessionId. diff --git a/jstests/core/list_sessions.js b/jstests/core/list_sessions.js index e2b8adb5a78..0636377a3be 100644 --- a/jstests/core/list_sessions.js +++ b/jstests/core/list_sessions.js @@ -5,10 +5,9 @@ load('jstests/aggregation/extras/utils.js'); const admin = db.getSiblingDB('admin'); - const config = db.getSiblingDB('config'); const pipeline = [{'$listSessions': {}}]; function listSessions() { - return config.system.sessions.aggregate(pipeline); + return admin.system.sessions.aggregate(pipeline); } // Start a new session and capture its sessionId. @@ -48,7 +47,7 @@ return {user: authUsers[0].user, db: authUsers[0].db}; })(); function listMySessions() { - return config.system.sessions.aggregate([{'$listSessions': {users: [myusername]}}]); + return admin.system.sessions.aggregate([{'$listSessions': {users: [myusername]}}]); } const myArray = listMySessions().toArray(); assert.eq(resultArray.length, myArray.length); diff --git a/jstests/noPassthrough/refresh_logical_session_cache_now.js b/jstests/noPassthrough/refresh_logical_session_cache_now.js index 6d10cbca451..e3fe583f074 100644 --- a/jstests/noPassthrough/refresh_logical_session_cache_now.js +++ b/jstests/noPassthrough/refresh_logical_session_cache_now.js @@ -8,7 +8,6 @@ // Start up a standalone server. var conn = MongoRunner.runMongod({nojournal: ""}); var admin = conn.getDB("admin"); - var config = conn.getDB("config"); // Trigger an initial refresh, as a sanity check. res = admin.runCommand(refresh); @@ -18,13 +17,13 @@ res = admin.runCommand(startSession); assert.commandWorked(res, "unable to start session"); - assert.eq(config.system.sessions.count(), 0, "should not have session records yet"); + assert.eq(admin.system.sessions.count(), 0, "should not have session records yet"); // Trigger a refresh. Session should now be in the collection. res = admin.runCommand(refresh); assert.commandWorked(res, "failed to refresh"); - assert.eq(config.system.sessions.count(), 1, "should have written session records"); + assert.eq(admin.system.sessions.count(), 1, "should have written session records"); // Start some new sessions. Should not be in the collection yet. var numSessions = 100; @@ -33,13 +32,13 @@ assert.commandWorked(res, "unable to start session"); } - assert.eq(config.system.sessions.count(), 1, "should not have more session records yet"); + assert.eq(admin.system.sessions.count(), 1, "should not have more session records yet"); // Trigger another refresh. All sessions should now be in the collection. res = admin.runCommand(refresh); assert.commandWorked(res, "failed to refresh"); assert.eq( - config.system.sessions.count(), numSessions + 1, "should have written session records"); + admin.system.sessions.count(), numSessions + 1, "should have written session records"); }()); diff --git a/jstests/noPassthrough/refresh_sessions_command.js b/jstests/noPassthrough/refresh_sessions_command.js index 80b249faca7..0c08d0891ce 100644 --- a/jstests/noPassthrough/refresh_sessions_command.js +++ b/jstests/noPassthrough/refresh_sessions_command.js @@ -37,14 +37,13 @@ admin.auth("admin", "admin"); result = admin.runCommand({ - createRole: 'readSessionsCollection', - privileges: [{resource: {db: 'config', collection: 'system.sessions'}, actions: ['find']}], + createRole: 'readAdmin', + privileges: [{resource: {db: 'admin', collection: 'system.sessions'}, actions: ['find']}], roles: [] }); - assert.commandWorked(result, "couldn't make readSessionsCollection role"); + assert.commandWorked(result, "couldn't make readAdmin role"); - admin.createUser( - {user: 'readSessionsCollection', pwd: 'pwd', roles: ['readSessionsCollection']}); + admin.createUser({user: 'readAdmin', pwd: 'pwd', roles: ['readAdmin']}); admin.logout(); // Test that we cannot run refreshSessions unauthenticated if --auth is on. @@ -76,12 +75,10 @@ // Test that once we force a refresh, all of these sessions are in the sessions collection. admin.logout(); - admin.auth("readSessionsCollection", "pwd"); + admin.auth("readAdmin", "pwd"); result = admin.runCommand({refreshLogicalSessionCacheNow: 1}); assert.commandWorked(result, "could not force refresh"); - - var config = conn.getDB("config"); - assert.eq(config.system.sessions.count(), 3, "should have refreshed all session records"); + assert.eq(admin.system.sessions.count(), 3, "should have refreshed all session records"); MongoRunner.stopMongod(conn); })(); diff --git a/jstests/noPassthrough/system_indexes.js b/jstests/noPassthrough/system_indexes.js index 95f9d90c4a2..dd27ea4a92d 100644 --- a/jstests/noPassthrough/system_indexes.js +++ b/jstests/noPassthrough/system_indexes.js @@ -6,7 +6,6 @@ (function() { let conn = MongoRunner.runMongod({smallfiles: ""}); - let config = conn.getDB("config"); let db = conn.getDB("admin"); // TEST: User and role collections start off with no indexes @@ -66,16 +65,15 @@ assert.eq(2, db.system.roles.getIndexes().length); // TEST: Inserting to the sessions collection creates indexes - config = conn.getDB("config"); - assert.eq(0, config.system.sessions.getIndexes().length); - config.system.sessions.insert({lastUse: new Date()}); - assert.eq(2, config.system.sessions.getIndexes().length); + 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 config.system.sessions index and restarting will recreate it - assert.commandWorked(config.system.sessions.dropIndexes()); + // 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}); - config = conn.getDB("config"); - assert.eq(2, config.system.sessions.getIndexes().length); + db = conn.getDB("admin"); + assert.eq(2, db.system.sessions.getIndexes().length); })(); diff --git a/jstests/noPassthrough/verify_session_cache_updates.js b/jstests/noPassthrough/verify_session_cache_updates.js index e2d51bd27e5..e9912144e6f 100644 --- a/jstests/noPassthrough/verify_session_cache_updates.js +++ b/jstests/noPassthrough/verify_session_cache_updates.js @@ -8,12 +8,12 @@ function verify(conn, nRecords) { conn.getDB("admin").runCommand({refreshLogicalSessionCacheNow: 1}); - assert.eq(nRecords, conn.getDB("config").system.sessions.find({}).count()); + assert.eq(nRecords, conn.getDB("admin").system.sessions.find({}).count()); } function getLastUse(conn) { conn.getDB("admin").runCommand({refreshLogicalSessionCacheNow: 1}); - return conn.getDB("config").system.sessions.findOne({}).lastUse; + return conn.getDB("admin").system.sessions.findOne({}).lastUse; } // initially we have no sessions diff --git a/jstests/replsets/refresh_sessions_rs.js b/jstests/replsets/refresh_sessions_rs.js index cc44affe6a2..abb71e22534 100644 --- a/jstests/replsets/refresh_sessions_rs.js +++ b/jstests/replsets/refresh_sessions_rs.js @@ -5,7 +5,7 @@ var startSession = {startSession: 1}; // Start up a replica set. - var dbName = "config"; + var dbName = "admin"; var replTest = new ReplSetTest({name: 'refresh', nodes: 3}); var nodes = replTest.startSet(); diff --git a/jstests/sharding/refresh_sessions.js b/jstests/sharding/refresh_sessions.js index 1e2bac22c8e..0e575fe6a69 100644 --- a/jstests/sharding/refresh_sessions.js +++ b/jstests/sharding/refresh_sessions.js @@ -1,7 +1,7 @@ (function() { "use strict"; - var sessionsDb = "config"; + var sessionsDb = "admin"; var refresh = {refreshLogicalSessionCacheNow: 1}; var startSession = {startSession: 1}; diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp index 035228b65ad..35fbde965dd 100644 --- a/src/mongo/db/namespace_string.cpp +++ b/src/mongo/db/namespace_string.cpp @@ -115,8 +115,7 @@ bool NamespaceString::isLegalClientSystemNS() const { return true; if (ns() == "admin.system.backup_users") return true; - } else if (db() == "config") { - if (ns() == "config.system.sessions") + if (ns() == "admin.system.sessions") return true; } if (ns() == "local.system.replset") diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp index de02fda5642..0b422f8882c 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") @@ -244,10 +246,6 @@ Status userAllowedCreateNS(StringData db, StringData coll) { if (coll == "system.keys") return Status::OK(); } - if (db == "config") { - if (coll == "system.sessions") - return Status::OK(); - } if (db == "local") { if (coll == "system.replset") return Status::OK(); diff --git a/src/mongo/db/pipeline/document_source_list_sessions.h b/src/mongo/db/pipeline/document_source_list_sessions.h index 47c08af9d73..38ba2b21b67 100644 --- a/src/mongo/db/pipeline/document_source_list_sessions.h +++ b/src/mongo/db/pipeline/document_source_list_sessions.h @@ -37,7 +37,7 @@ namespace mongo { /** * $listSessions: { allUsers: true/false, users: [ {user:"jsmith", db:"test"}, ... ] } - * Return all sessions in the config.system.sessions collection + * Return all sessions in the admin.system.sessions collection * or just sessions for the currently logged in user. (Default: false) * * This is essentially an alias for {$match:{"_id.uid": myid}} or {$match:{}} diff --git a/src/mongo/db/sessions_collection.h b/src/mongo/db/sessions_collection.h index 63fd34667cf..9d29924069c 100644 --- a/src/mongo/db/sessions_collection.h +++ b/src/mongo/db/sessions_collection.h @@ -49,9 +49,9 @@ class SessionsCollection { public: virtual ~SessionsCollection(); - static constexpr StringData kSessionsDb = "config"_sd; + static constexpr StringData kSessionsDb = "admin"_sd; static constexpr StringData kSessionsCollection = "system.sessions"_sd; - static constexpr StringData kSessionsFullNS = "config.system.sessions"_sd; + static constexpr StringData kSessionsFullNS = "admin.system.sessions"_sd; static const NamespaceString kSessionsNamespaceString; diff --git a/src/mongo/db/system_index.cpp b/src/mongo/db/system_index.cpp index be95f1d0758..0c07a4e46ad 100644 --- a/src/mongo/db/system_index.cpp +++ b/src/mongo/db/system_index.cpp @@ -67,7 +67,7 @@ IndexSpec v3SystemUsersIndexSpec; IndexSpec v3SystemRolesIndexSpec; IndexSpec v1SystemSessionsIndexSpec; -const NamespaceString sessionCollectionNamespace("config.system.sessions"); +const NamespaceString sessionCollectionNamespace("admin.system.sessions"); MONGO_INITIALIZER(AuthIndexKeyPatterns)(InitializerContext*) { v1SystemUsersKeyPattern = BSON("user" << 1 << "userSource" << 1); @@ -145,84 +145,72 @@ Status verifySystemIndexes(OperationContext* opCtx) { const NamespaceString& systemUsers = AuthorizationManager::usersCollectionNamespace; const NamespaceString& systemRoles = AuthorizationManager::rolesCollectionNamespace; - // Create indexes for collections on the admin db - { - AutoGetDb autoDb(opCtx, systemUsers.db(), MODE_X); - if (!autoDb.getDb()) { - return Status::OK(); - } - - Collection* collection = autoDb.getDb()->getCollection(opCtx, systemUsers); - if (collection) { - IndexCatalog* indexCatalog = collection->getIndexCatalog(); - invariant(indexCatalog); - - // Make sure the old unique index from v2.4 on system.users doesn't exist. - std::vector indexes; - indexCatalog->findIndexesByKeyPattern(opCtx, v1SystemUsersKeyPattern, false, &indexes); - - if (!indexes.empty()) { - fassert(ErrorCodes::AmbiguousIndexKeyPattern, indexes.size() == 1); - return Status(ErrorCodes::AuthSchemaIncompatible, - "Old 2.4 style user index identified. " - "The authentication schema needs to be updated by " - "running authSchemaUpgrade on a 2.6 server."); - } + AutoGetDb autoDb(opCtx, systemUsers.db(), MODE_X); + if (!autoDb.getDb()) { + return Status::OK(); + } - // Ensure that system indexes exist for the user collection - indexCatalog->findIndexesByKeyPattern(opCtx, v3SystemUsersKeyPattern, false, &indexes); - if (indexes.empty()) { - try { - generateSystemIndexForExistingCollection( - opCtx, collection, systemUsers, v3SystemUsersIndexSpec); - } catch (...) { - return exceptionToStatus(); - } - } + Collection* collection = autoDb.getDb()->getCollection(opCtx, systemUsers); + if (collection) { + IndexCatalog* indexCatalog = collection->getIndexCatalog(); + invariant(indexCatalog); + + // Make sure the old unique index from v2.4 on system.users doesn't exist. + std::vector indexes; + indexCatalog->findIndexesByKeyPattern(opCtx, v1SystemUsersKeyPattern, false, &indexes); + + if (!indexes.empty()) { + fassert(ErrorCodes::AmbiguousIndexKeyPattern, indexes.size() == 1); + return Status(ErrorCodes::AuthSchemaIncompatible, + "Old 2.4 style user index identified. " + "The authentication schema needs to be updated by " + "running authSchemaUpgrade on a 2.6 server."); } - // Ensure that system indexes exist for the roles collection, if it exists. - collection = autoDb.getDb()->getCollection(opCtx, systemRoles); - if (collection) { - IndexCatalog* indexCatalog = collection->getIndexCatalog(); - invariant(indexCatalog); - - std::vector indexes; - indexCatalog->findIndexesByKeyPattern(opCtx, v3SystemRolesKeyPattern, false, &indexes); - if (indexes.empty()) { - try { - generateSystemIndexForExistingCollection( - opCtx, collection, systemRoles, v3SystemRolesIndexSpec); - } catch (...) { - return exceptionToStatus(); - } + // Ensure that system indexes exist for the user collection + indexCatalog->findIndexesByKeyPattern(opCtx, v3SystemUsersKeyPattern, false, &indexes); + if (indexes.empty()) { + try { + generateSystemIndexForExistingCollection( + opCtx, collection, systemUsers, v3SystemUsersIndexSpec); + } catch (...) { + return exceptionToStatus(); } } } - // Create indexes for system collections in the config db. - { - AutoGetDb autoDb(opCtx, sessionCollectionNamespace.db(), MODE_X); - if (!autoDb.getDb()) { - return Status::OK(); + // Ensure that system indexes exist for the roles collection, if it exists. + collection = autoDb.getDb()->getCollection(opCtx, systemRoles); + if (collection) { + IndexCatalog* indexCatalog = collection->getIndexCatalog(); + invariant(indexCatalog); + + std::vector indexes; + indexCatalog->findIndexesByKeyPattern(opCtx, v3SystemRolesKeyPattern, false, &indexes); + if (indexes.empty()) { + try { + generateSystemIndexForExistingCollection( + opCtx, collection, systemRoles, v3SystemRolesIndexSpec); + } catch (...) { + return exceptionToStatus(); + } } + } - // Ensure that system indexes exist for the sessions collection, if it exists. - auto collection = autoDb.getDb()->getCollection(opCtx, sessionCollectionNamespace); - if (collection) { - IndexCatalog* indexCatalog = collection->getIndexCatalog(); - invariant(indexCatalog); - - std::vector indexes; - indexCatalog->findIndexesByKeyPattern( - opCtx, v1SystemSessionsKeyPattern, false, &indexes); - if (indexes.empty()) { - try { - generateSystemIndexForExistingCollection( - opCtx, collection, sessionCollectionNamespace, v1SystemSessionsIndexSpec); - } catch (...) { - return exceptionToStatus(); - } + // 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 indexes; + indexCatalog->findIndexesByKeyPattern(opCtx, v1SystemSessionsKeyPattern, false, &indexes); + if (indexes.empty()) { + try { + generateSystemIndexForExistingCollection( + opCtx, collection, sessionCollectionNamespace, v1SystemSessionsIndexSpec); + } catch (...) { + return exceptionToStatus(); } } } diff --git a/src/mongo/dbtests/logical_sessions_tests.cpp b/src/mongo/dbtests/logical_sessions_tests.cpp index 0b1b42df660..13ca0c434c8 100644 --- a/src/mongo/dbtests/logical_sessions_tests.cpp +++ b/src/mongo/dbtests/logical_sessions_tests.cpp @@ -45,7 +45,7 @@ namespace LogicalSessionTests { namespace { -constexpr StringData kTestNS = "config.system.sessions"_sd; +constexpr StringData kTestNS = "admin.system.sessions"_sd; LogicalSessionRecord makeRecord(Date_t time = Date_t::now()) { auto record = makeLogicalSessionRecordForTest(); -- cgit v1.2.1