r4591: - converted the other _p talloc functions to not need _p
[jelmer/samba4-debian.git] / source / smb_server / request.c
index b1cb8fe2df46966f1b9672a01700283155cc6fc1..2ac832b439dc0b8bb9fe316cca0b1d313b13438c 100644 (file)
 */
 
 #include "includes.h"
+#include "events.h"
 #include "dlinklist.h"
 #include "smb_server/smb_server.h"
 
 
 /* we over allocate the data buffer to prevent too many realloc calls */
-#define REQ_OVER_ALLOCATION 256
+#define REQ_OVER_ALLOCATION 0
 
 /* destroy a request structure */
 void req_destroy(struct smbsrv_request *req)
@@ -82,9 +83,11 @@ static void req_setup_chain_reply(struct smbsrv_request *req, uint_t wct, uint_t
        /* over allocate by a small amount */
        req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 
 
-       req->out.buffer = talloc_realloc(req, req->out.buffer, req->out.allocated);
+       req->out.buffer = talloc_realloc(req, req->out.buffer, 
+                                        uint8_t, req->out.allocated);
        if (!req->out.buffer) {
                smbsrv_terminate_connection(req->smb_conn, "allocation failed");
+               return;
        }
 
        req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
@@ -106,6 +109,8 @@ static void req_setup_chain_reply(struct smbsrv_request *req, uint_t wct, uint_t
 */
 void req_setup_reply(struct smbsrv_request *req, uint_t wct, uint_t buflen)
 {
+       uint16_t flags2;
+
        if (req->chain_count != 0) {
                req_setup_chain_reply(req, wct, buflen);
                return;
@@ -116,9 +121,18 @@ void req_setup_reply(struct smbsrv_request *req, uint_t wct, uint_t buflen)
        /* over allocate by a small amount */
        req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 
 
-       req->out.buffer = talloc(req, req->out.allocated);
+       req->out.buffer = talloc_size(req, req->out.allocated);
        if (!req->out.buffer) {
                smbsrv_terminate_connection(req->smb_conn, "allocation failed");
+               return;
+       }
+
+       flags2 = FLAGS2_LONG_PATH_COMPONENTS | 
+               FLAGS2_EXTENDED_ATTRIBUTES | 
+               FLAGS2_IS_LONG_NAME;
+       flags2 |= (req->flags2 & (FLAGS2_UNICODE_STRINGS|FLAGS2_EXTENDED_SECURITY));
+       if (req->smb_conn->negotiate.client_caps & CAP_STATUS32) {
+               flags2 |= FLAGS2_32_BIT_ERROR_CODES;
        }
 
        req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
@@ -133,13 +147,9 @@ void req_setup_reply(struct smbsrv_request *req, uint_t wct, uint_t buflen)
        SCVAL(req->out.hdr, HDR_WCT, wct);
        SSVAL(req->out.vwv, VWV(wct), buflen);
 
-
        memcpy(req->out.hdr, "\377SMB", 4);
        SCVAL(req->out.hdr,HDR_FLG, FLAG_REPLY | FLAG_CASELESS_PATHNAMES); 
-       SSVAL(req->out.hdr,HDR_FLG2, 
-             (req->flags2 & FLAGS2_UNICODE_STRINGS) |
-             FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_32_BIT_ERROR_CODES | FLAGS2_EXTENDED_SECURITY);
-
+       SSVAL(req->out.hdr,HDR_FLG2, flags2);
        SSVAL(req->out.hdr,HDR_PIDHIGH,0);
        memset(req->out.hdr + HDR_SS_FIELD, 0, 10);
 
@@ -217,7 +227,7 @@ int req_max_data(struct smbsrv_request *req)
 static void req_grow_allocation(struct smbsrv_request *req, uint_t new_size)
 {
        int delta;
-       char *buf2;
+       uint8_t *buf2;
 
        delta = new_size - req->out.data_size;
        if (delta + req->out.size <= req->out.allocated) {
@@ -227,7 +237,7 @@ static void req_grow_allocation(struct smbsrv_request *req, uint_t new_size)
 
        /* we need to realloc */
        req->out.allocated = req->out.size + delta + REQ_OVER_ALLOCATION;
-       buf2 = talloc_realloc(req, req->out.buffer, req->out.allocated);
+       buf2 = talloc_realloc(req, req->out.buffer, uint8_t, req->out.allocated);
        if (buf2 == NULL) {
                smb_panic("out of memory in req_grow_allocation");
        }
@@ -377,11 +387,11 @@ void req_reply_error(struct smbsrv_request *req, NTSTATUS status)
 
   if dest_len is -1 then no limit applies
 */
-size_t req_push_str(struct smbsrv_request *req, char *dest, const char *str, int dest_len, uint_t flags)
+size_t req_push_str(struct smbsrv_request *req, uint8_t *dest, const char *str, int dest_len, uint_t flags)
 {
        size_t len;
        uint_t grow_size;
-       char *buf0;
+       uint8_t *buf0;
        const int max_bytes_per_char = 3;
 
        if (!(flags & (STR_ASCII|STR_UNICODE))) {
@@ -459,7 +469,7 @@ 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 char *src, int byte_len, uint_t flags)
+static size_t req_pull_ucs2(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2, alignment=0;
        ssize_t ret;
@@ -488,6 +498,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, "");
+               return src_len2 + alignment;
+       }
+
        ret = convert_string_talloc(req, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
 
        if (ret == -1) {
@@ -512,7 +527,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 char *src, int byte_len, uint_t flags)
+static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, const uint8_t *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2;
        ssize_t ret;
@@ -531,7 +546,7 @@ static size_t req_pull_ascii(struct smbsrv_request *req, const char **dest, cons
                }
        }
 
-       src_len2 = strnlen(src, src_len);
+       src_len2 = strnlen((const char *)src, src_len);
        if (src_len2 <= src_len - 1) {
                /* include the termination if we didn't reach the end of the packet */
                src_len2++;
@@ -561,7 +576,7 @@ 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 char *src, int byte_len, uint_t flags)
+size_t req_pull_string(struct smbsrv_request *req, 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)))) {
@@ -581,7 +596,7 @@ size_t req_pull_string(struct smbsrv_request *req, const char **dest, const char
   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 char *src, uint_t flags)
+size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const uint8_t *src, uint_t flags)
 {
        ssize_t ret;
 
@@ -610,7 +625,7 @@ size_t req_pull_ascii4(struct smbsrv_request *req, const char **dest, const char
 
   return False if any part is outside the data portion of the packet
 */
-BOOL req_pull_blob(struct smbsrv_request *req, const char *src, int len, DATA_BLOB *blob)
+BOOL req_pull_blob(struct smbsrv_request *req, const uint8_t *src, int len, DATA_BLOB *blob)
 {
        if (len != 0 && req_data_oob(req, src, len)) {
                return False;
@@ -623,7 +638,7 @@ BOOL req_pull_blob(struct smbsrv_request *req, const char *src, int len, DATA_BL
 
 /* 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 char *ptr, uint32_t count)
+BOOL req_data_oob(struct smbsrv_request *req, const uint8_t *ptr, uint32_t count)
 {
        if (count == 0) {
                return False;
@@ -643,7 +658,7 @@ BOOL req_data_oob(struct smbsrv_request *req, const char *ptr, uint32_t count)
 /* 
    pull an open file handle from a packet, taking account of the chained_fnum
 */
-uint16_t req_fnum(struct smbsrv_request *req, const char *base, uint_t offset)
+uint16_t req_fnum(struct smbsrv_request *req, const uint8_t *base, uint_t offset)
 {
        if (req->chained_fnum != -1) {
                return req->chained_fnum;