r11754: make the SMB2 blob push routines take offsets, so they fit better with
authorAndrew Tridgell <tridge@samba.org>
Thu, 17 Nov 2005 03:32:38 +0000 (03:32 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:23 +0000 (13:46 -0500)
the rest of the packet construction code
(This used to be commit 387ec2b17ff30a1c040b460b498c8fa7d8770593)

source4/libcli/smb2/create.c
source4/libcli/smb2/request.c
source4/libcli/smb2/session.c
source4/libcli/smb2/tcon.c
source4/libcli/smb2/write.c

index 79d3341bd08b1826733357fad4b26a0b3901ab1f..47fd208643178c76782baff8b23dd03914b9984b 100644 (file)
@@ -48,13 +48,13 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
        SIVAL(req->out.body, 0x24, io->in.open_disposition);
        SIVAL(req->out.body, 0x28, io->in.create_options);
 
-       status = smb2_push_o16s16_string(&req->out, req->out.body+0x2C, io->in.fname);
+       status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(req);
                return NULL;
        }
 
-       status = smb2_push_o32s32_blob(&req->out, req->out.body+0x30, io->in.blob);
+       status = smb2_push_o32s32_blob(&req->out, 0x30, io->in.blob);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(req);
                return NULL;
index 3e80115e47fbe84c9d6463d711a1bf137ae4386f..1a98ba99876534751590d82a92764dbd75ad4888 100644 (file)
@@ -50,10 +50,9 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
 
        ZERO_STRUCT(req->in);
        
-       req->out.size      = SMB2_HDR_BODY+NBT_HDR_SIZE+
-               body_fixed_size+body_dynamic_size;
+       req->out.size      = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size;
 
-       req->out.allocated = req->out.size;
+       req->out.allocated = req->out.size + body_dynamic_size;
        req->out.buffer    = talloc_size(req, req->out.allocated);
        if (req->out.buffer == NULL) {
                talloc_free(req);
@@ -182,26 +181,30 @@ static size_t smb2_padding_size(uint32_t offset, size_t n)
        return n - (offset & (n-1));
 }
 
-static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t n)
+/*
+  grow a SMB2 buffer by the specified amount
+*/
+static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t increase)
 {
        size_t dynamic_ofs;
        uint8_t *buffer_ptr;
+       uint32_t newsize = buf->size + increase;
 
        /* a packet size should be limited a bit */
-       if (n >= 0x00FFFFFF) return NT_STATUS_MARSHALL_OVERFLOW;
+       if (newsize >= 0x00FFFFFF) return NT_STATUS_MARSHALL_OVERFLOW;
 
-       if (n <= buf->allocated) return NT_STATUS_OK;
+       if (newsize <= buf->allocated) return NT_STATUS_OK;
 
        dynamic_ofs = buf->dynamic - buf->buffer;
 
-       buffer_ptr = talloc_realloc_size(buf, buf->buffer, n);
+       buffer_ptr = talloc_realloc_size(buf, buf->buffer, newsize);
        NT_STATUS_HAVE_NO_MEMORY(buffer_ptr);
 
        buf->buffer     = buffer_ptr;
        buf->hdr        = buf->buffer + NBT_HDR_SIZE;
        buf->body       = buf->hdr    + SMB2_HDR_BODY;
        buf->dynamic    = buf->buffer + dynamic_ofs;
-       buf->allocated  = n;
+       buf->allocated  = newsize;
 
        return NT_STATUS_OK;
 }
@@ -232,15 +235,18 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 
 /*
   push a uint16_t ofs/ uint16_t length/blob triple into a data blob
-  the ptr points to the start of the offset/length pair
+  the ofs points to the start of the offset/length pair, and is relative
+  to the body start
 */
-NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob)
+NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, 
+                              uint16_t ofs, DATA_BLOB blob)
 {
        NTSTATUS status;
        size_t offset;
        size_t padding_length;
+       uint8_t *ptr = buf->body+ofs;
 
-       if (!buf->dynamic) {
+       if (buf->dynamic == NULL) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -267,7 +273,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA
        SSVAL(ptr, 0, offset);
        SSVAL(ptr, 2, blob.length);
 
-       status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length);
+       status = smb2_grow_buffer(buf, padding_length + blob.length);
        NT_STATUS_NOT_OK_RETURN(status);
 
        memset(buf->dynamic, 0, padding_length);
@@ -276,48 +282,27 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA
        memcpy(buf->dynamic, blob.data, blob.length);
        buf->dynamic += blob.length;
 
-       buf->size = buf->dynamic - buf->buffer;
+       buf->size += blob.length + padding_length;
+       buf->body_size += blob.length + padding_length;
 
        return NT_STATUS_OK;
 }
 
-/*
-  pull a uint16_t ofs/ uint32_t length/blob triple from a data blob
-  the ptr points to the start of the offset/length pair
-*/
-NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob)
-{
-       uint16_t ofs;
-       uint32_t size;
-
-       if (smb2_oob(buf, ptr, 6)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
-       }
-       ofs  = SVAL(ptr, 0);
-       size = IVAL(ptr, 2);
-       if (ofs == 0 || size == 0) {
-               *blob = data_blob(NULL, 0);
-               return NT_STATUS_OK;
-       }
-       if (smb2_oob(buf, buf->hdr + ofs, size)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
-       }
-       *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
-       NT_STATUS_HAVE_NO_MEMORY(blob->data);
-       return NT_STATUS_OK;
-}
 
 /*
   push a uint16_t ofs/ uint32_t length/blob triple into a data blob
-  the ptr points to the start of the offset/length pair
+  the ofs points to the start of the offset/length pair, and is relative
+  to the body start
 */
-NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob)
+NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, 
+                              uint16_t ofs, DATA_BLOB blob)
 {
        NTSTATUS status;
        size_t offset;
        size_t padding_length;
+       uint8_t *ptr = buf->body+ofs;
 
-       if (!buf->dynamic) {
+       if (buf->dynamic == NULL) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -339,7 +324,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA
        SSVAL(ptr, 0, offset);
        SIVAL(ptr, 2, blob.length);
 
-       status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length);
+       status = smb2_grow_buffer(buf, padding_length + blob.length);
        NT_STATUS_NOT_OK_RETURN(status);
 
        memset(buf->dynamic, 0, padding_length);
@@ -348,46 +333,27 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA
        memcpy(buf->dynamic, blob.data, blob.length);
        buf->dynamic += blob.length;
 
-       buf->size = buf->dynamic - buf->buffer;
+       buf->size += blob.length + padding_length;
+       buf->body_size += blob.length + padding_length;
 
        return NT_STATUS_OK;
 }
 
-/*
-  pull a uint32_t ofs/ uint32_t length/blob triple from a data blob
-  the ptr points to the start of the offset/length pair
-*/
-NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob)
-{
-       uint32_t ofs, size;
-       if (smb2_oob(buf, ptr, 8)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
-       }
-       ofs  = IVAL(ptr, 0);
-       size = IVAL(ptr, 4);
-       if (ofs == 0 || size == 0) {
-               *blob = data_blob(NULL, 0);
-               return NT_STATUS_OK;
-       }
-       if (smb2_oob(buf, buf->hdr + ofs, size)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
-       }
-       *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
-       NT_STATUS_HAVE_NO_MEMORY(blob->data);
-       return NT_STATUS_OK;
-}
 
 /*
   push a uint32_t ofs/ uint32_t length/blob triple into a data blob
-  the ptr points to the start of the offset/length pair
+  the ofs points to the start of the offset/length pair, and is relative
+  to the body start
 */
-NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob)
+NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, 
+                              uint32_t ofs, DATA_BLOB blob)
 {
        NTSTATUS status;
        size_t offset;
        size_t padding_length;
+       uint8_t *ptr = buf->body+ofs;
 
-       if (!buf->dynamic) {
+       if (buf->dynamic == NULL) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -409,7 +375,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA
        SIVAL(ptr, 0, offset);
        SIVAL(ptr, 4, blob.length);
 
-       status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length);
+       status = smb2_grow_buffer(buf, padding_length + blob.length);
        NT_STATUS_NOT_OK_RETURN(status);
 
        memset(buf->dynamic, 0, padding_length);
@@ -418,8 +384,59 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA
        memcpy(buf->dynamic, blob.data, blob.length);
        buf->dynamic += blob.length;
 
-       buf->size = buf->dynamic - buf->buffer;
+       buf->size += blob.length + padding_length;
+       buf->body_size += blob.length + padding_length;
+
+       return NT_STATUS_OK;
+}
+
+/*
+  pull a uint16_t ofs/ uint32_t length/blob triple from a data blob
+  the ptr points to the start of the offset/length pair
+*/
+NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob)
+{
+       uint16_t ofs;
+       uint32_t size;
+
+       if (smb2_oob(buf, ptr, 6)) {
+               return NT_STATUS_BUFFER_TOO_SMALL;
+       }
+       ofs  = SVAL(ptr, 0);
+       size = IVAL(ptr, 2);
+       if (ofs == 0 || size == 0) {
+               *blob = data_blob(NULL, 0);
+               return NT_STATUS_OK;
+       }
+       if (smb2_oob(buf, buf->hdr + ofs, size)) {
+               return NT_STATUS_BUFFER_TOO_SMALL;
+       }
+       *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
+       NT_STATUS_HAVE_NO_MEMORY(blob->data);
+       return NT_STATUS_OK;
+}
 
+/*
+  pull a uint32_t ofs/ uint32_t length/blob triple from a data blob
+  the ptr points to the start of the offset/length pair
+*/
+NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob)
+{
+       uint32_t ofs, size;
+       if (smb2_oob(buf, ptr, 8)) {
+               return NT_STATUS_BUFFER_TOO_SMALL;
+       }
+       ofs  = IVAL(ptr, 0);
+       size = IVAL(ptr, 4);
+       if (ofs == 0 || size == 0) {
+               *blob = data_blob(NULL, 0);
+               return NT_STATUS_OK;
+       }
+       if (smb2_oob(buf, buf->hdr + ofs, size)) {
+               return NT_STATUS_BUFFER_TOO_SMALL;
+       }
+       *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
+       NT_STATUS_HAVE_NO_MEMORY(blob->data);
        return NT_STATUS_OK;
 }
 
@@ -453,17 +470,14 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me
   UTF-16 without termination
 */
 NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf,
-                                uint8_t *ptr, const char *str)
+                                uint16_t ofs, const char *str)
 {
        DATA_BLOB blob;
        NTSTATUS status;
        ssize_t size;
 
        if (strcmp("", str) == 0) {
-               blob = data_blob(NULL, 0);
-               status = smb2_push_o16s16_blob(buf, ptr, blob);
-               NT_STATUS_NOT_OK_RETURN(status);
-               return NT_STATUS_OK;
+               return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0));
        }
 
        size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, 
@@ -473,11 +487,9 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf,
        }
        blob.length = size;
 
-       status = smb2_push_o16s16_blob(buf, ptr, blob);
+       status = smb2_push_o16s16_blob(buf, ofs, blob);
        data_blob_free(&blob);
-       NT_STATUS_NOT_OK_RETURN(status);
-
-       return NT_STATUS_OK;
+       return status;
 }
 
 /*
index e572227a487c3e952418e6210916ca5bcf113468..0a13a288fc98ec62a2b630c1dab3bcfa145946fd 100644 (file)
@@ -77,7 +77,7 @@ struct smb2_request *smb2_session_setup_send(struct smb2_session *session,
 
        req->session = session;
 
-       status = smb2_push_o16s16_blob(&req->out, req->out.body+0x0C, io->in.secblob);
+       status = smb2_push_o16s16_blob(&req->out, 0x0C, io->in.secblob);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(req);
                return NULL;
index 32ad05733ea870709bd4b749ab699075ff3ea037..886ed9828bf4f2f6cb447ad54d25e77a74d97cca 100644 (file)
@@ -61,7 +61,7 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree,
        SBVAL(req->out.hdr,  SMB2_HDR_UID, tree->session->uid);
 
        SIVAL(req->out.body, 0x00, io->in.unknown1);
-       status = smb2_push_o16s16_string(&req->out, req->out.body+0x04, io->in.path);
+       status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(req);
                return NULL;
index 0b28b820eccf80db2d864796d77819f714beab9c..591cf2c891c27e063a3b8db73e26efa5d59a1fb5 100644 (file)
@@ -36,7 +36,7 @@ struct smb2_request *smb2_write_send(struct smb2_tree *tree, struct smb2_write *
        req = smb2_request_init_tree(tree, SMB2_OP_WRITE, 0x30, io->in.data.length);
        if (req == NULL) return NULL;
 
-       status = smb2_push_o16s32_blob(&req->out, req->out.body+0x02, io->in.data);
+       status = smb2_push_o16s32_blob(&req->out, 0x02, io->in.data);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(req);
                return NULL;