C# 2.5 Driver, Command copydb failed: unable to login

54 views
Skip to first unread message

Sean Brown

unread,
Feb 12, 2018, 10:38:46 PM2/12/18
to mongodb-user
I am using the latest driver (2.5) for C#, trying to copy a database from one mongod instance to another.  As I understand it, the process to copy from the QA mongod to the Dev mongod is:
  • Instantiate an instance of the MongoClient for the dev instance
  • Get an instance of the 'admin' database
  • Generate a nonce from the admin database of the dev MongoClient
    • For this, I specify 'fromhost' as one of the qa mongod replica instances
  • Calculate the md5 hash of the key
  • Issue the appropriate 'copydb' command
I understand that authentication for the copydb command, since fromhost was specified, will be in the 'fromdb' defined in the command.  I have had our DBA give the same credentials dbOwner permissions for the fromdb specified, but I'm still unable to connect.  Since I'm doing my work through the C# driver, as I understand it, copydb command is available, but not copydatabase which seems to simplify the authentication process.

Is anyone able to see a problem with the following code?  All I can manage to get is an error stating: MongoCommandException: Command copydb failed: unable to login { ok: 0.0, errmsg: "auth failed", code: 18 }.  I'm able to manually connect to all the endpoints via Robo 3T and view collections.  Our DBA has verified that i'm set to dbOwner in all the appropriate places (admin DB, source/target DBs).

Here is the code that I'm trying to execute.  Any suggestions/help appreciated!

-Sean



        public static void CopyDatabase()
        {
            string mongoDBUsername = "someDbOwner";
            string mongoDBPassword = "superSecretPassword";

            var devClientSettings = new MongoClientSettings()
            {
                Credential = MongoCredential.CreateCredential("admin", mongoDBUsername, mongoDBPassword),
                ConnectionMode = ConnectionMode.ReplicaSet,
                Servers = new List<MongoServerAddress>() { new MongoServerAddress("dev01", 27017), new MongoServerAddress("dev02", 27017), new MongoServerAddress("dev03", 27017) }
            };

            var devClient = new MongoClient(devClientSettings);
            var devAdminDb = devClient.GetDatabase("admin");
            var nonceCommand = @"{ copydbgetnonce : 1, fromhost: 'qa01:27017' }";
            var nonceValueDev = devAdminDb.RunCommand<BsonDocument>(nonceCommand).ToString();
            string hashedSecret = CalculateMD5Hash(nonceValueDev + mongoDBUsername + CalculateMD5Hash(mongoDBUsername + ":mongo:" + mongoDBPassword));
            string commandString = @"{ copydb: 1, fromhost: 'qa01:27017', fromdb: 'qa01-db01', todb: 'qa01-db01', username:'" + mongoDBUsername + "', nonce: '" + nonceValueDev + "', key: '" + hashedSecret + "', slaveOk: 'true'}";

            devAdminDb.RunCommandAsync<BsonDocument>(commandString).Wait();
        }
        
        public static string CalculateMD5Hash(string input)
        {
            using (MD5 md5 = MD5.Create())
            {
                byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
                byte[] hash = md5.ComputeHash(inputBytes);

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < hash.Length; i++)
                {
                    sb.Append(hash[i].ToString("X2"));
                }

                return sb.ToString();
            }
        }

Sean Brown

unread,
Feb 13, 2018, 6:33:44 PM2/13/18
to mongodb-user
After working with this issue further, I think this is the issue:
  • C# driver (2.5) provided copydb command executes using MONGODB-CR authentication, with no option of instead using the updated SCRAM-SHA-1 (recommendation is to instead use copyDatabase which isn't supported in c# driver)
  • Our server version is 3.2, and was initially setup as such (not upgraded from 2.X version)
    • As a result of this, none of the users in the databases are setup to use MONGODB-CR
      • This is confirmed by running the following command: db.system.users.find({ "credentials.MONGODB-CR" : { $exists: true}}, { user: 1, db: 1})
      • All users instead show up using the following command: db.system.users.find({ "credentials.SCRAM-SHA-1" : { $exists: true}}, { user: 1, db: 1})
  • Various internet suggestions are that we could downgrade the auth version from 5 (current) to 3, then recreate a user.  This will provide the appropriate documents so that the MONGODB-CR auth can be used for that user.
    • Not sure what the ramifications of this change would be, but seems wide-ranging and potentially chaotic.  Not a great solution, and we don't have a great lab environment at the moment to test this change.
So, maybe this post will just serve as a reference for anyone else trying something similar in the future; but the issue I'm experiencing seems to be that the driver needs to be updated to support the new default authentication method provided by server versions 3.X.

Unless there is something I'm missing?  

-Sean

PS  Another useful bit of information was from the server logs after trying to authenticate.  They showed the following error:
2018-02-12T16:44:46.428-0800 I ACCESS   [conn57179] Failed to authenticate someDbOwner@qa01-db01 with mechanism MONGODB-CR: AuthenticationFailed: MONGODB-CR credentials missing in the user document
Reply all
Reply to author
Forward
0 new messages