Convert SMB and SMB2 code to use a common buffer handling structure
authorAndrew Tridgell <tridge@samba.org>
Wed, 13 Feb 2008 23:12:33 +0000 (10:12 +1100)
committerAndrew Tridgell <tridge@samba.org>
Wed, 13 Feb 2008 23:12:33 +0000 (10:12 +1100)
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)

28 files changed:
source4/libcli/raw/clisession.c
source4/libcli/raw/clitransport.c
source4/libcli/raw/clitree.c
source4/libcli/raw/libcliraw.h
source4/libcli/raw/rawfile.c
source4/libcli/raw/rawioctl.c
source4/libcli/raw/rawnegotiate.c
source4/libcli/raw/rawreadwrite.c
source4/libcli/raw/rawrequest.c
source4/libcli/raw/rawsearch.c
source4/libcli/raw/request.h
source4/libcli/raw/smb_signing.c
source4/libcli/smb2/request.c
source4/libcli/smb2/smb2.h
source4/libcli/smb2/transport.c
source4/smb_server/blob.c
source4/smb_server/smb/negprot.c
source4/smb_server/smb/nttrans.c
source4/smb_server/smb/receive.c
source4/smb_server/smb/reply.c
source4/smb_server/smb/request.c
source4/smb_server/smb/search.c
source4/smb_server/smb/trans2.c
source4/smb_server/smb2/fileinfo.c
source4/smb_server/smb2/negprot.c
source4/smb_server/smb2/receive.c
source4/smb_server/smb2/tcon.c
source4/smb_server/smb_server.h

index 617131c53c7a07163b3b71d103b2db6a834c320b..55cb3ef305a8e8f250e57836c09ec4bebcf6fa9b 100644 (file)
@@ -177,9 +177,9 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
                parms->old.out.action = SVAL(req->in.vwv, VWV(2));
                p = req->in.data;
                if (p) {
-                       p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
-                       p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
-                       p += smbcli_req_pull_string(req, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
+                       p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.os, p, -1, STR_TERMINATE);
+                       p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.lanman, p, -1, STR_TERMINATE);
+                       p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->old.out.domain, p, -1, STR_TERMINATE);
                }
                break;
 
@@ -190,10 +190,10 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
                parms->nt1.out.action = SVAL(req->in.vwv, VWV(2));
                p = req->in.data;
                if (p) {
-                       p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
-                       p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
+                       p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.os, p, -1, STR_TERMINATE);
+                       p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.lanman, p, -1, STR_TERMINATE);
                        if (p < (req->in.data + req->in.data_size)) {
-                               p += smbcli_req_pull_string(req, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
+                               p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->nt1.out.domain, p, -1, STR_TERMINATE);
                        }
                }
                break;
@@ -209,11 +209,11 @@ NTSTATUS smb_raw_sesssetup_recv(struct smbcli_request *req,
                        break;
                }
 
-               parms->spnego.out.secblob = smbcli_req_pull_blob(req, mem_ctx, p, len);
+               parms->spnego.out.secblob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, p, len);
                p += parms->spnego.out.secblob.length;
-               p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
-               p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
-               p += smbcli_req_pull_string(req, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
+               p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.os, p, -1, STR_TERMINATE);
+               p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.lanman, p, -1, STR_TERMINATE);
+               p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->spnego.out.workgroup, p, -1, STR_TERMINATE);
                break;
 
        case RAW_SESSSETUP_SMB2:
index 62c32d305845908c9780278bd6845b322bad8131..288f0612de61f66103ed6445f26c6b8d8c061e9b 100644 (file)
@@ -444,6 +444,8 @@ static NTSTATUS smbcli_transport_finish_recv(void *private, DATA_BLOB blob)
        req->in.ptr = req->in.data;
        req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
 
+       smb_setup_bufinfo(req);
+
        if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
                int class = CVAL(req->in.hdr,HDR_RCLS);
                int code = SVAL(req->in.hdr,HDR_ERR);
@@ -637,7 +639,7 @@ NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
        p->out.data = talloc_array(mem_ctx, uint8_t, p->out.size);
        NT_STATUS_HAVE_NO_MEMORY(p->out.data);
 
-       if (!smbcli_raw_pull_data(req, req->in.data, p->out.size, p->out.data)) {
+       if (!smbcli_raw_pull_data(&req->in.bufinfo, req->in.data, p->out.size, p->out.data)) {
                req->status = NT_STATUS_BUFFER_TOO_SMALL;
        }
 
index 35f33353226b63ac381032eb88c1ac49b4d86e2b..507bde999a3e9624f65597ce341138c632c3d107 100644 (file)
@@ -123,9 +123,9 @@ NTSTATUS smb_raw_tcon_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
                p = req->in.data;
                if (!p) break;
 
-               p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.dev_type, 
-                                        p, -1, STR_ASCII | STR_TERMINATE);
-               p += smbcli_req_pull_string(req, mem_ctx, &parms->tconx.out.fs_type, 
+               p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.dev_type, 
+                                           p, -1, STR_ASCII | STR_TERMINATE);
+               p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.fs_type, 
                                         p, -1, STR_TERMINATE);
                break;
 
index 0032eb4e948a7412f7bde5cf17221b93d5ff034e..7111649fc17450eb6f5f20b2c5d5228dad764593 100644 (file)
@@ -250,8 +250,8 @@ struct smbcli_request {
        /* the mid of this packet - used to match replies */
        uint16_t mid;
 
-       struct request_buffer in;
-       struct request_buffer out;
+       struct smb_request_buffer in;
+       struct smb_request_buffer out;
 
        /* information on what to do with a reply when it is received
           asyncronously. If this is not setup when a reply is received then
index 3b6ca685269fb10c96146e7bed9ef4b3c66319ae..d9383401b7af00f2155d652ea445adac5c9599a1 100644 (file)
@@ -616,7 +616,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
        case RAW_OPEN_CTEMP:
                SMBCLI_CHECK_WCT(req, 1);
                parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0));
-               smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
+               smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
                break;
 
        case RAW_OPEN_SPLOPEN:
@@ -675,7 +675,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
                parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5));
                if (parms->openxreadx.out.nread > 
                    MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) ||
-                   !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), 
+                   !smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)), 
                                          parms->openxreadx.out.nread, 
                                          parms->openxreadx.out.data)) {
                        req->status = NT_STATUS_BUFFER_TOO_SMALL;
index 9205f84e864d8660a6649bbe5441a0007edeea43..957e554c6ba14ab90398d9fc6bdd6e3d0b5b24c5 100644 (file)
@@ -59,7 +59,7 @@ static NTSTATUS smb_raw_smbioctl_recv(struct smbcli_request *req,
                return smbcli_request_destroy(req);
        }
 
-       parms->ioctl.out.blob = smbcli_req_pull_blob(req, mem_ctx, req->in.data, -1);
+       parms->ioctl.out.blob = smbcli_req_pull_blob(&req->in.bufinfo, mem_ctx, req->in.data, -1);
        return smbcli_request_destroy(req);
 }
 
index 1f5e34779b0809c54b5e40e35d062d3ec629e0fc..ec2ada53ff7fd73e016a16a3d96ff71519232e24 100644 (file)
@@ -135,14 +135,14 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req)
                        if (req->in.data_size < 16) {
                                goto failed;
                        }
-                       transport->negotiate.server_guid = smbcli_req_pull_blob(req, transport, req->in.data, 16);
-                       transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data + 16, req->in.data_size - 16);
+                       transport->negotiate.server_guid = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, 16);
+                       transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data + 16, req->in.data_size - 16);
                } else {
                        if (req->in.data_size < (transport->negotiate.key_len)) {
                                goto failed;
                        }
-                       transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, req->in.data, transport->negotiate.key_len);
-                       smbcli_req_pull_string(req, transport, &transport->negotiate.server_domain,
+                       transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, transport->negotiate.key_len);
+                       smbcli_req_pull_string(&req->in.bufinfo, transport, &transport->negotiate.server_domain,
                                            req->in.data+transport->negotiate.key_len,
                                            req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN);
                        /* here comes the server name */
@@ -168,7 +168,7 @@ NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req)
                if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) {
                        transport->negotiate.writebraw_supported = 1;
                }
-               transport->negotiate.secblob = smbcli_req_pull_blob(req, transport, 
+               transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, 
                                                                 req->in.data, req->in.data_size);
        } else {
                /* the old core protocol */
index b0c49ddab77b9119963de6167d7f49eb776a8d9c..2005e36e040104f4727d4dd90058b15e911e2d73 100644 (file)
@@ -137,7 +137,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms)
                SMBCLI_CHECK_WCT(req, 5);
                parms->lockread.out.nread = SVAL(req->in.vwv, VWV(0));
                if (parms->lockread.out.nread > parms->lockread.in.count ||
-                   !smbcli_raw_pull_data(req, req->in.data+3, 
+                   !smbcli_raw_pull_data(&req->in.bufinfo, req->in.data+3, 
                                       parms->lockread.out.nread, parms->lockread.out.data)) {
                        req->status = NT_STATUS_BUFFER_TOO_SMALL;
                }
@@ -148,7 +148,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms)
                SMBCLI_CHECK_WCT(req, 5);
                parms->read.out.nread = SVAL(req->in.vwv, VWV(0));
                if (parms->read.out.nread > parms->read.in.count ||
-                   !smbcli_raw_pull_data(req, req->in.data+3, 
+                   !smbcli_raw_pull_data(&req->in.bufinfo, req->in.data+3, 
                                       parms->read.out.nread, parms->read.out.data)) {
                        req->status = NT_STATUS_BUFFER_TOO_SMALL;
                }
@@ -175,7 +175,7 @@ NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms)
                }
 
                if (parms->readx.out.nread > MAX(parms->readx.in.mincnt, parms->readx.in.maxcnt) ||
-                   !smbcli_raw_pull_data(req, req->in.hdr + SVAL(req->in.vwv, VWV(6)), 
+                   !smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)), 
                                       parms->readx.out.nread, 
                                       parms->readx.out.data)) {
                        req->status = NT_STATUS_BUFFER_TOO_SMALL;
index 3551e5d441200bc1648bfb5d9ecb09cba6f59cc5..dd60cc7f621f30e96c113840601279efb1629b52 100644 (file)
 /* assume that a character will not consume more than 3 bytes per char */
 #define MAX_BYTES_PER_CHAR 3
 
+/* setup the bufinfo used for strings and range checking */
+void smb_setup_bufinfo(struct smbcli_request *req)
+{
+       req->in.bufinfo.mem_ctx    = req;
+       req->in.bufinfo.unicode    = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false;
+       req->in.bufinfo.align_base = req->in.buffer;
+       req->in.bufinfo.data       = req->in.data;
+       req->in.bufinfo.data_size  = req->in.data_size;
+}
+
+
 /* destroy a request structure and return final status */
 NTSTATUS smbcli_request_destroy(struct smbcli_request *req)
 {
@@ -298,6 +309,9 @@ NTSTATUS smbcli_chained_advance(struct smbcli_request *req)
        req->in.data = req->in.vwv + 2 + req->in.wct * 2;
        req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));
 
+       /* fix the bufinfo */
+       smb_setup_bufinfo(req);
+
        if (buffer + 3 + req->in.wct*2 + req->in.data_size > 
            req->in.buffer + req->in.size) {
                return NT_STATUS_BUFFER_TOO_SMALL;
@@ -544,13 +558,13 @@ size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *by
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the packet is returned
 */
-static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
+static size_t smbcli_req_pull_ucs2(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
                                char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2, alignment=0;
        ssize_t ret;
 
-       if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) {
+       if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {
                src++;
                alignment=1;
                if (byte_len != -1) {
@@ -558,7 +572,7 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c
                }
        }
 
-       src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
+       src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
        if (src_len < 0) {
                *dest = NULL;
                return 0;
@@ -597,13 +611,13 @@ static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_c
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the packet is returned
 */
-size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
+size_t smbcli_req_pull_ascii(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,
                             char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2;
        ssize_t ret;
 
-       src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
+       src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
        if (src_len < 0) {
                *dest = NULL;
                return 0;
@@ -640,15 +654,15 @@ size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the packet is returned
 */
-size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, 
+size_t smbcli_req_pull_string(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, 
                           char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        if (!(flags & STR_ASCII) && 
-           (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
-               return smbcli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags);
+           (((flags & STR_UNICODE) || bufinfo->unicode))) {
+               return smbcli_req_pull_ucs2(bufinfo, mem_ctx, dest, src, byte_len, flags);
        }
 
-       return smbcli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags);
+       return smbcli_req_pull_ascii(bufinfo, mem_ctx, dest, src, byte_len, flags);
 }
 
 
@@ -658,11 +672,11 @@ size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
 
   if byte_len is -1 then limit the blob only by packet size
 */
-DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len)
+DATA_BLOB smbcli_req_pull_blob(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len)
 {
        int src_len;
 
-       src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
+       src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
 
        if (src_len < 0) {
                return data_blob(NULL, 0);
@@ -677,13 +691,13 @@ DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
 
 /* check that a lump of data in a request is within the bounds of the data section of
    the packet */
-static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr, uint32_t count)
+static bool smbcli_req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count)
 {
        /* be careful with wraparound! */
-       if (ptr < req->in.data ||
-           ptr >= req->in.data + req->in.data_size ||
-           count > req->in.data_size ||
-           ptr + count > req->in.data + req->in.data_size) {
+       if (ptr < bufinfo->data ||
+           ptr >= bufinfo->data + bufinfo->data_size ||
+           count > bufinfo->data_size ||
+           ptr + count > bufinfo->data + bufinfo->data_size) {
                return true;
        }
        return false;
@@ -694,11 +708,11 @@ static bool smbcli_req_data_oob(struct smbcli_request *req, const uint8_t *ptr,
 
   return false if any part is outside the data portion of the packet
 */
-bool smbcli_raw_pull_data(struct smbcli_request *req, const uint8_t *src, int len, uint8_t *dest)
+bool smbcli_raw_pull_data(struct request_bufinfo *bufinfo, const uint8_t *src, int len, uint8_t *dest)
 {
        if (len == 0) return true;
 
-       if (smbcli_req_data_oob(req, src, len)) {
+       if (smbcli_req_data_oob(bufinfo, src, len)) {
                return false;
        }
 
index 33fa90d68d976af3ec44bdd2b0301ffd827f95b5..fb2b09467c48c90e3631c9da583f2cee8bbb23c8 100644 (file)
@@ -54,7 +54,7 @@ static void smb_raw_search_backend(struct smbcli_request *req,
                search_data.search.write_time       = raw_pull_dos_date(req->transport,
                                                                        p + 22);
                search_data.search.size             = IVAL(p, 26);
-               smbcli_req_pull_ascii(req, mem_ctx, &name, p+30, 13, STR_ASCII);
+               smbcli_req_pull_ascii(&req->in.bufinfo, mem_ctx, &name, p+30, 13, STR_ASCII);
                search_data.search.name = name;
                if (!callback(private, &search_data)) {
                        break;
index 803a450e3cac6ef77c7744e69a6c73aa0ef71aa6..6776d3c349b51fd89acbea3a3afe85f9d37ccc9f 100644 (file)
 
 #include "libcli/raw/signing.h"
 
+/*
+  buffer limit structure used by both SMB and SMB2
+ */
+struct request_bufinfo {
+       TALLOC_CTX *mem_ctx;
+       bool unicode;
+       const uint8_t *align_base;
+       const uint8_t *data;
+       size_t data_size;       
+};
+
 /*
   Shared state structure between client and server, representing the basic packet.
 */
 
-struct request_buffer {
+struct smb_request_buffer {
        /* the raw SMB buffer, including the 4 byte length header */
        uint8_t *buffer;
        
@@ -56,6 +67,9 @@ struct request_buffer {
         * a send packet is done we need to move this
         * pointer */
        uint8_t *ptr;
+
+       /* this is used to range check and align strings and buffers */
+       struct request_bufinfo bufinfo;
 };
 
 #endif
index 0053710aaf1d4c84a4f94c93faeee077b541e307..4acfb9d16df7635e16cee938652bb67b323de8e5 100644 (file)
@@ -65,7 +65,7 @@ static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport)
        return true;
 }
 
-void mark_packet_signed(struct request_buffer *out) 
+void mark_packet_signed(struct smb_request_buffer *out) 
 {
        uint16_t flags2;
        flags2 = SVAL(out->hdr, HDR_FLG2);
@@ -101,7 +101,7 @@ bool signing_good(struct smb_signing_context *sign_info,
        return true;
 }
 
-void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num) 
+void sign_outgoing_message(struct smb_request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num) 
 {
        uint8_t calc_md5_mac[16];
        struct MD5Context md5_ctx;
@@ -133,7 +133,7 @@ void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, unsig
        Uncomment this to test if the remote server actually verifies signitures...*/
 }
 
-bool check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) 
+bool check_signed_incoming_message(struct smb_request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) 
 {
        bool good;
        uint8_t calc_md5_mac[16];
index 46ec24145f096d584eaf98f86cf8c1ea8aeaa155..0b680fb1669d644b854744b9ea2c0c5e089ee66a 100644 (file)
 #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
 */
index db13ab69b33ef69debe8c69c8338df2f5531ada2..af08b0180aa52e8b96860e3ac97f1d9c8d3b2caa 100644 (file)
@@ -19,6 +19,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include "libcli/raw/request.h"
+
 struct smb2_options {
        uint32_t timeout;
 };
@@ -102,6 +104,9 @@ struct smb2_request_buffer {
         * this will be moved when some dynamic data is pushed
         */
        uint8_t *dynamic;
+
+       /* this is used to range check and align strings and buffers */
+       struct request_bufinfo bufinfo;
 };
 
 
index dceb78382a4e487573533e48bfd5bbb755d11e07..1d601fdbfe847466d8f3eddf8f617f842a61c93f 100644 (file)
@@ -216,6 +216,8 @@ static NTSTATUS smb2_transport_finish_recv(void *private, DATA_BLOB blob)
                }
        }
 
+       smb2_setup_bufinfo(req);
+
        DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum));
        dump_data(5, req->in.body, req->in.body_size);
 
index 2b870118ba6cfa154441796d47ebf825133969c5..caf6fb447d218c05fdbc55862b8fe1236972b071 100644 (file)
@@ -78,7 +78,7 @@ NTSTATUS smbsrv_blob_fill_data(TALLOC_CTX *mem_ctx,
 /*
   pull a string from a blob in a trans2 request
 */
-size_t smbsrv_blob_pull_string(struct smbsrv_request *req
+size_t smbsrv_blob_pull_string(struct request_bufinfo *bufinfo
                               const DATA_BLOB *blob,
                               uint16_t offset,
                               const char **str,
@@ -92,7 +92,7 @@ size_t smbsrv_blob_pull_string(struct smbsrv_request *req,
                return 0;
        }
        
-       return req_pull_string(req, str, 
+       return req_pull_string(bufinfo, str, 
                               blob->data + offset, 
                               blob->length - offset,
                               STR_NO_RANGE_CHECK | flags);
@@ -521,7 +521,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
                                        union smb_setfileinfo *st,
                                        const DATA_BLOB *blob,
                                        int default_str_flags,
-                                       struct smbsrv_request *req)
+                                       struct request_bufinfo *bufinfo)
 {
        uint32_t len;
        DATA_BLOB str_blob;
@@ -560,12 +560,8 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
 
        case RAW_SFILEINFO_RENAME_INFORMATION:
-               if (!req) {
-                       /* 
-                        * TODO: get rid of smbsrv_request argument of
-                        * smbsrv_blob_pull_string()
-                        */
-                       return NT_STATUS_NOT_IMPLEMENTED;
+               if (!bufinfo) {
+                       return NT_STATUS_INTERNAL_ERROR;
                }
                BLOB_CHECK_MIN_SIZE(blob, 12);
 
@@ -574,7 +570,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
                len                                 = IVAL(blob->data, 8);
                str_blob.data = blob->data+12;
                str_blob.length = MIN(blob->length, len);
-               smbsrv_blob_pull_string(req, &str_blob, 0,
+               smbsrv_blob_pull_string(bufinfo, &str_blob, 0,
                                        &st->rename_information.in.new_name,
                                        STR_UNICODE);
                if (st->rename_information.in.new_name == NULL) {
index b57e5e1d6452c19568f39df67abb621253a50bc4..00ff3862f5edbf678211a835dda8dc0d640dae71 100644 (file)
@@ -509,7 +509,7 @@ void smbsrv_reply_negprot(struct smbsrv_request *req)
                        return;
                }
                protos[protos_count] = NULL;
-               len = req_pull_ascii4(req, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
+               len = req_pull_ascii4(&req->in.bufinfo, (const char **)&protos[protos_count], p, STR_ASCII|STR_TERMINATE);
                p += len;
                if (len == 0 || !protos[protos_count]) break;
 
index dd2ec15e39c426d9640eedb4eb0a8a1d4323b97c..f6edc407d67fc67d68ea3b6b4653afef32d6bd45 100644 (file)
@@ -134,7 +134,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req,
        io->ntcreatex.in.sec_desc         = NULL;
        io->ntcreatex.in.ea_list          = NULL;
 
-       req_pull_string(req, &io->ntcreatex.in.fname, 
+       req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, 
                        params + 53, 
                        MIN(fname_len+1, trans->in.params.length - 53),
                        STR_NO_RANGE_CHECK | STR_TERMINATE);
@@ -622,8 +622,8 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req)
        memcpy(trans->in.setup, (char *)(req->in.vwv) + VWV(19),
               sizeof(uint16_t) * trans->in.setup_count);
 
-       if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
-           !req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
+       if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
+           !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
index 3f590decca013d36f76b2ca44b9cab53a760f090..e3d247cbc08cee893f23f2922fc61c79a3198e07 100644 (file)
@@ -151,6 +151,9 @@ NTSTATUS smbsrv_recv_smb_request(void *private, DATA_BLOB blob)
 
        req->flags2     = SVAL(req->in.hdr, HDR_FLG2);
 
+       /* fix the bufinfo */
+       smbsrv_setup_bufinfo(req);
+
        if (!smbsrv_signing_check_incoming(req)) {
                smbsrv_send_error(req, NT_STATUS_ACCESS_DENIED);
                return NT_STATUS_OK;
@@ -620,6 +623,9 @@ void smbsrv_chain_reply(struct smbsrv_request *req)
        req->in.data_size = data_size;
        req->in.ptr = data;
 
+       /* fix the bufinfo */
+       smbsrv_setup_bufinfo(req);
+
        req->chain_count++;
 
        SSVAL(req->out.vwv, VWV(0), chain_cmd);
index aff0587bc627b91b882776323ad05666b03fb86c..40cad91062b8b84681eec8519889a38dde049816 100644 (file)
@@ -58,9 +58,9 @@ void smbsrv_reply_tcon(struct smbsrv_request *req)
        con.tcon.level = RAW_TCON_TCON;
 
        p = req->in.data;       
-       p += req_pull_ascii4(req, &con.tcon.in.service, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &con.tcon.in.password, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &con.tcon.in.dev, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.service, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.password, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &con.tcon.in.dev, p, STR_TERMINATE);
 
        if (!con.tcon.in.service || !con.tcon.in.password || !con.tcon.in.dev) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
@@ -106,14 +106,14 @@ void smbsrv_reply_tcon_and_X(struct smbsrv_request *req)
 
        p = req->in.data;
 
-       if (!req_pull_blob(req, p, passlen, &con.tconx.in.password)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen, &con.tconx.in.password)) {
                smbsrv_send_error(req, NT_STATUS_ILL_FORMED_PASSWORD);
                return;
        }
        p += passlen;
 
-       p += req_pull_string(req, &con.tconx.in.path, p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &con.tconx.in.device, p, -1, STR_ASCII);
+       p += req_pull_string(&req->in.bufinfo, &con.tconx.in.path, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &con.tconx.in.device, p, -1, STR_ASCII);
 
        if (!con.tconx.in.path || !con.tconx.in.device) {
                smbsrv_send_error(req, NT_STATUS_BAD_DEVICE_TYPE);
@@ -223,7 +223,7 @@ void smbsrv_reply_chkpth(struct smbsrv_request *req)
        SMBSRV_TALLOC_IO_PTR(io, union smb_chkpath);
        SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
-       req_pull_ascii4(req, &io->chkpath.in.path, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &io->chkpath.in.path, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_chkpath(req->ntvfs, io));
 }
@@ -264,7 +264,7 @@ void smbsrv_reply_getatr(struct smbsrv_request *req)
        st->getattr.level = RAW_FILEINFO_GETATTR;
 
        /* parse request */
-       req_pull_ascii4(req, &st->getattr.in.file.path, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &st->getattr.in.file.path, req->in.data, STR_TERMINATE);
        if (!st->getattr.in.file.path) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
                return;
@@ -290,7 +290,7 @@ void smbsrv_reply_setatr(struct smbsrv_request *req)
        st->setattr.in.attrib     = SVAL(req->in.vwv, VWV(0));
        st->setattr.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
        
-       req_pull_ascii4(req, &st->setattr.in.file.path, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &st->setattr.in.file.path, req->in.data, STR_TERMINATE);
 
        if (!st->setattr.in.file.path) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -379,7 +379,7 @@ void smbsrv_reply_open(struct smbsrv_request *req)
        oi->openold.in.open_mode = SVAL(req->in.vwv, VWV(0));
        oi->openold.in.search_attrs = SVAL(req->in.vwv, VWV(1));
 
-       req_pull_ascii4(req, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
 
        if (!oi->openold.in.fname) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -452,7 +452,7 @@ void smbsrv_reply_open_and_X(struct smbsrv_request *req)
        oi->openx.in.size         = IVAL(req->in.vwv, VWV(9));
        oi->openx.in.timeout      = IVAL(req->in.vwv, VWV(11));
 
-       req_pull_ascii4(req, &oi->openx.in.fname, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->openx.in.fname, req->in.data, STR_TERMINATE);
 
        if (!oi->openx.in.fname) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -502,7 +502,7 @@ void smbsrv_reply_mknew(struct smbsrv_request *req)
        oi->mknew.in.attrib  = SVAL(req->in.vwv, VWV(0));
        oi->mknew.in.write_time  = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
 
-       req_pull_ascii4(req, &oi->mknew.in.fname, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->mknew.in.fname, req->in.data, STR_TERMINATE);
 
        if (!oi->mknew.in.fname) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -551,7 +551,7 @@ void smbsrv_reply_ctemp(struct smbsrv_request *req)
 
        /* the filename is actually a directory name, the server provides a filename
           in that directory */
-       req_pull_ascii4(req, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE);
 
        if (!oi->ctemp.in.directory) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -576,7 +576,7 @@ void smbsrv_reply_unlink(struct smbsrv_request *req)
        
        unl->unlink.in.attrib = SVAL(req->in.vwv, VWV(0));
 
-       req_pull_ascii4(req, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE);
        
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_unlink(req->ntvfs, unl));
 }
@@ -958,7 +958,7 @@ void smbsrv_reply_write(struct smbsrv_request *req)
        io->write.in.data        = req->in.data + 3;
 
        /* make sure they gave us the data they promised */
-       if (req_data_oob(req, io->write.in.data, io->write.in.count)) {
+       if (req_data_oob(&req->in.bufinfo, io->write.in.data, io->write.in.count)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1027,7 +1027,7 @@ void smbsrv_reply_write_and_X(struct smbsrv_request *req)
        }
 
        /* make sure the data is in bounds */
-       if (req_data_oob(req, io->writex.in.data, io->writex.in.count)) {
+       if (req_data_oob(&req->in.bufinfo, io->writex.in.data, io->writex.in.count)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1163,7 +1163,7 @@ void smbsrv_reply_writeclose(struct smbsrv_request *req)
        io->writeclose.in.data          = req->in.data + 1;
 
        /* make sure they gave us the data they promised */
-       if (req_data_oob(req, io->writeclose.in.data, io->writeclose.in.count)) {
+       if (req_data_oob(&req->in.bufinfo, io->writeclose.in.data, io->writeclose.in.count)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1313,7 +1313,7 @@ void smbsrv_reply_printopen(struct smbsrv_request *req)
        oi->splopen.in.setup_length = SVAL(req->in.vwv, VWV(0));
        oi->splopen.in.mode         = SVAL(req->in.vwv, VWV(1));
 
-       req_pull_ascii4(req, &oi->splopen.in.ident, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->splopen.in.ident, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
 }
@@ -1426,7 +1426,7 @@ void smbsrv_reply_printwrite(struct smbsrv_request *req)
        io->splwrite.in.data            = req->in.data + 3;
 
        /* make sure they gave us the data they promised */
-       if (req_data_oob(req, io->splwrite.in.data, io->splwrite.in.count)) {
+       if (req_data_oob(&req->in.bufinfo, io->splwrite.in.data, io->splwrite.in.count)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1449,7 +1449,7 @@ void smbsrv_reply_mkdir(struct smbsrv_request *req)
        SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->generic.level = RAW_MKDIR_MKDIR;
-       req_pull_ascii4(req, &io->mkdir.in.path, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &io->mkdir.in.path, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_mkdir(req->ntvfs, io));
 }
@@ -1467,7 +1467,7 @@ void smbsrv_reply_rmdir(struct smbsrv_request *req)
        SMBSRV_TALLOC_IO_PTR(io, struct smb_rmdir);
        SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
-       req_pull_ascii4(req, &io->in.path, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &io->in.path, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rmdir(req->ntvfs, io));
 }
@@ -1490,8 +1490,8 @@ void smbsrv_reply_mv(struct smbsrv_request *req)
        io->rename.in.attrib = SVAL(req->in.vwv, VWV(0));
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &io->rename.in.pattern1, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &io->rename.in.pattern2, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern1, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern2, p, STR_TERMINATE);
 
        if (!io->rename.in.pattern1 || !io->rename.in.pattern2) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
@@ -1521,8 +1521,8 @@ void smbsrv_reply_ntrename(struct smbsrv_request *req)
        io->ntrename.in.cluster_size = IVAL(req->in.vwv, VWV(2));
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &io->ntrename.in.old_name, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &io->ntrename.in.new_name, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.old_name, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.new_name, p, STR_TERMINATE);
 
        if (!io->ntrename.in.old_name || !io->ntrename.in.new_name) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
@@ -1568,8 +1568,8 @@ void smbsrv_reply_copy(struct smbsrv_request *req)
        cp->in.flags = SVAL(req->in.vwv, VWV(2));
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &cp->in.path1, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &cp->in.path2, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path1, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path2, p, STR_TERMINATE);
 
        if (!cp->in.path1 || !cp->in.path2) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
@@ -1638,7 +1638,7 @@ void smbsrv_reply_lockingX(struct smbsrv_request *req)
        }
 
        /* make sure we got the promised data */
-       if (req_data_oob(req, req->in.data, total_locks * lck_size)) {
+       if (req_data_oob(&req->in.bufinfo, req->in.data, total_locks * lck_size)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1877,22 +1877,22 @@ static void reply_sesssetup_old(struct smbsrv_request *req)
        passlen            = SVAL(req->in.vwv, VWV(7));
 
        /* check the request isn't malformed */
-       if (req_data_oob(req, req->in.data, passlen)) {
+       if (req_data_oob(&req->in.bufinfo, req->in.data, passlen)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        
        p = req->in.data;
-       if (!req_pull_blob(req, p, passlen, &io->old.in.password)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen, &io->old.in.password)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += passlen;
        
-       p += req_pull_string(req, &io->old.in.user,   p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->old.in.domain, p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->old.in.os,     p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->old.in.lanman, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.user,   p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.domain, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.os,     p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.lanman, p, -1, STR_TERMINATE);
 
        /* call the generic handler */
        smbsrv_sesssetup_backend(req, io);
@@ -1921,28 +1921,28 @@ static void reply_sesssetup_nt1(struct smbsrv_request *req)
        io->nt1.in.capabilities = IVAL(req->in.vwv, VWV(11));
 
        /* check the request isn't malformed */
-       if (req_data_oob(req, req->in.data, passlen1) ||
-           req_data_oob(req, req->in.data + passlen1, passlen2)) {
+       if (req_data_oob(&req->in.bufinfo, req->in.data, passlen1) ||
+           req_data_oob(&req->in.bufinfo, req->in.data + passlen1, passlen2)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        
        p = req->in.data;
-       if (!req_pull_blob(req, p, passlen1, &io->nt1.in.password1)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen1, &io->nt1.in.password1)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += passlen1;
-       if (!req_pull_blob(req, p, passlen2, &io->nt1.in.password2)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen2, &io->nt1.in.password2)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += passlen2;
        
-       p += req_pull_string(req, &io->nt1.in.user,   p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->nt1.in.domain, p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->nt1.in.os,     p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->nt1.in.lanman, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.user,   p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.domain, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.os,     p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.lanman, p, -1, STR_TERMINATE);
 
        /* call the generic handler */
        smbsrv_sesssetup_backend(req, io);
@@ -1971,15 +1971,15 @@ static void reply_sesssetup_spnego(struct smbsrv_request *req)
        io->spnego.in.capabilities = IVAL(req->in.vwv, VWV(10));
 
        p = req->in.data;
-       if (!req_pull_blob(req, p, blob_len, &io->spnego.in.secblob)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, blob_len, &io->spnego.in.secblob)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += blob_len;
        
-       p += req_pull_string(req, &io->spnego.in.os,        p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->spnego.in.lanman,    p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &io->spnego.in.workgroup, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->spnego.in.os,        p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->spnego.in.lanman,    p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->spnego.in.workgroup, p, -1, STR_TERMINATE);
 
        /* call the generic handler */
        smbsrv_sesssetup_backend(req, io);
@@ -2199,7 +2199,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
                fname_len++;
        }
 
-       req_pull_string(req, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE);
+       req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE);
        if (!io->ntcreatex.in.fname) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
index 8f6d66450026178264a03cfb58eef143d81e4373..724055499b36096c4d3437387718dfcb229580e7 100644 (file)
 /* we over allocate the data buffer to prevent too many realloc calls */
 #define REQ_OVER_ALLOCATION 0
 
+/* setup the bufinfo used for strings and range checking */
+void smbsrv_setup_bufinfo(struct smbsrv_request *req)
+{
+       req->in.bufinfo.mem_ctx    = req;
+       req->in.bufinfo.unicode    = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false;
+       req->in.bufinfo.align_base = req->in.buffer;
+       req->in.bufinfo.data       = req->in.data;
+       req->in.bufinfo.data_size  = req->in.data_size;
+}
+
+
 static int smbsrv_request_destructor(struct smbsrv_request *req)
 {
        DLIST_REMOVE(req->smb_conn->requests, req);
@@ -461,13 +472,13 @@ size_t req_append_var_block(struct smbsrv_request *req,
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the packet is returned
 */
-static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
+static size_t req_pull_ucs2(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2, alignment=0;
        ssize_t ret;
        char *dest2;
 
-       if (!(flags & STR_NOALIGN) && ucs2_align(req->in.buffer, src, flags)) {
+       if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {
                src++;
                alignment=1;
                if (byte_len != -1) {
@@ -478,7 +489,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
        if (flags & STR_NO_RANGE_CHECK) {
                src_len = byte_len;
        } else {
-               src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
+               src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
                if (byte_len != -1 && src_len > byte_len) {
                        src_len = byte_len;
                }
@@ -491,11 +502,11 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
        
        src_len2 = utf16_len_n(src, src_len);
        if (src_len2 == 0) {
-               *dest = talloc_strdup(req, "");
+               *dest = talloc_strdup(bufinfo->mem_ctx, "");
                return src_len2 + alignment;
        }
 
-       ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
+       ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
 
        if (ret == -1) {
                *dest = NULL;
@@ -519,7 +530,7 @@ static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the packet is returned
 */
-static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
+static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2;
        ssize_t ret;
@@ -528,7 +539,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
        if (flags & STR_NO_RANGE_CHECK) {
                src_len = byte_len;
        } else {
-               src_len = req->in.data_size - PTR_DIFF(src, req->in.data);
+               src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);
                if (src_len < 0) {
                        *dest = NULL;
                        return 0;
@@ -544,7 +555,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
                src_len2++;
        }
 
-       ret = convert_string_talloc(req, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);
+       ret = convert_string_talloc(bufinfo->mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);
 
        if (ret == -1) {
                *dest = NULL;
@@ -568,14 +579,14 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the packet is returned
 */
-size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
+size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        if (!(flags & STR_ASCII) && 
-           (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
-               return req_pull_ucs2(req, dest, src, byte_len, flags);
+           (((flags & STR_UNICODE) || bufinfo->unicode))) {
+               return req_pull_ucs2(bufinfo, dest, src, byte_len, flags);
        }
 
-       return req_pull_ascii(req, dest, src, byte_len, flags);
+       return req_pull_ascii(bufinfo, dest, src, byte_len, flags);
 }
 
 
@@ -588,13 +599,13 @@ size_t req_pull_string(struct smbsrv_request *req, const char **dest, const uint
   on failure *dest is set to the zero length string. This seems to
   match win2000 behaviour
 */
-size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint8_t *src, uint_t flags)
+size_t req_pull_ascii4(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, uint_t flags)
 {
        ssize_t ret;
 
-       if (PTR_DIFF(src, req->in.data) + 1 > req->in.data_size) {
+       if (PTR_DIFF(src, bufinfo->data) + 1 > bufinfo->data_size) {
                /* win2000 treats this as the empty string! */
-               (*dest) = talloc_strdup(req, "");
+               (*dest) = talloc_strdup(bufinfo->mem_ctx, "");
                return 0;
        }
 
@@ -603,9 +614,9 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint
           behaviour */
        src++;
 
-       ret = req_pull_string(req, dest, src, -1, flags);
+       ret = req_pull_string(bufinfo, dest, src, -1, flags);
        if (ret == -1) {
-               (*dest) = talloc_strdup(req, "");
+               (*dest) = talloc_strdup(bufinfo->mem_ctx, "");
                return 1;
        }
        
@@ -617,30 +628,30 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint
 
   return false if any part is outside the data portion of the packet
 */
-bool req_pull_blob(struct smbsrv_request *req, const uint8_t *src, int len, DATA_BLOB *blob)
+bool req_pull_blob(struct request_bufinfo *bufinfo, const uint8_t *src, int len, DATA_BLOB *blob)
 {
-       if (len != 0 && req_data_oob(req, src, len)) {
+       if (len != 0 && req_data_oob(bufinfo, src, len)) {
                return false;
        }
 
-       (*blob) = data_blob_talloc(req, src, len);
+       (*blob) = data_blob_talloc(bufinfo->mem_ctx, src, len);
 
        return true;
 }
 
 /* check that a lump of data in a request is within the bounds of the data section of
    the packet */
-bool req_data_oob(struct smbsrv_request *req, const uint8_t *ptr, uint32_t count)
+bool req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count)
 {
        if (count == 0) {
                return false;
        }
        
        /* be careful with wraparound! */
-       if (ptr < req->in.data ||
-           ptr >= req->in.data + req->in.data_size ||
-           count > req->in.data_size ||
-           ptr + count > req->in.data + req->in.data_size) {
+       if (ptr < bufinfo->data ||
+           ptr >= bufinfo->data + bufinfo->data_size ||
+           count > bufinfo->data_size ||
+           ptr + count > bufinfo->data + bufinfo->data_size) {
                return true;
        }
        return false;
index ccf2ff73655620e5f4ff49dc58dc061f7dbfd881..90b23312719047c8482d6c35449d2298c1da308c 100644 (file)
@@ -129,14 +129,14 @@ void smbsrv_reply_search(struct smbsrv_request *req)
        SMBSRV_TALLOC_IO_PTR(sf, union smb_search_first);
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &sf->search_first.in.pattern, 
+       p += req_pull_ascii4(&req->in.bufinfo, &sf->search_first.in.pattern, 
                             p, STR_TERMINATE);
        if (!sf->search_first.in.pattern) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
                return;
        }
 
-       if (req_data_oob(req, p, 3)) {
+       if (req_data_oob(&req->in.bufinfo, p, 3)) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                return;
        }
@@ -167,7 +167,7 @@ void smbsrv_reply_search(struct smbsrv_request *req)
                union smb_search_next *sn;
 
                if (resume_key_length != 21 || 
-                   req_data_oob(req, p, 21) ||
+                   req_data_oob(&req->in.bufinfo, p, 21) ||
                    level == RAW_SEARCH_FUNIQUE) {
                        smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                        return;
@@ -242,13 +242,13 @@ void smbsrv_reply_fclose(struct smbsrv_request *req)
        SMBSRV_SETUP_NTVFS_REQUEST(reply_fclose_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &pattern, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &pattern, p, STR_TERMINATE);
        if (pattern && *pattern) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                return;
        }
        
-       if (req_data_oob(req, p, 3)) {
+       if (req_data_oob(&req->in.bufinfo, p, 3)) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                return;
        }
@@ -264,7 +264,7 @@ void smbsrv_reply_fclose(struct smbsrv_request *req)
                return;
        }
 
-       if (req_data_oob(req, p, 21)) {
+       if (req_data_oob(&req->in.bufinfo, p, 21)) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                return;
        }
index 45ea234d09094af1e1e2a8d79a8d5b042060d647..3336169bb0462e4fc2d1680c54e2da1ab31701b6 100644 (file)
@@ -248,7 +248,7 @@ static NTSTATUS trans2_open(struct smbsrv_request *req, struct trans_op *op)
        io->t2open.in.num_eas      = 0;
        io->t2open.in.eas          = NULL;
 
-       smbsrv_blob_pull_string(req, &trans->in.params, 28, &io->t2open.in.fname, 0);
+       smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 28, &io->t2open.in.fname, 0);
        if (io->t2open.in.fname == NULL) {
                return NT_STATUS_FOOBAR;
        }
@@ -296,7 +296,7 @@ static NTSTATUS trans2_mkdir(struct smbsrv_request *req, struct trans_op *op)
        NT_STATUS_HAVE_NO_MEMORY(io);
 
        io->t2mkdir.level = RAW_MKDIR_T2MKDIR;
-       smbsrv_blob_pull_string(req, &trans->in.params, 4, &io->t2mkdir.in.path, 0);
+       smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 4, &io->t2mkdir.in.path, 0);
        if (io->t2mkdir.in.path == NULL) {
                return NT_STATUS_FOOBAR;
        }
@@ -461,7 +461,7 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request *req, struct trans_op *op
 
        level = SVAL(trans->in.params.data, 0);
 
-       smbsrv_blob_pull_string(req, &trans->in.params, 6, &st->generic.in.file.path, 0);
+       smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 6, &st->generic.in.file.path, 0);
        if (st->generic.in.file.path == NULL) {
                return NT_STATUS_FOOBAR;
        }
@@ -602,7 +602,7 @@ static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,
 
        return smbsrv_pull_passthru_sfileinfo(st, passthru_level, st,
                                              blob, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),
-                                             req);
+                                             &req->in.bufinfo);
 }
 
 /*
@@ -661,7 +661,7 @@ static NTSTATUS trans2_setpathinfo(struct smbsrv_request *req, struct trans_op *
 
        level = SVAL(trans->in.params.data, 0);
 
-       smbsrv_blob_pull_string(req, &trans->in.params, 6, &st->generic.in.file.path, 0);
+       smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 6, &st->generic.in.file.path, 0);
        if (st->generic.in.file.path == NULL) {
                return NT_STATUS_FOOBAR;
        }
@@ -859,7 +859,7 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct trans_op *op
        level                             = SVAL(trans->in.params.data, 6);
        search->t2ffirst.in.storage_type  = IVAL(trans->in.params.data, 8);
 
-       smbsrv_blob_pull_string(req, &trans->in.params, 12, &search->t2ffirst.in.pattern, 0);
+       smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 12, &search->t2ffirst.in.pattern, 0);
        if (search->t2ffirst.in.pattern == NULL) {
                return NT_STATUS_FOOBAR;
        }
@@ -945,7 +945,7 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct trans_op *op)
        search->t2fnext.in.resume_key    = IVAL(trans->in.params.data, 6);
        search->t2fnext.in.flags         = SVAL(trans->in.params.data, 10);
 
-       smbsrv_blob_pull_string(req, &trans->in.params, 12, &search->t2fnext.in.last_name, 0);
+       smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 12, &search->t2fnext.in.last_name, 0);
        if (search->t2fnext.in.last_name == NULL) {
                return NT_STATUS_FOOBAR;
        }
@@ -1240,11 +1240,11 @@ static void reply_trans_generic(struct smbsrv_request *req, uint8_t command)
        }
 
        if (command == SMBtrans) {
-               req_pull_string(req, &trans->in.trans_name, req->in.data, -1, STR_TERMINATE);
+               req_pull_string(&req->in.bufinfo, &trans->in.trans_name, req->in.data, -1, STR_TERMINATE);
        }
 
-       if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
-           !req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
+       if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
+           !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1302,8 +1302,8 @@ static void reply_transs_generic(struct smbsrv_request *req, uint8_t command)
        data_ofs              = SVAL(req->in.vwv, VWV(6));
        data_disp             = SVAL(req->in.vwv, VWV(7));
 
-       if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &params) ||
-           !req_pull_blob(req, req->in.hdr + data_ofs, data_count, &data)) {
+       if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &params) ||
+           !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &data)) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                return;
        }
index 00c455e35198726171c27a0e680e962e1d549ddb..e375b7308facc404acdc336c8e83b152335f2321 100644 (file)
@@ -268,7 +268,7 @@ static NTSTATUS smb2srv_setinfo_file(struct smb2srv_setinfo_op *op, uint8_t smb2
 
        status = smbsrv_pull_passthru_sfileinfo(io, io->generic.level, io,
                                                &op->info->in.blob,
-                                               STR_UNICODE, NULL);
+                                               STR_UNICODE, &op->req->in.bufinfo);
        NT_STATUS_NOT_OK_RETURN(status);
 
        return ntvfs_setfileinfo(op->req->ntvfs, io);
index 7c295c05abce09b9b761613c0da86f6399faea9b..578eadbe8fd90fbc547c23643cd53897b2059bd7 100644 (file)
@@ -238,6 +238,8 @@ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req)
        req->in.body_size = body_fixed_size;
        req->in.dynamic   = NULL;
 
+       smb2srv_setup_bufinfo(req);
+
        SIVAL(req->in.hdr, 0,                           SMB2_MAGIC);
        SSVAL(req->in.hdr, SMB2_HDR_LENGTH,             SMB2_HDR_BODY);
        SSVAL(req->in.hdr, SMB2_HDR_EPOCH,              0);
index 393b3f0cc57d6363d3f09295d7e809fb32fb6708..58070065fcaaaf52e75ef72991dcc2581d9b6559 100644 (file)
 #include "ntvfs/ntvfs.h"
 #include "param/param.h"
 
+
+/* fill in the bufinfo */
+void smb2srv_setup_bufinfo(struct smb2srv_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;
+       }
+}
+
 static int smb2srv_request_destructor(struct smb2srv_request *req)
 {
        DLIST_REMOVE(req->smb_conn->requests2.list, req);
@@ -180,6 +196,8 @@ static void smb2srv_chain_reply(struct smb2srv_request *p_req)
                }
        }
 
+       smb2srv_setup_bufinfo(req);
+
        if (p_req->chained_file_handle) {
                memcpy(req->_chained_file_handle,
                       p_req->_chained_file_handle,
@@ -430,6 +448,8 @@ NTSTATUS smbsrv_recv_smb2_request(void *private, DATA_BLOB blob)
                }
        }
 
+       smb2srv_setup_bufinfo(req);
+
        /* 
         * TODO: - make sure the length field is 64
         *       - make sure it's a request
index b375ce6b4ba5677f27a2698a77fc5dd3314f3a0a..50094b806daf0b593a9508b9b0ed35b0f85355d2 100644 (file)
@@ -55,6 +55,8 @@ static NTSTATUS smb2srv_send_oplock_break(void *p, struct ntvfs_handle *h, uint8
 
        req->seqnum             = UINT64_MAX;
 
+       smb2srv_setup_bufinfo(req);
+
        SIVAL(req->in.hdr, 0,                           SMB2_MAGIC);
        SSVAL(req->in.hdr, SMB2_HDR_LENGTH,             SMB2_HDR_BODY);
        SSVAL(req->in.hdr, SMB2_HDR_EPOCH,              0);
index bb0673b7d0523ea982662a9bd2de0da97bd16497..776fe1b71b1a50881a64c4f8ab448d88b0b1af62 100644 (file)
@@ -254,8 +254,8 @@ struct smbsrv_request {
        /* the sequence number for signing */
        uint64_t seq_num;
 
-       struct request_buffer in;
-       struct request_buffer out;
+       struct smb_request_buffer in;
+       struct smb_request_buffer out;
 };
 
 enum security_types {SEC_SHARE,SEC_USER};