diff options
Diffstat (limited to 'src/mongo/rpc/op_msg.cpp')
-rw-r--r-- | src/mongo/rpc/op_msg.cpp | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/mongo/rpc/op_msg.cpp b/src/mongo/rpc/op_msg.cpp index f93aa859368..be420d55e50 100644 --- a/src/mongo/rpc/op_msg.cpp +++ b/src/mongo/rpc/op_msg.cpp @@ -132,7 +132,7 @@ void OpMsg::appendChecksum(Message* message) { #endif } -OpMsg OpMsg::parse(const Message& message) try { +OpMsg OpMsg::parse(const Message& message, Client* client) try { // It is the caller's responsibility to call the correct parser for a given message type. invariant(!message.empty()); invariant(message.operation() == dbMsg); @@ -159,6 +159,7 @@ OpMsg OpMsg::parse(const Message& message) try { // TODO some validation may make more sense in the IDL parser. I've tagged them with comments. bool haveBody = false; OpMsg msg; + BSONObj securityToken; while (!sectionsBuf.atEof()) { const auto sectionKind = sectionsBuf.read<Section>(); switch (sectionKind) { @@ -166,6 +167,10 @@ OpMsg OpMsg::parse(const Message& message) try { uassert(40430, "Multiple body sections in message", !haveBody); haveBody = true; msg.body = sectionsBuf.read<Validated<BSONObj>>(); + + uassert(ErrorCodes::InvalidOptions, + "Multitenancy not enabled, cannot set $tenant in command body", + gMultitenancySupport || !msg.body["$tenant"_sd]); break; } @@ -197,7 +202,7 @@ OpMsg OpMsg::parse(const Message& message) try { uassert(ErrorCodes::Unauthorized, "Unsupported Security Token provided", gMultitenancySupport); - msg.securityToken = sectionsBuf.read<Validated<BSONObj>>(); + securityToken = sectionsBuf.read<Validated<BSONObj>>(); break; } @@ -228,6 +233,10 @@ OpMsg OpMsg::parse(const Message& message) try { *checksum == calculateChecksum(message)); } #endif + if (gMultitenancySupport) { + msg.validatedTenancyScope = + auth::ValidatedTenancyScope::create(client, msg.body, securityToken); + } return msg; } catch (const DBException& ex) { @@ -245,10 +254,13 @@ OpMsg OpMsg::parse(const Message& message) try { namespace { void serializeHelper(const std::vector<OpMsg::DocumentSequence>& sequences, const BSONObj& body, - const BSONObj& securityToken, + const boost::optional<auth::ValidatedTenancyScope>& validatedTenancyScope, OpMsgBuilder* output) { - if (securityToken.nFields() > 0) { - output->setSecurityToken(securityToken); + if (validatedTenancyScope) { + auto securityToken = validatedTenancyScope->getOriginalToken(); + if (securityToken.nFields() > 0) { + output->setSecurityToken(securityToken); + } } for (auto&& seq : sequences) { auto docSeq = output->beginDocSequence(seq.name); @@ -262,13 +274,13 @@ void serializeHelper(const std::vector<OpMsg::DocumentSequence>& sequences, Message OpMsg::serialize() const { OpMsgBuilder builder; - serializeHelper(sequences, body, securityToken, &builder); + serializeHelper(sequences, body, validatedTenancyScope, &builder); return builder.finish(); } Message OpMsg::serializeWithoutSizeChecking() const { OpMsgBuilder builder; - serializeHelper(sequences, body, securityToken, &builder); + serializeHelper(sequences, body, validatedTenancyScope, &builder); return builder.finishWithoutSizeChecking(); } @@ -283,9 +295,6 @@ void OpMsg::shareOwnershipWith(const ConstSharedBuffer& buffer) { } } } - if (!securityToken.isOwned()) { - securityToken.shareOwnershipWith(buffer); - } } BSONObjBuilder OpMsgBuilder::beginSecurityToken() { |