From 931a227eedca19bc05fc6318996ffd3c6a2c6f4b Mon Sep 17 00:00:00 2001 From: Hai-Kinh Hoang Date: Thu, 28 Jul 2016 16:45:52 -0400 Subject: [PATCH] SERVER-21378 add setParameter startupAuthSchemaValidation used to bypass auth metadata startup validation checks --- src/mongo/db/auth/authorization_manager.cpp | 8 +++ src/mongo/db/auth/authorization_manager.h | 18 +++++ .../db/auth/authorization_manager_global.cpp | 3 + src/mongo/db/db.cpp | 66 ++++++++++++------- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp index 046ed24a1bca0..131eeda34c6c8 100644 --- a/src/mongo/db/auth/authorization_manager.cpp +++ b/src/mongo/db/auth/authorization_manager.cpp @@ -266,6 +266,14 @@ std::unique_ptr AuthorizationManager::makeAuthorizationSes _externalState->makeAuthzSessionExternalState(this)); } +void AuthorizationManager::setShouldValidateAuthSchemaOnStartup(bool validate) { + _startupAuthSchemaValidation = validate; +} + +bool AuthorizationManager::shouldValidateAuthSchemaOnStartup() { + return _startupAuthSchemaValidation; +} + Status AuthorizationManager::getAuthorizationVersion(OperationContext* txn, int* version) { CacheGuard guard(this, CacheGuard::fetchSynchronizationManual); int newVersion = _version; diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h index 49b7cfb9a786b..43b1741841b28 100644 --- a/src/mongo/db/auth/authorization_manager.h +++ b/src/mongo/db/auth/authorization_manager.h @@ -164,6 +164,16 @@ class AuthorizationManager { */ std::unique_ptr makeAuthorizationSession(); + /** + * Sets whether or not startup AuthSchema validation checks should be applied in this manager. + */ + void setShouldValidateAuthSchemaOnStartup(bool validate); + + /** + * Returns true if startup AuthSchema validation checks should be applied in this manager. + */ + bool shouldValidateAuthSchemaOnStartup(); + /** * Sets whether or not access control enforcement is enabled for this manager. */ @@ -350,6 +360,14 @@ class AuthorizationManager { const UserName& userName, std::unique_ptr* acquiredUser); + /** + * True if AuthSchema startup checks should be applied in this AuthorizationManager. + * + * Defaults to true. Changes to its value are not synchronized, so it should only be set + * at initalization-time. + */ + bool _startupAuthSchemaValidation; + /** * True if access control enforcement is enabled in this AuthorizationManager. * diff --git a/src/mongo/db/auth/authorization_manager_global.cpp b/src/mongo/db/auth/authorization_manager_global.cpp index 9ffcc2e5714f9..f5f2ab8bffc3b 100644 --- a/src/mongo/db/auth/authorization_manager_global.cpp +++ b/src/mongo/db/auth/authorization_manager_global.cpp @@ -88,6 +88,8 @@ AuthorizationManager* getGlobalAuthorizationManager() { return globalAuthManager; } +MONGO_EXPORT_STARTUP_SERVER_PARAMETER(startupAuthSchemaValidation, bool, true); + MONGO_INITIALIZER_WITH_PREREQUISITES(CreateAuthorizationManager, ("SetupInternalSecurityUser", "OIDGeneration", @@ -99,6 +101,7 @@ MONGO_INITIALIZER_WITH_PREREQUISITES(CreateAuthorizationManager, stdx::make_unique(AuthzManagerExternalState::create()); authzManager->setAuthEnabled(serverGlobalParams.authState == ServerGlobalParams::AuthState::kEnabled); + authzManager->setShouldValidateAuthSchemaOnStartup(startupAuthSchemaValidation); AuthorizationManager::set(getGlobalServiceContext(), std::move(authzManager)); return Status::OK(); } diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 0a891813048b0..5c2b555e484a1 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -649,32 +649,48 @@ static ExitCode _initAndListen(int listenPort) { #ifndef _WIN32 mongo::signalForkSuccess(); #endif + AuthorizationManager* globalAuthzManager = getGlobalAuthorizationManager(); + if (globalAuthzManager->shouldValidateAuthSchemaOnStartup()) { + Status status = authindex::verifySystemIndexes(startupOpCtx.get()); + if (!status.isOK()) { + log() << status.reason(); + exitCleanly(EXIT_NEED_UPGRADE); + } - Status status = authindex::verifySystemIndexes(startupOpCtx.get()); - if (!status.isOK()) { - log() << status.reason(); - exitCleanly(EXIT_NEED_UPGRADE); - } - - // SERVER-14090: Verify that auth schema version is schemaVersion26Final. - int foundSchemaVersion; - status = getGlobalAuthorizationManager()->getAuthorizationVersion(startupOpCtx.get(), - &foundSchemaVersion); - if (!status.isOK()) { - log() << "Auth schema version is incompatible: " - << "User and role management commands require auth data to have " - << "at least schema version " << AuthorizationManager::schemaVersion26Final - << " but startup could not verify schema version: " << status.toString() << endl; - exitCleanly(EXIT_NEED_UPGRADE); - } - if (foundSchemaVersion < AuthorizationManager::schemaVersion26Final) { - log() << "Auth schema version is incompatible: " - << "User and role management commands require auth data to have " - << "at least schema version " << AuthorizationManager::schemaVersion26Final - << " but found " << foundSchemaVersion << ". In order to upgrade " - << "the auth schema, first downgrade MongoDB binaries to version " - << "2.6 and then run the authSchemaUpgrade command." << endl; - exitCleanly(EXIT_NEED_UPGRADE); + // SERVER-14090: Verify that auth schema version is schemaVersion26Final. + int foundSchemaVersion; + status = globalAuthzManager->getAuthorizationVersion(startupOpCtx.get(), + &foundSchemaVersion); + if (!status.isOK()) { + log() << "Auth schema version is incompatible: " + << "User and role management commands require auth data to have " + << "at least schema version " << AuthorizationManager::schemaVersion26Final + << " but startup could not verify schema version: " << status.toString() + << endl; + exitCleanly(EXIT_NEED_UPGRADE); + } + if (foundSchemaVersion < AuthorizationManager::schemaVersion26Final) { + log() << "Auth schema version is incompatible: " + << "User and role management commands require auth data to have " + << "at least schema version " << AuthorizationManager::schemaVersion26Final + << " but found " << foundSchemaVersion << ". In order to upgrade " + << "the auth schema, first downgrade MongoDB binaries to version " + << "2.6 and then run the authSchemaUpgrade command." << endl; + exitCleanly(EXIT_NEED_UPGRADE); + } + } else if (globalAuthzManager->isAuthEnabled()) { + error() << "Auth must be disabled when starting without auth schema validation"; + exitCleanly(EXIT_BADOPTIONS); + } else { + // If authSchemaValidation is disabled and server is running without auth, + // warn the user and continue startup without authSchema metadata checks. + log() << startupWarningsLog; + log() << "** WARNING: Startup auth schema validation checks are disabled for the " + "database." + << startupWarningsLog; + log() << "** This mode should only be used to manually repair corrupted auth " + "data." + << startupWarningsLog; } if (!storageGlobalParams.readOnly) {