From 92d18a3599f8068b9d576f9d0e7ed70192ce0c61 Mon Sep 17 00:00:00 2001 From: David Mulder Date: Fri, 18 Mar 2022 14:45:09 -0600 Subject: [PATCH] smbd: Move reply_outbuf and construct_reply_common_req to smb2_process.c Signed-off-by: David Mulder Reviewed-by: Jeremy Allison --- source3/smbd/process.c | 88 ------------------------------------- source3/smbd/proto.h | 7 ++- source3/smbd/smb2_process.c | 86 ++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 90 deletions(-) diff --git a/source3/smbd/process.c b/source3/smbd/process.c index e7d29adf560..9ed957a6e2e 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -64,8 +64,6 @@ struct pending_message_list { struct deferred_open_record *open_rec; }; -static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf, - char *outbuf); static bool smb_splice_chain(uint8_t **poutbuf, const uint8_t *andx_buf); static void smbd_echo_init(struct smbXsrv_connection *xconn) @@ -1087,61 +1085,6 @@ static const struct smb_message_struct { }; -/******************************************************************* - allocate and initialize a reply packet -********************************************************************/ - -static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req, - const uint8_t *inbuf, char **outbuf, - uint8_t num_words, uint32_t num_bytes) -{ - size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes; - - /* - * Protect against integer wrap. - * The SMB layer reply can be up to 0xFFFFFF bytes. - */ - if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) { - char *msg; - if (asprintf(&msg, "num_bytes too large: %u", - (unsigned)num_bytes) == -1) { - msg = discard_const_p(char, "num_bytes too large"); - } - smb_panic(msg); - } - - /* - * Here we include the NBT header for now. - */ - *outbuf = talloc_array(mem_ctx, char, - NBT_HDR_SIZE + smb_len); - if (*outbuf == NULL) { - return false; - } - - construct_reply_common(req->cmd, inbuf, *outbuf); - srv_set_message(*outbuf, num_words, num_bytes, false); - /* - * Zero out the word area, the caller has to take care of the bcc area - * himself - */ - if (num_words != 0) { - memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words)); - } - - return true; -} - -void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes) -{ - char *outbuf; - if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words, - num_bytes)) { - smb_panic("could not allocate output buffer\n"); - } - req->outbuf = (uint8_t *)outbuf; -} - /******************************************************************* Dump a packet to a file. @@ -1825,37 +1768,6 @@ void remove_from_common_flags2(uint32_t v) common_flags2 &= ~v; } -static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf, - char *outbuf) -{ - uint16_t in_flags2 = SVAL(inbuf,smb_flg2); - uint16_t out_flags2 = common_flags2; - - out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS; - out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES; - out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED; - - srv_set_message(outbuf,0,0,false); - - SCVAL(outbuf, smb_com, cmd); - SIVAL(outbuf,smb_rcls,0); - SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); - SSVAL(outbuf,smb_flg2, out_flags2); - memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh)); - memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8); - - SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid)); - SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid)); - SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh)); - SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid)); - SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid)); -} - -void construct_reply_common_req(struct smb_request *req, char *outbuf) -{ - construct_reply_common(req->cmd, req->inbuf, outbuf); -} - /** * @brief Find the smb_cmd offset of the last command pushed * @param[in] buf The buffer we're building up diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 8f0b0af50d0..b379dab00cd 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -853,12 +853,10 @@ bool smb1_srv_send(struct smbXsrv_connection *xconn, char *buffer, bool do_encrypt, struct smb_perfcount_data *pcd); NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid); -void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes); void smb_request_done(struct smb_request *req); const char *smb_fn_name(int type); void add_to_common_flags2(uint32_t v); void remove_from_common_flags2(uint32_t v); -void construct_reply_common_req(struct smb_request *req, char *outbuf); bool smb1_is_chain(const uint8_t *buf); bool smb1_walk_chain(const uint8_t *buf, bool (*fn)(uint8_t cmd, @@ -926,6 +924,11 @@ bool push_deferred_open_message_smb(struct smb_request *req, struct timeval timeout, struct file_id id, struct deferred_open_record *open_rec); +bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req, + const uint8_t *inbuf, char **outbuf, + uint8_t num_words, uint32_t num_bytes); +void construct_reply_common_req(struct smb_request *req, char *outbuf); +void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes); /* The following definitions come from smbd/quotas.c */ diff --git a/source3/smbd/smb2_process.c b/source3/smbd/smb2_process.c index 47519ec4d57..7f1bac6fc81 100644 --- a/source3/smbd/smb2_process.c +++ b/source3/smbd/smb2_process.c @@ -484,3 +484,89 @@ bool push_deferred_open_message_smb(struct smb_request *req, } #endif } + +static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf, + char *outbuf) +{ + uint16_t in_flags2 = SVAL(inbuf,smb_flg2); + uint16_t out_flags2 = common_flags2; + + out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS; + out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES; + out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED; + + srv_set_message(outbuf,0,0,false); + + SCVAL(outbuf, smb_com, cmd); + SIVAL(outbuf,smb_rcls,0); + SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); + SSVAL(outbuf,smb_flg2, out_flags2); + memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh)); + memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8); + + SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid)); + SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid)); + SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh)); + SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid)); + SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid)); +} + +void construct_reply_common_req(struct smb_request *req, char *outbuf) +{ + construct_reply_common(req->cmd, req->inbuf, outbuf); +} + +/******************************************************************* + allocate and initialize a reply packet +********************************************************************/ + +bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req, + const uint8_t *inbuf, char **outbuf, + uint8_t num_words, uint32_t num_bytes) +{ + size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes; + + /* + * Protect against integer wrap. + * The SMB layer reply can be up to 0xFFFFFF bytes. + */ + if ((num_bytes > 0xffffff) || (smb_len > 0xffffff)) { + char *msg; + if (asprintf(&msg, "num_bytes too large: %u", + (unsigned)num_bytes) == -1) { + msg = discard_const_p(char, "num_bytes too large"); + } + smb_panic(msg); + } + + /* + * Here we include the NBT header for now. + */ + *outbuf = talloc_array(mem_ctx, char, + NBT_HDR_SIZE + smb_len); + if (*outbuf == NULL) { + return false; + } + + construct_reply_common(req->cmd, inbuf, *outbuf); + srv_set_message(*outbuf, num_words, num_bytes, false); + /* + * Zero out the word area, the caller has to take care of the bcc area + * himself + */ + if (num_words != 0) { + memset(*outbuf + (NBT_HDR_SIZE + HDR_VWV), 0, VWV(num_words)); + } + + return true; +} + +void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t num_bytes) +{ + char *outbuf; + if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words, + num_bytes)) { + smb_panic("could not allocate output buffer\n"); + } + req->outbuf = (uint8_t *)outbuf; +}