summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorSpencer Jackson <spencer.jackson@mongodb.com>2017-07-31 11:21:40 -0400
committerSpencer Jackson <spencer.jackson@mongodb.com>2017-07-31 13:59:59 -0400
commit0a801f1e152136be8cd0d7c57fda71555042cca1 (patch)
tree801ca92c11597ec06e30bbad285ba4d6cd0889f8 /src/mongo
parent9096def9687739a40df79efe4e9e4d9b19215201 (diff)
downloadmongo-0a801f1e152136be8cd0d7c57fda71555042cca1.tar.gz
SERVER-29182: Add restriction support to the usersInfo command
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_local.cpp12
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_s.cpp2
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.cpp15
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.h9
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp61
5 files changed, 70 insertions, 29 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 c391dff44b0..ad8b34fbce5 100644
--- a/src/mongo/db/auth/authz_manager_external_state_local.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_local.cpp
@@ -254,12 +254,18 @@ void AuthzManagerExternalStateLocal::resolveUserRoles(mutablebson::Document* use
fassert(17158, userDoc->root().pushBack(privilegesElement));
addPrivilegeObjectsOrWarningsToArrayElement(privilegesElement, warningsElement, allPrivileges);
- auto authenticationRestrictionsElement =
+ auto inheritedAuthenticationRestrictionsElement =
userDoc->makeElementArray("inheritedAuthenticationRestrictions");
- fassert(40558, userDoc->root().pushBack(authenticationRestrictionsElement));
- addAuthenticationRestrictionObjectsToArrayElement(authenticationRestrictionsElement,
+ fassert(40558, userDoc->root().pushBack(inheritedAuthenticationRestrictionsElement));
+ addAuthenticationRestrictionObjectsToArrayElement(inheritedAuthenticationRestrictionsElement,
allAuthenticationRestrictions);
+ if (!mutablebson::findFirstChildNamed(userDoc->root(), "authenticationRestrictions").ok()) {
+ auto authenticationRestrictionsElement =
+ userDoc->makeElementArray("authenticationRestrictions");
+ fassert(40572, userDoc->root().pushBack(authenticationRestrictionsElement));
+ }
+
if (!isRoleGraphConsistent) {
fassert(17160,
warningsElement.appendString(
diff --git a/src/mongo/db/auth/authz_manager_external_state_s.cpp b/src/mongo/db/auth/authz_manager_external_state_s.cpp
index 852e66fda7a..2fb91f5b8ea 100644
--- a/src/mongo/db/auth/authz_manager_external_state_s.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_s.cpp
@@ -130,6 +130,8 @@ Status AuthzManagerExternalStateMongos::getUserDescription(OperationContext* opC
<< "showPrivileges"
<< true
<< "showCredentials"
+ << true
+ << "showAuthenticationRestrictions"
<< true);
BSONObjBuilder builder;
const bool ok = Grid::get(opCtx)->catalogClient()->runUserManagementReadCommand(
diff --git a/src/mongo/db/auth/user_management_commands_parser.cpp b/src/mongo/db/auth/user_management_commands_parser.cpp
index f1ab1f40735..ec10ce928f7 100644
--- a/src/mongo/db/auth/user_management_commands_parser.cpp
+++ b/src/mongo/db/auth/user_management_commands_parser.cpp
@@ -323,6 +323,7 @@ Status parseAndValidateDropAllUsersFromDatabaseCommand(const BSONObj& cmdObj,
Status parseUsersInfoCommand(const BSONObj& cmdObj, StringData dbname, UsersInfoArgs* parsedArgs) {
unordered_set<std::string> validFieldNames;
validFieldNames.insert("usersInfo");
+ validFieldNames.insert("showAuthenticationRestrictions");
validFieldNames.insert("showPrivileges");
validFieldNames.insert("showCredentials");
@@ -364,6 +365,20 @@ Status parseUsersInfoCommand(const BSONObj& cmdObj, StringData dbname, UsersInfo
return status;
}
+ const auto showAuthenticationRestrictions = cmdObj["showAuthenticationRestrictions"];
+ if (showAuthenticationRestrictions.eoo()) {
+ parsedArgs->authenticationRestrictionsFormat = AuthenticationRestrictionsFormat::kOmit;
+ } else {
+ bool show;
+ status = bsonExtractBooleanField(cmdObj, "showAuthenticationRestrictions", &show);
+ if (!status.isOK()) {
+ return status;
+ }
+ parsedArgs->authenticationRestrictionsFormat = show
+ ? AuthenticationRestrictionsFormat::kShow
+ : AuthenticationRestrictionsFormat::kOmit;
+ }
+
return Status::OK();
}
diff --git a/src/mongo/db/auth/user_management_commands_parser.h b/src/mongo/db/auth/user_management_commands_parser.h
index 2ccd6524ae9..23a19206739 100644
--- a/src/mongo/db/auth/user_management_commands_parser.h
+++ b/src/mongo/db/auth/user_management_commands_parser.h
@@ -101,10 +101,11 @@ Status parseAndValidateDropAllUsersFromDatabaseCommand(const BSONObj& cmdObj,
struct UsersInfoArgs {
std::vector<UserName> userNames;
- bool allForDB;
- bool showPrivileges;
- bool showCredentials;
- UsersInfoArgs() : allForDB(false), showPrivileges(false), showCredentials(false) {}
+ bool allForDB = false;
+ bool showPrivileges = false;
+ AuthenticationRestrictionsFormat authenticationRestrictionsFormat =
+ AuthenticationRestrictionsFormat::kOmit;
+ bool showCredentials = false;
};
/**
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index 533eabefc2e..4e77d630159 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -1201,17 +1201,21 @@ public:
return appendCommandStatus(result, status);
}
- if (args.allForDB && args.showPrivileges) {
+ if (args.allForDB &&
+ (args.showPrivileges ||
+ args.authenticationRestrictionsFormat == AuthenticationRestrictionsFormat::kShow)) {
return appendCommandStatus(
result,
Status(ErrorCodes::IllegalOperation,
- "Can only get privilege details on exact-match usersInfo "
+ "Can only get privilege or restriction details on exact-match usersInfo "
"queries."));
}
BSONArrayBuilder usersArrayBuilder;
- if (args.showPrivileges) {
- // If you want privileges you need to call getUserDescription on each user.
+ if (args.showPrivileges ||
+ args.authenticationRestrictionsFormat == AuthenticationRestrictionsFormat::kShow) {
+ // If you want privileges or restrictions you need to call getUserDescription on each
+ // user.
for (size_t i = 0; i < args.userNames.size(); ++i) {
BSONObj userDetails;
status = getGlobalAuthorizationManager()->getUserDescription(
@@ -1223,22 +1227,31 @@ public:
return appendCommandStatus(result, status);
}
- if (!args.showCredentials) {
- // getUserDescription always includes credentials, need to strip it out
- BSONObjBuilder userWithoutCredentials(usersArrayBuilder.subobjStart());
- for (BSONObjIterator it(userDetails); it.more();) {
- BSONElement e = it.next();
- if (e.fieldNameStringData() != "credentials" &&
- e.fieldNameStringData() != AuthorizationManager::USER_ID_FIELD_NAME)
- userWithoutCredentials.append(e);
+ // getUserDescription always includes credentials and restrictions, which may need
+ // to be stripped out
+ BSONObjBuilder strippedUser(usersArrayBuilder.subobjStart());
+ for (const BSONElement& e : userDetails) {
+ if (!args.showCredentials && e.fieldNameStringData() == "credentials") {
+ continue;
}
- userWithoutCredentials.doneFast();
- } else {
- usersArrayBuilder.append(userDetails);
+
+ if (e.fieldNameStringData() == AuthorizationManager::USER_ID_FIELD_NAME) {
+ continue;
+ }
+
+ if (e.fieldNameStringData() == "authenticationRestrictions" &&
+ args.authenticationRestrictionsFormat ==
+ AuthenticationRestrictionsFormat::kOmit) {
+ continue;
+ }
+
+ strippedUser.append(e);
}
+ strippedUser.doneFast();
}
} else {
- // If you don't need privileges, you can just do a regular query on system.users
+ // If you don't need privileges, or authenticationRestrictions, you can just do a
+ // regular query on system.users
BSONObjBuilder queryBuilder;
if (args.allForDB) {
queryBuilder.append("query",
@@ -1257,18 +1270,22 @@ public:
queryBuilder.append("orderby", BSON("user" << 1 << "db" << 1));
BSONObjBuilder projection;
+ projection.append("authenticationRestrictions", 0);
if (!args.showCredentials) {
projection.append(AuthorizationManager::USER_ID_FIELD_NAME, 0);
projection.append("credentials", 0);
}
const stdx::function<void(const BSONObj&)> function = stdx::bind(
appendBSONObjToBSONArrayBuilder, &usersArrayBuilder, stdx::placeholders::_1);
- queryAuthzDocument(opCtx,
- AuthorizationManager::usersCollectionNamespace,
- queryBuilder.done(),
- projection.done(),
- function)
- .transitional_ignore();
+
+ Status status = queryAuthzDocument(opCtx,
+ AuthorizationManager::usersCollectionNamespace,
+ queryBuilder.done(),
+ projection.done(),
+ function);
+ if (!status.isOK()) {
+ return appendCommandStatus(result, status);
+ }
}
result.append("users", usersArrayBuilder.arr());
return true;