diff options
author | Spencer Jackson <spencer.jackson@mongodb.com> | 2016-08-08 11:51:13 -0400 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2016-08-11 18:58:27 -0400 |
commit | 045a53f469fbede582cdbbd8ba532244d86d488e (patch) | |
tree | 0bd383c589f0c3344b50be5e86e819404a32dfd4 /src/mongo/db/auth/authz_manager_external_state_local.cpp | |
parent | 844007a979a51a1c7dd49c874f0c50cb66482360 (diff) | |
download | mongo-045a53f469fbede582cdbbd8ba532244d86d488e.tar.gz |
SERVER-22826 Support X509 Authorization
Diffstat (limited to 'src/mongo/db/auth/authz_manager_external_state_local.cpp')
-rw-r--r-- | src/mongo/db/auth/authz_manager_external_state_local.cpp | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/src/mongo/db/auth/authz_manager_external_state_local.cpp b/src/mongo/db/auth/authz_manager_external_state_local.cpp index 82bd5c29440..df38132a76c 100644 --- a/src/mongo/db/auth/authz_manager_external_state_local.cpp +++ b/src/mongo/db/auth/authz_manager_external_state_local.cpp @@ -152,9 +152,25 @@ bool AuthzManagerExternalStateLocal::hasAnyPrivilegeDocuments(OperationContext* Status AuthzManagerExternalStateLocal::getUserDescription(OperationContext* txn, const UserName& userName, BSONObj* result) { - Status status = _getUserDocument(txn, userName, result); - if (!status.isOK()) - return status; + Status status = Status::OK(); + + if (!shouldUseRolesFromConnection(txn, userName)) { + status = _getUserDocument(txn, userName, result); + if (!status.isOK()) + return status; + } else { + // We are able to artifically construct the external user from the request + BSONArrayBuilder userRoles; + for (const RoleName& role : txn->getClient()->session()->getX509PeerInfo().roles) { + userRoles << BSON("role" << role.getRole() << "db" << role.getDB()); + } + *result = BSON("_id" << userName.getUser() << "user" << userName.getUser() << "db" + << userName.getDB() + << "credentials" + << BSON("external" << true) + << "roles" + << userRoles.arr()); + } BSONElement directRolesElement; status = bsonExtractTypedField(*result, "roles", Array, &directRolesElement); @@ -241,14 +257,55 @@ Status AuthzManagerExternalStateLocal::_getUserDocument(OperationContext* txn, Status AuthzManagerExternalStateLocal::getRoleDescription(OperationContext* txn, const RoleName& roleName, - bool showPrivileges, + PrivilegeFormat showPrivileges, BSONObj* result) { + if (showPrivileges == PrivilegeFormat::kShowAsUserFragment) { + mutablebson::Document resultDoc; + mutablebson::Element rolesElement = resultDoc.makeElementArray("roles"); + fassert(40273, resultDoc.root().pushBack(rolesElement)); + addRoleNameObjectsToArrayElement( + rolesElement, makeRoleNameIteratorForContainer(std::vector<RoleName>{roleName})); + resolveUserRoles(&resultDoc, {roleName}); + *result = resultDoc.getObject(); + return Status::OK(); + } stdx::lock_guard<stdx::mutex> lk(_roleGraphMutex); return _getRoleDescription_inlock(roleName, showPrivileges, result); } +Status AuthzManagerExternalStateLocal::getRolesDescription(OperationContext* txn, + const std::vector<RoleName>& roles, + PrivilegeFormat showPrivileges, + BSONObj* result) { + if (showPrivileges == PrivilegeFormat::kShowAsUserFragment) { + mutablebson::Document resultDoc; + mutablebson::Element rolesElement = resultDoc.makeElementArray("roles"); + fassert(40274, resultDoc.root().pushBack(rolesElement)); + addRoleNameObjectsToArrayElement(rolesElement, makeRoleNameIteratorForContainer(roles)); + resolveUserRoles(&resultDoc, roles); + *result = resultDoc.getObject(); + return Status::OK(); + } + + stdx::lock_guard<stdx::mutex> lk(_roleGraphMutex); + BSONArrayBuilder resultBuilder; + for (const RoleName& role : roles) { + BSONObj roleDoc; + Status status = _getRoleDescription_inlock(role, showPrivileges, &roleDoc); + if (!status.isOK()) { + if (status.code() == ErrorCodes::RoleNotFound) { + continue; + } + return status; + } + resultBuilder << roleDoc; + } + *result = resultBuilder.arr(); + return Status::OK(); +} + Status AuthzManagerExternalStateLocal::_getRoleDescription_inlock(const RoleName& roleName, - bool showPrivileges, + PrivilegeFormat showPrivileges, BSONObj* result) { if (!_roleGraph.roleExists(roleName)) return Status(ErrorCodes::RoleNotFound, "No role named " + roleName.toString()); @@ -268,7 +325,7 @@ Status AuthzManagerExternalStateLocal::_getRoleDescription_inlock(const RoleName mutablebson::Element privilegesElement = resultDoc.makeElementArray("privileges"); mutablebson::Element inheritedPrivilegesElement = resultDoc.makeElementArray("inheritedPrivileges"); - if (showPrivileges) { + if (showPrivileges == PrivilegeFormat::kShowSeparate) { fassert(17166, resultDoc.root().pushBack(privilegesElement)); } mutablebson::Element warningsElement = resultDoc.makeElementArray("warnings"); @@ -277,7 +334,7 @@ Status AuthzManagerExternalStateLocal::_getRoleDescription_inlock(const RoleName if (_roleGraphState == roleGraphStateConsistent) { addRoleNameObjectsToArrayElement(inheritedRolesElement, _roleGraph.getIndirectSubordinates(roleName)); - if (showPrivileges) { + if (showPrivileges == PrivilegeFormat::kShowSeparate) { addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, _roleGraph.getDirectPrivileges(roleName)); @@ -286,7 +343,7 @@ Status AuthzManagerExternalStateLocal::_getRoleDescription_inlock(const RoleName fassert(17323, resultDoc.root().pushBack(inheritedPrivilegesElement)); } - } else if (showPrivileges) { + } else if (showPrivileges == PrivilegeFormat::kShowSeparate) { warningsElement.appendString( "", "Role graph state inconsistent; only direct privileges available."); addPrivilegeObjectsOrWarningsToArrayElement( @@ -301,11 +358,15 @@ Status AuthzManagerExternalStateLocal::_getRoleDescription_inlock(const RoleName Status AuthzManagerExternalStateLocal::getRoleDescriptionsForDB(OperationContext* txn, const std::string dbname, - bool showPrivileges, + PrivilegeFormat showPrivileges, bool showBuiltinRoles, vector<BSONObj>* result) { - stdx::lock_guard<stdx::mutex> lk(_roleGraphMutex); + if (showPrivileges == PrivilegeFormat::kShowAsUserFragment) { + return Status(ErrorCodes::IllegalOperation, + "Cannot get user fragment for all roles in a database"); + } + stdx::lock_guard<stdx::mutex> lk(_roleGraphMutex); for (RoleNameIterator it = _roleGraph.getRolesForDatabase(dbname); it.more(); it.next()) { if (!showBuiltinRoles && _roleGraph.isBuiltinRole(it.get())) { continue; |