diff options
7 files changed, 96 insertions, 10 deletions
diff --git a/src/mongo/db/auth/authz_manager_external_state.h b/src/mongo/db/auth/authz_manager_external_state.h index 0762e5f075e..1d65e488480 100644 --- a/src/mongo/db/auth/authz_manager_external_state.h +++ b/src/mongo/db/auth/authz_manager_external_state.h @@ -28,6 +28,7 @@ #pragma once +#include <boost/function.hpp> #include <string> #include <vector> @@ -105,6 +106,14 @@ namespace mongo { BSONObj* result) = 0; /** + * Finds all documents matching "query" in "collectionName". For each document returned, + * calls the function resultProcessor on it. + */ + virtual Status query(const NamespaceString& collectionName, + const BSONObj& query, + const boost::function<void(const BSONObj&)>& resultProcessor) = 0; + + /** * Inserts "document" into "collectionName". */ virtual Status insert(const NamespaceString& collectionName, diff --git a/src/mongo/db/auth/authz_manager_external_state_d.cpp b/src/mongo/db/auth/authz_manager_external_state_d.cpp index 2fb6f49be5a..f0967d919a2 100644 --- a/src/mongo/db/auth/authz_manager_external_state_d.cpp +++ b/src/mongo/db/auth/authz_manager_external_state_d.cpp @@ -179,6 +179,20 @@ namespace { return Status::OK(); } + Status AuthzManagerExternalStateMongod::query( + const NamespaceString& collectionName, + const BSONObj& query, + const boost::function<void(const BSONObj&)>& resultProcessor) { + try { + DBDirectClient client; + Client::GodScope gs; + client.query(resultProcessor, collectionName.ns(), query); + return Status::OK(); + } catch (const DBException& e) { + return e.toStatus(); + } + } + Status AuthzManagerExternalStateMongod::getAllDatabaseNames( std::vector<std::string>* dbnames) { Lock::GlobalWrite lk; diff --git a/src/mongo/db/auth/authz_manager_external_state_d.h b/src/mongo/db/auth/authz_manager_external_state_d.h index cef5a8aa883..ab7e1dd384d 100644 --- a/src/mongo/db/auth/authz_manager_external_state_d.h +++ b/src/mongo/db/auth/authz_manager_external_state_d.h @@ -28,6 +28,7 @@ #pragma once +#include <boost/function.hpp> #include <boost/thread/mutex.hpp> #include <string> @@ -68,6 +69,9 @@ namespace mongo { virtual Status findOne(const NamespaceString& collectionName, const BSONObj& query, BSONObj* result); + virtual Status query(const NamespaceString& collectionName, + const BSONObj& query, + const boost::function<void(const BSONObj&)>& resultProcessor); virtual Status insert(const NamespaceString& collectionName, const BSONObj& document, const BSONObj& writeConcern); diff --git a/src/mongo/db/auth/authz_manager_external_state_mock.cpp b/src/mongo/db/auth/authz_manager_external_state_mock.cpp index 0c4dd2add49..f62f8243a08 100644 --- a/src/mongo/db/auth/authz_manager_external_state_mock.cpp +++ b/src/mongo/db/auth/authz_manager_external_state_mock.cpp @@ -113,6 +113,22 @@ namespace mongo { return Status::OK(); } + Status AuthzManagerExternalStateMock::query( + const NamespaceString& collectionName, + const BSONObj& query, + const boost::function<void(const BSONObj&)>& resultProcessor) { + std::vector<BSONObjCollection::iterator> iterVector; + Status status = _queryVector(collectionName, query, &iterVector); + if (!status.isOK()) { + return status; + } + for (std::vector<BSONObjCollection::iterator>::iterator it = iterVector.begin(); + it != iterVector.end(); ++it) { + resultProcessor(**it); + } + return Status::OK(); + } + Status AuthzManagerExternalStateMock::insert( const NamespaceString& collectionName, const BSONObj& document, @@ -233,6 +249,22 @@ namespace mongo { const NamespaceString& collectionName, const BSONObj& query, BSONObjCollection::iterator* result) { + std::vector<BSONObjCollection::iterator> iterVector; + Status status = _queryVector(collectionName, query, &iterVector); + if (!status.isOK()) { + return status; + } + if (!iterVector.size()) { + return Status(ErrorCodes::NoMatchingDocument, "No matching document"); + } + *result = iterVector.front(); + return Status::OK(); + } + + Status AuthzManagerExternalStateMock::_queryVector( + const NamespaceString& collectionName, + const BSONObj& query, + std::vector<BSONObjCollection::iterator>* result) { StatusWithMatchExpression parseResult = MatchExpressionParser::parse(query); if (!parseResult.isOK()) { @@ -250,11 +282,10 @@ namespace mongo { ++vecIt) { if (matcher->matchesBSON(*vecIt)) { - *result = vecIt; - return Status::OK(); + result->push_back(vecIt); } } - return Status(ErrorCodes::NoMatchingDocument, "No matching document"); + return Status::OK(); } } // namespace mongo diff --git a/src/mongo/db/auth/authz_manager_external_state_mock.h b/src/mongo/db/auth/authz_manager_external_state_mock.h index 6b19164f1cc..c26152a8c74 100644 --- a/src/mongo/db/auth/authz_manager_external_state_mock.h +++ b/src/mongo/db/auth/authz_manager_external_state_mock.h @@ -28,6 +28,7 @@ #pragma once +#include <boost/function.hpp> #include <string> #include <map> #include <vector> @@ -78,6 +79,10 @@ namespace mongo { const BSONObj& query, BSONObj* result); + virtual Status query(const NamespaceString& collectionName, + const BSONObj& query, + const boost::function<void(const BSONObj&)>& resultProcessor); + // This implementation does not understand uniqueness constraints. virtual Status insert(const NamespaceString& collectionName, const BSONObj& document, @@ -118,6 +123,11 @@ namespace mongo { const BSONObj& query, BSONObjCollection::iterator* result); + Status _queryVector(const NamespaceString& collectionName, + const BSONObj& query, + std::vector<BSONObjCollection::iterator>* result); + + NamespaceDocumentMap _documents; // Mock database. }; diff --git a/src/mongo/db/auth/authz_manager_external_state_s.cpp b/src/mongo/db/auth/authz_manager_external_state_s.cpp index 8c38923f3c7..111170d10f6 100644 --- a/src/mongo/db/auth/authz_manager_external_state_s.cpp +++ b/src/mongo/db/auth/authz_manager_external_state_s.cpp @@ -53,7 +53,7 @@ namespace { AuthzManagerExternalStateMongos::~AuthzManagerExternalStateMongos() {} namespace { - ScopedDbConnection* getConnectionForUsersCollection(const std::string& ns) { + ScopedDbConnection* getConnectionForAuthzCollection(const std::string& ns) { // // Note: The connection mechanism here is *not* ideal, and should not be used elsewhere. // If the primary for the collection moves, this approach may throw rather than handle @@ -71,7 +71,7 @@ namespace { const BSONObj& query, BSONObj* result) { try { - scoped_ptr<ScopedDbConnection> conn(getConnectionForUsersCollection(usersNamespace)); + scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(usersNamespace)); *result = conn->get()->findOne(usersNamespace, query).getOwned(); conn->done(); if (result->isEmpty()) { @@ -83,12 +83,26 @@ namespace { } } + Status AuthzManagerExternalStateMongos::query( + const NamespaceString& collectionName, + const BSONObj& query, + const boost::function<void(const BSONObj&)>& resultProcessor) { + try { + scoped_ptr<ScopedDbConnection> conn( + getConnectionForAuthzCollection(collectionName.ns())); + conn->get()->query(resultProcessor, collectionName.ns(), query); + return Status::OK(); + } catch (const DBException& e) { + return e.toStatus(); + } + } + Status AuthzManagerExternalStateMongos::insertPrivilegeDocument(const string& dbname, const BSONObj& userObj, const BSONObj& writeConcern) { try { const std::string userNS = "admin.system.users"; - scoped_ptr<ScopedDbConnection> conn(getConnectionForUsersCollection(userNS)); + scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(userNS)); conn->get()->insert(userNS, userObj); @@ -121,7 +135,7 @@ namespace { const UserName& user, const BSONObj& updateObj, const BSONObj& writeConcern) { try { const std::string userNS = "admin.system.users"; - scoped_ptr<ScopedDbConnection> conn(getConnectionForUsersCollection(userNS)); + scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(userNS)); conn->get()->update( userNS, @@ -161,7 +175,7 @@ namespace { int* numRemoved) { try { string userNS = "admin.system.users"; - scoped_ptr<ScopedDbConnection> conn(getConnectionForUsersCollection(userNS)); + scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(userNS)); conn->get()->remove(userNS, query); @@ -189,7 +203,7 @@ namespace { std::vector<std::string>* dbnames) { try { scoped_ptr<ScopedDbConnection> conn( - getConnectionForUsersCollection(DatabaseType::ConfigNS)); + getConnectionForAuthzCollection(DatabaseType::ConfigNS)); auto_ptr<DBClientCursor> c = conn->get()->query(DatabaseType::ConfigNS, Query()); while (c->more()) { @@ -212,7 +226,7 @@ namespace { const std::string& dbname, std::vector<BSONObj>* privDocs) { try { std::string usersNamespace = dbname + ".system.users"; - scoped_ptr<ScopedDbConnection> conn(getConnectionForUsersCollection(usersNamespace)); + scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(usersNamespace)); auto_ptr<DBClientCursor> c = conn->get()->query(usersNamespace, Query()); while (c->more()) { diff --git a/src/mongo/db/auth/authz_manager_external_state_s.h b/src/mongo/db/auth/authz_manager_external_state_s.h index 5d47b462fc1..ae85d05adad 100644 --- a/src/mongo/db/auth/authz_manager_external_state_s.h +++ b/src/mongo/db/auth/authz_manager_external_state_s.h @@ -28,6 +28,7 @@ #pragma once +#include <boost/function.hpp> #include <boost/scoped_ptr.hpp> #include <string> @@ -69,6 +70,9 @@ namespace mongo { virtual Status findOne(const NamespaceString& collectionName, const BSONObj& query, BSONObj* result); + virtual Status query(const NamespaceString& collectionName, + const BSONObj& query, + const boost::function<void(const BSONObj&)>& resultProcessor); virtual Status insert(const NamespaceString& collectionName, const BSONObj& document, const BSONObj& writeConcern); |