r3591: to get a bit more useful info from valgrind I'm disabling the
[samba.git] / source4 / libcli / raw / rawrequest.c
index 35a2d363df4374ac11340ed9d9feb2fb2c50a74d..8d0767b3f53d9fc9c253ce9a2db0b37eaf880510 100644 (file)
 */
 
 /*
-  this file implements functions for manipulating the 'struct cli_request' structure in libsmb
+  this file implements functions for manipulating the 'struct smbcli_request' structure in libsmb
 */
 
 #include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "dlinklist.h"
 
 /* we over allocate the data buffer to prevent too many realloc calls */
-#define REQ_OVER_ALLOCATION 256
+#define REQ_OVER_ALLOCATION 0
 
 /* assume that a character will not consume more than 3 bytes per char */
 #define MAX_BYTES_PER_CHAR 3
 
 /* destroy a request structure and return final status */
-NTSTATUS cli_request_destroy(struct cli_request *req)
+NTSTATUS smbcli_request_destroy(struct smbcli_request *req)
 {
        NTSTATUS status;
 
@@ -43,13 +45,13 @@ NTSTATUS cli_request_destroy(struct cli_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_requests, req);
+               DLIST_REMOVE(req->transport->pending_recv, req);
        }
 
        /* ahh, its so nice to destroy a complex structure in such a
           simple way! */
        status = req->status;
-       talloc_destroy(req->mem_ctx);
+       talloc_free(req);
        return status;
 }
 
@@ -58,28 +60,18 @@ NTSTATUS cli_request_destroy(struct cli_request *req)
   low-level function to setup a request buffer for a non-SMB packet 
   at the transport level
 */
-struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, uint_t size)
+struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *transport, uint_t size)
 {
-       struct cli_request *req;
-       TALLOC_CTX *mem_ctx;
-       
-       /* each request gets its own talloc context. The request
-          structure itself is also allocated inside this context,
-          so we need to allocate it before we construct the request
-       */
-       mem_ctx = talloc_init("cli_request");
-       if (!mem_ctx) {
-               return NULL;
-       }
+       struct smbcli_request *req;
 
-       req = talloc(mem_ctx, sizeof(struct cli_request));
+       req = talloc_p(transport, struct smbcli_request);
        if (!req) {
                return NULL;
        }
        ZERO_STRUCTP(req);
 
        /* setup the request context */
-       req->mem_ctx = mem_ctx;
+       req->state = SMBCLI_REQUEST_INIT;
        req->transport = transport;
        req->session = NULL;
        req->tree = NULL;
@@ -88,7 +80,7 @@ struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, ui
        /* over allocate by a small amount */
        req->out.allocated = req->out.size + REQ_OVER_ALLOCATION; 
 
-       req->out.buffer = talloc(req->mem_ctx, req->out.allocated);
+       req->out.buffer = talloc(req, req->out.allocated);
        if (!req->out.buffer) {
                return NULL;
        }
@@ -102,12 +94,12 @@ struct cli_request *cli_request_setup_nonsmb(struct cli_transport *transport, ui
 /*
   setup a SMB packet at transport level
 */
-struct cli_request *cli_request_setup_transport(struct cli_transport *transport,
-                                               uint8 command, unsigned wct, unsigned buflen)
+struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
+                                               uint8_t command, uint_t wct, uint_t buflen)
 {
-       struct cli_request *req;
+       struct smbcli_request *req;
 
-       req = cli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen);
+       req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen);
 
        if (!req) return NULL;
        
@@ -128,7 +120,7 @@ struct cli_request *cli_request_setup_transport(struct cli_transport *transport,
        SSVAL(req->out.hdr,HDR_FLG2, 0);
 
        /* assign a mid */
-       req->mid = cli_transport_next_mid(transport);
+       req->mid = smbcli_transport_next_mid(transport);
 
        /* copy the pid, uid and mid to the request */
        SSVAL(req->out.hdr, HDR_PID, 0);
@@ -145,39 +137,21 @@ struct cli_request *cli_request_setup_transport(struct cli_transport *transport,
 /*
   setup a reply in req->out with the given word count and initial data
   buffer size.  the caller will then fill in the command words and
-  data before calling cli_request_send() to send the reply on its
+  data before calling smbcli_request_send() to send the reply on its
   way. This interface is used before a session is setup.
 */
-struct cli_request *cli_request_setup_session(struct cli_session *session,
-                                             uint8 command, unsigned wct, unsigned buflen)
+struct smbcli_request *smbcli_request_setup_session(struct smbcli_session *session,
+                                                   uint8_t command, uint_t wct, uint_t buflen)
 {
-       struct cli_request *req;
-       uint16 flags2;
-       uint32 capabilities;
+       struct smbcli_request *req;
 
-       req = cli_request_setup_transport(session->transport, command, wct, buflen);
+       req = smbcli_request_setup_transport(session->transport, command, wct, buflen);
 
        if (!req) return NULL;
 
        req->session = session;
-       
-       flags2 = FLAGS2_LONG_PATH_COMPONENTS;
-       capabilities = session->transport->negotiate.capabilities;
 
-       if (capabilities & CAP_UNICODE) {
-               flags2 |= FLAGS2_UNICODE_STRINGS;
-       }
-       if (capabilities & CAP_STATUS32) {
-               flags2 |= FLAGS2_32_BIT_ERROR_CODES;
-       }
-       if (capabilities & CAP_EXTENDED_SECURITY) {
-               flags2 |= FLAGS2_EXTENDED_SECURITY;
-       }
-       if (session->transport->negotiate.sign_info.doing_signing) {
-               flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
-       }
-
-       SSVAL(req->out.hdr, HDR_FLG2, flags2);
+       SSVAL(req->out.hdr, HDR_FLG2, session->flags2);
        SSVAL(req->out.hdr, HDR_PID, session->pid & 0xFFFF);
        SSVAL(req->out.hdr, HDR_PIDHIGH, session->pid >> 16);
        SSVAL(req->out.hdr, HDR_UID, session->vuid);
@@ -188,13 +162,13 @@ struct cli_request *cli_request_setup_session(struct cli_session *session,
 /*
   setup a request for tree based commands
 */
-struct cli_request *cli_request_setup(struct cli_tree *tree,
-                                     uint8 command, 
-                                     unsigned wct, unsigned buflen)
+struct smbcli_request *smbcli_request_setup(struct smbcli_tree *tree,
+                                     uint8_t command, 
+                                     uint_t wct, uint_t buflen)
 {
-       struct cli_request *req;
+       struct smbcli_request *req;
 
-       req = cli_request_setup_session(tree->session, command, wct, buflen);
+       req = smbcli_request_setup_session(tree->session, command, wct, buflen);
        if (req) {
                req->tree = tree;
                SSVAL(req->out.hdr,HDR_TID,tree->tid);
@@ -210,7 +184,7 @@ struct cli_request *cli_request_setup(struct cli_tree *tree,
   To cope with this req->out.ptr is supplied. This will be updated to
   point at the same offset into the packet as before this call
 */
-static void cli_req_grow_allocation(struct cli_request *req, unsigned new_size)
+static void smbcli_req_grow_allocation(struct smbcli_request *req, uint_t new_size)
 {
        int delta;
        char *buf2;
@@ -223,7 +197,7 @@ static void cli_req_grow_allocation(struct cli_request *req, unsigned new_size)
 
        /* we need to realloc */
        req->out.allocated = req->out.size + delta + REQ_OVER_ALLOCATION;
-       buf2 = talloc_realloc(req->mem_ctx, req->out.buffer, req->out.allocated);
+       buf2 = talloc_realloc(req, req->out.buffer, req->out.allocated);
        if (buf2 == NULL) {
                smb_panic("out of memory in req_grow_allocation");
        }
@@ -251,11 +225,11 @@ static void cli_req_grow_allocation(struct cli_request *req, unsigned new_size)
   To cope with this req->out.ptr is supplied. This will be updated to
   point at the same offset into the packet as before this call
 */
-static void cli_req_grow_data(struct cli_request *req, unsigned new_size)
+void smbcli_req_grow_data(struct smbcli_request *req, uint_t new_size)
 {
        int delta;
 
-       cli_req_grow_allocation(req, new_size);
+       smbcli_req_grow_allocation(req, new_size);
 
        delta = new_size - req->out.data_size;
 
@@ -266,32 +240,20 @@ static void cli_req_grow_data(struct cli_request *req, unsigned new_size)
        SSVAL(req->out.vwv, VWV(req->out.wct), new_size);
 }
 
+
 /*
   send a message
 */
-BOOL cli_request_send(struct cli_request *req)
+BOOL smbcli_request_send(struct smbcli_request *req)
 {
-       uint_t ret;
-
        if (IVAL(req->out.buffer, 0) == 0) {
                _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
        }
 
-       cli_request_calculate_sign_mac(req);
+       smbcli_request_calculate_sign_mac(req);
 
-       ret = cli_sock_write(req->transport->socket, req->out.buffer, req->out.size);
+       smbcli_transport_send(req);
 
-       if (req->out.size != ret) {
-               req->transport->error.etype = ETYPE_SOCKET;
-               req->transport->error.e.socket_error = SOCKET_WRITE_ERROR;
-               DEBUG(0,("Error writing %d bytes to server - %s\n",
-                        (int)req->out.size, strerror(errno)));
-               return False;
-       }
-
-       /* add it to the list of pending requests */
-       DLIST_ADD(req->transport->pending_requests, req);
-       
        return True;
 }
 
@@ -299,27 +261,33 @@ BOOL cli_request_send(struct cli_request *req)
 /*
   receive a response to a packet
 */
-BOOL cli_request_receive(struct cli_request *req)
+BOOL smbcli_request_receive(struct smbcli_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->in.buffer) {
-               if (!cli_transport_select(req->transport)) {
-                       req->status = NT_STATUS_UNSUCCESSFUL;
-                       return False;
-               }
-
-               if (!cli_request_receive_next(req->transport)) {
-                       cli_transport_dead(req->transport);
-                       req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+       while (req->state <= SMBCLI_REQUEST_RECV) {
+               if (event_loop_once(req->transport->event.ctx) != 0) {
                        return False;
                }
        }
 
-       return True;
+       return req->state == SMBCLI_REQUEST_DONE;
+}
+
+
+/*
+  receive another reply to a request - this is used for requests that
+  have multi-part replies (such as SMBtrans2)
+*/
+BOOL smbcli_request_receive_more(struct smbcli_request *req)
+{
+       req->state = SMBCLI_REQUEST_RECV;
+       DLIST_ADD(req->transport->pending_recv, req);
+
+       return smbcli_request_receive(req);
 }
 
 
@@ -327,11 +295,11 @@ BOOL cli_request_receive(struct cli_request *req)
   handle oplock break requests from the server - return True if the request was
   an oplock break
 */
-static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, const char *hdr, const char *vwv)
+BOOL handle_oplock_break(struct smbcli_transport *transport, uint_t len, const char *hdr, const char *vwv)
 {
        /* we must be very fussy about what we consider an oplock break to avoid
           matching readbraw replies */
-       if (len != MIN_SMB_SIZE + VWV(8) ||
+       if (len != MIN_SMB_SIZE + VWV(8) + NBT_HDR_SIZE ||
            (CVAL(hdr, HDR_FLG) & FLAG_REPLY) ||
            CVAL(hdr,HDR_COM) != SMBlockingX ||
            SVAL(hdr, HDR_MID) != 0xFFFF ||
@@ -341,180 +309,28 @@ static BOOL handle_oplock_break(struct cli_transport *transport, uint_t len, con
        }
 
        if (transport->oplock.handler) {
-               uint16 tid = SVAL(hdr, HDR_TID);
-               uint16 fnum = SVAL(vwv,VWV(2));
-               uint8 level = CVAL(vwv,VWV(3)+1);
+               uint16_t tid = SVAL(hdr, HDR_TID);
+               uint16_t fnum = SVAL(vwv,VWV(2));
+               uint8_t level = CVAL(vwv,VWV(3)+1);
                transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private);
        }
 
        return True;
 }
 
-
-/*
-  receive an async message from the server
-  this function assumes that the caller already knows that the socket is readable
-  and that there is a packet waiting
-
-  The packet is not actually returned by this function, instead any
-  registered async message handlers are called
-
-  return True if a packet was successfully received and processed
-  return False if the socket appears to be dead
-*/
-BOOL cli_request_receive_next(struct cli_transport *transport)
-{
-       BOOL ret;
-       int len;
-       char header[NBT_HDR_SIZE];
-       char *buffer, *hdr, *vwv;
-       TALLOC_CTX *mem_ctx;
-       struct cli_request *req;
-       uint16 wct, mid = 0;
-
-       len = cli_sock_read(transport->socket, header, 4);
-       if (len != 4) {
-               return False;
-       }
-       
-       len = smb_len(header);
-
-       mem_ctx = talloc_init("cli_request_receive_next");
-       
-       /* allocate the incoming buffer at the right size */
-       buffer = talloc(mem_ctx, len+NBT_HDR_SIZE);
-       if (!buffer) {
-               talloc_destroy(mem_ctx);
-               return False;
-       }
-
-       /* fill in the already received header */
-       memcpy(buffer, header, NBT_HDR_SIZE);
-
-       ret = cli_sock_read(transport->socket, buffer + NBT_HDR_SIZE, len);
-       /* If the server is not responding, note that now */
-       if (ret != len) {
-               return False;
-       }
-
-       hdr = buffer+NBT_HDR_SIZE;
-       vwv = hdr + HDR_VWV;
-
-       /* see if it could be an oplock break request */
-       if (handle_oplock_break(transport, len, hdr, vwv)) {
-               goto done;
-       }
-
-       /* at this point we need to check for a readbraw reply, as these can be any length */
-       if (transport->readbraw_pending) {
-               transport->readbraw_pending = 0;
-
-               /* it must match the first entry in the pending queue as the client is not allowed
-                  to have outstanding readbraw requests */
-               req = transport->pending_requests;
-               if (!req) goto done;
-
-               req->in.buffer = buffer;
-               talloc_steal(mem_ctx, req->mem_ctx, buffer);
-               req->in.size = len + NBT_HDR_SIZE;
-               req->in.allocated = req->in.size;
-               goto async;
-       }
-
-       if (len >= MIN_SMB_SIZE) {
-               /* extract the mid for matching to pending requests */
-               mid = SVAL(hdr, HDR_MID);
-               wct = CVAL(hdr, HDR_WCT);
-       }
-
-       /* match the incoming request against the list of pending requests */
-       for (req=transport->pending_requests; req; req=req->next) {
-               if (req->mid == mid) break;
-       }
-
-       if (!req) {
-               DEBUG(3,("Discarding unmatched reply with mid %d\n", mid));
-               goto done;
-       }
-
-       /* fill in the 'in' portion of the matching request */
-       req->in.buffer = buffer;
-       talloc_steal(mem_ctx, req->mem_ctx, buffer);
-       req->in.size = len + NBT_HDR_SIZE;
-       req->in.allocated = req->in.size;
-
-       /* handle non-SMB replies */
-       if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) {
-               goto done;
-       }
-
-       if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) {
-               DEBUG(2,("bad reply size for mid %d\n", mid));
-               req->status = NT_STATUS_UNSUCCESSFUL;
-               goto done;
-       }
-
-       req->in.hdr = hdr;
-       req->in.vwv = vwv;
-       req->in.wct = wct;
-       if (req->in.size >= NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) {
-               req->in.data = req->in.vwv + VWV(wct) + 2;
-               req->in.data_size = SVAL(req->in.vwv, VWV(wct));
-               if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct) + req->in.data_size) {
-                       DEBUG(3,("bad data size for mid %d\n", mid));
-                       /* blergh - w2k3 gives a bogus data size values in some
-                          openX replies */
-                       req->in.data_size = req->in.size - (NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct));
-               }
-       }
-       req->in.ptr = req->in.data;
-       req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
-
-       if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
-               transport->error.etype = ETYPE_DOS;
-               transport->error.e.dos.eclass = CVAL(req->in.hdr,HDR_RCLS);
-               transport->error.e.dos.ecode = SVAL(req->in.hdr,HDR_ERR);
-               req->status = dos_to_ntstatus(transport->error.e.dos.eclass, 
-                                             transport->error.e.dos.ecode);
-       } else {
-               transport->error.etype = ETYPE_NT;
-               transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS));
-               req->status = transport->error.e.nt_status;
-       }
-
-       if (!cli_request_check_sign_mac(req)) {
-               transport->error.etype = ETYPE_SOCKET;
-               transport->error.e.socket_error = SOCKET_READ_BAD_SIG;
-               return False;
-       };
-
-async:
-       /* if this request has an async handler then call that to
-          notify that the reply has been received. This might destroy
-          the request so it must happen last */
-       if (req->async.fn) {
-               req->async.fn(req);
-       }
-
-done:
-       talloc_destroy(mem_ctx);
-       return True;
-}
-
-
 /*
   wait for a reply to be received for a packet that just returns an error
   code and nothing more
 */
-NTSTATUS cli_request_simple_recv(struct cli_request *req)
+NTSTATUS smbcli_request_simple_recv(struct smbcli_request *req)
 {
-       cli_request_receive(req);
-       return cli_request_destroy(req);
+       smbcli_request_receive(req);
+       return smbcli_request_destroy(req);
 }
 
 
 /* Return true if the last packet was in error */
-BOOL cli_request_is_error(struct cli_request *req)
+BOOL smbcli_request_is_error(struct smbcli_request *req)
 {
        return NT_STATUS_IS_ERR(req->status);
 }
@@ -524,7 +340,7 @@ BOOL cli_request_is_error(struct cli_request *req)
 
   return the number of bytes added to the packet
 */
-size_t cli_req_append_string(struct cli_request *req, const char *str, unsigned flags)
+size_t smbcli_req_append_string(struct smbcli_request *req, const char *str, uint_t flags)
 {
        size_t len;
 
@@ -535,17 +351,18 @@ size_t cli_req_append_string(struct cli_request *req, const char *str, unsigned
 
        len = (strlen(str)+2) * MAX_BYTES_PER_CHAR;             
 
-       cli_req_grow_allocation(req, len + req->out.data_size);
+       smbcli_req_grow_allocation(req, len + req->out.data_size);
 
-       len = push_string(NULL, req->out.data + req->out.data_size, str, len, flags);
+       len = push_string(req->out.data + req->out.data_size, str, len, flags);
 
-       cli_req_grow_data(req, len + req->out.data_size);
+       smbcli_req_grow_data(req, len + req->out.data_size);
 
        return len;
 }
 
+
 /*
-  this is like cli_req_append_string but it also return the
+  this is like smbcli_req_append_string but it also return the
   non-terminated string byte length, which can be less than the number
   of bytes consumed in the packet for 2 reasons:
 
@@ -555,7 +372,7 @@ size_t cli_req_append_string(struct cli_request *req, const char *str, unsigned
  this is used in places where the non-terminated string byte length is
  placed in the packet as a separate field  
 */
-size_t cli_req_append_string_len(struct cli_request *req, const char *str, unsigned flags, int *len)
+size_t smbcli_req_append_string_len(struct smbcli_request *req, const char *str, uint_t flags, int *len)
 {
        int diff = 0;
        size_t ret;
@@ -571,7 +388,7 @@ size_t cli_req_append_string_len(struct cli_request *req, const char *str, unsig
        }
 
        /* do the hard work */
-       ret = cli_req_append_string(req, str, flags);
+       ret = smbcli_req_append_string(req, str, flags);
 
        /* see if we need to subtract the termination */
        if (flags & STR_TERMINATE) {
@@ -596,11 +413,11 @@ size_t cli_req_append_string_len(struct cli_request *req, const char *str, unsig
 
   if dest_len is -1 then no limit applies
 */
-size_t cli_req_append_ascii4(struct cli_request *req, const char *str, unsigned flags)
+size_t smbcli_req_append_ascii4(struct smbcli_request *req, const char *str, uint_t flags)
 {
        size_t size;
-       cli_req_append_bytes(req, (const uint8 *)"\4", 1);
-       size = cli_req_append_string(req, str, flags);
+       smbcli_req_append_bytes(req, (const uint8_t *)"\4", 1);
+       size = smbcli_req_append_string(req, str, flags);
        return size + 1;
 }
 
@@ -611,11 +428,11 @@ size_t cli_req_append_ascii4(struct cli_request *req, const char *str, unsigned
 
   if dest is NULL, then put the blob at the end of the data portion of the packet
 */
-size_t cli_req_append_blob(struct cli_request *req, const DATA_BLOB *blob)
+size_t smbcli_req_append_blob(struct smbcli_request *req, const DATA_BLOB *blob)
 {
-       cli_req_grow_allocation(req, req->out.data_size + blob->length);
+       smbcli_req_grow_allocation(req, req->out.data_size + blob->length);
        memcpy(req->out.data + req->out.data_size, blob->data, blob->length);
-       cli_req_grow_data(req, req->out.data_size + blob->length);
+       smbcli_req_grow_data(req, req->out.data_size + blob->length);
        return blob->length;
 }
 
@@ -623,11 +440,11 @@ size_t cli_req_append_blob(struct cli_request *req, const DATA_BLOB *blob)
   append raw bytes into the data portion of the request packet
   return the number of bytes added
 */
-size_t cli_req_append_bytes(struct cli_request *req, const uint8 *bytes, size_t byte_len)
+size_t smbcli_req_append_bytes(struct smbcli_request *req, const uint8_t *bytes, size_t byte_len)
 {
-       cli_req_grow_allocation(req, byte_len + req->out.data_size);
+       smbcli_req_grow_allocation(req, byte_len + req->out.data_size);
        memcpy(req->out.data + req->out.data_size, bytes, byte_len);
-       cli_req_grow_data(req, byte_len + req->out.data_size);
+       smbcli_req_grow_data(req, byte_len + req->out.data_size);
        return byte_len;
 }
 
@@ -635,15 +452,15 @@ size_t cli_req_append_bytes(struct cli_request *req, const uint8 *bytes, size_t
   append variable block (type 5 buffer) into the data portion of the request packet
   return the number of bytes added
 */
-size_t cli_req_append_var_block(struct cli_request *req, const uint8 *bytes, uint16 byte_len)
+size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *bytes, uint16_t byte_len)
 {
-       cli_req_grow_allocation(req, byte_len + 3 + req->out.data_size);
+       smbcli_req_grow_allocation(req, byte_len + 3 + req->out.data_size);
        SCVAL(req->out.data + req->out.data_size, 0, 5);
        SSVAL(req->out.data + req->out.data_size, 1, byte_len);         /* add field length */
        if (byte_len > 0) {
                memcpy(req->out.data + req->out.data_size + 3, bytes, byte_len);
        }
-       cli_req_grow_data(req, byte_len + 3 + req->out.data_size);
+       smbcli_req_grow_data(req, byte_len + 3 + req->out.data_size);
        return byte_len + 3;
 }
 
@@ -661,8 +478,8 @@ size_t cli_req_append_var_block(struct cli_request *req, const uint8 *bytes, uin
   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 cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx,
-                               char **dest, const char *src, int byte_len, unsigned flags)
+static size_t smbcli_req_pull_ucs2(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
+                               char **dest, const char *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2, alignment=0;
        ssize_t ret;
@@ -684,11 +501,7 @@ static size_t cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx,
                src_len = byte_len;
        }
 
-       src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2;
-       if (src_len2 < src_len - 2) {
-               /* include the termination if we didn't reach the end of the packet */
-               src_len2 += 2;
-       }
+       src_len2 = utf16_len_n(src, src_len);
 
        /* ucs2 strings must be at least 2 bytes long */
        if (src_len2 < 2) {
@@ -696,7 +509,7 @@ static size_t cli_req_pull_ucs2(struct cli_request *req, TALLOC_CTX *mem_ctx,
                return 0;
        }
 
-       ret = convert_string_talloc(mem_ctx, CH_UCS2, CH_UNIX, src, src_len2, (const void **)dest);
+       ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest);
        if (ret == -1) {
                *dest = NULL;
                return 0;
@@ -718,8 +531,8 @@ static size_t cli_req_pull_ucs2(struct cli_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 cli_req_pull_ascii(struct cli_request *req, TALLOC_CTX *mem_ctx,
-                         char **dest, const char *src, int byte_len, unsigned flags)
+size_t smbcli_req_pull_ascii(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
+                            char **dest, const char *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2;
        ssize_t ret;
@@ -738,7 +551,7 @@ size_t cli_req_pull_ascii(struct cli_request *req, TALLOC_CTX *mem_ctx,
                src_len2++;
        }
 
-       ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (const void **)dest);
+       ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)dest);
 
        if (ret == -1) {
                *dest = NULL;
@@ -761,15 +574,15 @@ size_t cli_req_pull_ascii(struct cli_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 cli_req_pull_string(struct cli_request *req, TALLOC_CTX *mem_ctx, 
-                          char **dest, const char *src, int byte_len, unsigned flags)
+size_t smbcli_req_pull_string(struct smbcli_request *req, TALLOC_CTX *mem_ctx, 
+                          char **dest, const char *src, int byte_len, uint_t flags)
 {
        if (!(flags & STR_ASCII) && 
            (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
-               return cli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags);
+               return smbcli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags);
        }
 
-       return cli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags);
+       return smbcli_req_pull_ascii(req, mem_ctx, dest, src, byte_len, flags);
 }
 
 
@@ -779,7 +592,7 @@ size_t cli_req_pull_string(struct cli_request *req, TALLOC_CTX *mem_ctx,
 
   if byte_len is -1 then limit the blob only by packet size
 */
-DATA_BLOB cli_req_pull_blob(struct cli_request *req, TALLOC_CTX *mem_ctx, const char *src, int byte_len)
+DATA_BLOB smbcli_req_pull_blob(struct smbcli_request *req, TALLOC_CTX *mem_ctx, const char *src, int byte_len)
 {
        int src_len;
 
@@ -798,7 +611,7 @@ DATA_BLOB cli_req_pull_blob(struct cli_request *req, TALLOC_CTX *mem_ctx, const
 
 /* check that a lump of data in a request is within the bounds of the data section of
    the packet */
-static BOOL cli_req_data_oob(struct cli_request *req, const char *ptr, uint32 count)
+static BOOL smbcli_req_data_oob(struct smbcli_request *req, const char *ptr, uint32_t count)
 {
        /* be careful with wraparound! */
        if (ptr < req->in.data ||
@@ -815,11 +628,11 @@ static BOOL cli_req_data_oob(struct cli_request *req, const char *ptr, uint32 co
 
   return False if any part is outside the data portion of the packet
 */
-BOOL cli_raw_pull_data(struct cli_request *req, const char *src, int len, char *dest)
+BOOL smbcli_raw_pull_data(struct smbcli_request *req, const char *src, int len, char *dest)
 {
        if (len == 0) return True;
 
-       if (cli_req_data_oob(req, src, len)) {
+       if (smbcli_req_data_oob(req, src, len)) {
                return False;
        }
 
@@ -831,21 +644,17 @@ BOOL cli_raw_pull_data(struct cli_request *req, const char *src, int len, char *
 /*
   put a NTTIME into a packet
 */
-
-void cli_push_nttime(void *base, uint16 offset, NTTIME *t)
+void smbcli_push_nttime(void *base, uint16_t offset, NTTIME t)
 {
-       SIVAL(base, offset,   t->low);
-       SIVAL(base, offset+4, t->high);
+       SBVAL(base, offset, t);
 }
 
 /*
   pull a NTTIME from a packet
 */
-NTTIME cli_pull_nttime(void *base, uint16 offset)
+NTTIME smbcli_pull_nttime(void *base, uint16_t offset)
 {
-       NTTIME ret;
-       ret.low = IVAL(base, offset);
-       ret.high = IVAL(base, offset+4);
+       NTTIME ret = BVAL(base, offset);
        return ret;
 }
 
@@ -862,12 +671,13 @@ NTTIME cli_pull_nttime(void *base, uint16 offset)
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the blob is returned
 */
-static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx,
+static size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx,
                                 DATA_BLOB *blob, const char **dest, 
-                                const char *src, int byte_len, unsigned flags)
+                                const char *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2, alignment=0;
        ssize_t ret;
+       char *dest2;
 
        if (src < (const char *)blob->data ||
            src >= (const char *)(blob->data + blob->length)) {
@@ -892,18 +702,14 @@ static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx,
                return 0;
        }
 
-       src_len2 = strnlen_w((const smb_ucs2_t *)src, src_len/2) * 2;
-
-       if (src_len2 < src_len - 2) {
-               /* include the termination if we didn't reach the end of the packet */
-               src_len2 += 2;
-       }
+       src_len2 = utf16_len_n(src, src_len);
 
-       ret = convert_string_talloc(mem_ctx, CH_UCS2, CH_UNIX, src, src_len2, (const void **)dest);
+       ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);
        if (ret == -1) {
                *dest = NULL;
                return 0;
        }
+       *dest = dest2;
 
        return src_len2 + alignment;
 }
@@ -921,12 +727,13 @@ static size_t cli_blob_pull_ucs2(TALLOC_CTX* mem_ctx,
   on failure zero is returned and *dest is set to NULL, otherwise the number
   of bytes consumed in the blob is returned
 */
-static size_t cli_blob_pull_ascii(TALLOC_CTX *mem_ctx,
+static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx,
                                  DATA_BLOB *blob, const char **dest, 
-                                 const char *src, int byte_len, unsigned flags)
+                                 const char *src, int byte_len, uint_t flags)
 {
        int src_len, src_len2;
        ssize_t ret;
+       char *dest2;
 
        src_len = blob->length - PTR_DIFF(src, blob->data);
        if (src_len < 0) {
@@ -943,12 +750,13 @@ static size_t cli_blob_pull_ascii(TALLOC_CTX *mem_ctx,
                src_len2++;
        }
 
-       ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (const void **)dest);
+       ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);
 
        if (ret == -1) {
                *dest = NULL;
                return 0;
        }
+       *dest = dest2;
 
        return ret;
 }
@@ -967,22 +775,25 @@ static size_t cli_blob_pull_ascii(TALLOC_CTX *mem_ctx,
   on failure zero is returned and dest->s is set to NULL, otherwise the number
   of bytes consumed in the blob is returned
 */
-size_t cli_blob_pull_string(struct cli_session *session,
+size_t smbcli_blob_pull_string(struct smbcli_session *session,
                            TALLOC_CTX *mem_ctx,
                            DATA_BLOB *blob, 
                            WIRE_STRING *dest, 
-                           uint16 len_offset, uint16 str_offset, 
-                           unsigned flags)
+                           uint16_t len_offset, uint16_t str_offset, 
+                           uint_t flags)
 {
        int extra;
        dest->s = NULL;
        
-       if (len_offset > blob->length-4) {
-               return 0;
-       }
        if (flags & STR_LEN8BIT) {
+               if (len_offset > blob->length-1) {
+                       return 0;
+               }
                dest->private_length = CVAL(blob->data, len_offset);
        } else {
+               if (len_offset > blob->length-4) {
+                       return 0;
+               }
                dest->private_length = IVAL(blob->data, len_offset);
        }
        extra = 0;
@@ -997,7 +808,7 @@ size_t cli_blob_pull_string(struct cli_session *session,
                if (flags & STR_LEN_NOTERM) {
                        extra = 2;
                }
-               return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, &dest->s, 
+               return align + extra + smbcli_blob_pull_ucs2(mem_ctx, blob, &dest->s, 
                                                          blob->data+str_offset+align, 
                                                          dest->private_length, flags);
        }
@@ -1006,7 +817,7 @@ size_t cli_blob_pull_string(struct cli_session *session,
                extra = 1;
        }
 
-       return extra + cli_blob_pull_ascii(mem_ctx, blob, &dest->s, 
+       return extra + smbcli_blob_pull_ascii(mem_ctx, blob, &dest->s, 
                                           blob->data+str_offset, dest->private_length, flags);
 }
 
@@ -1022,12 +833,12 @@ size_t cli_blob_pull_string(struct cli_session *session,
   on failure zero is returned and dest->s is set to NULL, otherwise the number
   of bytes consumed in the blob is returned
 */
-size_t cli_blob_pull_unix_string(struct cli_session *session,
+size_t smbcli_blob_pull_unix_string(struct smbcli_session *session,
                            TALLOC_CTX *mem_ctx,
                            DATA_BLOB *blob, 
                            const char **dest, 
-                           uint16 str_offset, 
-                           unsigned flags)
+                           uint16_t str_offset, 
+                           uint_t flags)
 {
        int extra = 0;
        *dest = NULL;
@@ -1042,7 +853,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session,
                if (flags & STR_LEN_NOTERM) {
                        extra = 2;
                }
-               return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, dest, 
+               return align + extra + smbcli_blob_pull_ucs2(mem_ctx, blob, dest, 
                                                          blob->data+str_offset+align, 
                                                          -1, flags);
        }
@@ -1051,7 +862,7 @@ size_t cli_blob_pull_unix_string(struct cli_session *session,
                extra = 1;
        }
 
-       return extra + cli_blob_pull_ascii(mem_ctx, blob, dest,
+       return extra + smbcli_blob_pull_ascii(mem_ctx, blob, dest,
                                           blob->data+str_offset, -1, flags);
 }
 
@@ -1059,9 +870,9 @@ size_t cli_blob_pull_unix_string(struct cli_session *session,
 /*
   append a string into a blob
 */
-size_t cli_blob_append_string(struct cli_session *session,
+size_t smbcli_blob_append_string(struct smbcli_session *session,
                              TALLOC_CTX *mem_ctx, DATA_BLOB *blob, 
-                             const char *str, unsigned flags)
+                             const char *str, uint_t flags)
 {
        size_t max_len;
        int len;
@@ -1080,7 +891,7 @@ size_t cli_blob_append_string(struct cli_session *session,
                return 0;
        }
 
-       len = push_string(NULL, blob->data + blob->length, str, max_len, flags);
+       len = push_string(blob->data + blob->length, str, max_len, flags);
 
        blob->length += len;