diff options
author | Spencer T Brody <spencer@mongodb.com> | 2014-02-27 19:07:54 +1100 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2014-03-05 12:08:07 -0500 |
commit | 0ee6886263937f9ed0e9d74fa8753cac02a18617 (patch) | |
tree | d5256ed8f3eb819d35a7714410eacf59f627a5aa | |
parent | 5a44d3b3913f27180c04fa072a1db57ad1a09d9d (diff) | |
download | mongo-0ee6886263937f9ed0e9d74fa8753cac02a18617.tar.gz |
SERVER-12854 Prevent mongorestore from restoring user data to a 2.6 system with 2.4 schema users
-rw-r--r-- | jstests/multiVersion/dumprestore_24_auth.js | 5 | ||||
-rw-r--r-- | src/mongo/tools/restore.cpp | 62 |
2 files changed, 39 insertions, 28 deletions
diff --git a/jstests/multiVersion/dumprestore_24_auth.js b/jstests/multiVersion/dumprestore_24_auth.js index 5699430c503..80dce2736bb 100644 --- a/jstests/multiVersion/dumprestore_24_auth.js +++ b/jstests/multiVersion/dumprestore_24_auth.js @@ -54,11 +54,6 @@ function multiVersionDumpRestoreTest(opts) { } multiVersionDumpRestoreTest({mongodSourceVersion: "2.4", - mongodDestVersion: "latest", - mongoDumpVersion: "latest", - mongoRestoreVersion: "latest"}); - -multiVersionDumpRestoreTest({mongodSourceVersion: "2.4", mongodDestVersion: "2.4", mongoDumpVersion: "latest", mongoRestoreVersion: "latest"}); diff --git a/src/mongo/tools/restore.cpp b/src/mongo/tools/restore.cpp index bf362f4b947..9cc6c877dbe 100644 --- a/src/mongo/tools/restore.cpp +++ b/src/mongo/tools/restore.cpp @@ -64,6 +64,7 @@ public: string _curns; string _curdb; string _curcoll; + string _serverBinVersion; // Version identifier of the server we're restoring to set<UserName> _users; // Holds users that are already in the cluster when restoring with --drop set<RoleName> _roles; // Holds roles that are already in the cluster when restoring with --drop scoped_ptr<Matcher> _opmatcher; // For oplog replay @@ -117,18 +118,30 @@ public: return -1; } - if (mongoRestoreGlobalParams.restoreUsersAndRoles) { - storeRemoteAuthzVersion(); // populate _serverAuthzVersion + { + // Store server's version + BSONObj out; + if (! conn().simpleCommand("admin", &out, "buildinfo")) { + toolError() << "buildinfo command failed: " + << out["errmsg"].String() << std::endl; + return -1; + } + + _serverBinVersion = out["version"].String(); + } + storeRemoteAuthzVersion(); // populate _serverAuthzVersion + + if (mongoRestoreGlobalParams.restoreUsersAndRoles) { if (_serverAuthzVersion == AuthorizationManager::schemaVersion26Final) { - uassert(17408, + uassert(17410, mongoutils::str::stream() << mongoRestoreGlobalParams.tempUsersColl << " collection already exists, but is needed to restore user data. " "Drop this collection or specify a different collection (via " "--tempUsersColl) to use to temporarily hold user data during the " "restore process", !conn().exists(mongoRestoreGlobalParams.tempUsersColl)); - uassert(17407, + uassert(17411, mongoutils::str::stream() << mongoRestoreGlobalParams.tempRolesColl << " collection already exists, but is needed to restore role data. " "Drop this collection or specify a different collection (via " @@ -142,12 +155,6 @@ public: // Will populate _dumpFileAuthzVersion processFileAndMetadata(root / "admin" / "system.version.bson", "admin.system.version"); - uassert(17371, - mongoutils::str::stream() << "Server's authorization data schema version " - "does not match that of the data in the dump file. Server's schema" - " version: " << _serverAuthzVersion << ", schema version in dump: " - << _dumpFileAuthzVersion, - _serverAuthzVersion == _dumpFileAuthzVersion); } else if (!toolGlobalParams.db.empty()) { // DB-specific restore if (exists(root / "$admin.system.users.bson")) { @@ -191,15 +198,7 @@ public: return -1; } - - BSONObj out; - if (! conn().simpleCommand("admin", &out, "buildinfo")) { - toolError() << "buildinfo command failed: " << out["errmsg"].String() << std::endl; - return -1; - } - - StringData version = out["version"].valuestr(); - if (versionCmp(version, "1.7.4-pre-") < 0) { + if (versionCmp(_serverBinVersion, "1.7.4-pre-") < 0) { toolError() << "Can only replay oplog to server version >= 1.7.4" << std::endl; return -1; } @@ -617,6 +616,16 @@ public: conn().insert(mongoRestoreGlobalParams.tempRolesColl, obj); } else if (_curcoll == "system.users") { + uassert(17416, + mongoutils::str::stream() << "Cannot modify user data on a server with version " + "greater than or equal to 2.5.4 that has not yet updated the " + "authorization data to schema version " << + AuthorizationManager::schemaVersion26Final << + ". Found server version " << _serverBinVersion << " with " + "authorization schema version " << _serverAuthzVersion, + versionCmp(_serverBinVersion, "2.5.4") < 0 || + _serverAuthzVersion == AuthorizationManager::schemaVersion26Final); + if (obj.hasField("credentials")) { if (_serverAuthzVersion == AuthorizationManager::schemaVersion24) { // v3 user, v1 system @@ -643,10 +652,11 @@ public: } else { if (_serverAuthzVersion == AuthorizationManager::schemaVersion26Final && !_serverAuthzVersionDocExists) { - // This is a clean 2.6 system without any users, so it is okay to restore - // 2.4-schema users into it. This will make the system a 2.4 schema version - // system. - _serverAuthzVersion = AuthorizationManager::schemaVersion24; + // server with schemaVersion26Final implies it is running 2.5.4 or greater. + uasserted(17415, + mongoutils::str::stream() << "Cannot restore users with schema " << + "version " << AuthorizationManager::schemaVersion24 << + " to a system with server version 2.5.4 or greater"); } if (_serverAuthzVersion == AuthorizationManager::schemaVersion24 || @@ -690,6 +700,12 @@ public: AuthorizationManager::schemaVersionFieldName, &authVersion)); _dumpFileAuthzVersion = static_cast<int>(authVersion); + uassert(17371, + mongoutils::str::stream() << "Server's authorization data schema version " + "does not match that of the data in the dump file. Server's schema" + " version: " << _serverAuthzVersion << ", schema version in dump: " + << _dumpFileAuthzVersion, + _serverAuthzVersion == _dumpFileAuthzVersion); } conn().insert(_curns, obj); } |