summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2017-07-21 14:48:00 -0400
committerSara Golemon <sara.golemon@mongodb.com>2017-07-24 21:46:43 -0400
commit090d9cf938b5825cf4ae7eb0a2642be10e53b81a (patch)
tree795349f61807953f85e1f2fd1c52860fa7e6a794 /src/mongo/db
parentd8094ad9be285cb5bf588faff20af785bb76ce4b (diff)
downloadmongo-090d9cf938b5825cf4ae7eb0a2642be10e53b81a.tar.gz
SERVER-29180 Add restriction support to the createRole
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/auth/address_restriction.cpp39
-rw-r--r--src/mongo/db/auth/address_restriction.h7
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.cpp18
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.h1
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp5
5 files changed, 70 insertions, 0 deletions
diff --git a/src/mongo/db/auth/address_restriction.cpp b/src/mongo/db/auth/address_restriction.cpp
index e8b5c64a881..607aa3056e9 100644
--- a/src/mongo/db/auth/address_restriction.cpp
+++ b/src/mongo/db/auth/address_restriction.cpp
@@ -98,3 +98,42 @@ mongo::StatusWith<mongo::SharedRestrictionDocument> mongo::parseAuthenticationRe
return std::make_shared<document_type>(std::move(doc));
}
+
+mongo::StatusWith<mongo::BSONArray> mongo::getRawAuthenticationRestrictions(
+ const BSONArray& arr) noexcept try {
+ BSONArrayBuilder builder;
+
+ if (serverGlobalParams.featureCompatibility.version.load() <
+ ServerGlobalParams::FeatureCompatibility::Version::k36) {
+ return Status(ErrorCodes::UnsupportedFormat,
+ "'authenticationRestrictions' requires 3.6 feature compatibility version");
+ }
+
+ for (auto const& elem : arr) {
+ if (elem.type() != Object) {
+ return Status(ErrorCodes::UnsupportedFormat,
+ "'authenticationRestrictions' array sub-documents must be address "
+ "restriction objects");
+ }
+ IDLParserErrorContext ctx("address restriction");
+ auto const ar = Address_restriction::parse(ctx, elem.Obj());
+ if (auto const&& client = ar.getClientSource()) {
+ // Validate
+ ClientSourceRestriction(client.get());
+ }
+ if (auto const&& server = ar.getServerAddress()) {
+ // Validate
+ ServerAddressRestriction(server.get());
+ }
+ if (!ar.getClientSource() && !ar.getServerAddress()) {
+ return Status(ErrorCodes::CollectionIsEmpty,
+ "At least one of 'clientSource' and/or 'serverAddress' must be set");
+ }
+ builder.append(ar.toBSON());
+ }
+ return builder.arr();
+} catch (const DBException& e) {
+ return Status(ErrorCodes::BadValue, e.what());
+} catch (const std::exception& e) {
+ return Status(ErrorCodes::InternalError, e.what());
+}
diff --git a/src/mongo/db/auth/address_restriction.h b/src/mongo/db/auth/address_restriction.h
index 73881651024..05930e7340d 100644
--- a/src/mongo/db/auth/address_restriction.h
+++ b/src/mongo/db/auth/address_restriction.h
@@ -190,6 +190,13 @@ StatusWith<RestrictionSet<>> parseAddressRestrictionSet(const BSONObj& obj);
*/
StatusWith<SharedRestrictionDocument> parseAuthenticationRestriction(const BSONArray& arr);
+/**
+ * Parse and validate a BSONArray containing AuthenticationRestrictions
+ * and return a new BSONArray representing a sanitized portion thereof.
+ */
+StatusWith<BSONArray> getRawAuthenticationRestrictions(const BSONArray& arr) noexcept;
+
+
template <>
inline BSONObjBuilder& BSONObjBuilderValueStream::operator<<<ClientSourceRestriction>(
ClientSourceRestriction value) {
diff --git a/src/mongo/db/auth/user_management_commands_parser.cpp b/src/mongo/db/auth/user_management_commands_parser.cpp
index e712ad27cba..9a7742d14a4 100644
--- a/src/mongo/db/auth/user_management_commands_parser.cpp
+++ b/src/mongo/db/auth/user_management_commands_parser.cpp
@@ -37,6 +37,7 @@
#include "mongo/base/status.h"
#include "mongo/bson/util/bson_extract.h"
#include "mongo/db/auth/action_type.h"
+#include "mongo/db/auth/address_restriction.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/privilege_parser.h"
@@ -489,6 +490,7 @@ Status parseCreateOrUpdateRoleCommands(const BSONObj& cmdObj,
validFieldNames.insert(cmdName.toString());
validFieldNames.insert("privileges");
validFieldNames.insert("roles");
+ validFieldNames.insert("authenticationRestrictions");
Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
if (!status.isOK()) {
@@ -536,6 +538,22 @@ Status parseCreateOrUpdateRoleCommands(const BSONObj& cmdObj,
}
parsedArgs->hasRoles = true;
}
+
+ // Parse restrictions
+ if (cmdObj.hasField("authenticationRestrictions")) {
+ BSONElement restrictionsElement;
+ status = bsonExtractTypedField(
+ cmdObj, "authenticationRestrictions", Array, &restrictionsElement);
+ if (!status.isOK()) {
+ return status;
+ }
+ auto restrictions = getRawAuthenticationRestrictions(BSONArray(restrictionsElement.Obj()));
+ if (!restrictions.isOK()) {
+ return restrictions.getStatus();
+ }
+ parsedArgs->authenticationRestrictions = restrictions.getValue();
+ }
+
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 5c942a97a09..2ccd6524ae9 100644
--- a/src/mongo/db/auth/user_management_commands_parser.h
+++ b/src/mongo/db/auth/user_management_commands_parser.h
@@ -134,6 +134,7 @@ struct CreateOrUpdateRoleArgs {
std::vector<RoleName> roles;
bool hasPrivileges = false;
PrivilegeVector privileges;
+ boost::optional<BSONArray> authenticationRestrictions;
};
/**
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index 293c6d83fd4..016d44ed577 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -1357,6 +1357,11 @@ public:
roleObjBuilder.append("roles", rolesVectorToBSONArray(args.roles));
+ if (args.authenticationRestrictions && !args.authenticationRestrictions->isEmpty()) {
+ roleObjBuilder.append("authenticationRestrictions",
+ args.authenticationRestrictions.get());
+ }
+
ServiceContext* serviceContext = opCtx->getClient()->getServiceContext();
stdx::lock_guard<stdx::mutex> lk(getAuthzDataMutex(serviceContext));