Tuesday, February 27, 2018

Creating a user in MongoDB not knowing the admin credentials

Last week I had to setup a staging machine for one of our applications in an environment with a pre-installed MongoDB instance. After creating all the infrastructure in AWS, setting up the environment and configuring the application I got a failed logon attempt to the database. Trying to connect directly (not through the application) resulted in the same error:

 
> mongo --port 27017 -u usuario -p minhasenha --authenticationDatabase novoBD

  Error: 18 { code: 18, ok: 0.0, errmsg: "auth fails" }


OK, it seemed the user didn't have access to the database. In MongoDB authentication is managed at a database level. When trying to connect to the MongoDB using a database, it checks for the provided credentials in the collection <database>.system.users. Solution: create the user in the database.

Well, easy solution if you have the admin credentials, but that was not the case. Workaround: as I had root access to the OS, I disabled MongoDB authentication:


> vim /etc/mongod.conf

  noauth=true
  #auth=true


Then logged in MongoDB and created an admin user:


> mongo --port 27017

  use admin;

  db.createUser(
    {
        user: "admin",
        pwd: "minhasenha",
        roles:["root"]
    });


Logged out MongoDB and enabled authentication back again:


> vim /etc/mongod.conf

  #noauth=true
  auth=true


Logged in MongoDB back with admin user (saved its credentials for future use!) and created the user in the new database:


> mongo --port 27017 -u admin -p minhasenha --authenticationDatabase admin

  use novoBD;

  db.createUser(
    {
        user: "usuario",
        pwd: "minhasenha",
        roles:[{ role: "readWrite", db: "novoBD" }, { role: "dbAdmin", db: "novoBD" }]
    });


After that the application happily connected to MongoDB. If the application is happy, I'm happy too!

Monday, February 19, 2018

Simulating cron environment

Ever added a script to crontab just to discover it didn't run as expected? Well, cron environment is not the same as your user environment and that could make a huge difference depending what your script is doing.

To help me writing scripts taking into account this difference I use the following tip by mmccoo (https://stackoverflow.com/questions/2135478/how-to-simulate-the-environment-cron-executes-a-script-with).

Add this to crontab:

 
30 08 * * * env > ~/cronenv


After it runs, do this:

 
env - `cat ~/cronenv` /bin/sh


This assumes that your cron runs /bin/sh, which is the default regardless of the user's default shell.

If you want to use another shell just change /bin/sh for your favorite shell and don't forget to also change the shell used by cron by adding this to your crontab:

 
SHELL=<your_favorite_shell>