summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorADAM David Alan Martin <adam.martin@10gen.com>2017-07-11 12:41:24 -0400
committerSpencer Jackson <spencer.jackson@mongodb.com>2017-07-12 11:15:35 -0400
commitcddf5ed098ea4eb8df1d946d750edd4280e022e3 (patch)
treeb18e5a4ebdf3e130b35479d724b5590ef75944b2 /src/mongo/db
parent1d1b6ba0a7387b36d8ad0e47b77121e6c6c156f1 (diff)
downloadmongo-cddf5ed098ea4eb8df1d946d750edd4280e022e3.tar.gz
SERVER-29176: Implement --clusterIpSourceWhitelist
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/SConscript2
-rw-r--r--src/mongo/db/auth/SConscript75
-rw-r--r--src/mongo/db/auth/address_restriction.h28
-rw-r--r--src/mongo/db/auth/address_restriction_test.cpp4
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp28
-rw-r--r--src/mongo/db/auth/restriction_set.h16
-rw-r--r--src/mongo/db/mongod_options.cpp23
-rw-r--r--src/mongo/db/mongod_options.h6
-rw-r--r--src/mongo/db/storage/mmap_v1/SConscript8
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp6
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_options.cpp31
11 files changed, 154 insertions, 73 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 70b7fa064a1..d3728542f69 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -411,11 +411,11 @@ env.Library(
"mongod_options.cpp",
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/storage/mmap_v1/mmap_v1_options',
'$BUILD_DIR/mongo/util/options_parser/options_parser_init',
'diag_log',
'repl/repl_settings',
'server_options',
- "storage/mmap_v1/storage_mmapv1",
'storage/storage_options',
],
)
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 8eab9b9c948..596c75d7f8b 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -52,39 +52,48 @@ env.CppUnitTest(
# Just the data structures used
-env.Library('authcore', ['action_set.cpp',
- 'action_type.cpp',
- 'authorization_manager.cpp',
- 'authorization_session.cpp',
- 'auth_decorations.cpp',
- 'authz_manager_external_state.cpp',
- 'authz_manager_external_state_local.cpp',
- 'authz_session_external_state.cpp',
- 'privilege.cpp',
- 'privilege_parser.cpp',
- 'resource_pattern.cpp',
- 'role_graph.cpp',
- 'role_graph_update.cpp',
- 'role_graph_builtin_roles.cpp',
- 'user.cpp',
- 'user_document_parser.cpp',
- 'user_management_commands_parser.cpp',
- 'user_set.cpp'],
- LIBDEPS=['auth_rolename',
- 'authentication_restriction',
- 'sasl_options',
- 'user_name',
- '$BUILD_DIR/mongo/base',
- '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
- '$BUILD_DIR/mongo/bson/util/bson_extract',
- '$BUILD_DIR/mongo/crypto/scramauth',
- '$BUILD_DIR/mongo/db/catalog/document_validation',
- '$BUILD_DIR/mongo/db/common',
- '$BUILD_DIR/mongo/db/namespace_string',
- '$BUILD_DIR/mongo/db/service_context',
- '$BUILD_DIR/mongo/db/update/update_driver',
- '$BUILD_DIR/mongo/util/md5',
- '$BUILD_DIR/mongo/util/net/network'])
+env.Library(
+ target='authcore',
+ source=[
+ 'action_set.cpp',
+ 'action_type.cpp',
+ 'authorization_manager.cpp',
+ 'authorization_session.cpp',
+ 'auth_decorations.cpp',
+ 'authz_manager_external_state.cpp',
+ 'authz_manager_external_state_local.cpp',
+ 'authz_session_external_state.cpp',
+ 'privilege.cpp',
+ 'privilege_parser.cpp',
+ 'resource_pattern.cpp',
+ 'role_graph.cpp',
+ 'role_graph_update.cpp',
+ 'role_graph_builtin_roles.cpp',
+ 'user.cpp',
+ 'user_document_parser.cpp',
+ 'user_management_commands_parser.cpp',
+ 'user_set.cpp',
+ ],
+ LIBDEPS=[
+ 'address_restriction',
+ 'auth_rolename',
+ 'authentication_restriction',
+ 'sasl_options',
+ 'user_name',
+ '$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/bson/mutable/mutable_bson',
+ '$BUILD_DIR/mongo/bson/util/bson_extract',
+ '$BUILD_DIR/mongo/crypto/scramauth',
+ '$BUILD_DIR/mongo/db/catalog/document_validation',
+ '$BUILD_DIR/mongo/db/common',
+ '$BUILD_DIR/mongo/db/mongod_options',
+ '$BUILD_DIR/mongo/db/namespace_string',
+ '$BUILD_DIR/mongo/db/service_context',
+ '$BUILD_DIR/mongo/db/update/update_driver',
+ '$BUILD_DIR/mongo/util/md5',
+ '$BUILD_DIR/mongo/util/net/network',
+ ],
+)
env.Library('authcommon',
['internal_user_auth.cpp'],
diff --git a/src/mongo/db/auth/address_restriction.h b/src/mongo/db/auth/address_restriction.h
index 0f993ef117a..27fd2c8259e 100644
--- a/src/mongo/db/auth/address_restriction.h
+++ b/src/mongo/db/auth/address_restriction.h
@@ -75,39 +75,13 @@ public:
/**
* Construct an AddressRestriction based on several human readable subnet specs
*/
- explicit AddressRestriction(const std::vector<StringData>& ranges) {
+ explicit AddressRestriction(const std::vector<std::string>& ranges) {
for (auto const& range : ranges) {
_ranges.emplace_back(range);
}
}
/**
- * If the given BSONElement represents a valid CIDR range,
- * constructs and returns the AddressRestriction.
- * Otherwise returns an error.
- */
- static StatusWith<AddressRestriction<T>> parse(BSONElement from) noexcept {
- auto cidr = CIDR::parse(from);
- if (cidr.isOK()) {
- return AddressRestriction<T>(std::move(cidr.getValue()));
- }
- return cidr.getStatus();
- }
-
- /**
- * If the given string represents a valid CIDR range,
- * constructs and returns the AddressRestriction.
- * Otherwise returns an error.
- */
- static StatusWith<AddressRestriction<T>> parse(StringData from) noexcept {
- auto cidr = CIDR::parse(from);
- if (cidr.isOK()) {
- return AddressRestriction<T>(std::move(cidr.getValue()));
- }
- return cidr.getStatus();
- }
-
- /**
* Returns true if the Environment's client/server's address
* satisfies this restriction set.
*/
diff --git a/src/mongo/db/auth/address_restriction_test.cpp b/src/mongo/db/auth/address_restriction_test.cpp
index 88b803cc284..abfcc34b01b 100644
--- a/src/mongo/db/auth/address_restriction_test.cpp
+++ b/src/mongo/db/auth/address_restriction_test.cpp
@@ -71,7 +71,7 @@ TEST(AddressRestrictionTest, toAndFromStringSingle) {
TEST(AddressRestrictionTest, toAndFromStringVector) {
const struct {
- std::vector<StringData> input;
+ std::vector<std::string> input;
std::string output;
} tests[] = {
{{"127.0.0.1", "169.254.0.0/16", "::1"},
@@ -101,7 +101,7 @@ TEST(AddressRestrictionTest, toAndFromStringVector) {
TEST(AddressRestrictionTest, contains) {
enableIPv6(true);
const struct {
- std::vector<StringData> range;
+ std::vector<std::string> range;
std::string address;
bool valid;
} contains[] = {
diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp
index 1bcebbc502f..4bf0ae2ba4a 100644
--- a/src/mongo/db/auth/authorization_manager.cpp
+++ b/src/mongo/db/auth/authorization_manager.cpp
@@ -43,6 +43,7 @@
#include "mongo/bson/util/bson_extract.h"
#include "mongo/crypto/mechanism_scram.h"
#include "mongo/db/auth/action_set.h"
+#include "mongo/db/auth/address_restriction.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/authz_manager_external_state.h"
#include "mongo/db/auth/privilege.h"
@@ -53,6 +54,7 @@
#include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user_name_hash.h"
#include "mongo/db/jsobj.h"
+#include "mongo/db/mongod_options.h"
#include "mongo/platform/compiler.h"
#include "mongo/platform/unordered_map.h"
#include "mongo/stdx/memory.h"
@@ -63,14 +65,17 @@
namespace mongo {
+using std::begin;
+using std::end;
using std::endl;
+using std::back_inserter;
using std::string;
using std::vector;
AuthInfo internalSecurity;
-MONGO_INITIALIZER_WITH_PREREQUISITES(SetupInternalSecurityUser, MONGO_NO_PREREQUISITES)
-(InitializerContext* context) {
+MONGO_INITIALIZER_WITH_PREREQUISITES(SetupInternalSecurityUser, ("EndStartupOptionStorage"))
+(InitializerContext* const context) try {
User* user = new User(UserName("__system", "local"));
user->incrementRefCount(); // Pin this user so the ref count never drops below 1.
@@ -79,9 +84,26 @@ MONGO_INITIALIZER_WITH_PREREQUISITES(SetupInternalSecurityUser, MONGO_NO_PREREQU
PrivilegeVector privileges;
RoleGraph::generateUniversalPrivileges(&privileges);
user->addPrivileges(privileges);
+
+ if (mongodGlobalParams.whitelistedClusterNetwork) {
+ const auto& whitelist = *mongodGlobalParams.whitelistedClusterNetwork;
+
+ auto restriction = stdx::make_unique<ClientSourceRestriction>(whitelist);
+ auto restrictionSet = stdx::make_unique<RestrictionSet<>>(std::move(restriction));
+ auto restrictionDocument =
+ stdx::make_unique<RestrictionDocument<>>(std::move(restrictionSet));
+
+ RestrictionDocuments clusterWhiteList(std::move(restrictionDocument));
+
+ user->setRestrictions(std::move(clusterWhiteList));
+ }
+
+
internalSecurity.user = user;
return Status::OK();
+} catch (...) {
+ return exceptionToStatus();
}
const std::string AuthorizationManager::USER_NAME_FIELD_NAME = "user";
@@ -581,7 +603,7 @@ Status AuthorizationManager::_fetchUserV2(OperationContext* opCtx,
// Put the new user into an unique_ptr temporarily in case there's an error while
// initializing the user.
- std::unique_ptr<User> user(new User(userName));
+ auto user = stdx::make_unique<User>(userName);
status = _initializeUserFromPrivilegeDocument(user.get(), userObj);
if (!status.isOK()) {
diff --git a/src/mongo/db/auth/restriction_set.h b/src/mongo/db/auth/restriction_set.h
index a6e48e3d0a9..8731b105d03 100644
--- a/src/mongo/db/auth/restriction_set.h
+++ b/src/mongo/db/auth/restriction_set.h
@@ -54,6 +54,11 @@ public:
noexcept(Sequence<Pointer<T>>(std::move(std::declval<Sequence<Pointer<T>>>()))))
: _restrictions(std::move(restrictions)) {}
+ template <typename U>
+ explicit RestrictionSetAny(std::unique_ptr<U> restriction) {
+ _restrictions.push_back(std::move(restriction));
+ }
+
Status validate(const RestrictionEnvironment& environment) const final {
if (_restrictions.empty()) {
return Status::OK();
@@ -97,6 +102,17 @@ public:
explicit RestrictionSetAll(Sequence<Pointer<T>> restrictions)
: _restrictions(std::move(restrictions)) {}
+ template <typename U>
+ explicit RestrictionSetAll(std::unique_ptr<U> restriction) {
+ _restrictions.push_back(std::move(restriction));
+ }
+
+ template <typename R>
+ explicit RestrictionSetAll(const R& restriction) {
+ static_assert(std::is_base_of<Restriction, R>::value, "Must pass a Restriction type.");
+ _restrictions.push_back(stdx::make_unique<R>(restriction));
+ }
+
Status validate(const RestrictionEnvironment& environment) const final {
for (const Pointer<T>& restriction : _restrictions) {
Status status = restriction->validate(environment);
diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp
index cb801830e55..ae7407bbd6a 100644
--- a/src/mongo/db/mongod_options.cpp
+++ b/src/mongo/db/mongod_options.cpp
@@ -50,6 +50,7 @@
#include "mongo/util/mongoutils/str.h"
#include "mongo/util/net/ssl_options.h"
#include "mongo/util/options_parser/startup_options.h"
+#include "mongo/util/stringutils.h"
#include "mongo/util/version.h"
namespace mongo {
@@ -99,6 +100,15 @@ Status addMongodOptions(moe::OptionSection* options) {
.setSources(moe::SourceAllLegacy)
.incompatibleWith("noauth");
+ // IP Whitelisting Options
+ general_options
+ .addOptionChaining("security.clusterIpSourceWhitelist",
+ "clusterIpSourceWhitelist",
+ moe::StringVector,
+ "Network CIDR specification of permitted origin for `__system` access.")
+ .composing();
+
+
// Way to enable or disable auth in JSON Config
general_options
.addOptionChaining(
@@ -1046,6 +1056,19 @@ Status storeMongodOptions(const moe::Environment& params) {
if (params.count("security.javascriptEnabled")) {
mongodGlobalParams.scriptingEnabled = params["security.javascriptEnabled"].as<bool>();
}
+
+ if (params.count("security.clusterIpSourceWhitelist")) {
+ mongodGlobalParams.whitelistedClusterNetwork = std::vector<std::string>();
+ for (const std::string& whitelistEntry :
+ params["security.clusterIpSourceWhitelist"].as<std::vector<std::string>>()) {
+ std::vector<std::string> intermediates;
+ splitStringDelim(whitelistEntry, &intermediates, ',');
+ std::copy(intermediates.begin(),
+ intermediates.end(),
+ std::back_inserter(*mongodGlobalParams.whitelistedClusterNetwork));
+ }
+ }
+
if (params.count("storage.mmapv1.preallocDataFiles")) {
mmapv1GlobalOptions.prealloc = params["storage.mmapv1.preallocDataFiles"].as<bool>();
cout << "note: noprealloc may hurt performance in many applications" << endl;
diff --git a/src/mongo/db/mongod_options.h b/src/mongo/db/mongod_options.h
index 27fb778cfdf..05bb6d8d5a5 100644
--- a/src/mongo/db/mongod_options.h
+++ b/src/mongo/db/mongod_options.h
@@ -28,6 +28,8 @@
#pragma once
+#include <boost/optional.hpp>
+
#include "mongo/base/status.h"
#include "mongo/db/repl/repl_settings.h"
#include "mongo/db/server_options.h"
@@ -45,9 +47,9 @@ class Environment;
namespace moe = mongo::optionenvironment;
struct MongodGlobalParams {
- bool scriptingEnabled; // --noscripting
+ bool scriptingEnabled = true; // --noscripting
- MongodGlobalParams() : scriptingEnabled(true) {}
+ boost::optional<std::vector<std::string>> whitelistedClusterNetwork;
};
extern MongodGlobalParams mongodGlobalParams;
diff --git a/src/mongo/db/storage/mmap_v1/SConscript b/src/mongo/db/storage/mmap_v1/SConscript
index f569c2a6bd5..e3eb4a43ba6 100644
--- a/src/mongo/db/storage/mmap_v1/SConscript
+++ b/src/mongo/db/storage/mmap_v1/SConscript
@@ -16,6 +16,13 @@ env.Library(
)
env.Library(
+ target='mmap_v1_options',
+ source=[
+ 'mmap_v1_options.cpp',
+ ],
+)
+
+env.Library(
target = 'storage_mmapv1',
source = [ "aligned_builder.cpp",
"catalog/hashtab.cpp",
@@ -52,6 +59,7 @@ env.Library(
'logfile',
'compress',
'paths',
+ 'mmap_v1_options',
'$BUILD_DIR/mongo/db/catalog/collection_options',
'$BUILD_DIR/mongo/db/catalog/database',
'$BUILD_DIR/mongo/db/catalog/database_holder',
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
index c43e148d3f4..1dd2c2e8cc3 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
@@ -1,5 +1,3 @@
-// mmap_v1_engine.cpp
-
/**
* Copyright (C) 2014 MongoDB Inc.
*
@@ -66,8 +64,6 @@ using std::string;
using std::stringstream;
using std::vector;
-MMAPV1Options mmapv1GlobalOptions;
-
namespace {
#if !defined(__sun)
@@ -411,4 +407,4 @@ void MMAPV1Engine::cleanShutdown() {
void MMAPV1Engine::setJournalListener(JournalListener* jl) {
dur::setJournalListener(jl);
}
-} // namespace
+} // namespace mongo
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_options.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_options.cpp
new file mode 100644
index 00000000000..87986746d93
--- /dev/null
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_options.cpp
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2017 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/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/db/storage/mmap_v1/mmap_v1_options.h"
+
+mongo::MMAPV1Options mongo::mmapv1GlobalOptions;