1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-11 08:23:49 +03:00

Convert SMB and SMB2 code to use a common buffer handling structure

This converts our SMB and SMB2 code to use a common structure "struct
request_bufinfo" for information on the buffer bounds of a packet,
alignment information and string handling. This allows us to use a
common backend for SMB and SMB2 code, while still using all the same
string and blob handling functions.

Up to now we had been passing a NULL req handle into these common
routines from the SMB2 side of the server, which meant that we failed
any operation which did a bounds checked string extraction (such as a
RenameInformation setinfo call, which is what Vista uses for renaming
files)

There is still some more work to be done on this - for example we can
now remove many of the SMB2 specific buffer handling functions that we
had, and use the SMB ones.
This commit is contained in:
Andrew Tridgell
2008-02-14 10:12:33 +11:00
parent 36a31f31c4
commit ca6d9be6cb
28 changed files with 246 additions and 157 deletions

View File

@@ -34,6 +34,17 @@
/* assume that a character will not consume more than 3 bytes per char */
#define MAX_BYTES_PER_CHAR 3
/* setup the bufinfo used for strings and range checking */
void smb_setup_bufinfo(struct smbcli_request *req)
{
req->in.bufinfo.mem_ctx = req;
req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false;
req->in.bufinfo.align_base = req->in.buffer;
req->in.bufinfo.data = req->in.data;
req->in.bufinfo.data_size = req->in.data_size;
}
/* destroy a request structure and return final status */
NTSTATUS smbcli_request_destroy(struct smbcli_request *req)
{
@@ -298,6 +309,9 @@ NTSTATUS smbcli_chained_advance(struct smbcli_request *req)
req->in.data = req->in.vwv + 2 + req->in.wct * 2;
req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));
/* fix the bufinfo */
smb_setup_bufinfo(req);
if (buffer + 3 + req->in.wct*2 + req->in.data_size >
req->in.buffer + req->in.size) {
return NT_STATUS_BUFFER_TOO_SMALL;
@@ -544,13 +558,13 @@ size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *by
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
static size_t smbcli_req_pull_ucs2(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2, alignment=0;
ssize_t ret;
if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) {
if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {
src++;
alignment=1;
if (byte_len != -1) {
@@ -558,7 +572,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c
}
}
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
if (src_len < 0) {
*dest = NULL;
return 0;
@@ -597,13 +611,13 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
size_t smbcli_req_pull_ascii(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
int src_len, src_len2;
ssize_t ret;
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
if (src_len < 0) {
*dest = NULL;
return 0;
@@ -640,15 +654,15 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
on failure zero is returned and *dest is set to NULL, otherwise the number
of bytes consumed in the packet is returned
*/
size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
size_t smbcli_req_pull_string(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
char **dest, const uint8_t *src, int byte_len, uint_t flags)
{
if (!(flags & STR_ASCII) &&
(((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
return smbcli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags);
(((flags & STR_UNICODE) || bufinfo->unicode))) {
return smbcli_req_pull_ucs2(bufinfo, mem_ctx, dest, src, byte_len, flags);
}
return smbcli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags);
return smbcli_req_pull_ascii(bufinfo, mem_ctx, dest, src, byte_len, flags);
}
@@ -658,11 +672,11 @@ size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
if byte_len is -1 then limit the blob only by packet size
*/
DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len)
DATA_BLOB smbcli_req_pull_blob(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len)
{
int src_len;
src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
if (src_len < 0) {
return data_blob(NULL, 0);
@@ -677,13 +691,13 @@ DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
/* check that a lump of data in a request is within the bounds of the data section of
the packet */
static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count)
static bool smbcli_req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count)
{
/* be careful with wraparound! */
if (ptr < req->in.data ||
ptr >= req->in.data + req->in.data_size ||
count > req->in.data_size ||
ptr + count > req->in.data + req->in.data_size) {
if (ptr < bufinfo->data ||
ptr >= bufinfo->data + bufinfo->data_size ||
count > bufinfo->data_size ||
ptr + count > bufinfo->data + bufinfo->data_size) {
return true;
}
return false;
@@ -694,11 +708,11 @@ static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr,
return false if any part is outside the data portion of the packet
*/
bool smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest)
bool smbcli_raw_pull_data(struct request_bufinfo *bufinfo, const uint8_t *src, int len, uint8_t *dest)
{
if (len == 0) return true;
if (smbcli_req_data_oob(req, src, len)) {
if (smbcli_req_data_oob(bufinfo, src, len)) {
return false;
}