summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@10gen.com>2013-07-17 18:06:14 -0400
committerAndy Schwerin <schwerin@10gen.com>2013-07-22 14:23:01 -0400
commitaa44eb2ce901ab2d82e8faa0799550ca15ccaf7e (patch)
treee12ae3ab43869b05e8d312fe2f70c26f7e2d645e /src/mongo/db
parent819bc8fc804a9be8f36dc53d2f0008072adb137c (diff)
downloadmongo-aa44eb2ce901ab2d82e8faa0799550ca15ccaf7e.tar.gz
SERVER-1891 Add redactForLogging() to Command.
Command::redactForLogging(mutablebson::Document* cmdObj) transforms "cmdObj" into a form suitable for writing to logs. This patch provides a sample implementation for the user management commands that censors password fields, and updates the audit hook for commands, appropriately.
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/audit.cpp2
-rw-r--r--src/mongo/db/audit.h6
-rw-r--r--src/mongo/db/commands.cpp13
-rw-r--r--src/mongo/db/commands.h11
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp23
5 files changed, 50 insertions, 5 deletions
diff --git a/src/mongo/db/audit.cpp b/src/mongo/db/audit.cpp
index 6c78ded58c6..86eb3577339 100644
--- a/src/mongo/db/audit.cpp
+++ b/src/mongo/db/audit.cpp
@@ -27,7 +27,7 @@ namespace audit {
void logCommandAuthzCheck(ClientBasic* client,
const NamespaceString& ns,
- const BSONObj& cmdObj,
+ const mutablebson::Document& cmdObj,
ErrorCodes::Error result) MONGO_AUDIT_STUB
void logDeleteAuthzCheck(
diff --git a/src/mongo/db/audit.h b/src/mongo/db/audit.h
index 84ed98ca4bc..ef25fea0a6c 100644
--- a/src/mongo/db/audit.h
+++ b/src/mongo/db/audit.h
@@ -29,6 +29,10 @@ namespace mongo {
class ClientBasic;
class NamespaceString;
+namespace mutablebson {
+ class Document;
+} // namespace mutablebson
+
namespace audit {
//
@@ -44,7 +48,7 @@ namespace audit {
void logCommandAuthzCheck(
ClientBasic* client,
const NamespaceString& ns,
- const BSONObj& cmdObj,
+ const mutablebson::Document& cmdObj,
ErrorCodes::Error result);
/**
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 395b6ae81ae..14a82536e03 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+#include "mongo/bson/mutable/document.h"
#include "mongo/db/audit.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
@@ -210,6 +211,8 @@ namespace mongo {
return client->getAuthorizationSession()->checkAuthForPrivileges(privileges);
}
+ void Command::redactForLogging(mutablebson::Document* cmdObj) {}
+
void Command::appendCommandStatus(BSONObjBuilder& result, const Status& status) {
appendCommandStatus(result, status.isOK(), status.reason());
BSONObj tmp = result.asTempObj();
@@ -230,6 +233,7 @@ namespace mongo {
const std::string& dbname,
const BSONObj& cmdObj,
bool fromRepl) {
+ namespace mmb = mutablebson;
if ( c->adminOnly() && ! fromRepl && dbname != "admin" ) {
return Status(ErrorCodes::Unauthorized, str::stream() << c->name <<
" may only be run against the admin database.");
@@ -237,9 +241,11 @@ namespace mongo {
if (AuthorizationManager::isAuthEnabled()) {
Status status = c->checkAuthForCommand(client, dbname, cmdObj);
if (status == ErrorCodes::Unauthorized) {
+ mmb::Document cmdToLog(cmdObj, mmb::Document::kInPlaceDisabled);
+ c->redactForLogging(&cmdToLog);
return Status(ErrorCodes::Unauthorized,
str::stream() << "not authorized on " << dbname <<
- " to execute command " << cmdObj);
+ " to execute command " << cmdToLog.toString());
}
if (!status.isOK()) {
return status;
@@ -260,13 +266,16 @@ namespace mongo {
const std::string& dbname,
const BSONObj& cmdObj,
bool fromRepl) {
+ namespace mmb = mutablebson;
Status status = _checkAuthorizationImpl(c, client, dbname, cmdObj, fromRepl);
if (!status.isOK()) {
log() << status << std::endl;
}
+ mmb::Document cmdToLog(cmdObj, mmb::Document::kInPlaceDisabled);
+ c->redactForLogging(&cmdToLog);
audit::logCommandAuthzCheck(client,
NamespaceString(c->parseNs(dbname, cmdObj)),
- cmdObj,
+ cmdToLog,
status.code());
return status;
}
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index edaa185e867..8ebbd644f86 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -31,6 +31,10 @@ namespace mongo {
class Client;
class Timer;
+namespace mutablebson {
+ class Document;
+} // namespace mutablebson
+
/** mongodb "commands" (sent via db.$cmd.findOne(...))
subclass to make a command. define a singleton object for it.
*/
@@ -119,6 +123,13 @@ namespace mongo {
const std::string& dbname,
const BSONObj& cmdObj);
+ /**
+ * Redacts "cmdObj" in-place to a form suitable for writing to logs.
+ *
+ * The default implementation does nothing.
+ */
+ virtual void redactForLogging(mutablebson::Document* cmdObj);
+
/* Return true if a replica set secondary should go into "recovering"
(unreadable) state while running this command.
*/
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index f3cb4102755..9200429104a 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -18,6 +18,8 @@
#include <vector>
#include "mongo/base/status.h"
+#include "mongo/bson/mutable/algorithm.h"
+#include "mongo/bson/mutable/document.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/client/dbclientinterface.h"
#include "mongo/db/auth/action_set.h"
@@ -32,7 +34,7 @@
namespace mongo {
- void addStatus(const Status& status, BSONObjBuilder& builder) {
+ static void addStatus(const Status& status, BSONObjBuilder& builder) {
builder.append("ok", status.isOK() ? 1.0: 0.0);
if (!status.isOK())
builder.append("code", status.code());
@@ -40,6 +42,17 @@ namespace mongo {
builder.append("errmsg", status.reason());
}
+ static void redactPasswordData(mutablebson::Element parent) {
+ namespace mmb = mutablebson;
+ const StringData pwdFieldName("pwd", StringData::LiteralTag());
+ for (mmb::Element pwdElement = mmb::findFirstChildNamed(parent, pwdFieldName);
+ pwdElement.ok();
+ pwdElement = mmb::findElementNamed(pwdElement.rightSibling(), pwdFieldName)) {
+
+ pwdElement.setValueString("xxx");
+ }
+ }
+
class CmdCreateUser : public Command {
public:
@@ -147,6 +160,10 @@ namespace mongo {
return true;
}
+ virtual void redactForLogging(mutablebson::Document* cmdObj) {
+ redactPasswordData(cmdObj->root());
+ }
+
private:
Status _parseAndValidateInput(BSONObj cmdObj, CreateUserArgs* parsedArgs) const {
@@ -325,6 +342,10 @@ namespace mongo {
return true;
}
+ virtual void redactForLogging(mutablebson::Document* cmdObj) {
+ redactPasswordData(cmdObj->root());
+ }
+
private:
Status _parseAndValidateInput(BSONObj cmdObj, UpdateUserArgs* parsedArgs) const {