/** * Copyright (C) 2018-present MongoDB, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the Server Side Public License, version 1, * as published by MongoDB, Inc. * * 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 * Server Side Public License for more details. * * You should have received a copy of the Server Side Public License * along with this program. If not, see * . * * 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 Server Side 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/platform/basic.h" #include #include "mongo/db/auth/address_restriction.h" #include "mongo/db/auth/address_restriction_gen.h" #include "mongo/db/server_options.h" constexpr mongo::StringData mongo::address_restriction_detail::ClientSource::label; constexpr mongo::StringData mongo::address_restriction_detail::ClientSource::field; constexpr mongo::StringData mongo::address_restriction_detail::ServerAddress::label; constexpr mongo::StringData mongo::address_restriction_detail::ServerAddress::field; mongo::StatusWith> mongo::parseAddressRestrictionSet( const BSONObj& obj) try { IDLParserErrorContext ctx("address restriction"); const auto ar = Address_restriction::parse(ctx, obj); std::vector> vec; const boost::optional>& client = ar.getClientSource(); if (client) { vec.push_back(std::make_unique(client.get())); } const boost::optional>& server = ar.getServerAddress(); if (server) { vec.push_back(std::make_unique(server.get())); } if (vec.empty()) { return Status(ErrorCodes::CollectionIsEmpty, "At least one of 'clientSource' or 'serverAddress' must be set"); } return RestrictionSet<>(std::move(vec)); } catch (const DBException& e) { return Status(ErrorCodes::BadValue, e.what()); } mongo::StatusWith mongo::parseAuthenticationRestriction( const BSONArray& arr) { static_assert( std::is_same>, SharedRestrictionDocument>::value, "SharedRestrictionDocument expected to be a shared_ptr to a RestrictionDocument<>"); using document_type = SharedRestrictionDocument::element_type; static_assert(std::is_same>::value, "SharedRestrictionDocument expected to contain a sequence of unique_ptrs"); document_type::sequence_type doc; for (const auto& elem : arr) { if (elem.type() != Object) { return Status(ErrorCodes::UnsupportedFormat, "restriction array sub-documents must be address restriction objects"); } auto restriction = parseAddressRestrictionSet(elem.Obj()); if (!restriction.isOK()) { return restriction.getStatus(); } doc.emplace_back( std::make_unique(std::move(restriction.getValue()))); } return std::make_shared(std::move(doc)); } mongo::StatusWith mongo::getRawAuthenticationRestrictions( const BSONArray& arr) noexcept try { BSONArrayBuilder builder; 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()); }