summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth/authz_manager_external_state_local.cpp
diff options
context:
space:
mode:
authorSpencer Jackson <spencer.jackson@mongodb.com>2016-08-08 11:51:13 -0400
committerSpencer Jackson <spencer.jackson@mongodb.com>2016-08-11 18:58:27 -0400
commit045a53f469fbede582cdbbd8ba532244d86d488e (patch)
tree0bd383c589f0c3344b50be5e86e819404a32dfd4 /src/mongo/db/auth/authz_manager_external_state_local.cpp
parent844007a979a51a1c7dd49c874f0c50cb66482360 (diff)
downloadmongo-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.cpp81
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;