diff options
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/audit.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/audit.h | 6 | ||||
-rw-r--r-- | src/mongo/db/commands.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 11 | ||||
-rw-r--r-- | src/mongo/db/commands/user_management_commands.cpp | 23 |
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 { |