summaryrefslogtreecommitdiff
path: root/src/mongo/rpc
diff options
context:
space:
mode:
authorJonathan Reams <jbreams@mongodb.com>2018-08-16 16:02:16 -0400
committerJonathan Reams <jbreams@mongodb.com>2018-09-14 11:12:45 -0400
commit2ea069aa505c750cad6a7ba6ae6d4ac897f396d1 (patch)
treeb8093da62175046189de9fbb876b5ef8b79181b1 /src/mongo/rpc
parent7087350d1d5c943520e9972ac1f8b85252c0eceb (diff)
downloadmongo-2ea069aa505c750cad6a7ba6ae6d4ac897f396d1.tar.gz
SERVER-5261 Include authentication information in currentOp output
Diffstat (limited to 'src/mongo/rpc')
-rw-r--r--src/mongo/rpc/SConscript19
-rw-r--r--src/mongo/rpc/metadata.cpp10
-rw-r--r--src/mongo/rpc/metadata/audit_metadata.cpp71
-rw-r--r--src/mongo/rpc/metadata/audit_metadata.h83
-rw-r--r--src/mongo/rpc/metadata/impersonated_user_metadata.cpp93
-rw-r--r--src/mongo/rpc/metadata/impersonated_user_metadata.h73
-rw-r--r--src/mongo/rpc/metadata/impersonated_user_metadata.idl35
7 files changed, 216 insertions, 168 deletions
diff --git a/src/mongo/rpc/SConscript b/src/mongo/rpc/SConscript
index 53757b9fcb7..f7883dbc9e2 100644
--- a/src/mongo/rpc/SConscript
+++ b/src/mongo/rpc/SConscript
@@ -80,7 +80,7 @@ env.Library(
],
LIBDEPS=[
'client_metadata',
- 'audit_metadata',
+ 'metadata_impersonated_user',
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/bson/util/bson_extract',
'$BUILD_DIR/mongo/client/read_preference',
@@ -90,20 +90,21 @@ env.Library(
],
)
-env.Clone().InjectModule("enterprise").Library(
+env.Library(
target=[
- 'audit_metadata',
+ 'metadata_impersonated_user'
],
source=[
- 'metadata/audit_metadata.cpp',
- ],
- LIBDEPS_PRIVATE=[
- '$BUILD_DIR/mongo/bson/util/bson_extract',
- '$BUILD_DIR/mongo/db/auth/auth_rolename',
- '$BUILD_DIR/mongo/db/auth/user_name',
+ 'metadata/impersonated_user_metadata.cpp',
+ env.Idlc('metadata/impersonated_user_metadata.idl')[0],
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/service_context',
+ ],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/auth/auth',
+ '$BUILD_DIR/mongo/db/server_options',
],
)
diff --git a/src/mongo/rpc/metadata.cpp b/src/mongo/rpc/metadata.cpp
index 74360ead237..6359c9e1952 100644
--- a/src/mongo/rpc/metadata.cpp
+++ b/src/mongo/rpc/metadata.cpp
@@ -36,9 +36,9 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/logical_clock.h"
#include "mongo/db/logical_time_validator.h"
-#include "mongo/rpc/metadata/audit_metadata.h"
#include "mongo/rpc/metadata/client_metadata_ismaster.h"
#include "mongo/rpc/metadata/config_server_metadata.h"
+#include "mongo/rpc/metadata/impersonated_user_metadata.h"
#include "mongo/rpc/metadata/logical_time_metadata.h"
#include "mongo/rpc/metadata/sharding_metadata.h"
#include "mongo/rpc/metadata/tracking_metadata.h"
@@ -53,18 +53,16 @@ BSONObj makeEmptyMetadata() {
void readRequestMetadata(OperationContext* opCtx, const BSONObj& metadataObj, bool requiresAuth) {
BSONElement readPreferenceElem;
- BSONElement auditElem;
BSONElement configSvrElem;
BSONElement trackingElem;
BSONElement clientElem;
BSONElement logicalTimeElem;
+ BSONElement impersonationElem;
for (const auto& metadataElem : metadataObj) {
auto fieldName = metadataElem.fieldNameStringData();
if (fieldName == "$readPreference") {
readPreferenceElem = metadataElem;
- } else if (fieldName == AuditMetadata::fieldName()) {
- auditElem = metadataElem;
} else if (fieldName == ConfigServerMetadata::fieldName()) {
configSvrElem = metadataElem;
} else if (fieldName == ClientMetadata::fieldName()) {
@@ -73,6 +71,8 @@ void readRequestMetadata(OperationContext* opCtx, const BSONObj& metadataObj, bo
trackingElem = metadataElem;
} else if (fieldName == LogicalTimeMetadata::fieldName()) {
logicalTimeElem = metadataElem;
+ } else if (fieldName == kImpersonationMetadataSectionName) {
+ impersonationElem = metadataElem;
}
}
@@ -81,7 +81,7 @@ void readRequestMetadata(OperationContext* opCtx, const BSONObj& metadataObj, bo
uassertStatusOK(ReadPreferenceSetting::fromInnerBSON(readPreferenceElem));
}
- AuditMetadata::get(opCtx) = uassertStatusOK(AuditMetadata::readFromMetadata(auditElem));
+ readImpersonatedUserMetadata(impersonationElem, opCtx);
uassertStatusOK(ClientMetadataIsMasterState::readFromMetadata(opCtx, clientElem));
diff --git a/src/mongo/rpc/metadata/audit_metadata.cpp b/src/mongo/rpc/metadata/audit_metadata.cpp
deleted file mode 100644
index 1dacabd7dc4..00000000000
--- a/src/mongo/rpc/metadata/audit_metadata.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/rpc/metadata/audit_metadata.h"
-
-#include <utility>
-
-#include "mongo/base/status_with.h"
-#include "mongo/bson/util/bson_extract.h"
-#include "mongo/db/auth/role_name.h"
-#include "mongo/db/auth/user_name.h"
-
-namespace mongo {
-namespace rpc {
-
-const OperationContext::Decoration<AuditMetadata> AuditMetadata::get =
- OperationContext::declareDecoration<AuditMetadata>();
-
-AuditMetadata::AuditMetadata(boost::optional<UsersAndRoles> impersonatedUsersAndRoles)
- : _impersonatedUsersAndRoles(std::move(impersonatedUsersAndRoles)) {}
-
-#if !defined(MONGO_ENTERPRISE_VERSION)
-
-StatusWith<AuditMetadata> AuditMetadata::readFromMetadata(const BSONObj&) {
- return AuditMetadata{};
-}
-
-StatusWith<AuditMetadata> AuditMetadata::readFromMetadata(const BSONElement&) {
- return AuditMetadata{};
-}
-
-Status AuditMetadata::writeToMetadata(BSONObjBuilder*) const {
- return Status::OK();
-}
-
-#endif
-
-const boost::optional<AuditMetadata::UsersAndRoles>& AuditMetadata::getImpersonatedUsersAndRoles()
- const {
- return _impersonatedUsersAndRoles;
-}
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/metadata/audit_metadata.h b/src/mongo/rpc/metadata/audit_metadata.h
deleted file mode 100644
index 0724001d97c..00000000000
--- a/src/mongo/rpc/metadata/audit_metadata.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2015 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#pragma once
-
-#include <boost/optional.hpp>
-#include <vector>
-
-#include "mongo/base/disallow_copying.h"
-#include "mongo/db/auth/role_name.h"
-#include "mongo/db/auth/user_name.h"
-#include "mongo/db/operation_context.h"
-
-namespace mongo {
-class BSONObj;
-class BSONObjBuilder;
-class Status;
-template <typename T>
-class StatusWith;
-
-namespace rpc {
-
-/**
- * This class comprises the request metadata fields involving auditing.
- */
-class AuditMetadata {
-public:
- static const OperationContext::Decoration<AuditMetadata> get;
-
- // Decorable requires a default constructor.
- AuditMetadata() = default;
-
- static StatusWith<AuditMetadata> readFromMetadata(const BSONObj& metadataObj);
-
- /**
- * Parses AuditMetadata from a pre-extracted BSONElement. When reading a metadata object, this
- * form is more efficient as it permits parsing the metadata in one pass.
- */
- static StatusWith<AuditMetadata> readFromMetadata(const BSONElement& metadataElem);
-
- Status writeToMetadata(BSONObjBuilder* metadataBob) const;
-
- using UsersAndRoles = std::tuple<std::vector<UserName>, std::vector<RoleName>>;
-
- const boost::optional<UsersAndRoles>& getImpersonatedUsersAndRoles() const;
-
- AuditMetadata(boost::optional<UsersAndRoles> impersonatedUsersAndRoles);
-
- static StringData fieldName() {
- return "$audit";
- }
-
-private:
- boost::optional<UsersAndRoles> _impersonatedUsersAndRoles;
-};
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/metadata/impersonated_user_metadata.cpp b/src/mongo/rpc/metadata/impersonated_user_metadata.cpp
new file mode 100644
index 00000000000..b8e9e77c595
--- /dev/null
+++ b/src/mongo/rpc/metadata/impersonated_user_metadata.cpp
@@ -0,0 +1,93 @@
+/**
+ * Copyright (C) 2018 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/rpc/metadata/impersonated_user_metadata.h"
+
+#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/server_options.h"
+
+namespace mongo {
+namespace rpc {
+namespace {
+
+static const OperationContext::Decoration<MaybeImpersonatedUserMetadata> getForOpCtx =
+ OperationContext::declareDecoration<MaybeImpersonatedUserMetadata>();
+} // namespace
+
+MaybeImpersonatedUserMetadata getImpersonatedUserMetadata(OperationContext* opCtx) {
+ return opCtx ? getForOpCtx(opCtx) : boost::none;
+}
+
+void readImpersonatedUserMetadata(const BSONElement& elem, OperationContext* opCtx) {
+ // If we have no opCtx, which does appear to happen, don't do anything.
+ if (!opCtx) {
+ return;
+ }
+
+ // Always reset the current impersonation data to boost::none.
+ getForOpCtx(opCtx) = boost::none;
+ if (elem.type() == Object) {
+ IDLParserErrorContext errCtx(kImpersonationMetadataSectionName);
+ auto data = ImpersonatedUserMetadata::parse(errCtx, elem.embeddedObject());
+
+ // Set the impersonation data only if there are actually impersonated
+ // users/roles.
+ if ((!data.getUsers().empty()) || (!data.getRoles().empty())) {
+ getForOpCtx(opCtx) = std::move(data);
+ }
+ }
+}
+
+void writeAuthDataToImpersonatedUserMetadata(OperationContext* opCtx, BSONObjBuilder* out) {
+ // If we have no opCtx, which does appear to happen, don't do anything.
+ if (!opCtx) {
+ return;
+ }
+
+ // Otherwise construct a metadata section from the list of authenticated users/roles
+ auto authSession = AuthorizationSession::get(opCtx->getClient());
+ ImpersonatedUserMetadata metadata;
+ metadata.setUsers(userNameIteratorToContainer<std::vector<UserName>>(
+ authSession->getAuthenticatedUserNames()));
+
+ metadata.setRoles(roleNameIteratorToContainer<std::vector<RoleName>>(
+ authSession->getAuthenticatedRoleNames()));
+
+ // If there are no users/roles being impersonated just exit
+ if (metadata.getUsers().empty() && metadata.getRoles().empty()) {
+ return;
+ }
+
+ BSONObjBuilder section(out->subobjStart(kImpersonationMetadataSectionName));
+ metadata.serialize(&section);
+}
+
+} // namespace rpc
+} // namespace mongo
diff --git a/src/mongo/rpc/metadata/impersonated_user_metadata.h b/src/mongo/rpc/metadata/impersonated_user_metadata.h
new file mode 100644
index 00000000000..f379b509d4c
--- /dev/null
+++ b/src/mongo/rpc/metadata/impersonated_user_metadata.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2018 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
+ */
+
+#pragma once
+
+#include "boost/optional.hpp"
+
+#include "mongo/db/operation_context.h"
+#include "mongo/rpc/metadata/impersonated_user_metadata_gen.h"
+
+namespace mongo {
+namespace rpc {
+
+/*
+ * The name of the BSON element in message metadata that contains the impersonated user data
+ *
+ * This is called "$audit" because in pre-4.2 the enterprise audit subsystem already passed
+ * the impersonated users info around in metadata for auditing purposes. This has been lifted
+ * into the community edition and appears in network messages as "$audit" for backwards
+ * compatibility.
+ *
+ * This metadata should only appear in requests from mongos to mongod.
+ */
+static constexpr auto kImpersonationMetadataSectionName = "$audit"_sd;
+
+/*
+ * A type that maybe contains parsed ImpersonationUserMetadata
+ */
+using MaybeImpersonatedUserMetadata = boost::optional<ImpersonatedUserMetadata>;
+
+/*
+ * Gets the current impersonation data from the OpCtx (assumes readImpersonatedUserMetadata
+ * has already been called)
+ */
+MaybeImpersonatedUserMetadata getImpersonatedUserMetadata(OperationContext* opCtx);
+
+/*
+ * Parses any impersonation data out of a metdata bson obj and into the opCtx
+ */
+void readImpersonatedUserMetadata(const BSONElement& elem, OperationContext* opCtx);
+
+/*
+ * Writes the current impersonation metadata off the opCtx and into a BSONObjBuilder
+ */
+void writeAuthDataToImpersonatedUserMetadata(OperationContext* opCtx, BSONObjBuilder* out);
+
+} // namespace rpc
+} // namespace mongo
diff --git a/src/mongo/rpc/metadata/impersonated_user_metadata.idl b/src/mongo/rpc/metadata/impersonated_user_metadata.idl
new file mode 100644
index 00000000000..c2b15e325fc
--- /dev/null
+++ b/src/mongo/rpc/metadata/impersonated_user_metadata.idl
@@ -0,0 +1,35 @@
+# Copyright (C) 2018 MongoDB Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License, version 3,
+# as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+global:
+ cpp_namespace: "mongo::rpc"
+
+imports:
+ - "mongo/idl/basic_types.idl"
+ - "mongo/db/auth/auth_types.idl"
+
+structs:
+ # This is the IDL version of the old enterprise-only Audit metadata struct
+ ImpersonatedUserMetadata:
+ description: "A struct representing the impersonated users from a mongos"
+ strict: true
+ fields:
+ "$impersonatedUsers":
+ type: array<UserName>
+ cpp_name: "users"
+ "$impersonatedRoles":
+ type: array<RoleName>
+ cpp_name: "roles"
+