diff options
author | Spencer T Brody <spencer@10gen.com> | 2013-04-01 16:48:11 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2013-04-18 11:46:48 -0400 |
commit | e01102d1dfdfe64293bd7db38d798da87c48c01a (patch) | |
tree | 317d0202b01145b5650ea6cb64142e2d3ca01da4 | |
parent | 036337a5c0757e7a06ea3fc3f98efd467b27b43e (diff) | |
download | mongo-e01102d1dfdfe64293bd7db38d798da87c48c01a.tar.gz |
SERVER-9093 Make copydb command work on mongos with auth
Conflicts:
src/mongo/s/commands_public.cpp
-rw-r--r-- | jstests/sharding/auth_copydb.js | 40 | ||||
-rw-r--r-- | src/mongo/db/cloner.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 26 | ||||
-rw-r--r-- | src/mongo/s/commands_public.cpp | 21 |
4 files changed, 53 insertions, 36 deletions
diff --git a/jstests/sharding/auth_copydb.js b/jstests/sharding/auth_copydb.js new file mode 100644 index 00000000000..23be714127b --- /dev/null +++ b/jstests/sharding/auth_copydb.js @@ -0,0 +1,40 @@ +// Tests the copydb command on mongos with auth + + +var st = new ShardingTest({ shards : 1, + mongos : 1, + keyFile : "jstests/libs/key1"}); +var mongos = st.s0; +var destAdminDB = mongos.getDB('admin'); +var destTestDB = mongos.getDB('test'); + +var sourceMongodConn = MongoRunner.runMongod({}); +var sourceTestDB = sourceMongodConn.getDB('test'); + +sourceTestDB.foo.insert({a:1}); + +destAdminDB.addUser('admin', 'password'); // Turns on access control enforcement + +jsTestLog("Running copydb that should fail"); +var res = destAdminDB.runCommand({copydb:1, + fromhost: sourceMongodConn.host, + fromdb:'test', + todb:'test'}); +printjson(res); +assert.commandFailed(res); + +destAdminDB.auth('admin', 'password'); +assert.eq(0, destTestDB.foo.count()); // Be extra sure the copydb didn't secretly succeed. + +jsTestLog("Running copydb that should succeed"); +res = destAdminDB.runCommand({copydb:1, + fromhost: sourceMongodConn.host, + fromdb:'test', + todb:'test'}); +printjson(res); +assert.commandWorked(res); + +assert.eq(1, destTestDB.foo.count()); +assert.eq(1, destTestDB.foo.findOne().a); + +st.stop(); diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp index 233410b4590..d9600912715 100644 --- a/src/mongo/db/cloner.cpp +++ b/src/mongo/db/cloner.cpp @@ -762,7 +762,7 @@ namespace mongo { // source DB. ActionSet actions; actions.addAction(ActionType::copyDBTarget); - out->push_back(Privilege(dbname, actions)); + out->push_back(Privilege(dbname, actions)); // NOTE: dbname is always admin } virtual void help( stringstream &help ) const { help << "copy a database from another host to this host\n"; diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index 3ae7c1d6200..b041a726412 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -187,32 +187,6 @@ namespace mongo { static int testCommandsEnabled; }; - // This will be registered instead of the real implementations of any commands that don't work - // when auth is enabled. - class NotWithAuthCmd : public Command { - public: - NotWithAuthCmd(const char* cmdName) : Command(cmdName) { } - virtual bool slaveOk() const { return true; } - virtual LockType locktype() const { return NONE; } - virtual bool requiresAuth() { return false; } - virtual void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) {} - virtual void help( stringstream &help ) const { - help << name << " is not supported when running with authentication enabled"; - } - virtual bool run(const string&, - BSONObj& cmdObj, - int, - string& errmsg, - BSONObjBuilder& result, - bool fromRepl) { - errmsg = name + " is not supported when running with authentication enabled"; - log() << errmsg << std::endl; - return false; - } - }; - class CmdShutdown : public Command { public: virtual bool requiresAuth() { return true; } diff --git a/src/mongo/s/commands_public.cpp b/src/mongo/s/commands_public.cpp index e408cca73db..1c2ff52364a 100644 --- a/src/mongo/s/commands_public.cpp +++ b/src/mongo/s/commands_public.cpp @@ -522,12 +522,18 @@ namespace mongo { class CopyDBCmd : public PublicGridCommand { public: CopyDBCmd() : PublicGridCommand( "copydb" ) {} + virtual bool adminOnly() const { + return true; + } virtual void addRequiredPrivileges(const std::string& dbname, const BSONObj& cmdObj, std::vector<Privilege>* out) { - // Should never get here because this command shouldn't get registered when auth is - // enabled - verify(0); + // Note: privileges required are currently only granted to old-style users for + // backwards compatibility, since we can't properly handle auth checking for the + // read from the source DB. + ActionSet actions; + actions.addAction(ActionType::copyDBTarget); + out->push_back(Privilege(dbname, actions)); // NOTE: dbname is always admin } bool run(const string& dbName, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { string todb = cmdObj.getStringField("todb"); @@ -562,12 +568,9 @@ namespace mongo { } }; MONGO_INITIALIZER(RegisterCopyDBCommand)(InitializerContext* context) { - if (noauth) { - // Leaked intentionally: a Command registers itself when constructed. - new CopyDBCmd(); - } else { - new NotWithAuthCmd("copydb"); - } + // Leaked intentionally: a Command registers itself when constructed. + // NOTE: this initializer block cannot be removed due to SERVER-9167 + new CopyDBCmd(); return Status::OK(); } |