MongoDB - User privileges - mongodb

This is probably a stupid newbie question. I scoured the Google-scape for answers and found a few things on stackoverflow, but nothing really works yet.
I am trying to create a database, and a user who can insert entries to the db.
So far I managed to create the following users & associated privileges:
$ ./mongo localhost:29525/admin -username admin -password "somesecret"
MongoDB shell version: 2.4.9
connecting to: localhost:29525/admin
> db.system.users.find()
{ "_id" : ObjectId("533dc34753178fa1d0707308"), "user" : "admin", "pwd" : "145efb041abb3f9dd2531b26c90f2a4c", "roles" : [ "userAdminAnyDatabase" ] }
{ "_id" : ObjectId("533dc9c03eb5b535e9691f21"), "user" : "node", "pwd" : "a2cbb645cec16dedd4a4f9ee53a332a7", "roles" : [ "readWrite", "dbAdmin" ] }
{ "_id" : ObjectId("533dd1c52d0f16b6fae61188"), "user" : "node2", "pwd" : "488fba587da677d48825b425ebf7031e", "roles" : [ "userAdminAnyDatabase", "userAdmin", "clusterAdmin", "dbAdminAnyDatabase" ] }
I ideally wanted to give the "admin" user full privileges, but unfortunately admin's 'userAdminAnyDatabase' privilege is not enough to enable this:
> db.users.update({"admin" : "somesecret"}, {$addToSet: {'roles': [ 'dbAdminAnyDatabase', 'clusterAdmin']}}, false, false)
not authorized for update on admin.users
I wondered if maybe I just wasn't actually executing the command as "admin", so I re-authenticated as user admin. Still no joy:
> db.auth("admin", "somesecret")
1
> db.users.update({"admin" : "somesecret"}, {$addToSet: {'roles': [ 'dbAdminAnyDatabase', 'clusterAdmin']}}, false, false)
not authorized for update on admin.users
So I tried the "node2" user - I had created that with more privileges (dbAdminAnyDatabase, clusterAdmin, ..), so maybe that would work? But alas it also fails:
> db.auth("node2", "anothersecret")
1
> db.users.update({"admin" : "somesecret"}, {$addToSet: {'roles': [ 'dbAdminAnyDatabase', 'clusterAdmin']}}, false, false)
not authorized for update on admin.users
That aside, I tried to create a database 'mynewdb', and add a collection 'users'. As the user with most privileges is "node2", I switched to that user first. But that user cannot insert records into the new database's new collection:
> db.auth("node2", "anothersecret")
1
> use mynewdb
switched to db mynewdb
> db.users.save( {username: "philipp"})
not authorized for insert on testapp.users
Nor for that matter can "admin".
Sorry for my ignorance, I have spent some hours Googling here and am still struggling to piece together jigsaw pieces presented by the many disparit bits of info on the MongoDB docs.
Thanks for any help!

This answer ONLY pertains to MongoDB 2.4.X and lower. The methods for doing this are significantly different under MongoDB 2.6
You are correctly querying the "system.users" collection in your examples:
db.system.users.find()
But your updates are to the "users" collection, which the admin user cannot access as it only has "userAdminAnyDatabase". Can you try running your update against "system.users" instead? ie
db.system.users.update({"admin" : "somesecret"}, {$addToSet: {'roles': [ 'dbAdminAnyDatabase', 'clusterAdmin']}})

Related

mongodb: how to list all users across all authentication databases

I'm pretty new to Mongo, so this may be a silly question, but I have not found a way to list all users (and their privileges) across all (authentication) databases. Similarly, I have not found a way to list all (authentication) databases. The "show users", "show databases" and their "db.adminCommand(...) versions all seem to run against the current database (the one specified with the "use" command), but what I need is a list of all(!) users and/or all(!) databases, regardless of those users' authentication databases.
Why do I (think) I need this? Well, I periodically must set up Mongo accounts for large groups of users, with each user having his/her/their own database. A few months later, I have to drop those users and their databases. I have a Python program that creates/drops these users and their databases. It all seems to work just fine. When creating a user, I give them their own authenticationDatabase (rather than adding them to "admin") with ReadWrite privileges on that database. As said, all of that seems to work just fine.
However... I need a way to see if, after the program runs (create or drop), users have indeed be created or databases have indeed be dropped by the Python program. Similarly, I need, from time to time, to see who all the users are and what databases I might still have around. Hence, a command for listing all users across all (authentication) databases and for listing all databases across all authentication databases would be welcome.
Hope someone can help (sorry for the long read).
R.
There is no built-in command that does that as far as I know but it is straightforward to implement this functionality:
Obtain the list of databases.
For each database, obtain the list of users.
I have not found a way to list all users (and their privileges) across
all (authentication) databases.
I have not found a way to list all
(authentication) databases.
... what I need is a list of all(!) users
and/or all(!) databases, regardless of those users' authentication
databases.
Here is a way to get the info you are looking for. Assuming you have the privilege to read other user's information (viewUser action), from the mongo shell you can query as follows:
> db.getUsers( { usersInfo: { forAllDBs: true } } )
This returns an array of all users and authentication databases and other related information. You are interested in "user" and "db fields, mostly. For example:
[
{
"_id" : "admin.user1",
"userId" : UUID("4f7369f6-bffa-45d9-bbdc-5bf50c196ea3"),
"user" : "user1",
"db" : "admin",
"roles" : [ { "role" : "read", "db" : "test" } ],
"mechanisms" : [ "SCRAM-SHA-1", ... ]
},
{
"_id" : "test.user2",
"userId" : UUID("1e36faaf-0667-4ec5-bbe9-3f703712cd9a"),
"user" : "user2",
"db" : "test",
"roles" : [ { "role" : "readWrite", "db" : "test" } ],
...
},
{
"_id" : "admin.super1",
"userId" : UUID("bcb2f424-7367-4686-82d8-115748fab951"),
"user" : "super1",
"db" : "admin",
"roles" : [ { "role" : "root", "db" : "admin" } ],
...
}
]
Since you need specific info, the query is customized as follows:
(1) To list all authentication databases, you can query like this:
var dbs = new Set()
db.getUsers( { usersInfo: { forAllDBs: true } } ).forEach(doc => dbs.add(doc.db))
print([...dbs])
The output is a list of unique authentication database names:
admin
test
(2) To list all authentication databases and users:
var dbUsers = [ ]
db.getUsers( { usersInfo: { forAllDBs: true } } ).forEach(doc => dbUsers.push(doc.db + ", " + doc.user))
dbUsers.sort()
dbUsers.forEach(printjson)
This get the ouput sorted by the authentication database and the user:
"admin, user1"
"admin, super1"
"test, user2"
(3) There are other ways to query too. For example, you can add a filter to get users with authentication database "admin":
db.getUsers( { usersInfo: { forAllDBs: true }, filter: { db: "admin" } } ).forEach(doc => print(doc.user))
This prints users only for "admin":
super1
user1
NOTES:
For more details see the User Management command usersInfo. The mongo shell provides the db.getUser() helper for this command, and this is used in the above examples.
The server version I tried with is the MongoDB version 4.2.

MongoDB - userAdminAnyDatabase can't create users

Currently I've got a siteUserAdmin authenticated on the admin database:
{
"_id" : "admin.siteUserAdmin",
"user" : "siteUserAdmin",
"db" : "admin",
"credentials" : {
"MONGODB-CR" : "...."
},
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
When I run:
use admin;
db.auth('siteUserAdmin', 'supersecret');
Everything authenticates just fine.
However when I then do:
use myotherdb
db.addUser({ user: 'chris', pwd: 'anothersecretpassword', roles: ['dbOwner']});
It doesn't add the user, I get the following:
couldn't add user: not authorized for insert on admin.system.users at src/mongo/shell/db.js:128
What am I doing wrong? This all looks nuts.
FYIL I'm using MongoDB version 2.6.10.
Random side note: weirdly createUser isn't a function, even though according to the MongoDB docs it was added in 2.6.
I was seeing this exact error in Robomongo 0.8.5. I copy/pasted the command to the the Mongo cli client and it worked fine.
Authenticated as siteUserAdmin to admin db on both clients.
Hopefully this helps someone else.

MongoDB 2.4 unauthorized to setProfilingLevel with admin role

I am the admin of a MongoDB 2.4 which is in production. When I am trying to activate profiling on some databases, it returns:
{ "ok" : 0, "errmsg" : "unauthorized" }
all the other profile-related commands return also a sort of unauthorized error messages.
my admin roles and rights are as follows:
{ "_id" : ObjectId("..."), "pwd" : "...", "roles" : [ "userAdminAnyDatabase", "readWriteAnyDatabase", "clusterAdmin" ], "user" : "admin" }
Do I need any other role to be able to profile, or there is another problem?
You need to add the dbAdminAnyDatabase role:
dbAdminAnyDatabase
dbAdminAnyDatabase provides users with the same access to database
administration operations as dbAdmin, except it applies to all logical
databases in the MongoDB environment.
http://docs.mongodb.org/v2.4/reference/user-privileges/

Able query only admin database

I just upgraded to 2.6. I run the authSchemaUpgrade. But after that, I managed to remove all users from the database (Its a private small database, so that is nothing too bad). Now I have created a new user admin:
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
After I have db.auth("admin","..") on the admin database I should be able to query any other databases too, but after I do:
user otherDatabase
show collections
I get:
2014-06-09T09:33:36.853+0000 error: {
"$err" : "not authorized for query on otherDatabase.system.namespaces",
"code" : 13
} at src/mongo/shell/query.js:131
What am I missing?
You need to give your admin user the role readWriteAnyDatabase in order to allow that user to query other databases.
You may want to also consider giving your admin user dbAdminAnyDatabase and clusterAdmin roles.

Add user in mongodb on debian without storing password in clear text

I have a mongodb server installed on my debian linux machine. Now to secure it before allowing remote login I'm trying to add an admin user, with the command:
db.addUser( { user: "admin",pwd: "MY_PASSWORD",roles: [ "userAdminAnyDatabase" ] } )
I must be doing something terribly wrong since my password ends up unencrypted in the database along with a md5 hashed version of it. I tried hashing it manually using md5 before running the command but still no luck...
This is what I get in the DB:
{ "_id" : ObjectId("5260fc9f51f87eba8d937701"), "user" : { "user" : "admin", "pwd" : "MY_PASSOWRD", "roles" : [ "userAdminAnyDatabase" ] }, "readOnly" : false, "pwd" : "HASHED_VERSION_OF_MY_PASSWORD" }
How do I add a user without ending up with cleartext passwords in the database?
You are probably using an older version which expected different syntax. The addUser function in 2.2 expected a string as username, another string as password. It seems you added a user whose entire full username is '{ "user" : "admin", "pwd" : "MY_PASSOWRD", "roles" : [ "userAdminAnyDatabase" ] }' - probably the shell should give an error, but it does not.
Try instead the expected 2.2 syntax:
> db.addUser( "admin", "MY_PASSWORD")
You can confirm the server version by running:
> db.version()