summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@10gen.com>2013-07-17 14:43:10 -0400
committerAndy Schwerin <schwerin@10gen.com>2013-07-17 17:47:36 -0400
commit0eb227c15841da86dbf9d21e7e593c7659040963 (patch)
treeb65159d2b8f30bf978b6003289a492734cfb69b9 /src/mongo/db
parent752f704bc0fb5c771b74a033364eaa045eda2040 (diff)
downloadmongo-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.cpp63
-rw-r--r--src/mongo/db/audit.h104
-rw-r--r--src/mongo/db/clientcursor.cpp15
-rw-r--r--src/mongo/db/instance.cpp57
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;