summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2014-02-27 19:07:54 +1100
committerSpencer T Brody <spencer@mongodb.com>2014-03-05 12:08:07 -0500
commit0ee6886263937f9ed0e9d74fa8753cac02a18617 (patch)
treed5256ed8f3eb819d35a7714410eacf59f627a5aa
parent5a44d3b3913f27180c04fa072a1db57ad1a09d9d (diff)
downloadmongo-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.js5
-rw-r--r--src/mongo/tools/restore.cpp62
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);
}