diff options
author | Spencer T Brody <spencer@mongodb.com> | 2014-02-06 14:16:40 -0500 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2014-02-07 15:41:33 -0500 |
commit | 75d912c25ab2a2aabaab73b22a6cafddeb6c4906 (patch) | |
tree | 4cd664b59d85c1d09580994c3c6fd661004c6892 /src/mongo/db/auth | |
parent | 8ca048383099f4e0c70f79d2bccdcebd1c1df33c (diff) | |
download | mongo-75d912c25ab2a2aabaab73b22a6cafddeb6c4906.tar.gz |
Move some code out of auth_helpers.cpp back to the AuthorizationManager
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r-- | src/mongo/db/auth/authorization_manager.cpp | 105 |
1 files changed, 102 insertions, 3 deletions
diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp index 95fe058f2eb..318952e82cd 100644 --- a/src/mongo/db/auth/authorization_manager.cpp +++ b/src/mongo/db/auth/authorization_manager.cpp @@ -913,6 +913,24 @@ namespace { const BSONObj& oldUserDoc, const BSONObj& writeConcern) { + uassert(17387, + mongoutils::str::stream() << "While preparing to upgrade user doc from the 2.4 " + "user data schema to the 2.6 schema, found a user doc with a " + "\"credentials\" field, indicating that the doc already has the new " + "schema. Make sure that all documents in admin.system.users have the same " + "user data schema and that the version document in admin.system.version " + "indicates the correct schema version. User doc found: " << + oldUserDoc.toString(), + !oldUserDoc.hasField("credentials")); + + uassert(17386, + mongoutils::str::stream() << "While preparing to upgrade user doc from " + "the 2.4 user data schema to the 2.6 schema, found a user doc " + "that doesn't conform to the 2.4 *or* 2.6 schema. Doc found: " + << oldUserDoc.toString(), + oldUserDoc.hasField("user") && + (oldUserDoc.hasField("userSource") || oldUserDoc.hasField("pwd"))); + std::string oldUserSource; uassertStatusOK(bsonExtractStringFieldWithDefault( oldUserDoc, @@ -923,9 +941,90 @@ namespace { if (oldUserSource == "local") return; // Skips users from "local" database, which cannot be upgraded. - BSONObj query; - BSONObj update; - auth::getUpdateToUpgradeUser(sourceDB, oldUserDoc, &query, &update); + const std::string oldUserName = oldUserDoc["user"].String(); + BSONObj query = BSON("_id" << oldUserSource + "." + oldUserName); + + BSONObjBuilder updateBuilder; + { + BSONObjBuilder toSetBuilder(updateBuilder.subobjStart("$set")); + toSetBuilder << "user" << oldUserName << "db" << oldUserSource; + BSONElement pwdElement = oldUserDoc["pwd"]; + if (!pwdElement.eoo()) { + toSetBuilder << "credentials" << BSON("MONGODB-CR" << pwdElement.String()); + } + else if (oldUserSource == "$external") { + toSetBuilder << "credentials" << BSON("external" << true); + } + } + { + BSONObjBuilder pushAllBuilder(updateBuilder.subobjStart("$pushAll")); + BSONArrayBuilder rolesBuilder(pushAllBuilder.subarrayStart("roles")); + + const bool readOnly = oldUserDoc["readOnly"].trueValue(); + const BSONElement rolesElement = oldUserDoc["roles"]; + if (readOnly) { + // Handles the cases where there is a truthy readOnly field, which is a 2.2-style + // read-only user. + if (sourceDB == "admin") { + rolesBuilder << BSON("role" << "readAnyDatabase" << "db" << "admin"); + } + else { + rolesBuilder << BSON("role" << "read" << "db" << sourceDB); + } + } + else if (rolesElement.eoo()) { + // Handles the cases where the readOnly field is absent or falsey, but the + // user is known to be 2.2-style because it lacks a roles array. + if (sourceDB == "admin") { + rolesBuilder << BSON("role" << "root" << "db" << "admin"); + } + else { + rolesBuilder << BSON("role" << "dbOwner" << "db" << sourceDB); + } + } + else { + // Handles 2.4-style user documents, with roles arrays and (optionally, in admin db) + // otherDBRoles objects. + uassert(17252, + "roles field in v2.4 user documents must be an array", + rolesElement.type() == Array); + for (BSONObjIterator oldRoles(rolesElement.Obj()); + oldRoles.more(); + oldRoles.next()) { + + BSONElement roleElement = *oldRoles; + rolesBuilder << BSON("role" << roleElement.String() << "db" << sourceDB); + } + + BSONElement otherDBRolesElement = oldUserDoc["otherDBRoles"]; + if (sourceDB == "admin" && !otherDBRolesElement.eoo()) { + uassert(17253, + "otherDBRoles field in v2.4 user documents must be an object.", + otherDBRolesElement.type() == Object); + + for (BSONObjIterator otherDBs(otherDBRolesElement.Obj()); + otherDBs.more(); + otherDBs.next()) { + + BSONElement otherDBRoles = *otherDBs; + if (otherDBRoles.fieldNameStringData() == "local") + continue; + uassert(17254, + "Member fields of otherDBRoles objects must be arrays.", + otherDBRoles.type() == Array); + for (BSONObjIterator oldRoles(otherDBRoles.Obj()); + oldRoles.more(); + oldRoles.next()) { + + BSONElement roleElement = *oldRoles; + rolesBuilder << BSON("role" << roleElement.String() << + "db" << otherDBRoles.fieldNameStringData()); + } + } + } + } + } + BSONObj update = updateBuilder.obj(); uassertStatusOK(externalState->updateOne( AuthorizationManager::usersAltCollectionNamespace, |