From ac293f85342a77777c2164a53c8ec43ddc1c1aed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 04:45:38 +0000 Subject: r11662: the beginnings of a SMB2 client library. Very hackish, meant for experimentation (This used to be commit 68422dc73f6ea51bf906f3db223ae8abf077aba1) --- source4/libcli/smb2/request.c | 171 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 source4/libcli/smb2/request.c (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c new file mode 100644 index 0000000000..1b2dc5e64c --- /dev/null +++ b/source4/libcli/smb2/request.c @@ -0,0 +1,171 @@ +/* + Unix SMB/CIFS implementation. + + SMB2 client request handling + + Copyright (C) Andrew Tridgell 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" +#include "include/dlinklist.h" +#include "lib/events/events.h" +#include "librpc/gen_ndr/ndr_misc.h" + +/* + initialise a smb2 request +*/ +struct smb2_request *smb2_request_init(struct smb2_transport *transport, + uint16_t opcode, uint32_t body_size) +{ + struct smb2_request *req; + + req = talloc(transport, struct smb2_request); + if (req == NULL) return NULL; + + req->state = SMB2_REQUEST_INIT; + req->transport = transport; + req->seqnum = transport->seqnum++; + req->status = NT_STATUS_OK; + req->async.fn = NULL; + req->next = req->prev = NULL; + + ZERO_STRUCT(req->in); + + req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_size; + req->out.buffer = talloc_size(req, req->out.allocated); + if (req->out.buffer == NULL) { + talloc_free(req); + return NULL; + } + + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE + body_size; + req->out.hdr = req->out.buffer + NBT_HDR_SIZE; + req->out.body = req->out.hdr + SMB2_HDR_BODY; + req->out.body_size = body_size; + req->out.ptr = req->out.body; + + SIVAL(req->out.hdr, 0, SMB2_MAGIC); + SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); + SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); + SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); + SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); + SSVAL(req->out.hdr, SMB2_HDR_PAD2, 0); + SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); + SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN, 0); + SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); + SIVAL(req->out.hdr, SMB2_HDR_PID, 0); + SIVAL(req->out.hdr, SMB2_HDR_TID, 0); + SIVAL(req->out.hdr, SMB2_HDR_UID, 0); + SIVAL(req->out.hdr, SMB2_HDR_UID2, 0); + memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); + + return req; +} + +/* destroy a request structure and return final status */ +NTSTATUS smb2_request_destroy(struct smb2_request *req) +{ + NTSTATUS status; + + /* this is the error code we give the application for when a + _send() call fails completely */ + if (!req) return NT_STATUS_UNSUCCESSFUL; + + if (req->transport) { + /* remove it from the list of pending requests (a null op if + its not in the list) */ + DLIST_REMOVE(req->transport->pending_recv, req); + } + + if (req->state == SMBCLI_REQUEST_ERROR && + NT_STATUS_IS_OK(req->status)) { + req->status = NT_STATUS_INTERNAL_ERROR; + } + + status = req->status; + talloc_free(req); + return status; +} + +/* + receive a response to a packet +*/ +BOOL smb2_request_receive(struct smb2_request *req) +{ + /* req can be NULL when a send has failed. This eliminates lots of NULL + checks in each module */ + if (!req) return False; + + /* keep receiving packets until this one is replied to */ + while (req->state <= SMB2_REQUEST_RECV) { + if (event_loop_once(req->transport->socket->event.ctx) != 0) { + return False; + } + } + + return req->state == SMB2_REQUEST_DONE; +} + +/* Return true if the last packet was in error */ +BOOL smb2_request_is_error(struct smb2_request *req) +{ + return NT_STATUS_IS_ERR(req->status); +} + +/* + check if a range in the reply body is out of bounds +*/ +BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size) +{ + /* be careful with wraparound! */ + if (ptr < req->in.body || + ptr >= req->in.body + req->in.body_size || + size > req->in.body_size || + ptr + size > req->in.body + req->in.body_size) { + return True; + } + return False; +} + +/* + pull a data blob from the body of a reply +*/ +DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) +{ + if (smb2_oob(req, ptr, size)) { + return data_blob(NULL, 0); + } + return data_blob_talloc(req, ptr, size); +} + +/* + pull a guid from the reply body +*/ +NTSTATUS smb2_pull_guid(struct smb2_request *req, uint8_t *ptr, struct GUID *guid) +{ + NTSTATUS status; + DATA_BLOB blob = smb2_pull_blob(req, ptr, 16); + if (blob.data == NULL) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + status = ndr_pull_struct_blob(&blob, req, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + data_blob_free(&blob); + return status; +} -- cgit From 555b45e12c281eb3980d15b12728c59c6b73c302 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 05:53:54 +0000 Subject: r11665: started to put some meat on the structure used for the SMB2 library the call definitions will be in smb2_calls.h, which will play a similar role that smb_interfaces.h plays for the old SMB protocol (This used to be commit 4ef3902a8a99a0b8caa81a07ba07830d7cbbc32c) --- source4/libcli/smb2/request.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1b2dc5e64c..e71fc84471 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -25,7 +25,6 @@ #include "libcli/smb2/smb2.h" #include "include/dlinklist.h" #include "lib/events/events.h" -#include "librpc/gen_ndr/ndr_misc.h" /* initialise a smb2 request @@ -154,18 +153,3 @@ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) return data_blob_talloc(req, ptr, size); } -/* - pull a guid from the reply body -*/ -NTSTATUS smb2_pull_guid(struct smb2_request *req, uint8_t *ptr, struct GUID *guid) -{ - NTSTATUS status; - DATA_BLOB blob = smb2_pull_blob(req, ptr, 16); - if (blob.data == NULL) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - status = ndr_pull_struct_blob(&blob, req, guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); - data_blob_free(&blob); - return status; -} -- cgit From 7a78d2d6b083fbd408c766116693d01b57628f28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 07:23:45 +0000 Subject: r11668: yay! we get a successful session setup with SMB2, and get back a 64bit uid (This used to be commit 72b34a7c1b66af6be02f66639efc55a19c73e387) --- source4/libcli/smb2/request.c | 56 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index e71fc84471..93f8043d0c 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -130,7 +130,7 @@ BOOL smb2_request_is_error(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size) +BOOL smb2_oob_in(struct smb2_request *req, const uint8_t *ptr, uint_t size) { /* be careful with wraparound! */ if (ptr < req->in.body || @@ -142,14 +142,66 @@ BOOL smb2_oob(struct smb2_request *req, const uint8_t *ptr, uint_t size) return False; } +/* + check if a range in the outgoing body is out of bounds +*/ +BOOL smb2_oob_out(struct smb2_request *req, const uint8_t *ptr, uint_t size) +{ + /* be careful with wraparound! */ + if (ptr < req->out.body || + ptr >= req->out.body + req->out.body_size || + size > req->out.body_size || + ptr + size > req->out.body + req->out.body_size) { + return True; + } + return False; +} + /* pull a data blob from the body of a reply */ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) { - if (smb2_oob(req, ptr, size)) { + if (smb2_oob_in(req, ptr, size)) { return data_blob(NULL, 0); } return data_blob_talloc(req, ptr, size); } +/* + pull a ofs/length/blob triple into a data blob + the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *blob) +{ + uint16_t ofs, size; + if (smb2_oob_in(req, ptr, 4)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ofs = SVAL(ptr, 0); + size = SVAL(ptr, 2); + if (smb2_oob_in(req, req->in.hdr + ofs, size)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *blob = data_blob_talloc(req, req->in.hdr+ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; +} + +/* + push a ofs/length/blob triple into a data blob + the ptr points to the start of the offset/length pair + + NOTE: assumes blob goes immediately after the offset/length pair. Needs + to be generalised +*/ +NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB blob) +{ + if (smb2_oob_out(req, ptr, 4+blob.length)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + SSVAL(ptr, 0, 4 + (ptr - req->out.hdr)); + SSVAL(ptr, 2, blob.length); + memcpy(ptr+4, blob.data, blob.length); + return NT_STATUS_OK; +} -- cgit From d9d90e105b493cfb7676eb65af4456dfb572a5b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Nov 2005 08:00:05 +0000 Subject: r11670: fix the build metze (This used to be commit c0eebe293f341dcf35229c2cbbc3029f6f853abb) --- source4/libcli/smb2/request.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 93f8043d0c..28e7018ecc 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -70,8 +70,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SIVAL(req->out.hdr, SMB2_HDR_UID, 0); - SIVAL(req->out.hdr, SMB2_HDR_UID2, 0); + SBVAL(req->out.hdr, SMB2_HDR_UID, (uint64_t)0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); return req; -- cgit From 3e54c36fa459ec6f5e721b90ce4e4c1d0e31d85c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 09:11:51 +0000 Subject: r11674: SMB2 tree connect now works. We do 2 session setups and 2 tree connects, giving the following output: Running SMB2-CONNECT Negprot reply: current_time = Fri Nov 11 20:10:42 2005 EST boot_time = Sat Nov 12 10:34:33 2005 EST Session setup gave UID 0x40000000071 Session setup gave UID 0x140000000075 Tree connect gave tid = 0x7500000001 Tree connect gave tid = 0x7500000005 SMB2-CONNECT took 0.049024 secs (This used to be commit a24a4c311005dec4c5638e9c7c10e5e2f9872f4d) --- source4/libcli/smb2/request.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 28e7018ecc..deadd1794f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -204,3 +204,40 @@ NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB bl memcpy(ptr+4, blob.data, blob.length); return NT_STATUS_OK; } + +/* + pull a string in a ofs/length/blob format +*/ +NTSTATUS smb2_pull_ofs_string(struct smb2_request *req, uint8_t *ptr, + const char **str) +{ + DATA_BLOB blob; + NTSTATUS status; + ssize_t size; + void *vstr; + status = smb2_pull_ofs_blob(req, ptr, &blob); + NT_STATUS_NOT_OK_RETURN(status); + size = convert_string_talloc(req, CH_UTF16, CH_UNIX, + blob.data, blob.length, &vstr); + data_blob_free(&blob); + (*str) = vstr; + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + return NT_STATUS_OK; +} + +/* + create a UTF16 string in a blob from a char* +*/ +NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) +{ + ssize_t size; + size = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, + str, strlen(str), (void **)&blob->data); + if (size == -1) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + blob->length = size; + return NT_STATUS_OK; +} -- cgit From 7935df168f4e98e5d3da352ea555883b0be8bbd3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 11 Nov 2005 10:46:31 +0000 Subject: r11675: a more general way of getting rid of compiler warnings and errors metze (This used to be commit 653f5ccd61f2555bbd49b81c5cc660962b31aa68) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index deadd1794f..7e25de99a8 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -70,7 +70,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SBVAL(req->out.hdr, SMB2_HDR_UID, (uint64_t)0); + SBVAL(req->out.hdr, SMB2_HDR_UID, 0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); return req; -- cgit From 2e753f851885930000eadbd4b69660d85124c716 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 12:37:16 +0000 Subject: r11679: opening/creating files in SMB2 now works. Lots of unknown parameters in the call tho. (This used to be commit 548fbd86b3b114493943b50669bdcba2f4ed87f2) --- source4/libcli/smb2/request.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 7e25de99a8..108cf0ca55 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -76,6 +76,22 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, return req; } +/* + initialise a smb2 request for tree operations +*/ +struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, + uint16_t opcode, uint32_t body_size) +{ + struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, + body_size); + if (req == NULL) return NULL; + + SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); + SIVAL(req->out.hdr, SMB2_HDR_TID, tree->tid); + + return req; +} + /* destroy a request structure and return final status */ NTSTATUS smb2_request_destroy(struct smb2_request *req) { -- cgit From 2b7ee2ceee0a1b2be596a602997908f72a3af14d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 01:08:43 +0000 Subject: r11692: added a full composite (async) spnego session setup for SMB2. This simplies the torture code a lot. (This used to be commit 7bf1046fbb7fd83fecb2fa645628ba9a17aab037) --- source4/libcli/smb2/request.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 108cf0ca55..ccffef9b88 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -39,6 +39,8 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, req->state = SMB2_REQUEST_INIT; req->transport = transport; + req->session = NULL; + req->tree = NULL; req->seqnum = transport->seqnum++; req->status = NT_STATUS_OK; req->async.fn = NULL; @@ -88,6 +90,8 @@ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); SIVAL(req->out.hdr, SMB2_HDR_TID, tree->tid); + req->session = tree->session; + req->tree = tree; return req; } -- cgit From 67a85b3f1bca7e0590ae97d07a6ef32c418e64d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 12 Nov 2005 07:48:56 +0000 Subject: r11697: - added a generic SMB2 getinfo call - added a SMB2-SCANGETINFO test for scanning for available info levels - added names for the info levels I recognise to smb2.h (This used to be commit fe5986067e2aaca039d70393ccc8761434f18fe6) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index ccffef9b88..4b95d141a3 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -188,7 +188,7 @@ DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) } /* - pull a ofs/length/blob triple into a data blob + pull a ofs/length/blob triple from a data blob the ptr points to the start of the offset/length pair */ NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *blob) -- cgit From c6395a30b057c87de8ce410d5ea5ebe2e017093d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Nov 2005 05:09:26 +0000 Subject: r11715: added SMB2 read and write requests (This used to be commit d3556cbfa38447d2d385b697c1855b3c13d42744) --- source4/libcli/smb2/request.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 4b95d141a3..a06121df05 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" #include "include/dlinklist.h" #include "lib/events/events.h" @@ -261,3 +262,14 @@ NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) blob->length = size; return NT_STATUS_OK; } + + +/* + put a file handle into a buffer +*/ +void smb2_put_handle(uint8_t *data, struct smb2_handle h) +{ + SBVAL(data, 0, h.data[0]); + SBVAL(data, 8, h.data[1]); +} + -- cgit From 61317df8aab2fe2fd47baba8a137566df7b23395 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 Nov 2005 07:06:16 +0000 Subject: r11721: Fix warnings (This used to be commit d760583e388157ff25e317da06c57e5a42f171bd) --- source4/libcli/smb2/request.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index a06121df05..4e40b1884a 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -267,9 +267,9 @@ NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) /* put a file handle into a buffer */ -void smb2_put_handle(uint8_t *data, struct smb2_handle h) +void smb2_put_handle(uint8_t *data, struct smb2_handle *h) { - SBVAL(data, 0, h.data[0]); - SBVAL(data, 8, h.data[1]); + SBVAL(data, 0, h->data[0]); + SBVAL(data, 8, h->data[1]); } -- cgit From de5d71aebe4e415fcebbfacb852b190498cbf7bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 Nov 2005 12:31:02 +0000 Subject: r11722: make the smb2_push/pull functions take a smb2_request_buffer and the pull ones also a TALLOC_CTX, then we can reuse this functions in the server later metze (This used to be commit 9b616516cae269f0870e9b9a9cecd8ee3f0a9095) --- source4/libcli/smb2/request.c | 59 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 32 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 4e40b1884a..457b7a4531 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -150,60 +150,57 @@ BOOL smb2_request_is_error(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob_in(struct smb2_request *req, const uint8_t *ptr, uint_t size) +BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) { /* be careful with wraparound! */ - if (ptr < req->in.body || - ptr >= req->in.body + req->in.body_size || - size > req->in.body_size || - ptr + size > req->in.body + req->in.body_size) { + if (ptr < buf->body || + ptr >= buf->body + buf->body_size || + size > buf->body_size || + ptr + size > buf->body + buf->body_size) { return True; } return False; } /* - check if a range in the outgoing body is out of bounds + pull a data blob from the body of a reply */ -BOOL smb2_oob_out(struct smb2_request *req, const uint8_t *ptr, uint_t size) +DATA_BLOB smb2_pull_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, uint_t size) { - /* be careful with wraparound! */ - if (ptr < req->out.body || - ptr >= req->out.body + req->out.body_size || - size > req->out.body_size || - ptr + size > req->out.body + req->out.body_size) { - return True; + if (smb2_oob(buf, ptr, size)) { + return data_blob(NULL, 0); } - return False; + return data_blob_talloc(mem_ctx, ptr, size); } /* - pull a data blob from the body of a reply + push a data blob from the body of a reply */ -DATA_BLOB smb2_pull_blob(struct smb2_request *req, uint8_t *ptr, uint_t size) +NTSTATUS smb2_push_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) { - if (smb2_oob_in(req, ptr, size)) { - return data_blob(NULL, 0); + if (smb2_oob(buf, ptr, blob.length)) { + return NT_STATUS_BUFFER_TOO_SMALL; } - return data_blob_talloc(req, ptr, size); + memcpy(ptr, blob.data, blob.length); + return NT_STATUS_OK; } /* pull a ofs/length/blob triple from a data blob the ptr points to the start of the offset/length pair */ -NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *blob) +NTSTATUS smb2_pull_ofs_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { uint16_t ofs, size; - if (smb2_oob_in(req, ptr, 4)) { + if (smb2_oob(buf, ptr, 4)) { return NT_STATUS_BUFFER_TOO_SMALL; } ofs = SVAL(ptr, 0); size = SVAL(ptr, 2); - if (smb2_oob_in(req, req->in.hdr + ofs, size)) { + if (smb2_oob(buf, buf->hdr + ofs, size)) { return NT_STATUS_BUFFER_TOO_SMALL; } - *blob = data_blob_talloc(req, req->in.hdr+ofs, size); + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); NT_STATUS_HAVE_NO_MEMORY(blob->data); return NT_STATUS_OK; } @@ -215,12 +212,12 @@ NTSTATUS smb2_pull_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB *b NOTE: assumes blob goes immediately after the offset/length pair. Needs to be generalised */ -NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_push_ofs_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) { - if (smb2_oob_out(req, ptr, 4+blob.length)) { + if (smb2_oob(buf, ptr, 4+blob.length)) { return NT_STATUS_BUFFER_TOO_SMALL; } - SSVAL(ptr, 0, 4 + (ptr - req->out.hdr)); + SSVAL(ptr, 0, 4 + (ptr - buf->hdr)); SSVAL(ptr, 2, blob.length); memcpy(ptr+4, blob.data, blob.length); return NT_STATUS_OK; @@ -229,16 +226,16 @@ NTSTATUS smb2_push_ofs_blob(struct smb2_request *req, uint8_t *ptr, DATA_BLOB bl /* pull a string in a ofs/length/blob format */ -NTSTATUS smb2_pull_ofs_string(struct smb2_request *req, uint8_t *ptr, - const char **str) +NTSTATUS smb2_pull_ofs_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, + uint8_t *ptr, const char **str) { DATA_BLOB blob; NTSTATUS status; ssize_t size; void *vstr; - status = smb2_pull_ofs_blob(req, ptr, &blob); + status = smb2_pull_ofs_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); - size = convert_string_talloc(req, CH_UTF16, CH_UNIX, + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); (*str) = vstr; @@ -263,7 +260,6 @@ NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) return NT_STATUS_OK; } - /* put a file handle into a buffer */ @@ -272,4 +268,3 @@ void smb2_put_handle(uint8_t *data, struct smb2_handle *h) SBVAL(data, 0, h->data[0]); SBVAL(data, 8, h->data[1]); } - -- cgit From e9eb56068573d89f8ce45f08220ca870b3daa669 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 11:01:15 +0000 Subject: r11741: - the buffer code (first 2 bytes in the SMB2 body) seem to be the length of the fixed body part, and +1 if there's a dynamic part - there're 3 types of dynamic blobs with uint16_t offset/uint16_t size with uint16_t offset/uint32_t size with uint32_t offset/uint32_t size /* aligned to 8 bytes */ - strings are transmitted in UTF-16 with no termination and packet into a uint16/uint16 blob metze (This used to be commit 79103c51e5c752fbdb4d25a0047b65002828df89) --- source4/libcli/smb2/request.c | 290 +++++++++++++++++++++++++++++++++++------- 1 file changed, 246 insertions(+), 44 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 457b7a4531..bb8ff06e2d 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -3,7 +3,8 @@ SMB2 client request handling - Copyright (C) Andrew Tridgell 2005 + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Stefan Metzmacher 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,8 +31,8 @@ /* initialise a smb2 request */ -struct smb2_request *smb2_request_init(struct smb2_transport *transport, - uint16_t opcode, uint32_t body_size) +struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode, + uint16_t body_fixed_size, uint32_t body_dynamic_size) { struct smb2_request *req; @@ -49,18 +50,18 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, ZERO_STRUCT(req->in); - req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_size; + req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+body_dynamic_size; req->out.buffer = talloc_size(req, req->out.allocated); if (req->out.buffer == NULL) { talloc_free(req); return NULL; } - req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE + body_size; + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+(body_dynamic_size?1:0); req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.body = req->out.hdr + SMB2_HDR_BODY; - req->out.body_size = body_size; - req->out.ptr = req->out.body; + req->out.body_size = body_fixed_size; + req->out.dynamic = (body_dynamic_size ? req->out.body + body_fixed_size : NULL); SIVAL(req->out.hdr, 0, SMB2_MAGIC); SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); @@ -76,17 +77,28 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, SBVAL(req->out.hdr, SMB2_HDR_UID, 0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); + /* set the length of the fixed body part and +1 if there's a dynamic part also */ + SSVAL(req->out.body, 0, body_fixed_size + (body_dynamic_size?1:0)); + + /* + * if we have a dynamic part, make sure the first byte + * which is always be part of the packet is initialized + */ + if (body_dynamic_size) { + SCVAL(req->out.dynamic, 0, 0); + } + return req; } /* initialise a smb2 request for tree operations */ -struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, - uint16_t opcode, uint32_t body_size) +struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opcode, + uint16_t body_fixed_size, uint32_t body_dynamic_size) { struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, - body_size); + body_fixed_size, body_dynamic_size); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); @@ -162,41 +174,123 @@ BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) return False; } +static size_t smb2_padding_size(uint32_t offset, size_t n) +{ + if ((offset & (n-1)) == 0) return 0; + return n - (offset & (n-1)); +} + +static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t n) +{ + size_t dynamic_ofs; + uint8_t *buffer_ptr; + + /* a packet size should be limited a bit */ + if (n >= 0x00FFFFFF) return NT_STATUS_MARSHALL_OVERFLOW; + + if (n <= buf->allocated) return NT_STATUS_OK; + + dynamic_ofs = buf->dynamic - buf->buffer; + + buffer_ptr = talloc_realloc_size(buf, buf->buffer, n); + 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; + + return NT_STATUS_OK; +} + /* - pull a data blob from the body of a reply + pull a uint16_t ofs/ uint16_t length/blob triple from a data blob + the ptr points to the start of the offset/length pair */ -DATA_BLOB smb2_pull_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, uint_t size) +NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { - if (smb2_oob(buf, ptr, size)) { - return data_blob(NULL, 0); + uint16_t ofs, size; + if (smb2_oob(buf, ptr, 4)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + ofs = SVAL(ptr, 0); + size = SVAL(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; } - return data_blob_talloc(mem_ctx, ptr, size); + *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size); + NT_STATUS_HAVE_NO_MEMORY(blob->data); + return NT_STATUS_OK; } /* - push a data blob from the body of a reply + 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 */ -NTSTATUS smb2_push_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) { - if (smb2_oob(buf, ptr, blob.length)) { + NTSTATUS status; + size_t offset; + size_t padding_length; + + if (!buf->dynamic) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* we have only 16 bit for the size */ + if (blob.length > 0xFFFF) { return NT_STATUS_BUFFER_TOO_SMALL; } - memcpy(ptr, blob.data, blob.length); + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 4)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 2); + offset += padding_length; + + SSVAL(ptr, 0, offset); + SSVAL(ptr, 2, blob.length); + + status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + buf->size = buf->dynamic - buf->buffer; + return NT_STATUS_OK; } /* - pull a ofs/length/blob triple from a data blob + 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_ofs_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) +NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { - uint16_t ofs, size; - if (smb2_oob(buf, ptr, 4)) { + uint16_t ofs; + uint32_t size; + + if (smb2_oob(buf, ptr, 6)) { return NT_STATUS_BUFFER_TOO_SMALL; } ofs = SVAL(ptr, 0); - size = SVAL(ptr, 2); + 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; } @@ -206,35 +300,124 @@ NTSTATUS smb2_pull_ofs_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx } /* - push a ofs/length/blob triple into a data blob + 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 +*/ +NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +{ + NTSTATUS status; + size_t offset; + size_t padding_length; - NOTE: assumes blob goes immediately after the offset/length pair. Needs - to be generalised + if (!buf->dynamic) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 6)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 2); + offset += padding_length; + + SSVAL(ptr, 0, offset); + SIVAL(ptr, 2, blob.length); + + status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + buf->size = buf->dynamic - buf->buffer; + + 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_push_ofs_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob) { - if (smb2_oob(buf, ptr, 4+blob.length)) { + uint32_t ofs, size; + if (smb2_oob(buf, ptr, 8)) { return NT_STATUS_BUFFER_TOO_SMALL; } - SSVAL(ptr, 0, 4 + (ptr - buf->hdr)); - SSVAL(ptr, 2, blob.length); - memcpy(ptr+4, blob.data, blob.length); + 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; } /* - pull a string in a ofs/length/blob format + 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 */ -NTSTATUS smb2_pull_ofs_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, - uint8_t *ptr, const char **str) +NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DATA_BLOB blob) +{ + NTSTATUS status; + size_t offset; + size_t padding_length; + + if (!buf->dynamic) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 8); + offset += padding_length; + + SIVAL(ptr, 0, offset); + SIVAL(ptr, 4, blob.length); + + status = smb2_grow_buffer(buf, NBT_HDR_SIZE + offset + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + buf->size = buf->dynamic - buf->buffer; + + return NT_STATUS_OK; +} + +/* + pull a string in a uint16_t ofs/ uint16_t length/blob format + UTF-16 without termination +*/ +NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, + uint8_t *ptr, const char **str) { DATA_BLOB blob; NTSTATUS status; ssize_t size; void *vstr; - status = smb2_pull_ofs_blob(buf, mem_ctx, ptr, &blob); + + status = smb2_pull_o16s16_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); @@ -246,25 +429,44 @@ NTSTATUS smb2_pull_ofs_string(struct smb2_request_buffer *buf, TALLOC_CTX *mem_c } /* - create a UTF16 string in a blob from a char* + push a string in a uint16_t ofs/ uint16_t length/blob format + UTF-16 without termination */ -NTSTATUS smb2_string_blob(TALLOC_CTX *mem_ctx, const char *str, DATA_BLOB *blob) +NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, + uint8_t *ptr, const char *str) { + DATA_BLOB blob; + NTSTATUS status; ssize_t size; - size = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, - str, strlen(str), (void **)&blob->data); + + size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, + str, strlen(str), (void **)&blob.data); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; } - blob->length = size; - return NT_STATUS_OK; + blob.length = size; + + status = smb2_push_o16s16_blob(buf, ptr, blob); + data_blob_free(&blob); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; } /* - put a file handle into a buffer + push a file handle into a buffer */ -void smb2_put_handle(uint8_t *data, struct smb2_handle *h) +void smb2_push_handle(uint8_t *data, struct smb2_handle *h) { SBVAL(data, 0, h->data[0]); SBVAL(data, 8, h->data[1]); } + +/* + pull a file handle from a buffer +*/ +void smb2_pull_handle(uint8_t *ptr, struct smb2_handle *h) +{ + h->data[0] = BVAL(ptr, 0); + h->data[1] = BVAL(ptr, 8); +} -- cgit From ed069c1771843e0de0489bad7e0959c34fd260c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 13:34:56 +0000 Subject: r11742: fix pushing of 0 length blobs metze (This used to be commit e985ab117c6afb2ea575b55bfaa97b0795ec5745) --- source4/libcli/smb2/request.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index bb8ff06e2d..a9a7e6b71f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -252,6 +252,12 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA return NT_STATUS_BUFFER_TOO_SMALL; } + if (blob.length == 0) { + SSVAL(ptr, 0, 0); + SSVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; @@ -318,6 +324,12 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA return NT_STATUS_BUFFER_TOO_SMALL; } + if (blob.length == 0) { + SSVAL(ptr, 0, 0); + SIVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; @@ -382,6 +394,12 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA return NT_STATUS_BUFFER_TOO_SMALL; } + if (blob.length == 0) { + SIVAL(ptr, 0, 0); + SIVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 8); offset += padding_length; -- cgit From fb90bebab64c8eb02dc190d829b44eb592230302 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Nov 2005 15:47:44 +0000 Subject: r11743: - push the length at the correct offset - let us push empty strings metze (This used to be commit 17c4b6298d757f2e53fe764608504bf737005cbe) --- source4/libcli/smb2/request.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index a9a7e6b71f..bc278897a5 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -254,7 +254,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA if (blob.length == 0) { SSVAL(ptr, 0, 0); - SSVAL(ptr, 4, 0); + SSVAL(ptr, 2, 0); return NT_STATUS_OK; } @@ -326,7 +326,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, uint8_t *ptr, DA if (blob.length == 0) { SSVAL(ptr, 0, 0); - SIVAL(ptr, 4, 0); + SIVAL(ptr, 2, 0); return NT_STATUS_OK; } @@ -457,6 +457,13 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, 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; + } + size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { -- cgit From 1c71db99aa78f489a66d58e1116884c23b0c10f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 00:47:50 +0000 Subject: r11751: fixed the req->out.size calculation (it needs to be the complete request size, including dynamic portion) (This used to be commit 1b5cdf92cc7793b08d7c46ef00d4ff696b31c15e) --- source4/libcli/smb2/request.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index bc278897a5..3e80115e47 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -50,14 +50,16 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ ZERO_STRUCT(req->in); - req->out.allocated = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+body_dynamic_size; + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+ + body_fixed_size+body_dynamic_size; + + req->out.allocated = req->out.size; req->out.buffer = talloc_size(req, req->out.allocated); if (req->out.buffer == NULL) { talloc_free(req); return NULL; } - req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size+(body_dynamic_size?1:0); req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.body = req->out.hdr + SMB2_HDR_BODY; req->out.body_size = body_fixed_size; -- cgit From fe996e8ac687dbf5b5cfdd795f14aed89663f06d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Nov 2005 03:32:38 +0000 Subject: r11754: make the SMB2 blob push routines take offsets, so they fit better with the rest of the packet construction code (This used to be commit 387ec2b17ff30a1c040b460b498c8fa7d8770593) --- source4/libcli/smb2/request.c | 172 ++++++++++++++++++++++-------------------- 1 file changed, 92 insertions(+), 80 deletions(-) (limited to 'source4/libcli/smb2/request.c') 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; } /* -- cgit From 2ff21db535897eb2a4eae428b7465337bd7cfdd1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 06:28:15 +0000 Subject: r11771: - split out the setinfo blob construction in the libcli/raw code - added a smb2_setinfo call - added smb2_setinfo_file*() calls (This used to be commit da0b6fb93683331134ef2f4abd8707e0c3fc6d9d) --- source4/libcli/smb2/request.c | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1a98ba9987..41e2ad74e2 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -390,6 +390,57 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, return NT_STATUS_OK; } + +/* + push a uint32_t length/ uint32_t ofs/blob triple into a data blob + the ofs points to the start of the length/offset pair, and is relative + to the body start +*/ +NTSTATUS smb2_push_s32o32_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 == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if there're enough room for ofs and size */ + if (smb2_oob(buf, ptr, 8)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + if (blob.length == 0) { + SIVAL(ptr, 0, 0); + SIVAL(ptr, 4, 0); + return NT_STATUS_OK; + } + + offset = buf->dynamic - buf->hdr; + padding_length = smb2_padding_size(offset, 8); + offset += padding_length; + + SIVAL(ptr, 0, blob.length); + SIVAL(ptr, 4, offset); + + status = smb2_grow_buffer(buf, padding_length + blob.length); + NT_STATUS_NOT_OK_RETURN(status); + + memset(buf->dynamic, 0, padding_length); + buf->dynamic += padding_length; + + memcpy(buf->dynamic, blob.data, blob.length); + buf->dynamic += blob.length; + + 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 -- cgit From c8c7fb2492d3f19939df67f98e4ea6ad423274da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 09:25:25 +0000 Subject: r11775: added support for creating files on SMB2 with initial EA lists and an ACL (This used to be commit ff197092988cee64742f83df23c43ae664a196f9) --- source4/libcli/smb2/request.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 41e2ad74e2..3f09c9aeec 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -160,6 +160,12 @@ BOOL smb2_request_is_error(struct smb2_request *req) return NT_STATUS_IS_ERR(req->status); } +/* Return true if the last packet was OK */ +BOOL smb2_request_is_ok(struct smb2_request *req) +{ + return NT_STATUS_IS_OK(req->status); +} + /* check if a range in the reply body is out of bounds */ -- cgit From d5f37ecf94e2b63511102b3fd34c0e7bcd8d7879 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Nov 2005 11:45:24 +0000 Subject: r11780: it turns out that the MxAc tag isn't a security descriptor, its a request that the server return its own MxAc blob which contains the maximum allowed access_mask for the returned file handle (This used to be commit c0288aa8cd46ca384074f89430c226d725c39475) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 3f09c9aeec..03c0ed4350 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -181,7 +181,7 @@ BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) return False; } -static size_t smb2_padding_size(uint32_t offset, size_t n) +size_t smb2_padding_size(uint32_t offset, size_t n) { if ((offset & (n-1)) == 0) return 0; return n - (offset & (n-1)); -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/libcli/smb2/request.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 03c0ed4350..9fe9ad12fa 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -24,7 +24,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" -#include "libcli/smb2/smb2_calls.h" #include "include/dlinklist.h" #include "lib/events/events.h" -- cgit From baa62e5637b24bccbfe41fc5ec8e4eafc0b92191 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Mar 2006 05:52:45 +0000 Subject: r14434: use the right enum type (This used to be commit 507def57cb83a3e12a3c8d60eb833fe47e9ec9e8) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 9fe9ad12fa..1f3e2f54e4 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -124,7 +124,7 @@ NTSTATUS smb2_request_destroy(struct smb2_request *req) DLIST_REMOVE(req->transport->pending_recv, req); } - if (req->state == SMBCLI_REQUEST_ERROR && + if (req->state == SMB2_REQUEST_ERROR && NT_STATUS_IS_OK(req->status)) { req->status = NT_STATUS_INTERNAL_ERROR; } -- cgit From 0eddf14b307e905663b95296aa695a10d3fb90f7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 09:36:09 +0000 Subject: r15191: Avoid uint_t as it's not standard. (This used to be commit 7af59357b94e3819415b3a9257be0ced745ce130) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1f3e2f54e4..2476270d49 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -168,7 +168,7 @@ BOOL smb2_request_is_ok(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, uint_t size) +BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) { /* be careful with wraparound! */ if (ptr < buf->body || -- cgit From dc86ab3e454d7219608d01879145dec5609acaa3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 11 May 2006 10:47:37 +0000 Subject: r15532: add a BOOL body_dynamic_present, because the body_dynamic_size can be 0 also if the dynamic flag should be set metze (This used to be commit 7829100e1ee79f4f5d24004af221288e19c09b3e) --- source4/libcli/smb2/request.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2476270d49..136b81e977 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -31,10 +31,19 @@ initialise a smb2 request */ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode, - uint16_t body_fixed_size, uint32_t body_dynamic_size) + uint16_t body_fixed_size, BOOL body_dynamic_present, + uint32_t body_dynamic_size) { struct smb2_request *req; + if (body_dynamic_present) { + if (body_dynamic_size == 0) { + body_dynamic_size = 1; + } + } else { + body_dynamic_size = 0; + } + req = talloc(transport, struct smb2_request); if (req == NULL) return NULL; @@ -95,10 +104,12 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ initialise a smb2 request for tree operations */ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opcode, - uint16_t body_fixed_size, uint32_t body_dynamic_size) + uint16_t body_fixed_size, BOOL body_dynamic_present, + uint32_t body_dynamic_size) { struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, - body_fixed_size, body_dynamic_size); + body_fixed_size, body_dynamic_present, + body_dynamic_size); if (req == NULL) return NULL; SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); -- cgit From 6885c6253e81fca9633c9396a5669fc7fe27ef7d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 11:50:10 +0000 Subject: r15744: convert_string_talloc() handles src_len == 0 as error but it's valid in this case metze (This used to be commit 92c19b1ba4e89bd1e973e084b254087c98ceac18) --- source4/libcli/smb2/request.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 136b81e977..e631375a52 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -522,6 +522,14 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me status = smb2_pull_o16s16_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); + if (blob.length == 0) { + char *s; + s = talloc_strdup(mem_ctx, ""); + NT_STATUS_HAVE_NO_MEMORY(s); + *str = s; + return NT_STATUS_OK; + } + size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); -- cgit From 1911475976de4a54787ac263eb4b15cb3db5eea3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 10:13:49 +0000 Subject: r15770: when there's a dynamic body, we need to send the first byte even if the dynamic size if 0 metze (This used to be commit c7e8e79d75fd53fa37e9220e5bc9cac7ab574ff6) --- source4/libcli/smb2/request.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index e631375a52..43445575f0 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -94,6 +94,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ * which is always be part of the packet is initialized */ if (body_dynamic_size) { + req->out.size += 1; SCVAL(req->out.dynamic, 0, 0); } -- cgit From 7dc22bf3e019d2f68e52cbeab8eb3ad14d903cff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Jun 2006 17:16:14 +0000 Subject: r16566: add pull function for a site32/offset32 blob metze (This used to be commit 81702c36c28e9e32860c5d91887d2ad2121ce306) --- source4/libcli/smb2/request.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 43445575f0..2f1117cf30 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -508,6 +508,30 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ return NT_STATUS_OK; } +/* + pull a uint32_t length/ uint32_t ofs/blob triple from a data blob + the ptr points to the start of the offset/length pair +*/ +NTSTATUS smb2_pull_s32o32_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; + } + size = IVAL(ptr, 0); + ofs = 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; +} + /* pull a string in a uint16_t ofs/ uint16_t length/blob format UTF-16 without termination -- cgit From bd0dcebe36ea926e2ad9a32a6eb103a88325c930 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Jun 2006 23:11:07 +0000 Subject: r16705: fix a bug found by valgrind... as we setup the 1 padding byte for non present dynamic part, we need to overwrite it when we're getting a real dynamic part, so we need to remove the buf->size +=1 when we do the first push to the dynamic part (when buf->dynamic is still but->body + buf->body_fixed) metze (This used to be commit f309209629ad1b63a76fc06163a3eeb07dce4c86) --- source4/libcli/smb2/request.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2f1117cf30..60fd6ca3ae 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -69,6 +69,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.body = req->out.hdr + SMB2_HDR_BODY; + req->out.body_fixed= body_fixed_size; req->out.body_size = body_fixed_size; req->out.dynamic = (body_dynamic_size ? req->out.body + body_fixed_size : NULL); @@ -198,6 +199,14 @@ size_t smb2_padding_size(uint32_t offset, size_t n) return n - (offset & (n-1)); } +static size_t smb2_padding_fix(struct smb2_request_buffer *buf) +{ + if (buf->dynamic == (buf->body + buf->body_fixed)) { + return 1; + } + return 0; +} + /* grow a SMB2 buffer by the specified amount */ @@ -261,6 +270,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -286,6 +296,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SSVAL(ptr, 0, offset); SSVAL(ptr, 2, blob.length); @@ -299,8 +310,8 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } @@ -317,6 +328,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -337,6 +349,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 2); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SSVAL(ptr, 0, offset); SIVAL(ptr, 2, blob.length); @@ -350,8 +363,8 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } @@ -368,6 +381,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -388,6 +402,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 8); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SIVAL(ptr, 0, offset); SIVAL(ptr, 4, blob.length); @@ -401,8 +416,8 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } @@ -419,6 +434,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, NTSTATUS status; size_t offset; size_t padding_length; + size_t padding_fix; uint8_t *ptr = buf->body+ofs; if (buf->dynamic == NULL) { @@ -439,6 +455,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, offset = buf->dynamic - buf->hdr; padding_length = smb2_padding_size(offset, 8); offset += padding_length; + padding_fix = smb2_padding_fix(buf); SIVAL(ptr, 0, blob.length); SIVAL(ptr, 4, offset); @@ -452,8 +469,8 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, memcpy(buf->dynamic, blob.data, blob.length); buf->dynamic += blob.length; - buf->size += blob.length + padding_length; - buf->body_size += blob.length + padding_length; + buf->size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length - padding_fix; return NT_STATUS_OK; } -- cgit From 6acd9aed93b09b74e53a3b854085c6c8fab41819 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 1 Jul 2006 14:14:11 +0000 Subject: r16734: the 2 bytes after the opcode and before the flags, is no padding... the following patch is needed for vista beta2 to connect to samba4 metze (This used to be commit 58baae8fc463cd2c4e4ce532c153ad80313b03eb) --- source4/libcli/smb2/request.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 60fd6ca3ae..016c885675 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -78,9 +78,9 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); - SSVAL(req->out.hdr, SMB2_HDR_PAD2, 0); + SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1,0); SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN, 0); + SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN2,0); SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); -- cgit From 7c810db7da89c992a7886757b7aec68eef0cf3eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Jul 2006 08:34:35 +0000 Subject: r16873: - grow the buffer with the correct size, we maybe had 1 byte preallocated - body_size doesn't contain the preallocated byte so don't remove it metze (This used to be commit 3cf50e26b7dc11d85c46ef81a36c74acf97085c0) --- source4/libcli/smb2/request.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 016c885675..c37325fc34 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -301,7 +301,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, SSVAL(ptr, 0, offset); SSVAL(ptr, 2, blob.length); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -311,7 +311,7 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } @@ -354,7 +354,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, SSVAL(ptr, 0, offset); SIVAL(ptr, 2, blob.length); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -364,7 +364,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } @@ -407,7 +407,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, SIVAL(ptr, 0, offset); SIVAL(ptr, 4, blob.length); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -417,7 +417,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } @@ -460,7 +460,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, SIVAL(ptr, 0, blob.length); SIVAL(ptr, 4, offset); - status = smb2_grow_buffer(buf, padding_length + blob.length); + status = smb2_grow_buffer(buf, blob.length + padding_length - padding_fix); NT_STATUS_NOT_OK_RETURN(status); memset(buf->dynamic, 0, padding_length); @@ -470,7 +470,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, buf->dynamic += blob.length; buf->size += blob.length + padding_length - padding_fix; - buf->body_size += blob.length + padding_length - padding_fix; + buf->body_size += blob.length + padding_length; return NT_STATUS_OK; } -- cgit From a5bafffd66f511375dda4c974e6a1f152fc7aa16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 Jul 2006 09:36:52 +0000 Subject: r17083: - implement SMB2 Cancel in the client - the 0xffffffffffffffff seqnum is reserved for SMB2 Break (oplock breaks) so don't use it in a request. we should someday try to test this... metze (This used to be commit 730cdc4475822e28cb400116641294a7f98ad0b5) --- source4/libcli/smb2/request.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index c37325fc34..72b9ade3e2 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -35,6 +35,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ uint32_t body_dynamic_size) { struct smb2_request *req; + uint64_t seqnum; if (body_dynamic_present) { if (body_dynamic_size == 0) { @@ -47,17 +48,23 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req = talloc(transport, struct smb2_request); if (req == NULL) return NULL; + seqnum = transport->seqnum++; + if (seqnum == UINT64_MAX) { + seqnum = transport->seqnum++; + } + req->state = SMB2_REQUEST_INIT; req->transport = transport; req->session = NULL; req->tree = NULL; - req->seqnum = transport->seqnum++; + req->seqnum = seqnum; req->status = NT_STATUS_OK; req->async.fn = NULL; req->next = req->prev = NULL; + ZERO_STRUCT(req->cancel); ZERO_STRUCT(req->in); - + req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size; req->out.allocated = req->out.size + body_dynamic_size; -- cgit From 0329d755a7611ba3897fc1ee9bdce410cc33d7f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Aug 2006 11:29:34 +0000 Subject: r17930: Merge noinclude branch: * Move dlinklist.h, smb.h to subsystem-specific directories * Clean up ads.h and move what is left of it to dsdb/ (only place where it's used) (This used to be commit f7afa1cb77f3cfa7020b57de12e6003db7cfcc42) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 72b9ade3e2..87c4dd78e1 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -24,7 +24,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb2/smb2.h" -#include "include/dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" /* -- cgit From bf62b6642c77e14142cdb724dc99dd3f8bfd89ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 18:02:49 +0000 Subject: r22866: handle incoming chained smb2 requests in our server code to let the windows explorer in longhorn beta3 work. metze (This used to be commit 2390c9f24daccec917608cac0870890cdc73cb1c) --- source4/libcli/smb2/request.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 87c4dd78e1..ef024d53f8 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -80,18 +80,18 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req->out.body_size = body_fixed_size; req->out.dynamic = (body_dynamic_size ? req->out.body + body_fixed_size : NULL); - SIVAL(req->out.hdr, 0, SMB2_MAGIC); - SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); - SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); - SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1,0); - SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->out.hdr, SMB2_HDR_UNKNOWN2,0); - SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); - SIVAL(req->out.hdr, SMB2_HDR_PID, 0); - SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SBVAL(req->out.hdr, SMB2_HDR_UID, 0); + SIVAL(req->out.hdr, 0, SMB2_MAGIC); + SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); + SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); + SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); + SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); + SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0); + SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); + SIVAL(req->out.hdr, SMB2_HDR_CHAIN_OFFSET, 0); + SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); + SIVAL(req->out.hdr, SMB2_HDR_PID, 0); + SIVAL(req->out.hdr, SMB2_HDR_TID, 0); + SBVAL(req->out.hdr, SMB2_HDR_UID, 0); memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); /* set the length of the fixed body part and +1 if there's a dynamic part also */ -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/libcli/smb2/request.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index ef024d53f8..d857fc8c5b 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 6cf69fee189857ae6f85cd3f81a6a58364839942 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 13:31:15 +0000 Subject: r24994: Fix some C++ warnings. (This used to be commit 925abf74fa1ed5ae726bae8781ec549302786b39) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index d857fc8c5b..392fec1cb9 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -229,7 +229,7 @@ static NTSTATUS smb2_grow_buffer(struct smb2_request_buffer *buf, size_t increas dynamic_ofs = buf->dynamic - buf->buffer; - buffer_ptr = talloc_realloc_size(buf, buf->buffer, newsize); + buffer_ptr = talloc_realloc(buf, buf->buffer, uint8_t, newsize); NT_STATUS_HAVE_NO_MEMORY(buffer_ptr); buf->buffer = buffer_ptr; -- cgit From cd962355abad90a2161765a7be7d26e63572cab7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 Sep 2007 15:08:14 +0000 Subject: r25000: Fix some more C++ compatibility warnings. (This used to be commit 08bb1ef643ab906f1645cf6f32763dc73b1884e4) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 392fec1cb9..545f3c8353 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -67,7 +67,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ req->out.size = SMB2_HDR_BODY+NBT_HDR_SIZE+body_fixed_size; req->out.allocated = req->out.size + body_dynamic_size; - req->out.buffer = talloc_size(req, req->out.allocated); + req->out.buffer = talloc_array(req, uint8_t, req->out.allocated); if (req->out.buffer == NULL) { talloc_free(req); return NULL; -- cgit From dccf3f99e45137b6cd18c1de1c79808ad67130d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 13:27:14 +0000 Subject: r25027: Fix more warnings. (This used to be commit 5085c53fcfade614e83d21fc2c1a5bc43bb2a729) --- source4/libcli/smb2/request.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 545f3c8353..cca4f861de 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -25,6 +25,7 @@ #include "libcli/smb2/smb2.h" #include "lib/util/dlinklist.h" #include "lib/events/events.h" +#include "libcli/smb2/smb2_calls.h" /* initialise a smb2 request -- cgit From 98b57d5eb61094a9c88e2f7d90d3e21b7e74e9d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 16:46:30 +0000 Subject: r25035: Fix some more warnings, use service pointer rather than service number in more places. (This used to be commit df9cebcb97e20564359097148665bd519f31bc6f) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index cca4f861de..2d2c8252a1 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -582,7 +582,7 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); - (*str) = vstr; + (*str) = (char *)vstr; if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; } -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/libcli/smb2/request.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2d2c8252a1..576e2b6fcf 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -31,7 +31,7 @@ initialise a smb2 request */ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_t opcode, - uint16_t body_fixed_size, BOOL body_dynamic_present, + uint16_t body_fixed_size, bool body_dynamic_present, uint32_t body_dynamic_size) { struct smb2_request *req; @@ -113,7 +113,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ initialise a smb2 request for tree operations */ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opcode, - uint16_t body_fixed_size, BOOL body_dynamic_present, + uint16_t body_fixed_size, bool body_dynamic_present, uint32_t body_dynamic_size) { struct smb2_request *req = smb2_request_init(tree->session->transport, opcode, @@ -157,16 +157,16 @@ NTSTATUS smb2_request_destroy(struct smb2_request *req) /* receive a response to a packet */ -BOOL smb2_request_receive(struct smb2_request *req) +bool smb2_request_receive(struct smb2_request *req) { /* req can be NULL when a send has failed. This eliminates lots of NULL checks in each module */ - if (!req) return False; + if (!req) return false; /* keep receiving packets until this one is replied to */ while (req->state <= SMB2_REQUEST_RECV) { if (event_loop_once(req->transport->socket->event.ctx) != 0) { - return False; + return false; } } @@ -174,13 +174,13 @@ BOOL smb2_request_receive(struct smb2_request *req) } /* Return true if the last packet was in error */ -BOOL smb2_request_is_error(struct smb2_request *req) +bool smb2_request_is_error(struct smb2_request *req) { return NT_STATUS_IS_ERR(req->status); } /* Return true if the last packet was OK */ -BOOL smb2_request_is_ok(struct smb2_request *req) +bool smb2_request_is_ok(struct smb2_request *req) { return NT_STATUS_IS_OK(req->status); } @@ -188,16 +188,16 @@ BOOL smb2_request_is_ok(struct smb2_request *req) /* check if a range in the reply body is out of bounds */ -BOOL smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) +bool smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) { /* be careful with wraparound! */ if (ptr < buf->body || ptr >= buf->body + buf->body_size || size > buf->body_size || ptr + size > buf->body + buf->body_size) { - return True; + return true; } - return False; + return false; } size_t smb2_padding_size(uint32_t offset, size_t n) -- cgit From 39ee38d9c1aabf4db065b433d067d0da053d7d61 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 17:52:23 +0100 Subject: r26316: Use contexts for conversion functions. (This used to be commit f6420d933b5b011d428974f3a2a57edf19e6f482) --- source4/libcli/smb2/request.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 576e2b6fcf..5a7534f906 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -579,7 +579,7 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me return NT_STATUS_OK; } - size = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + size = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); (*str) = (char *)vstr; @@ -604,7 +604,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } - size = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16, + size = convert_string_talloc(buf->buffer, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; -- cgit From d891c0c74a03d797aed1c5ac0329fd9d1d78da63 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:09 +0100 Subject: r26429: Avoid use of global_smb_iconv_convenience. (This used to be commit d37136b7abfbba75ef2e5ab855eb3382b9648b8c) --- source4/libcli/smb2/request.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 5a7534f906..73c74dcfeb 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -26,6 +26,7 @@ #include "lib/util/dlinklist.h" #include "lib/events/events.h" #include "libcli/smb2/smb2_calls.h" +#include "param/param.h" /* initialise a smb2 request @@ -579,7 +580,7 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me return NT_STATUS_OK; } - size = convert_string_talloc(mem_ctx, global_smb_iconv_convenience, CH_UTF16, CH_UNIX, + size = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, blob.data, blob.length, &vstr); data_blob_free(&blob); (*str) = (char *)vstr; @@ -604,7 +605,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } - size = convert_string_talloc(buf->buffer, global_smb_iconv_convenience, CH_UNIX, CH_UTF16, + size = convert_string_talloc(buf->buffer, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { return NT_STATUS_ILLEGAL_CHARACTER; -- cgit From a2505c5a2cc2b7b692ffbcdd8c6b86000a15d2c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Feb 2008 17:00:35 +1100 Subject: updated SMB2 header defines to match WSPP docs (This used to be commit d2c6ad55eca27f50a38fc6e2a85032eddb3f0aae) --- source4/libcli/smb2/request.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 73c74dcfeb..46ec24145f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -83,17 +83,17 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ SIVAL(req->out.hdr, 0, SMB2_MAGIC); SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY); - SSVAL(req->out.hdr, SMB2_HDR_PAD1, 0); + SSVAL(req->out.hdr, SMB2_HDR_EPOCH, 0); SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0); SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode); - SSVAL(req->out.hdr, SMB2_HDR_UNKNOWN1, 0); + SSVAL(req->out.hdr, SMB2_HDR_CREDIT, 0); SIVAL(req->out.hdr, SMB2_HDR_FLAGS, 0); - SIVAL(req->out.hdr, SMB2_HDR_CHAIN_OFFSET, 0); - SBVAL(req->out.hdr, SMB2_HDR_SEQNUM, req->seqnum); + SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, 0); + SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID, req->seqnum); SIVAL(req->out.hdr, SMB2_HDR_PID, 0); SIVAL(req->out.hdr, SMB2_HDR_TID, 0); - SBVAL(req->out.hdr, SMB2_HDR_UID, 0); - memset(req->out.hdr+SMB2_HDR_SIG, 0, 16); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, 0); + memset(req->out.hdr+SMB2_HDR_SIGNATURE, 0, 16); /* set the length of the fixed body part and +1 if there's a dynamic part also */ SSVAL(req->out.body, 0, body_fixed_size + (body_dynamic_size?1:0)); @@ -122,7 +122,7 @@ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opc body_dynamic_size); if (req == NULL) return NULL; - SBVAL(req->out.hdr, SMB2_HDR_UID, tree->session->uid); + SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID, tree->session->uid); SIVAL(req->out.hdr, SMB2_HDR_TID, tree->tid); req->session = tree->session; req->tree = tree; -- cgit From e870cfec9f3512b0f1bd3110d7b975652525e28a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 10:12:33 +1100 Subject: 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 used to be commit ca6d9be6cb6a403a81b18fa6e9a6a0518d7f0f68) --- source4/libcli/smb2/request.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 46ec24145f..0b680fb166 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -28,6 +28,21 @@ #include "libcli/smb2/smb2_calls.h" #include "param/param.h" +/* fill in the bufinfo */ +void smb2_setup_bufinfo(struct smb2_request *req) +{ + req->in.bufinfo.mem_ctx = req; + req->in.bufinfo.unicode = true; + req->in.bufinfo.align_base = req->in.buffer; + if (req->in.dynamic) { + req->in.bufinfo.data = req->in.dynamic; + req->in.bufinfo.data_size = req->in.body_size - req->in.body_fixed; + } else { + req->in.bufinfo.data = NULL; + req->in.bufinfo.data_size = 0; + } +} + /* initialise a smb2 request */ -- cgit From 839ab724dc2d204bfbb0693aeed64f6f83a4266b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 12:30:31 +1100 Subject: Fixed SMB2 rename operations from Vista clients We needed a flag in bufinfo to mark packets as SMB2, as it seems that SMB2 uses a different format for the RenameInformation buffer than SMB does Also handle the fact that SMB2 clients give the full path to the target file in the rename, not a relative path (This used to be commit 52d7972d95ddc19d22a4187b4d4428a6c3ed32d5) --- source4/libcli/smb2/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 0b680fb166..35229dc45f 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -32,7 +32,7 @@ void smb2_setup_bufinfo(struct smb2_request *req) { req->in.bufinfo.mem_ctx = req; - req->in.bufinfo.unicode = true; + req->in.bufinfo.flags = BUFINFO_FLAG_UNICODE | BUFINFO_FLAG_SMB2; req->in.bufinfo.align_base = req->in.buffer; if (req->in.dynamic) { req->in.bufinfo.data = req->in.dynamic; -- cgit From b640f475be9b0f83e7812a5c7756344c5891cba3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 17:11:36 +1100 Subject: updated SMB2 code for getinfo according to WSPP docs - Updated getinfo structures and field names - also updated the protocol revision number handling to reflect new docs (This used to be commit 3aaa2e86d94675c6c68d66d75292c3e34bfbc81b) --- source4/libcli/smb2/request.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 35229dc45f..7a0311f886 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -548,6 +548,33 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ 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 + + In this varient the uint16_t is padded by an extra 2 bytes, making + the size aligned on 4 byte boundary +*/ +NTSTATUS smb2_pull_o16As32_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 = SVAL(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; +} + /* pull a uint32_t length/ uint32_t ofs/blob triple from a data blob the ptr points to the start of the offset/length pair -- cgit From 2e4e06c6e69d881b0fc3c53df50db607fcce4a91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Feb 2008 07:25:38 +1100 Subject: fixed handling of zero sized buffers versus NULL buffers in SMB2. Thanks to Metze for spotting this. (This used to be commit fbcf3e65b9284e5d1862c98706d7f148a36afe47) --- source4/libcli/smb2/request.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 7a0311f886..1de0531d9a 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -206,6 +206,10 @@ bool smb2_request_is_ok(struct smb2_request *req) */ bool smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) { + if (size == 0) { + /* zero bytes is never out of range */ + return false; + } /* be careful with wraparound! */ if (ptr < buf->body || ptr >= buf->body + buf->body_size || @@ -270,7 +274,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } ofs = SVAL(ptr, 0); size = SVAL(ptr, 2); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -310,7 +314,10 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SSVAL(ptr, 0, 0); SSVAL(ptr, 2, 0); return NT_STATUS_OK; @@ -363,7 +370,10 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SSVAL(ptr, 0, 0); SIVAL(ptr, 2, 0); return NT_STATUS_OK; @@ -416,7 +426,10 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SIVAL(ptr, 0, 0); SIVAL(ptr, 4, 0); return NT_STATUS_OK; @@ -469,7 +482,10 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf, return NT_STATUS_BUFFER_TOO_SMALL; } - if (blob.length == 0) { + if (blob.data == NULL) { + if (blob.length != 0) { + return NT_STATUS_INTERNAL_ERROR; + } SIVAL(ptr, 0, 0); SIVAL(ptr, 4, 0); return NT_STATUS_OK; @@ -512,7 +528,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } ofs = SVAL(ptr, 0); size = IVAL(ptr, 2); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -536,7 +552,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } ofs = IVAL(ptr, 0); size = IVAL(ptr, 4); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -563,7 +579,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem } ofs = SVAL(ptr, 0); size = IVAL(ptr, 4); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -587,7 +603,7 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ } size = IVAL(ptr, 0); ofs = IVAL(ptr, 4); - if (ofs == 0 || size == 0) { + if (ofs == 0) { *blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -614,6 +630,11 @@ NTSTATUS smb2_pull_o16s16_string(struct smb2_request_buffer *buf, TALLOC_CTX *me status = smb2_pull_o16s16_blob(buf, mem_ctx, ptr, &blob); NT_STATUS_NOT_OK_RETURN(status); + if (blob.data == NULL) { + *str = NULL; + return NT_STATUS_OK; + } + if (blob.length == 0) { char *s; s = talloc_strdup(mem_ctx, ""); @@ -643,7 +664,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, NTSTATUS status; ssize_t size; - if (strcmp("", str) == 0) { + if (str == NULL) { return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } -- cgit From 26b8701321909e10aac124324695f9f4891b1f8d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Feb 2008 14:53:48 +1100 Subject: handle pushing of zero length smb2 strings (This used to be commit 66d0502228b31533b5d93731128a681992c22eda) --- source4/libcli/smb2/request.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 1de0531d9a..2471fcaa4d 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -668,6 +668,12 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, return smb2_push_o16s16_blob(buf, ofs, data_blob(NULL, 0)); } + if (*str == 0) { + blob.data = str; + blob.length = 0; + return smb2_push_o16s16_blob(buf, ofs, blob); + } + size = convert_string_talloc(buf->buffer, lp_iconv_convenience(global_loadparm), CH_UNIX, CH_UTF16, str, strlen(str), (void **)&blob.data); if (size == -1) { -- cgit From 11703b298685c9984a6a3c3a64eddb8a1a516b90 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Apr 2008 15:20:39 +0200 Subject: fix the overflow/wrap checks in Samba4 for new gcc optimisation behavior The approach I have used is as set out in https://www.securecoding.cert.org/confluence/display/seccode/ARR38-C.+Do+not+add+or+subtract+an+integer+to+a+pointer+if+the+resulting+value+does+not+refer+to+an+element+within+the+array (This used to be commit 92d5fb531db39be655f0cbd2d75b5f675a0a4cfa) --- source4/libcli/smb2/request.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index 2471fcaa4d..f52b0ceef2 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -211,10 +211,10 @@ bool smb2_oob(struct smb2_request_buffer *buf, const uint8_t *ptr, size_t size) return false; } /* be careful with wraparound! */ - if (ptr < buf->body || - ptr >= buf->body + buf->body_size || + if ((uintptr_t)ptr < (uintptr_t)buf->body || + (uintptr_t)ptr >= (uintptr_t)buf->body + buf->body_size || size > buf->body_size || - ptr + size > buf->body + buf->body_size) { + (uintptr_t)ptr + size > (uintptr_t)buf->body + buf->body_size) { return true; } return false; @@ -669,7 +669,7 @@ NTSTATUS smb2_push_o16s16_string(struct smb2_request_buffer *buf, } if (*str == 0) { - blob.data = str; + blob.data = discard_const(str); blob.length = 0; return smb2_push_o16s16_blob(buf, ofs, blob); } -- cgit From c7d7577fb978dfa822b4aab238440816188099c6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:03:58 +1000 Subject: private -> private_data for struct smb2_request (This used to be commit 67290e0ad69df2f2fe651249c6550b8e32dd641b) --- source4/libcli/smb2/request.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'source4/libcli/smb2/request.c') diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c index f52b0ceef2..64d427f889 100644 --- a/source4/libcli/smb2/request.c +++ b/source4/libcli/smb2/request.c @@ -43,6 +43,18 @@ void smb2_setup_bufinfo(struct smb2_request *req) } } + +/* destroy a request structure */ +static int smb2_request_destructor(struct smb2_request *req) +{ + if (req->transport) { + /* remove it from the list of pending requests (a null op if + its not in the list) */ + DLIST_REMOVE(req->transport->pending_recv, req); + } + return 0; +} + /* initialise a smb2 request */ @@ -122,6 +134,8 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_ SCVAL(req->out.dynamic, 0, 0); } + talloc_set_destructor(req, smb2_request_destructor); + return req; } @@ -154,18 +168,13 @@ NTSTATUS smb2_request_destroy(struct smb2_request *req) _send() call fails completely */ if (!req) return NT_STATUS_UNSUCCESSFUL; - if (req->transport) { - /* remove it from the list of pending requests (a null op if - its not in the list) */ - DLIST_REMOVE(req->transport->pending_recv, req); - } - if (req->state == SMB2_REQUEST_ERROR && NT_STATUS_IS_OK(req->status)) { - req->status = NT_STATUS_INTERNAL_ERROR; + status = NT_STATUS_INTERNAL_ERROR; + } else { + status = req->status; } - status = req->status; talloc_free(req); return status; } -- cgit