diff options
author | Volker Lendecke <vl@samba.org> | 2009-12-22 13:53:13 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-12-22 13:54:43 +0100 |
commit | b6f446ca35810f13208ab82ec9720271fb64af44 (patch) | |
tree | cc4235ebca83e10537e9df0b63da5f620d63d639 | |
parent | 585900deb58944f35bdf03c0b8cba3509d5b0076 (diff) | |
download | samba-b6f446ca35810f13208ab82ec9720271fb64af44.tar.gz samba-b6f446ca35810f13208ab82ec9720271fb64af44.tar.bz2 samba-b6f446ca35810f13208ab82ec9720271fb64af44.zip |
s3: Move smb_splice_chain to smbd/process.c, its only user
-rw-r--r-- | source3/include/async_smb.h | 5 | ||||
-rw-r--r-- | source3/libsmb/async_smb.c | 174 | ||||
-rw-r--r-- | source3/smbd/process.c | 174 |
3 files changed, 174 insertions, 179 deletions
diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h index 03dd274539..47fed92739 100644 --- a/source3/include/async_smb.h +++ b/source3/include/async_smb.h @@ -22,11 +22,6 @@ #include "includes.h" -bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command, - uint8_t wct, const uint16_t *vwv, - size_t bytes_alignment, - uint32_t num_bytes, const uint8_t *bytes); - /* * Fetch an error out of a NBT packet */ diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 6edfe514b8..bbabba30bc 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -153,180 +153,6 @@ void cli_set_error(struct cli_state *cli, NTSTATUS status) } /** - * @brief Find the smb_cmd offset of the last command pushed - * @param[in] buf The buffer we're building up - * @retval Where can we put our next andx cmd? - * - * While chaining requests, the "next" request we're looking at needs to put - * its SMB_Command before the data the previous request already built up added - * to the chain. Find the offset to the place where we have to put our cmd. - */ - -static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs) -{ - uint8_t cmd; - size_t ofs; - - cmd = CVAL(buf, smb_com); - - SMB_ASSERT(is_andx_req(cmd)); - - ofs = smb_vwv0; - - while (CVAL(buf, ofs) != 0xff) { - - if (!is_andx_req(CVAL(buf, ofs))) { - return false; - } - - /* - * ofs is from start of smb header, so add the 4 length - * bytes. The next cmd is right after the wct field. - */ - ofs = SVAL(buf, ofs+2) + 4 + 1; - - SMB_ASSERT(ofs+4 < talloc_get_size(buf)); - } - - *pofs = ofs; - return true; -} - -/** - * @brief Do the smb chaining at a buffer level - * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified - * @param[in] smb_command The command that we want to issue - * @param[in] wct How many words? - * @param[in] vwv The words, already in network order - * @param[in] bytes_alignment How shall we align "bytes"? - * @param[in] num_bytes How many bytes? - * @param[in] bytes The data the request ships - * - * smb_splice_chain() adds the vwv and bytes to the request already present in - * *poutbuf. - */ - -bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command, - uint8_t wct, const uint16_t *vwv, - size_t bytes_alignment, - uint32_t num_bytes, const uint8_t *bytes) -{ - uint8_t *outbuf; - size_t old_size, new_size; - size_t ofs; - size_t chain_padding = 0; - size_t bytes_padding = 0; - bool first_request; - - old_size = talloc_get_size(*poutbuf); - - /* - * old_size == smb_wct means we're pushing the first request in for - * libsmb/ - */ - - first_request = (old_size == smb_wct); - - if (!first_request && ((old_size % 4) != 0)) { - /* - * Align the wct field of subsequent requests to a 4-byte - * boundary - */ - chain_padding = 4 - (old_size % 4); - } - - /* - * After the old request comes the new wct field (1 byte), the vwv's - * and the num_bytes field. After at we might need to align the bytes - * given to us to "bytes_alignment", increasing the num_bytes value. - */ - - new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2; - - if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) { - bytes_padding = bytes_alignment - (new_size % bytes_alignment); - } - - new_size += bytes_padding + num_bytes; - - if ((smb_command != SMBwriteX) && (new_size > 0xffff)) { - DEBUG(1, ("splice_chain: %u bytes won't fit\n", - (unsigned)new_size)); - return false; - } - - outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size); - if (outbuf == NULL) { - DEBUG(0, ("talloc failed\n")); - return false; - } - *poutbuf = outbuf; - - if (first_request) { - SCVAL(outbuf, smb_com, smb_command); - } else { - size_t andx_cmd_ofs; - - if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) { - DEBUG(1, ("invalid command chain\n")); - *poutbuf = TALLOC_REALLOC_ARRAY( - NULL, *poutbuf, uint8_t, old_size); - return false; - } - - if (chain_padding != 0) { - memset(outbuf + old_size, 0, chain_padding); - old_size += chain_padding; - } - - SCVAL(outbuf, andx_cmd_ofs, smb_command); - SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4); - } - - ofs = old_size; - - /* - * Push the chained request: - * - * wct field - */ - - SCVAL(outbuf, ofs, wct); - ofs += 1; - - /* - * vwv array - */ - - memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct); - ofs += sizeof(uint16_t) * wct; - - /* - * bcc (byte count) - */ - - SSVAL(outbuf, ofs, num_bytes + bytes_padding); - ofs += sizeof(uint16_t); - - /* - * padding - */ - - if (bytes_padding != 0) { - memset(outbuf + ofs, 0, bytes_padding); - ofs += bytes_padding; - } - - /* - * The bytes field - */ - - memcpy(outbuf + ofs, bytes, num_bytes); - - return true; -} - -/** * Figure out if there is an andx command behind the current one * @param[in] buf The smb buffer to look at * @param[in] ofs The offset to the wct field that is followed by the cmd diff --git a/source3/smbd/process.c b/source3/smbd/process.c index cc2e290227..572f37dbbe 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1608,6 +1608,180 @@ static void fixup_chain_error_packet(struct smb_request *req) SCVAL(req->outbuf, smb_vwv0, 0xff); } +/** + * @brief Find the smb_cmd offset of the last command pushed + * @param[in] buf The buffer we're building up + * @retval Where can we put our next andx cmd? + * + * While chaining requests, the "next" request we're looking at needs to put + * its SMB_Command before the data the previous request already built up added + * to the chain. Find the offset to the place where we have to put our cmd. + */ + +static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs) +{ + uint8_t cmd; + size_t ofs; + + cmd = CVAL(buf, smb_com); + + SMB_ASSERT(is_andx_req(cmd)); + + ofs = smb_vwv0; + + while (CVAL(buf, ofs) != 0xff) { + + if (!is_andx_req(CVAL(buf, ofs))) { + return false; + } + + /* + * ofs is from start of smb header, so add the 4 length + * bytes. The next cmd is right after the wct field. + */ + ofs = SVAL(buf, ofs+2) + 4 + 1; + + SMB_ASSERT(ofs+4 < talloc_get_size(buf)); + } + + *pofs = ofs; + return true; +} + +/** + * @brief Do the smb chaining at a buffer level + * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified + * @param[in] smb_command The command that we want to issue + * @param[in] wct How many words? + * @param[in] vwv The words, already in network order + * @param[in] bytes_alignment How shall we align "bytes"? + * @param[in] num_bytes How many bytes? + * @param[in] bytes The data the request ships + * + * smb_splice_chain() adds the vwv and bytes to the request already present in + * *poutbuf. + */ + +static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command, + uint8_t wct, const uint16_t *vwv, + size_t bytes_alignment, + uint32_t num_bytes, const uint8_t *bytes) +{ + uint8_t *outbuf; + size_t old_size, new_size; + size_t ofs; + size_t chain_padding = 0; + size_t bytes_padding = 0; + bool first_request; + + old_size = talloc_get_size(*poutbuf); + + /* + * old_size == smb_wct means we're pushing the first request in for + * libsmb/ + */ + + first_request = (old_size == smb_wct); + + if (!first_request && ((old_size % 4) != 0)) { + /* + * Align the wct field of subsequent requests to a 4-byte + * boundary + */ + chain_padding = 4 - (old_size % 4); + } + + /* + * After the old request comes the new wct field (1 byte), the vwv's + * and the num_bytes field. After at we might need to align the bytes + * given to us to "bytes_alignment", increasing the num_bytes value. + */ + + new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2; + + if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) { + bytes_padding = bytes_alignment - (new_size % bytes_alignment); + } + + new_size += bytes_padding + num_bytes; + + if ((smb_command != SMBwriteX) && (new_size > 0xffff)) { + DEBUG(1, ("splice_chain: %u bytes won't fit\n", + (unsigned)new_size)); + return false; + } + + outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size); + if (outbuf == NULL) { + DEBUG(0, ("talloc failed\n")); + return false; + } + *poutbuf = outbuf; + + if (first_request) { + SCVAL(outbuf, smb_com, smb_command); + } else { + size_t andx_cmd_ofs; + + if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) { + DEBUG(1, ("invalid command chain\n")); + *poutbuf = TALLOC_REALLOC_ARRAY( + NULL, *poutbuf, uint8_t, old_size); + return false; + } + + if (chain_padding != 0) { + memset(outbuf + old_size, 0, chain_padding); + old_size += chain_padding; + } + + SCVAL(outbuf, andx_cmd_ofs, smb_command); + SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4); + } + + ofs = old_size; + + /* + * Push the chained request: + * + * wct field + */ + + SCVAL(outbuf, ofs, wct); + ofs += 1; + + /* + * vwv array + */ + + memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct); + ofs += sizeof(uint16_t) * wct; + + /* + * bcc (byte count) + */ + + SSVAL(outbuf, ofs, num_bytes + bytes_padding); + ofs += sizeof(uint16_t); + + /* + * padding + */ + + if (bytes_padding != 0) { + memset(outbuf + ofs, 0, bytes_padding); + ofs += bytes_padding; + } + + /* + * The bytes field + */ + + memcpy(outbuf + ofs, bytes, num_bytes); + + return true; +} + /**************************************************************************** Construct a chained reply and add it to the already made reply ****************************************************************************/ |