Fix include paths to new location of libutil.
[samba.git] / source4 / libcli / smb2 / request.c
index 2471fcaa4ddae7342679e789153b101fb18c74e5..cc355fc33e7c5601f927020ca8aad0b77a35c742 100644 (file)
@@ -23,7 +23,7 @@
 #include "includes.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/smb2/smb2.h"
-#include "lib/util/dlinklist.h"
+#include "../lib/util/dlinklist.h"
 #include "lib/events/events.h"
 #include "libcli/smb2/smb2_calls.h"
 #include "param/param.h"
@@ -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;
 }
@@ -211,10 +220,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;
@@ -270,7 +279,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 {
        uint16_t ofs, size;
        if (smb2_oob(buf, ptr, 4)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        ofs  = SVAL(ptr, 0);
        size = SVAL(ptr, 2);
@@ -279,7 +288,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
                return NT_STATUS_OK;
        }
        if (smb2_oob(buf, buf->hdr + ofs, size)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
        NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -306,12 +315,12 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf,
 
        /* we have only 16 bit for the size */
        if (blob.length > 0xFFFF) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        /* check if there're enough room for ofs and size */
        if (smb2_oob(buf, ptr, 4)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (blob.data == NULL) {
@@ -367,7 +376,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf,
 
        /* check if there're enough room for ofs and size */
        if (smb2_oob(buf, ptr, 6)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (blob.data == NULL) {
@@ -423,7 +432,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf,
 
        /* check if there're enough room for ofs and size */
        if (smb2_oob(buf, ptr, 8)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (blob.data == NULL) {
@@ -479,7 +488,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf,
 
        /* check if there're enough room for ofs and size */
        if (smb2_oob(buf, ptr, 8)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (blob.data == NULL) {
@@ -524,7 +533,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
        uint32_t size;
 
        if (smb2_oob(buf, ptr, 6)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        ofs  = SVAL(ptr, 0);
        size = IVAL(ptr, 2);
@@ -533,7 +542,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
                return NT_STATUS_OK;
        }
        if (smb2_oob(buf, buf->hdr + ofs, size)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
        NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -548,7 +557,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 {
        uint32_t ofs, size;
        if (smb2_oob(buf, ptr, 8)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        ofs  = IVAL(ptr, 0);
        size = IVAL(ptr, 4);
@@ -557,7 +566,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
                return NT_STATUS_OK;
        }
        if (smb2_oob(buf, buf->hdr + ofs, size)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
        NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -575,7 +584,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem
 {
        uint32_t ofs, size;
        if (smb2_oob(buf, ptr, 8)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        ofs  = SVAL(ptr, 0);
        size = IVAL(ptr, 4);
@@ -584,7 +593,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem
                return NT_STATUS_OK;
        }
        if (smb2_oob(buf, buf->hdr + ofs, size)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
        NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -599,7 +608,7 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 {
        uint32_t ofs, size;
        if (smb2_oob(buf, ptr, 8)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        size = IVAL(ptr, 0);
        ofs  = IVAL(ptr, 4);
@@ -608,7 +617,31 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
                return NT_STATUS_OK;
        }
        if (smb2_oob(buf, buf->hdr + ofs, size)) {
-               return NT_STATUS_BUFFER_TOO_SMALL;
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       *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/ uint16_t ofs/blob triple from a data blob
+  the ptr points to the start of the offset/length pair
+*/
+NTSTATUS smb2_pull_s32o16_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_INVALID_PARAMETER;
+       }
+       size = IVAL(ptr, 0);
+       ofs  = SVAL(ptr, 4);
+       if (ofs == 0) {
+               *blob = data_blob(NULL, 0);
+               return NT_STATUS_OK;
+       }
+       if (smb2_oob(buf, buf->hdr + ofs, size)) {
+               return NT_STATUS_INVALID_PARAMETER;
        }
        *blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
        NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -669,7 +702,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);
        }