diff options
-rw-r--r-- | src/mongo/db/auth/auth_index_d.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager.cpp | 26 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager.h | 8 | ||||
-rw-r--r-- | src/mongo/db/auth/authorization_manager_global.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/auth/authz_manager_external_state.h | 1 | ||||
-rw-r--r-- | src/mongo/db/auth/authz_manager_external_state_local.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/commands/user_management_commands.cpp | 20 |
7 files changed, 56 insertions, 19 deletions
diff --git a/src/mongo/db/auth/auth_index_d.cpp b/src/mongo/db/auth/auth_index_d.cpp index 5834b7d53c7..8c59f8e9ca3 100644 --- a/src/mongo/db/auth/auth_index_d.cpp +++ b/src/mongo/db/auth/auth_index_d.cpp @@ -29,6 +29,7 @@ #include "mongo/db/auth/auth_index_d.h" #include "mongo/base/init.h" +#include "mongo/base/status.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_manager_global.h" #include "mongo/db/client.h" @@ -72,8 +73,13 @@ namespace { } // namespace void configureSystemIndexes(const StringData& dbname) { - if (dbname == "admin" && getGlobalAuthorizationManager()->getAuthorizationVersion() == - AuthorizationManager::schemaVersion26Final) { + int authzVersion; + Status status = getGlobalAuthorizationManager()->getAuthorizationVersion(&authzVersion); + if (!status.isOK()) { + return; + } + + if (dbname == "admin" && authzVersion == AuthorizationManager::schemaVersion26Final) { NamespaceString systemUsers(dbname, "system.users"); // Make sure the old unique index from v2.4 on system.users doesn't exist. diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp index 6dd12289342..6c409592f6d 100644 --- a/src/mongo/db/auth/authorization_manager.cpp +++ b/src/mongo/db/auth/authorization_manager.cpp @@ -256,7 +256,7 @@ namespace mongo { } } - int AuthorizationManager::getAuthorizationVersion() { + Status AuthorizationManager::getAuthorizationVersion(int* version) { CacheGuard guard(this, CacheGuard::fetchSynchronizationManual); int newVersion = _version; if (schemaVersionInvalid == newVersion) { @@ -265,16 +265,19 @@ namespace mongo { guard.beginFetchPhase(); Status status = _externalState->getStoredAuthorizationVersion(&newVersion); guard.endFetchPhase(); - if (status.isOK()) { - if (guard.isSameCacheGeneration()) { - _version = newVersion; - } + if (!status.isOK()) { + warning() << "Problem fetching the stored schema version of authorization data: " + << status; + *version = schemaVersionInvalid; + return status; } - else { - warning() << "Could not determine schema version of authorization data. " << status; + + if (guard.isSameCacheGeneration()) { + _version = newVersion; } } - return newVersion; + *version = newVersion; + return Status::OK(); } void AuthorizationManager::setSupportOldStylePrivilegeDocuments(bool enabled) { @@ -1287,7 +1290,12 @@ namespace { } // namespace Status AuthorizationManager::upgradeSchemaStep(const BSONObj& writeConcern, bool* isDone) { - int authzVersion = getAuthorizationVersion(); + int authzVersion; + Status status = getAuthorizationVersion(&authzVersion); + if (!status.isOK()) { + return status; + } + switch (authzVersion) { case schemaVersion24: *isDone = false; diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h index 589f20ad59f..08a99cf0ee1 100644 --- a/src/mongo/db/auth/authorization_manager.h +++ b/src/mongo/db/auth/authorization_manager.h @@ -166,9 +166,13 @@ namespace mongo { bool isAuthEnabled() const; /** - * Returns the version number of the authorization system. + * Returns via the output parameter "version" the version number of the authorization + * system. Returns Status::OK() if it was able to successfully fetch the current + * authorization version. If it has problems fetching the most up to date version it + * returns a non-OK status. When returning a non-OK status, *version will be set to + * schemaVersionInvalid (0). */ - int getAuthorizationVersion(); + Status getAuthorizationVersion(int* version); // Returns true if there exists at least one privilege document in the system. bool hasAnyPrivilegeDocuments() const; diff --git a/src/mongo/db/auth/authorization_manager_global.cpp b/src/mongo/db/auth/authorization_manager_global.cpp index 36354d7d08d..fb99d63aef8 100644 --- a/src/mongo/db/auth/authorization_manager_global.cpp +++ b/src/mongo/db/auth/authorization_manager_global.cpp @@ -61,7 +61,9 @@ namespace { ServerParameter(sps, name, false, false) {} void AuthzVersionParameter::append(BSONObjBuilder& b, const std::string& name) { - b.append(name, getGlobalAuthorizationManager()->getAuthorizationVersion()); + int authzVersion; + uassertStatusOK(getGlobalAuthorizationManager()->getAuthorizationVersion(&authzVersion)); + b.append(name, authzVersion); } Status AuthzVersionParameter::set(const BSONElement& newValueElement) { diff --git a/src/mongo/db/auth/authz_manager_external_state.h b/src/mongo/db/auth/authz_manager_external_state.h index 22d1a56aab2..8656847036d 100644 --- a/src/mongo/db/auth/authz_manager_external_state.h +++ b/src/mongo/db/auth/authz_manager_external_state.h @@ -62,6 +62,7 @@ namespace mongo { /** * Retrieves the schema version of the persistent data describing users and roles. + * Will leave *outVersion unmodified on non-OK status return values. */ virtual Status getStoredAuthorizationVersion(int* outVersion) = 0; 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 e62ca411f52..ce9f095c1c1 100644 --- a/src/mongo/db/auth/authz_manager_external_state_local.cpp +++ b/src/mongo/db/auth/authz_manager_external_state_local.cpp @@ -77,8 +77,10 @@ namespace mongo { } else { return Status(ErrorCodes::TypeMismatch, mongoutils::str::stream() << - "Bad (non-numeric) type " << versionElement.type() << - " for " << AuthorizationManager::schemaVersionFieldName << + "Could not determine schema version of authorization data. " + "Bad (non-numeric) type " << typeName(versionElement.type()) << + " (" << versionElement.type() << ") for " << + AuthorizationManager::schemaVersionFieldName << " field in version document"); } } diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp index 199d2cef9a3..a0a5163a44e 100644 --- a/src/mongo/db/commands/user_management_commands.cpp +++ b/src/mongo/db/commands/user_management_commands.cpp @@ -266,7 +266,12 @@ namespace mongo { } static Status requireAuthSchemaVersion26Final(AuthorizationManager* authzManager) { - const int foundSchemaVersion = authzManager->getAuthorizationVersion(); + int foundSchemaVersion; + Status status = authzManager->getAuthorizationVersion(&foundSchemaVersion); + if (!status.isOK()) { + return status; + } + if (foundSchemaVersion != AuthorizationManager::schemaVersion26Final) { return Status( ErrorCodes::AuthSchemaIncompatible, @@ -278,7 +283,12 @@ namespace mongo { } static Status requireAuthSchemaVersion26UpgradeOrFinal(AuthorizationManager* authzManager) { - const int foundSchemaVersion = authzManager->getAuthorizationVersion(); + int foundSchemaVersion; + Status status = authzManager->getAuthorizationVersion(&foundSchemaVersion); + if (!status.isOK()) { + return status; + } + if (foundSchemaVersion != AuthorizationManager::schemaVersion26Final && foundSchemaVersion != AuthorizationManager::schemaVersion26Upgrade) { return Status( @@ -1134,7 +1144,11 @@ namespace mongo { } AuthorizationManager* authzManager = getGlobalAuthorizationManager(); - int authzVersion = authzManager->getAuthorizationVersion(); + int authzVersion; + Status status = authzManager->getAuthorizationVersion(&authzVersion); + if (!status.isOK()) { + return appendCommandStatus(result, status); + } NamespaceString usersNamespace = authzVersion== AuthorizationManager::schemaVersion26Final ? AuthorizationManager::usersCollectionNamespace : |