summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r--src/mongo/db/auth/action_types.txt1
-rw-r--r--src/mongo/db/auth/authorization_session.cpp30
-rw-r--r--src/mongo/db/auth/authorization_session.h22
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.cpp8
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.h11
-rw-r--r--src/mongo/db/auth/user_name.h76
-rw-r--r--src/mongo/db/auth/user_set.cpp24
-rw-r--r--src/mongo/db/auth/user_set.h33
-rw-r--r--src/mongo/db/auth/user_set_test.cpp4
9 files changed, 166 insertions, 43 deletions
diff --git a/src/mongo/db/auth/action_types.txt b/src/mongo/db/auth/action_types.txt
index 9c06abbc2fb..ecf7bf9ad87 100644
--- a/src/mongo/db/auth/action_types.txt
+++ b/src/mongo/db/auth/action_types.txt
@@ -59,6 +59,7 @@
"grantRolesToUser", # Not used for permissions checks, but to id the event in logs.
"handshake",
"hostInfo",
+"impersonate",
"indexStats",
"inprog",
"insert",
diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp
index bbab218f0b1..a9f0887253e 100644
--- a/src/mongo/db/auth/authorization_session.cpp
+++ b/src/mongo/db/auth/authorization_session.cpp
@@ -51,7 +51,8 @@ namespace {
const std::string ADMIN_DBNAME = "admin";
} // namespace
- AuthorizationSession::AuthorizationSession(AuthzSessionExternalState* externalState) {
+ AuthorizationSession::AuthorizationSession(AuthzSessionExternalState* externalState)
+ : _impersonationFlag(false) {
_externalState.reset(externalState);
}
@@ -78,6 +79,9 @@ namespace {
return status;
}
+ // If there are any users in the impersonate list, clear them.
+ clearImpersonatedUserNames();
+
// Calling add() on the UserSet may return a user that was replaced because it was from the
// same database.
User* replacedUser = _authenticatedUsers.add(user);
@@ -97,19 +101,20 @@ namespace {
}
void AuthorizationSession::logoutDatabase(const std::string& dbname) {
+ clearImpersonatedUserNames();
User* removedUser = _authenticatedUsers.removeByDBName(dbname);
if (removedUser) {
getAuthorizationManager().releaseUser(removedUser);
}
}
- UserSet::NameIterator AuthorizationSession::getAuthenticatedUserNames() {
+ UserNameIterator AuthorizationSession::getAuthenticatedUserNames() {
return _authenticatedUsers.getNames();
}
std::string AuthorizationSession::getAuthenticatedUserNamesToken() {
std::string ret;
- for (UserSet::NameIterator nameIter = getAuthenticatedUserNames();
+ for (UserNameIterator nameIter = getAuthenticatedUserNames();
nameIter.more();
nameIter.next()) {
ret += '\0'; // Using a NUL byte which isn't valid in usernames to separate them.
@@ -475,4 +480,23 @@ namespace {
return false;
}
+ void AuthorizationSession::setImpersonatedUserNames(const std::vector<UserName>& names) {
+ _impersonatedUserNames = names;
+ _impersonationFlag = true;
+ }
+
+ // Clear the vector of impersonated UserNames.
+ void AuthorizationSession::clearImpersonatedUserNames() {
+ _impersonatedUserNames.clear();
+ _impersonationFlag = false;
+ }
+
+ UserNameIterator AuthorizationSession::getImpersonatedUserNames() const {
+ return makeUserNameIteratorForContainer(_impersonatedUserNames);
+ }
+
+ bool AuthorizationSession::isImpersonating() const {
+ return _impersonationFlag;
+ }
+
} // namespace mongo
diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h
index c9c9178791a..3a64792b611 100644
--- a/src/mongo/db/auth/authorization_session.h
+++ b/src/mongo/db/auth/authorization_session.h
@@ -89,7 +89,7 @@ namespace mongo {
size_t getNumAuthenticatedUsers();
// Gets an iterator over the names of all authenticated users stored in this manager.
- UserSet::NameIterator getAuthenticatedUserNames();
+ UserNameIterator getAuthenticatedUserNames();
// Returns a string representing all logged-in users on the current session.
// WARNING: this string will contain NUL bytes so don't call c_str()!
@@ -180,6 +180,21 @@ namespace mongo {
// isAuthorizedForActionsOnResource(ResourcePattern::forExactNamespace(ns), actions).
bool isAuthorizedForActionsOnNamespace(const NamespaceString& ns, const ActionSet& actions);
+ // Replaces the vector of UserNames that a system user is impersonating with a new vector.
+ // The auditing system adds these to each audit record in the log.
+ void setImpersonatedUserNames(const std::vector<UserName>& names);
+
+ // Returns an iterator to a vector of impersonated usernames.
+ UserNameIterator getImpersonatedUserNames() const;
+
+ // Clears the vector of impersonated UserNames.
+ void clearImpersonatedUserNames();
+
+ // Tells whether impersonation is active or not. This state is set when
+ // setImpersonatedUserNames is called and cleared when clearImpersonatedUserNames is
+ // called.
+ bool isImpersonating() const;
+
private:
// If any users authenticated on this session are marked as invalid this updates them with
@@ -195,6 +210,11 @@ namespace mongo {
// All Users who have been authenticated on this connection
UserSet _authenticatedUsers;
+
+ // A vector of impersonated UserNames. These are used in the auditing system.
+ // They are not used for authz checks.
+ std::vector<UserName> _impersonatedUserNames;
+ bool _impersonationFlag;
};
} // namespace mongo
diff --git a/src/mongo/db/auth/user_management_commands_parser.cpp b/src/mongo/db/auth/user_management_commands_parser.cpp
index 002880c2050..61023fe6a25 100644
--- a/src/mongo/db/auth/user_management_commands_parser.cpp
+++ b/src/mongo/db/auth/user_management_commands_parser.cpp
@@ -137,7 +137,7 @@ namespace auth {
return Status::OK();
}
- Status _parseUserNamesFromBSONArray(const BSONArray& usersArray,
+ Status parseUserNamesFromBSONArray(const BSONArray& usersArray,
const StringData& dbname,
std::vector<UserName>* parsedUserNames) {
return _parseNamesFromBSONArray(usersArray,
@@ -359,9 +359,9 @@ namespace auth {
if (cmdObj["usersInfo"].numberInt() == 1) {
parsedArgs->allForDB = true;
} else if (cmdObj["usersInfo"].type() == Array) {
- status = _parseUserNamesFromBSONArray(BSONArray(cmdObj["usersInfo"].Obj()),
- dbname,
- &parsedArgs->userNames);
+ status = parseUserNamesFromBSONArray(BSONArray(cmdObj["usersInfo"].Obj()),
+ dbname,
+ &parsedArgs->userNames);
if (!status.isOK()) {
return status;
}
diff --git a/src/mongo/db/auth/user_management_commands_parser.h b/src/mongo/db/auth/user_management_commands_parser.h
index d5e10f7574d..befeb2731ba 100644
--- a/src/mongo/db/auth/user_management_commands_parser.h
+++ b/src/mongo/db/auth/user_management_commands_parser.h
@@ -194,7 +194,7 @@ namespace auth {
PrivilegeVector* parsedPrivileges);
/**
- * Takes a BSONArray of name,source pair documents, parses that array and returns (via the
+ * Takes a BSONArray of name,db pair documents, parses that array and returns (via the
* output param parsedRoleNames) a list of the role names in the input array.
* Performs syntactic validation of "rolesArray", only.
*/
@@ -202,5 +202,14 @@ namespace auth {
const StringData& dbname,
std::vector<RoleName>* parsedRoleNames);
+ /**
+ * Takes a BSONArray of name,db pair documents, parses that array and returns (via the
+ * output param parsedUserNames) a list of the usernames in the input array.
+ * Performs syntactic validation of "usersArray", only.
+ */
+ Status parseUserNamesFromBSONArray(const BSONArray& usersArray,
+ const StringData& dbname,
+ std::vector<UserName>* parsedUserNames);
+
} // namespace auth
} // namespace mongo
diff --git a/src/mongo/db/auth/user_name.h b/src/mongo/db/auth/user_name.h
index acee87f8ada..9104fded846 100644
--- a/src/mongo/db/auth/user_name.h
+++ b/src/mongo/db/auth/user_name.h
@@ -18,6 +18,9 @@
#include <iosfwd>
#include <string>
+#include <boost/scoped_ptr.hpp>
+
+#include "mongo/base/disallow_copying.h"
#include "mongo/base/string_data.h"
namespace mongo {
@@ -71,4 +74,77 @@ namespace mongo {
std::ostream& operator<<(std::ostream& os, const UserName& name);
+ /**
+ * Iterator over an unspecified container of UserName objects.
+ */
+ class UserNameIterator {
+ public:
+ class Impl {
+ MONGO_DISALLOW_COPYING(Impl);
+ public:
+ Impl() {};
+ virtual ~Impl() {};
+ static Impl* clone(Impl* orig) { return orig ? orig->doClone(): NULL; }
+ virtual bool more() const = 0;
+ virtual const UserName& get() const = 0;
+
+ virtual const UserName& next() = 0;
+
+ private:
+ virtual Impl* doClone() const = 0;
+ };
+
+ UserNameIterator() : _impl(NULL) {}
+ UserNameIterator(const UserNameIterator& other) : _impl(Impl::clone(other._impl.get())) {}
+ explicit UserNameIterator(Impl* impl) : _impl(impl) {}
+
+ UserNameIterator& operator=(const UserNameIterator& other) {
+ _impl.reset(Impl::clone(other._impl.get()));
+ return *this;
+ }
+
+ bool more() const { return _impl.get() && _impl->more(); }
+ const UserName& get() const { return _impl->get(); }
+
+ const UserName& next() { return _impl->next(); }
+
+ const UserName& operator*() const { return get(); }
+ const UserName* operator->() const { return &get(); }
+
+ private:
+ boost::scoped_ptr<Impl> _impl;
+ };
+
+
+ template <typename ContainerIterator>
+ class UserNameContainerIteratorImpl : public UserNameIterator::Impl {
+ MONGO_DISALLOW_COPYING(UserNameContainerIteratorImpl);
+ public:
+ UserNameContainerIteratorImpl(const ContainerIterator& begin,
+ const ContainerIterator& end) :
+ _curr(begin), _end(end) {}
+ virtual ~UserNameContainerIteratorImpl() {}
+ virtual bool more() const { return _curr != _end; }
+ virtual const UserName& next() { return *(_curr++); }
+ virtual const UserName& get() const { return *_curr; }
+ virtual UserNameIterator::Impl* doClone() const {
+ return new UserNameContainerIteratorImpl(_curr, _end);
+ }
+
+ private:
+ ContainerIterator _curr;
+ ContainerIterator _end;
+ };
+
+ template <typename ContainerIterator>
+ UserNameIterator makeUserNameIterator(const ContainerIterator& begin,
+ const ContainerIterator& end) {
+ return UserNameIterator( new UserNameContainerIteratorImpl<ContainerIterator>(begin, end));
+ }
+
+ template <typename Container>
+ UserNameIterator makeUserNameIteratorForContainer(const Container& container) {
+ return makeUserNameIterator(container.begin(), container.end());
+ }
+
} // namespace mongo
diff --git a/src/mongo/db/auth/user_set.cpp b/src/mongo/db/auth/user_set.cpp
index c36a1c093f7..34c1318ab9d 100644
--- a/src/mongo/db/auth/user_set.cpp
+++ b/src/mongo/db/auth/user_set.cpp
@@ -23,6 +23,27 @@
namespace mongo {
+namespace {
+ class UserSetNameIteratorImpl : public UserNameIterator::Impl {
+ MONGO_DISALLOW_COPYING(UserSetNameIteratorImpl);
+ public:
+ UserSetNameIteratorImpl(const UserSet::iterator& begin,
+ const UserSet::iterator& end) :
+ _curr(begin), _end(end) {}
+ virtual ~UserSetNameIteratorImpl() {}
+ virtual bool more() const { return _curr != _end; }
+ virtual const UserName& next() { return (*(_curr++))->getName(); }
+ virtual const UserName& get() const { return (*_curr)->getName(); }
+ virtual UserNameIterator::Impl* doClone() const {
+ return new UserSetNameIteratorImpl(_curr, _end);
+ }
+
+ private:
+ UserSet::iterator _curr;
+ UserSet::iterator _end;
+ };
+} // namespace
+
UserSet::UserSet() : _users(), _usersEnd(_users.end()) {}
UserSet::~UserSet() {}
@@ -90,4 +111,7 @@ namespace mongo {
return NULL;
}
+ UserNameIterator UserSet::getNames() const {
+ return UserNameIterator(new UserSetNameIteratorImpl(begin(), end()));
+ }
} // namespace mongo
diff --git a/src/mongo/db/auth/user_set.h b/src/mongo/db/auth/user_set.h
index ad193654e52..591a9bdb9fa 100644
--- a/src/mongo/db/auth/user_set.h
+++ b/src/mongo/db/auth/user_set.h
@@ -37,37 +37,6 @@ namespace mongo {
public:
typedef std::vector<User*>::const_iterator iterator;
- /**
- * Forward iterator over the names of the users stored in a UserSet.
- *
- * Instances are valid until the underlying vector<User*> is modified.
- *
- * more() must be the first method called after construction, and must be checked
- * after each call to next() before calling any other methods.
- */
- class NameIterator {
- public:
- explicit NameIterator(iterator begin, iterator end) : _curr(begin), _end(end) {}
-
- NameIterator() {}
-
- bool more() { return _curr != _end; }
- const UserName& next() {
- const UserName& ret = get();
- ++_curr;
- return ret;
- }
-
- const UserName& get() const { return (*_curr)->getName(); }
-
- const UserName& operator*() const { return get(); }
- const UserName* operator->() const { return &get(); }
-
- private:
- std::vector<User*>::const_iterator _curr;
- std::vector<User*>::const_iterator _end;
- };
-
UserSet();
~UserSet();
@@ -121,7 +90,7 @@ namespace mongo {
// Gets an iterator over the names of the users stored in the set. The iterator is
// valid until the next non-const method is called on the UserSet.
- NameIterator getNames() const { return NameIterator(begin(), end()); }
+ UserNameIterator getNames() const;
iterator begin() const { return _users.begin(); }
iterator end() const { return _usersEnd; }
diff --git a/src/mongo/db/auth/user_set_test.cpp b/src/mongo/db/auth/user_set_test.cpp
index fb30d00bee7..5063f727412 100644
--- a/src/mongo/db/auth/user_set_test.cpp
+++ b/src/mongo/db/auth/user_set_test.cpp
@@ -75,7 +75,7 @@ namespace {
ASSERT_EQUALS(p3, set.lookup(UserName("Bob", "test2")));
ASSERT_EQUALS(p3, set.lookupByDBName("test2"));
- UserSet::NameIterator iter = set.getNames();
+ UserNameIterator iter = set.getNames();
ASSERT_TRUE(iter.more());
ASSERT_EQUALS(iter.next(), UserName("Bob", "test2"));
ASSERT_FALSE(iter.more());
@@ -83,7 +83,7 @@ namespace {
TEST(UserSetTest, IterateNames) {
UserSet pset;
- UserSet::NameIterator iter = pset.getNames();
+ UserNameIterator iter = pset.getNames();
ASSERT(!iter.more());
ASSERT_NULL(pset.add(new User(UserName("bob", "test"))));