diff options
-rw-r--r-- | jstests/auth/profile.js | 50 | ||||
-rw-r--r-- | src/mongo/db/introspect.cpp | 23 |
2 files changed, 68 insertions, 5 deletions
diff --git a/jstests/auth/profile.js b/jstests/auth/profile.js new file mode 100644 index 00000000000..2be1db4d912 --- /dev/null +++ b/jstests/auth/profile.js @@ -0,0 +1,50 @@ +// Check that username information gets recorded properly in profiler. +var conn = startMongodTest(); +var db1 = conn.getDB("profile-a"); +var db2 = db1.getSisterDB("profile-b"); +var username = "user"; +db1.addUser(username, "password"); +db2.addUser(username, "password"); + + +function lastOp(db) { + return db.system.profile.find().sort( { $natural:-1 } ).next(); +} + +function principalName(user, db) { + return user + "@" + db.getName(); +} + +db1.setProfilingLevel(0); +db1.system.profile.drop(); +assert.eq(0, db1.system.profile.count()); + +db1.setProfilingLevel(2); + +db1.foo.findOne(); +var last = lastOp(db1); +assert.eq("", last.user); +assert.eq(0, last.allUsers.length); + +db1.auth(username, "password"); + +db1.foo.findOne(); +var last = lastOp(db1); +assert.eq(principalName(username, db1), last.user); +assert.eq(1, last.allUsers.length); +assert.eq(principalName(username, db1), last.allUsers[0]); + +db2.auth(username, "password"); + +db1.foo.findOne(); +var last = lastOp(db1); +// Which user gets put in "user" and the ordering of users in "allUsers" is undefined. +assert((principalName(username, db1) == last.user) || (principalName(username, db2) == last.user)); +assert.eq(2, last.allUsers.length); +assert.gte(last.allUsers.indexOf(principalName(username, db1)), 0); +assert.gte(last.allUsers.indexOf(principalName(username, db2)), 0); + + +db1.setProfilingLevel(0); +db1.dropDatabase(); +db2.dropDatabase(); diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp index 56b281384a6..6029281d0c0 100644 --- a/src/mongo/db/introspect.cpp +++ b/src/mongo/db/introspect.cpp @@ -19,6 +19,8 @@ #include "mongo/pch.h" #include "mongo/bson/util/builder.h" +#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/principal_set.h" #include "mongo/db/curop.h" #include "mongo/db/databaseholder.h" #include "mongo/db/introspect.h" @@ -32,6 +34,19 @@ namespace { namespace mongo { +namespace { + void _appendUserInfo(BSONObjBuilder& builder, AuthorizationManager* authManager) { + PrincipalSet::NameIterator nameIter = authManager->getAuthenticatedPrincipalNames(); + + builder.append("user", nameIter.more() ? nameIter->getFullName() : ""); + BSONArrayBuilder allUsers(builder.subarrayStart("allUsers")); + for ( ; nameIter.more(); nameIter.next()) { + allUsers.append(nameIter->getFullName()); + } + allUsers.doneFast(); + } +} // namespace + static void _profile(const Client& c, CurOp& currentOp, BufBuilder& profileBufBuilder) { Database *db = c.database(); DEV verify( db ); @@ -46,9 +61,8 @@ namespace mongo { b.appendDate("ts", jsTime()); b.append("client", c.clientAddress()); - if (c.getAuthenticationInfo()) { - b.append("user", c.getAuthenticationInfo()->getUser(nsToDatabase(ns))); - } + AuthorizationManager* authManager = c.getAuthorizationManager(); + _appendUserInfo(b, authManager); BSONObj p = b.done(); @@ -61,8 +75,7 @@ namespace mongo { BSONObjBuilder b(profileBufBuilder); b.appendDate("ts", jsTime()); b.append("client", c.clientAddress() ); - if ( c.getAuthenticationInfo() ) - b.append( "user" , c.getAuthenticationInfo()->getUser( nsToDatabase( ns ) ) ); + _appendUserInfo(b, authManager); b.append("err", "profile line too large (max is 100KB)"); |