summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth
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/db/auth
parent7087350d1d5c943520e9972ac1f8b85252c0eceb (diff)
downloadmongo-2ea069aa505c750cad6a7ba6ae6d4ac897f396d1.tar.gz
SERVER-5261 Include authentication information in currentOp output
Diffstat (limited to 'src/mongo/db/auth')
-rw-r--r--src/mongo/db/auth/SConscript31
-rw-r--r--src/mongo/db/auth/auth_types.idl38
-rw-r--r--src/mongo/db/auth/impersonation_session.cpp20
-rw-r--r--src/mongo/db/auth/impersonation_session.h2
-rw-r--r--src/mongo/db/auth/role_name.cpp38
-rw-r--r--src/mongo/db/auth/role_name.h18
-rw-r--r--src/mongo/db/auth/user_name.cpp44
-rw-r--r--src/mongo/db/auth/user_name.h11
8 files changed, 164 insertions, 38 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 35c418f448d..a8f89e223b1 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -18,16 +18,6 @@ generateActionTypes = env.Command(
env.Alias('generated-sources', generateActionTypes)
env.Library(
- target='auth_rolename',
- source=[
- 'role_name.cpp'
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/base',
- ],
-)
-
-env.Library(
target='authentication_restriction',
source=[
'restriction_environment.cpp',
@@ -58,24 +48,12 @@ env.Library(
'authorization_manager.cpp',
'authorization_session.cpp',
'auth_decorations.cpp',
- ],
- LIBDEPS=[
- 'auth_rolename',
- 'user_name',
- '$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/db/service_context',
- '$BUILD_DIR/mongo/rpc/audit_metadata',
- ],
-)
-
-
-env.Library(
- target='user_name',
- source=[
'user_name.cpp',
+ 'role_name.cpp'
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/service_context',
],
)
@@ -154,7 +132,6 @@ env.Library(
LIBDEPS=[
'address_restriction',
'auth',
- 'auth_rolename',
'authentication_restriction',
'authorization_manager_global',
'authprivilege',
@@ -196,6 +173,9 @@ env.Library(
'$BUILD_DIR/mongo/bson/mutable/mutable_bson',
'$BUILD_DIR/mongo/db/common',
],
+ LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/rpc/metadata_impersonated_user',
+ ]
)
env.Library(
@@ -299,7 +279,6 @@ env.Library(
'authprivilege',
'sasl_options',
'user',
- 'user_name',
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/base/secure_allocator',
'$BUILD_DIR/mongo/crypto/sha_block_${MONGO_CRYPTO}',
diff --git a/src/mongo/db/auth/auth_types.idl b/src/mongo/db/auth/auth_types.idl
new file mode 100644
index 00000000000..f035dc7f488
--- /dev/null
+++ b/src/mongo/db/auth/auth_types.idl
@@ -0,0 +1,38 @@
+# 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"
+ cpp_includes:
+ - "mongo/db/auth/user_name.h"
+ - "mongo/db/auth/role_name.h"
+
+imports:
+ - "mongo/idl/basic_types.idl"
+
+types:
+ UserName:
+ bson_serialization_type: any
+ description: "A struct representing a UserName"
+ cpp_type: "UserName"
+ deserializer: "mongo::UserName::parseFromBSON"
+ serializer: "mongo::UserName::serializeToBSON"
+
+ RoleName:
+ bson_serialization_type: any
+ description: "A struct representing a Role"
+ cpp_type: "RoleName"
+ deserializer: "mongo::RoleName::parseFromBSON"
+ serializer: "mongo::RoleName::serializeToBSON"
diff --git a/src/mongo/db/auth/impersonation_session.cpp b/src/mongo/db/auth/impersonation_session.cpp
index 8b9a5f09fc7..666522cd043 100644
--- a/src/mongo/db/auth/impersonation_session.cpp
+++ b/src/mongo/db/auth/impersonation_session.cpp
@@ -39,7 +39,7 @@
#include "mongo/db/auth/resource_pattern.h"
#include "mongo/db/client.h"
#include "mongo/db/operation_context.h"
-#include "mongo/rpc/metadata/audit_metadata.h"
+#include "mongo/rpc/metadata/impersonated_user_metadata.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/destructor_guard.h"
@@ -47,28 +47,24 @@ namespace mongo {
ImpersonationSessionGuard::ImpersonationSessionGuard(OperationContext* opCtx) : _opCtx(opCtx) {
auto authSession = AuthorizationSession::get(_opCtx->getClient());
-
- const auto& impersonatedUsersAndRoles =
- rpc::AuditMetadata::get(opCtx).getImpersonatedUsersAndRoles();
-
- if (impersonatedUsersAndRoles != boost::none) {
+ const auto impersonatedUsersAndRoles = rpc::getImpersonatedUserMetadata(opCtx);
+ if (impersonatedUsersAndRoles) {
uassert(ErrorCodes::Unauthorized,
"Unauthorized use of impersonation metadata.",
authSession->isAuthorizedForPrivilege(
Privilege(ResourcePattern::forClusterResource(), ActionType::impersonate)));
-
fassert(ErrorCodes::InternalError, !authSession->isImpersonating());
-
- authSession->setImpersonatedUserData(std::get<0>(*impersonatedUsersAndRoles),
- std::get<1>(*impersonatedUsersAndRoles));
+ authSession->setImpersonatedUserData(impersonatedUsersAndRoles->getUsers(),
+ impersonatedUsersAndRoles->getRoles());
_active = true;
+ return;
}
}
ImpersonationSessionGuard::~ImpersonationSessionGuard() {
- DESTRUCTOR_GUARD(if (_active) {
+ if (_active) {
AuthorizationSession::get(_opCtx->getClient())->clearImpersonatedUserData();
- })
+ }
}
} // namespace mongo
diff --git a/src/mongo/db/auth/impersonation_session.h b/src/mongo/db/auth/impersonation_session.h
index a2986cb0e86..e32363be4e9 100644
--- a/src/mongo/db/auth/impersonation_session.h
+++ b/src/mongo/db/auth/impersonation_session.h
@@ -27,6 +27,7 @@
*/
#include "mongo/base/disallow_copying.h"
+#include "mongo/rpc/metadata/impersonated_user_metadata.h"
namespace mongo {
class OperationContext;
@@ -43,6 +44,7 @@ public:
~ImpersonationSessionGuard();
private:
+ rpc::MaybeImpersonatedUserMetadata _oldImpersonationData;
OperationContext* _opCtx;
bool _active{false};
};
diff --git a/src/mongo/db/auth/role_name.cpp b/src/mongo/db/auth/role_name.cpp
index 6c22d03a7c5..a49b80e1fba 100644
--- a/src/mongo/db/auth/role_name.cpp
+++ b/src/mongo/db/auth/role_name.cpp
@@ -33,6 +33,7 @@
#include <string>
#include "mongo/base/string_data.h"
+#include "mongo/db/auth/authorization_manager.h"
#include "mongo/util/assert_util.h"
namespace mongo {
@@ -52,4 +53,41 @@ std::ostream& operator<<(std::ostream& os, const RoleName& name) {
return os << name.getFullName();
}
+RoleName RoleName::parseFromBSON(const BSONElement& elem) {
+ auto obj = elem.embeddedObjectUserCheck();
+ std::array<BSONElement, 2> fields;
+ obj.getFields(
+ {AuthorizationManager::ROLE_NAME_FIELD_NAME, AuthorizationManager::ROLE_DB_FIELD_NAME},
+ &fields);
+ const auto& nameField = fields[0];
+ uassert(ErrorCodes::BadValue,
+ str::stream() << "user name must contain a string field named: "
+ << AuthorizationManager::ROLE_NAME_FIELD_NAME,
+ nameField.type() == String);
+
+ const auto& dbField = fields[1];
+ uassert(ErrorCodes::BadValue,
+ str::stream() << "role name must contain a string field named: "
+ << AuthorizationManager::ROLE_DB_FIELD_NAME,
+ nameField.type() == String);
+
+ return RoleName(nameField.valueStringData(), dbField.valueStringData());
+}
+
+void RoleName::serializeToBSON(StringData fieldName, BSONObjBuilder* bob) const {
+ BSONObjBuilder sub(bob->subobjStart(fieldName));
+ _serializeToSubObj(&sub);
+}
+
+void RoleName::serializeToBSON(BSONArrayBuilder* bob) const {
+ BSONObjBuilder sub(bob->subobjStart());
+ _serializeToSubObj(&sub);
+}
+
+void RoleName::_serializeToSubObj(BSONObjBuilder* sub) const {
+ sub->append(AuthorizationManager::ROLE_NAME_FIELD_NAME, getRole());
+ sub->append(AuthorizationManager::ROLE_DB_FIELD_NAME, getDB());
+}
+
+
} // namespace mongo
diff --git a/src/mongo/db/auth/role_name.h b/src/mongo/db/auth/role_name.h
index 5d9981cf9dc..809aa2c4d69 100644
--- a/src/mongo/db/auth/role_name.h
+++ b/src/mongo/db/auth/role_name.h
@@ -36,6 +36,8 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/string_data.h"
+#include "mongo/bson/bsonelement.h"
+#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/platform/hash_namespace.h"
#include "mongo/util/assert_util.h"
@@ -51,6 +53,11 @@ public:
RoleName() : _splitPoint(0) {}
RoleName(StringData role, StringData dbname);
+ // Added for IDL support
+ static RoleName parseFromBSON(const BSONElement& elem);
+ void serializeToBSON(StringData fieldName, BSONObjBuilder* bob) const;
+ void serializeToBSON(BSONArrayBuilder* bob) const;
+
/**
* Gets the name of the role excluding the "@dbname" component.
*/
@@ -88,6 +95,8 @@ public:
private:
std::string _fullName; // The full name, stored as a string. "role@db".
size_t _splitPoint; // The index of the "@" separating the role and db name parts.
+
+ void _serializeToSubObj(BSONObjBuilder* sub) const;
};
static inline bool operator==(const RoleName& lhs, const RoleName& rhs) {
@@ -213,4 +222,13 @@ RoleNameIterator makeRoleNameIteratorForContainer(const Container& container) {
return makeRoleNameIterator(container.begin(), container.end());
}
+template <typename Container>
+Container roleNameIteratorToContainer(RoleNameIterator it) {
+ Container container;
+ while (it.more()) {
+ container.emplace_back(it.next());
+ }
+ return container;
+}
+
} // namespace mongo
diff --git a/src/mongo/db/auth/user_name.cpp b/src/mongo/db/auth/user_name.cpp
index 3bcdf3ad813..dd16bc993b3 100644
--- a/src/mongo/db/auth/user_name.cpp
+++ b/src/mongo/db/auth/user_name.cpp
@@ -32,6 +32,7 @@
#include <string>
#include "mongo/base/string_data.h"
+#include "mongo/db/auth/authorization_manager.h"
#include "mongo/util/assert_util.h"
namespace mongo {
@@ -62,6 +63,49 @@ StatusWith<UserName> UserName::parse(StringData userNameStr) {
return UserName(userNamePortion, userDBPortion);
}
+UserName UserName::parseFromBSON(const BSONElement& elem) {
+ if (elem.type() == String) {
+ return uassertStatusOK(UserName::parse(elem.valueStringData()));
+ } else if (elem.type() == Object) {
+ const auto obj = elem.embeddedObject();
+ std::array<BSONElement, 2> fields;
+ obj.getFields(
+ {AuthorizationManager::USER_NAME_FIELD_NAME, AuthorizationManager::USER_DB_FIELD_NAME},
+ &fields);
+
+ const auto& nameField = fields[0];
+ uassert(ErrorCodes::BadValue,
+ str::stream() << "username must contain a string field named: "
+ << AuthorizationManager::USER_NAME_FIELD_NAME,
+ nameField.type() == String);
+
+ const auto& dbField = fields[1];
+ uassert(ErrorCodes::BadValue,
+ str::stream() << "username must contain a string field named: "
+ << AuthorizationManager::USER_DB_FIELD_NAME,
+ dbField.type() == String);
+
+ return UserName(nameField.valueStringData(), dbField.valueStringData());
+ } else {
+ uasserted(ErrorCodes::BadValue, "username must be either a string or an object");
+ }
+}
+
+void UserName::serializeToBSON(StringData fieldName, BSONObjBuilder* bob) const {
+ BSONObjBuilder sub(bob->subobjStart(fieldName));
+ _serializeToSubObj(&sub);
+}
+
+void UserName::serializeToBSON(BSONArrayBuilder* bab) const {
+ BSONObjBuilder sub(bab->subobjStart());
+ _serializeToSubObj(&sub);
+}
+
+void UserName::_serializeToSubObj(BSONObjBuilder* sub) const {
+ *sub << AuthorizationManager::USER_NAME_FIELD_NAME << getUser()
+ << AuthorizationManager::USER_DB_FIELD_NAME << getDB();
+}
+
std::ostream& operator<<(std::ostream& os, const UserName& name) {
return os << name.getFullName();
}
diff --git a/src/mongo/db/auth/user_name.h b/src/mongo/db/auth/user_name.h
index a1b04f010d4..22c62db2d82 100644
--- a/src/mongo/db/auth/user_name.h
+++ b/src/mongo/db/auth/user_name.h
@@ -36,6 +36,8 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/status_with.h"
#include "mongo/base/string_data.h"
+#include "mongo/bson/bsonelement.h"
+#include "mongo/bson/bsonobjbuilder.h"
namespace mongo {
@@ -54,6 +56,13 @@ public:
*/
static StatusWith<UserName> parse(StringData userNameStr);
+ /*
+ * These methods support parsing usernames from IDL
+ */
+ static UserName parseFromBSON(const BSONElement& elem);
+ void serializeToBSON(StringData fieldName, BSONObjBuilder* bob) const;
+ void serializeToBSON(BSONArrayBuilder* bob) const;
+
/**
* Gets the user part of a UserName.
*/
@@ -95,6 +104,8 @@ public:
}
private:
+ void _serializeToSubObj(BSONObjBuilder* sub) const;
+
std::string _fullName; // The full name, stored as a string. "user@db".
size_t _splitPoint; // The index of the "@" separating the user and db name parts.
};