summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/smb2/create.c4
-rw-r--r--source4/libcli/smb2/request.c172
-rw-r--r--source4/libcli/smb2/session.c2
-rw-r--r--source4/libcli/smb2/tcon.c2
-rw-r--r--source4/libcli/smb2/write.c2
5 files changed, 97 insertions, 85 deletions
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 79d3341bd0..47fd208643 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -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;
diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c
index 3e80115e47..1a98ba9987 100644
--- a/source4/libcli/smb2/request.c
+++ b/source4/libcli/smb2/request.c
@@ -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;
}
/*
diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c
index e572227a48..0a13a288fc 100644
--- a/source4/libcli/smb2/session.c
+++ b/source4/libcli/smb2/session.c
@@ -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;
diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c
index 32ad05733e..886ed9828b 100644
--- a/source4/libcli/smb2/tcon.c
+++ b/source4/libcli/smb2/tcon.c
@@ -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;
diff --git a/source4/libcli/smb2/write.c b/source4/libcli/smb2/write.c
index 0b28b820ec..591cf2c891 100644
--- a/source4/libcli/smb2/write.c
+++ b/source4/libcli/smb2/write.c
@@ -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;