diff options
author | Andy Schwerin <schwerin@10gen.com> | 2013-07-17 14:43:10 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@10gen.com> | 2013-07-17 17:47:36 -0400 |
commit | 0eb227c15841da86dbf9d21e7e593c7659040963 (patch) | |
tree | b65159d2b8f30bf978b6003289a492734cfb69b9 /src/mongo/db | |
parent | 752f704bc0fb5c771b74a033364eaa045eda2040 (diff) | |
download | mongo-0eb227c15841da86dbf9d21e7e593c7659040963.tar.gz |
SERVER-1891 Add audit logging hooks for authorization checks in mongod.
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/audit.cpp | 63 | ||||
-rw-r--r-- | src/mongo/db/audit.h | 104 | ||||
-rw-r--r-- | src/mongo/db/clientcursor.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/instance.cpp | 57 |
4 files changed, 212 insertions, 27 deletions
diff --git a/src/mongo/db/audit.cpp b/src/mongo/db/audit.cpp index 15d7814d84f..6c78ded58c6 100644 --- a/src/mongo/db/audit.cpp +++ b/src/mongo/db/audit.cpp @@ -16,7 +16,11 @@ #include "mongo/db/audit.h" -#if !MONGO_ENTERPRISE_VERSION +#if MONGO_ENTERPRISE_VERSION +#define MONGO_AUDIT_STUB ; +#else +#define MONGO_AUDIT_STUB {} +#endif namespace mongo { namespace audit { @@ -24,8 +28,61 @@ namespace audit { void logCommandAuthzCheck(ClientBasic* client, const NamespaceString& ns, const BSONObj& cmdObj, - ErrorCodes::Error result) {} + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logDeleteAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& pattern, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logFsyncUnlockAuthzCheck( + ClientBasic* client, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logGetMoreAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + long long cursorId, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logInProgAuthzCheck( + ClientBasic* client, + const BSONObj& filter, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logInsertAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& insertedObj, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logKillCursorsAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + long long cursorId, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logKillOpAuthzCheck( + ClientBasic* client, + const BSONObj& filter, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logQueryAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& query, + ErrorCodes::Error result) MONGO_AUDIT_STUB + + void logUpdateAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& query, + const BSONObj& updateObj, + bool isUpsert, + bool isMulti, + ErrorCodes::Error result) MONGO_AUDIT_STUB + } // namespace audit } // namespace mongo -#endif // !MONGO_ENTERPRISE diff --git a/src/mongo/db/audit.h b/src/mongo/db/audit.h index 6a703e41238..84ed98ca4bc 100644 --- a/src/mongo/db/audit.h +++ b/src/mongo/db/audit.h @@ -14,6 +14,11 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/** + * This module describes free functions for logging various operations of interest to a + * party interested in generating logs of user activity in a MongoDB server instance. + */ + #pragma once #include "mongo/base/error_codes.h" @@ -26,12 +31,101 @@ namespace mongo { namespace audit { + // + // Authorization (authz) logging functions. + // + // These functions generate log messages describing the disposition of access control + // checks. + // + + /** + * Logs the result of a command authorization check. + */ + void logCommandAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& cmdObj, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for an OP_DELETE wire protocol message. + */ + void logDeleteAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& pattern, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for the "unlock" pseudo-command. + */ + void logFsyncUnlockAuthzCheck( + ClientBasic* client, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for an OP_GET_MORE wire protocol message. + */ + void logGetMoreAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + long long cursorId, + ErrorCodes::Error result); + /** - * Logs the result of an authorization (access control) check. + * Logs the result of an authorization check for an "inprog" pseudo-command. */ - void logCommandAuthzCheck(ClientBasic* client, - const NamespaceString& ns, - const BSONObj& cmdObj, - ErrorCodes::Error result); + void logInProgAuthzCheck( + ClientBasic* client, + const BSONObj& filter, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for an OP_INSERT wire protocol message. + */ + void logInsertAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& insertedObj, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for an OP_KILL_CURSORS wire protocol message. + */ + void logKillCursorsAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + long long cursorId, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for a "killop" pseudo-command. + */ + void logKillOpAuthzCheck( + ClientBasic* client, + const BSONObj& filter, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for an OP_QUERY wire protocol message. + */ + void logQueryAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& query, + ErrorCodes::Error result); + + /** + * Logs the result of an authorization check for an OP_UPDATE wire protocol message. + */ + void logUpdateAuthzCheck( + ClientBasic* client, + const NamespaceString& ns, + const BSONObj& query, + const BSONObj& updateObj, + bool isUpsert, + bool isMulti, + ErrorCodes::Error result); + } // namespace audit } // namespace mongo diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp index 22afbd4fcea..811a6217a29 100644 --- a/src/mongo/db/clientcursor.cpp +++ b/src/mongo/db/clientcursor.cpp @@ -31,6 +31,7 @@ #include <vector> #include "mongo/client/dbclientinterface.h" +#include "mongo/db/audit.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_session.h" @@ -870,13 +871,25 @@ namespace mongo { recursive_scoped_lock lock(ccmutex); ClientCursor* cursor = find_inlock(id); if (!cursor) { + audit::logKillCursorsAuthzCheck( + &cc(), + NamespaceString(""), + id, + ErrorCodes::CursorNotFound); return false; } ns = cursor->ns(); } // Can't be in a lock when checking authorization - if (!cc().getAuthorizationSession()->checkAuthorization(ns, ActionType::killCursors)) { + const bool isAuthorized = cc().getAuthorizationSession()->checkAuthorization( + ns, ActionType::killCursors); + audit::logKillCursorsAuthzCheck( + &cc(), + NamespaceString(ns), + id, + isAuthorized ? ErrorCodes::OK : ErrorCodes::Unauthorized); + if (!isAuthorized) { return false; } diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp index 38fe5e0ec81..5a4beb2135f 100644 --- a/src/mongo/db/instance.cpp +++ b/src/mongo/db/instance.cpp @@ -29,6 +29,7 @@ #include "mongo/base/status.h" #include "mongo/bson/util/atomic_int.h" +#include "mongo/db/audit.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_session.h" @@ -128,15 +129,20 @@ namespace mongo { } void inProgCmd( Message &m, DbResponse &dbresponse ) { + DbMessage d(m); + QueryMessage q(d); BSONObjBuilder b; - if (!cc().getAuthorizationSession()->checkAuthorization( - AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::inprog)) { + const bool isAuthorized = cc().getAuthorizationSession()->checkAuthorization( + AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::inprog); + + audit::logInProgAuthzCheck( + &cc(), q.query, isAuthorized ? ErrorCodes::OK : ErrorCodes::Unauthorized); + + if (!isAuthorized) { b.append("err", "unauthorized"); } else { - DbMessage d(m); - QueryMessage q(d); bool all = q.query["$all"].trueValue(); vector<BSONObj> vals; { @@ -183,17 +189,21 @@ namespace mongo { } void killOp( Message &m, DbResponse &dbresponse ) { + DbMessage d(m); + QueryMessage q(d); BSONObj obj; - if (!cc().getAuthorizationSession()->checkAuthorization( - AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::killop)) { + const bool isAuthorized = cc().getAuthorizationSession()->checkAuthorization( + AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::killop); + audit::logKillOpAuthzCheck(&cc(), + q.query, + isAuthorized ? ErrorCodes::OK : ErrorCodes::Unauthorized); + if (!isAuthorized) { obj = fromjson("{\"err\":\"unauthorized\"}"); } /*else if( !dbMutexInfo.isLocked() ) obj = fromjson("{\"info\":\"no op in progress/not locked\"}"); */ else { - DbMessage d(m); - QueryMessage q(d); BSONElement e = q.query.getField("op"); if( !e.isNumber() ) { obj = fromjson("{\"err\":\"no op number field specified?\"}"); @@ -210,8 +220,11 @@ namespace mongo { bool _unlockFsync(); void unlockFsync(const char *ns, Message& m, DbResponse &dbresponse) { BSONObj obj; - if (!cc().getAuthorizationSession()->checkAuthorization( - AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::unlock)) { + const bool isAuthorized = cc().getAuthorizationSession()->checkAuthorization( + AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::unlock); + audit::logFsyncUnlockAuthzCheck( + &cc(), isAuthorized ? ErrorCodes::OK : ErrorCodes::Unauthorized); + if (!isAuthorized) { obj = fromjson("{\"err\":\"unauthorized\"}"); } else if (strncmp(ns, "admin.", 6) != 0 ) { @@ -244,9 +257,12 @@ namespace mongo { try { if (!NamespaceString(d.getns()).isCommand()) { // Auth checking for Commands happens later. - Status status = cc().getAuthorizationSession()->checkAuthForQuery(d.getns(), - q.query); - uassert(16550, status.reason(), status.isOK()); + Client* client = &cc(); + Status status = client->getAuthorizationSession()->checkAuthForQuery(d.getns(), + q.query); + audit::logQueryAuthzCheck( + client, NamespaceString(d.getns()), q.query, status.code()); + uassertStatusOK(status); } dbresponse.exhaustNS = runQuery(m, q, op, *resp); verify( !resp->empty() ); @@ -577,7 +593,9 @@ namespace mongo { query, toupdate, upsert); - uassert(16538, status.reason(), status.isOK()); + audit::logUpdateAuthzCheck( + &cc(), NamespaceString(ns), query, toupdate, upsert, multi, status.code()); + uassertStatusOK(status); op.debug().query = query; op.setQuery(query); @@ -617,9 +635,10 @@ namespace mongo { bool broadcast = flags & RemoveOption_Broadcast; verify( d.moreJSObjs() ); BSONObj pattern = d.nextJsObj(); - + Status status = cc().getAuthorizationSession()->checkAuthForDelete(ns, pattern); - uassert(16542, status.reason(), status.isOK()); + audit::logDeleteAuthzCheck(&cc(), NamespaceString(ns), pattern, status.code()); + uassertStatusOK(status); op.debug().query = pattern; op.setQuery(pattern); @@ -678,7 +697,8 @@ namespace mongo { uassert( 16258, str::stream() << "Invalid ns [" << ns << "]", nsString.isValid() ); Status status = cc().getAuthorizationSession()->checkAuthForGetMore(ns, cursorid); - uassert(16543, status.reason(), status.isOK()); + audit::logGetMoreAuthzCheck(&cc(), NamespaceString(ns), cursorid, status.code()); + uassertStatusOK(status); if (str::startsWith(ns, "local.oplog.")){ while (MONGO_FAIL_POINT(rsStopGetMore)) { @@ -841,7 +861,8 @@ namespace mongo { // Check auth for insert (also handles checking if this is an index build and checks // for the proper privileges in that case). Status status = cc().getAuthorizationSession()->checkAuthForInsert(ns, obj); - uassert(16544, status.reason(), status.isOK()); + audit::logInsertAuthzCheck(&cc(), NamespaceString(ns), obj, status.code()); + uassertStatusOK(status); } PageFaultRetryableSection s; |