Replace sid_string_static by sid_string_dbg in DEBUGs
[samba.git] / source / smbd / nttrans.c
index 965da90a64d37ebde8c6e259a4f314febe38cf75..641670c484f5a7efe6825ce3af35a54bd52e11c3 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Unix SMB/CIFS implementation.
    SMB NT transaction handling
-   Copyright (C) Jeremy Allison                        1994-1998
+   Copyright (C) Jeremy Allison                        1994-2007
    Copyright (C) Stefan (metze) Metzmacher     2003
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
 extern int max_send;
 extern enum protocol_types Protocol;
-extern int smb_read_error;
 extern struct current_user current_user;
 
 static const char *known_nt_pipes[] = {
@@ -52,7 +50,7 @@ static char *nttrans_realloc(char **ptr, size_t size)
        if (ptr==NULL) {
                smb_panic("nttrans_realloc() called with NULL ptr");
        }
-               
+
        *ptr = (char *)SMB_REALLOC(*ptr, size);
        if(*ptr == NULL) {
                return NULL;
@@ -68,14 +66,9 @@ static char *nttrans_realloc(char **ptr, size_t size)
  HACK ! Always assumes smb_setup field is zero.
 ****************************************************************************/
 
-int send_nt_replies(const char *inbuf,
-                       char *outbuf,
-                       int bufsize,
-                       NTSTATUS nt_error,
-                       char *params,
-                       int paramsize,
-                       char *pdata,
-                       int datasize)
+void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
+                    char *params, int paramsize,
+                    char *pdata, int datasize)
 {
        int data_to_send = datasize;
        int params_to_send = paramsize;
@@ -87,27 +80,14 @@ int send_nt_replies(const char *inbuf,
        int data_alignment_offset = 0;
 
        /*
-        * Initially set the wcnt area to be 18 - this is true for all
-        * transNT replies.
-        */
-
-       set_message(inbuf,outbuf,18,0,True);
-
-       if (NT_STATUS_V(nt_error)) {
-               ERROR_NT(nt_error);
-       }
-
-       /* 
         * If there genuinely are no parameters or data to send just send
         * the empty packet.
         */
 
        if(params_to_send == 0 && data_to_send == 0) {
-               show_msg(outbuf);
-               if (!send_smb(smbd_server_fd(),outbuf)) {
-                       exit_server_cleanly("send_nt_replies: send_smb failed.");
-               }
-               return 0;
+               reply_outbuf(req, 18, 0);
+               show_msg((char *)req->outbuf);
+               return;
        }
 
        /*
@@ -120,16 +100,17 @@ int send_nt_replies(const char *inbuf,
                data_alignment_offset = 4 - (params_to_send % 4);
        }
 
-       /* 
+       /*
         * Space is bufsize minus Netbios over TCP header minus SMB header.
         * The alignment_offset is to align the param bytes on a four byte
-        * boundary (2 bytes for data len, one byte pad). 
+        * boundary (2 bytes for data len, one byte pad).
         * NT needs this to work correctly.
         */
 
-       useable_space = bufsize - ((smb_buf(outbuf)+
-                               alignment_offset+data_alignment_offset) -
-                               outbuf);
+       useable_space = max_send - (smb_size
+                                   + 2 * 18 /* wct */
+                                   + alignment_offset
+                                   + data_alignment_offset);
 
        /*
         * useable_space can never be more than max_send minus the
@@ -149,22 +130,22 @@ int send_nt_replies(const char *inbuf,
                total_sent_thistime = params_to_send + data_to_send +
                                        alignment_offset + data_alignment_offset;
 
-               /* 
+               /*
                 * We can never send more than useable_space.
                 */
 
                total_sent_thistime = MIN(total_sent_thistime, useable_space);
 
-               set_message(inbuf,outbuf, 18, total_sent_thistime, True);
+               reply_outbuf(req, 18, total_sent_thistime);
 
                /*
                 * Set total params and data to be sent.
                 */
 
-               SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
-               SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
+               SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize);
+               SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize);
 
-               /* 
+               /*
                 * Calculate how many parameters and data we can fit into
                 * this packet. Parameters get precedence.
                 */
@@ -173,11 +154,12 @@ int send_nt_replies(const char *inbuf,
                data_sent_thistime = useable_space - params_sent_thistime;
                data_sent_thistime = MIN(data_sent_thistime,data_to_send);
 
-               SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
+               SIVAL(req->outbuf, smb_ntr_ParameterCount,
+                     params_sent_thistime);
 
                if(params_sent_thistime == 0) {
-                       SIVAL(outbuf,smb_ntr_ParameterOffset,0);
-                       SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
+                       SIVAL(req->outbuf,smb_ntr_ParameterOffset,0);
+                       SIVAL(req->outbuf,smb_ntr_ParameterDisplacement,0);
                } else {
                        /*
                         * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
@@ -186,41 +168,50 @@ int send_nt_replies(const char *inbuf,
                         * them from the calculation.
                         */
 
-                       SIVAL(outbuf,smb_ntr_ParameterOffset,
-                               ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
-                       /* 
+                       SIVAL(req->outbuf,smb_ntr_ParameterOffset,
+                             ((smb_buf(req->outbuf)+alignment_offset)
+                              - smb_base(req->outbuf)));
+                       /*
                         * Absolute displacement of param bytes sent in this packet.
                         */
 
-                       SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
+                       SIVAL(req->outbuf, smb_ntr_ParameterDisplacement,
+                             pp - params);
                }
 
                /*
                 * Deal with the data portion.
                 */
 
-               SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
+               SIVAL(req->outbuf, smb_ntr_DataCount, data_sent_thistime);
 
                if(data_sent_thistime == 0) {
-                       SIVAL(outbuf,smb_ntr_DataOffset,0);
-                       SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
+                       SIVAL(req->outbuf,smb_ntr_DataOffset,0);
+                       SIVAL(req->outbuf,smb_ntr_DataDisplacement, 0);
                } else {
                        /*
                         * The offset of the data bytes is the offset of the
                         * parameter bytes plus the number of parameters being sent this time.
                         */
 
-                       SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
-                               smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
-                               SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
+                       SIVAL(req->outbuf, smb_ntr_DataOffset,
+                             ((smb_buf(req->outbuf)+alignment_offset) -
+                              smb_base(req->outbuf))
+                             + params_sent_thistime + data_alignment_offset);
+                       SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata);
                }
 
-               /* 
+               /*
                 * Copy the param bytes into the packet.
                 */
 
                if(params_sent_thistime) {
-                       memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
+                       if (alignment_offset != 0) {
+                               memset(smb_buf(req->outbuf), 0,
+                                      alignment_offset);
+                       }
+                       memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
+                              params_sent_thistime);
                }
 
                /*
@@ -228,24 +219,38 @@ int send_nt_replies(const char *inbuf,
                 */
 
                if(data_sent_thistime) {
-                       memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
-                               data_alignment_offset,pd,data_sent_thistime);
+                       if (data_alignment_offset != 0) {
+                               memset((smb_buf(req->outbuf)+alignment_offset+
+                                       params_sent_thistime), 0,
+                                      data_alignment_offset);
+                       }
+                       memcpy(smb_buf(req->outbuf)+alignment_offset
+                              +params_sent_thistime+data_alignment_offset,
+                              pd,data_sent_thistime);
                }
-    
+
                DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
                        params_sent_thistime, data_sent_thistime, useable_space));
                DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
                        params_to_send, data_to_send, paramsize, datasize));
-    
+
+               if (NT_STATUS_V(nt_error)) {
+                       error_packet_set((char *)req->outbuf,
+                                        0, 0, nt_error,
+                                        __LINE__,__FILE__);
+               }
+
                /* Send the packet */
-               show_msg(outbuf);
-               if (!send_smb(smbd_server_fd(),outbuf)) {
+               show_msg((char *)req->outbuf);
+               if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) {
                        exit_server_cleanly("send_nt_replies: send_smb failed.");
                }
-    
+
+               TALLOC_FREE(req->outbuf);
+
                pp += params_sent_thistime;
                pd += data_sent_thistime;
-    
+
                params_to_send -= params_sent_thistime;
                data_to_send -= data_sent_thistime;
 
@@ -256,18 +261,16 @@ int send_nt_replies(const char *inbuf,
                if(params_to_send < 0 || data_to_send < 0) {
                        DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
                                params_to_send, data_to_send));
-                       return -1;
+                       return;
                }
-       } 
-
-       return 0;
+       }
 }
 
 /****************************************************************************
  Is it an NTFS stream name ?
 ****************************************************************************/
 
-BOOL is_ntfs_stream_name(const char *fname)
+bool is_ntfs_stream_name(const char *fname)
 {
        if (lp_posix_pathnames()) {
                return False;
@@ -276,67 +279,23 @@ BOOL is_ntfs_stream_name(const char *fname)
 }
 
 /****************************************************************************
- Save case statics.
-****************************************************************************/
-
-static BOOL saved_case_sensitive;
-static BOOL saved_case_preserve;
-static BOOL saved_short_case_preserve;
-
-/****************************************************************************
- Save case semantics.
-****************************************************************************/
-
-static uint32 set_posix_case_semantics(connection_struct *conn, uint32 file_attributes)
-{
-       if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
-               return file_attributes;
-       }
-
-       saved_case_sensitive = conn->case_sensitive;
-       saved_case_preserve = conn->case_preserve;
-       saved_short_case_preserve = conn->short_case_preserve;
-
-       /* Set to POSIX. */
-       conn->case_sensitive = True;
-       conn->case_preserve = True;
-       conn->short_case_preserve = True;
-
-       return (file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
-}
-
-/****************************************************************************
- Restore case semantics.
+ Reply to an NT create and X call on a pipe
 ****************************************************************************/
 
-static void restore_case_semantics(connection_struct *conn, uint32 file_attributes)
-{
-       if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
-               return;
-       }
-
-       conn->case_sensitive = saved_case_sensitive;
-       conn->case_preserve = saved_case_preserve;
-       conn->short_case_preserve = saved_short_case_preserve;
-}
-
-/****************************************************************************
- Reply to an NT create and X call on a pipe.
-****************************************************************************/
-
-static int nt_open_pipe(char *fname, connection_struct *conn,
-                       char *inbuf, char *outbuf, int *ppnum)
+static void nt_open_pipe(char *fname, connection_struct *conn,
+                        struct smb_request *req, int *ppnum)
 {
        smb_np_struct *p = NULL;
-       uint16 vuid = SVAL(inbuf, smb_uid);
        int i;
+
        DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
-    
+
        /* See if it is one we want to handle. */
 
        if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) {
-               return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
+               reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+                               ERRDOS, ERRbadpipe);
+               return;
        }
 
        for( i = 0; known_nt_pipes[i]; i++ ) {
@@ -344,53 +303,65 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
                        break;
                }
        }
-    
+
        if ( known_nt_pipes[i] == NULL ) {
-               return(ERROR_BOTH(NT_STATUS_OBJECT_NAME_NOT_FOUND,ERRDOS,ERRbadpipe));
+               reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+                               ERRDOS, ERRbadpipe);
+               return;
        }
-    
+
        /* Strip \\ off the name. */
        fname++;
-    
+
        DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
 
-       p = open_rpc_pipe_p(fname, conn, vuid);
+       p = open_rpc_pipe_p(fname, conn, req->vuid);
        if (!p) {
-               return(ERROR_DOS(ERRSRV,ERRnofids));
+               reply_doserror(req, ERRSRV, ERRnofids);
+               return;
        }
 
        /* TODO: Add pipe to db */
-       
+
        if ( !store_pipe_opendb( p ) ) {
                DEBUG(3,("nt_open_pipe: failed to store %s pipe open.\n", fname));
        }
-       
+
        *ppnum = p->pnum;
-       return 0;
+       return;
 }
 
 /****************************************************************************
  Reply to an NT create and X call for pipes.
 ****************************************************************************/
 
-static int do_ntcreate_pipe_open(connection_struct *conn,
-                        char *inbuf,char *outbuf,int length,int bufsize)
+static void do_ntcreate_pipe_open(connection_struct *conn,
+                                 struct smb_request *req)
 {
-       pstring fname;
-       int ret;
+       char *fname = NULL;
        int pnum = -1;
        char *p = NULL;
-       uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
+       uint32 flags = IVAL(req->inbuf,smb_ntcreate_Flags);
+       TALLOC_CTX *ctx = talloc_tos();
 
-       srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
+       srvstr_pull_buf_talloc(ctx, (char *)req->inbuf, req->flags2, &fname,
+                       smb_buf(req->inbuf), STR_TERMINATE);
 
-       if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
-               return ret;
+       if (!fname) {
+               reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+                               ERRDOS, ERRbadpipe);
+               return;
+       }
+       nt_open_pipe(fname, conn, req, &pnum);
+
+       if (req->outbuf) {
+               /* error reply */
+               return;
        }
 
        /*
         * Deal with pipe return.
-        */  
+        */
 
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                /* This is very strange. We
@@ -398,13 +369,13 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
                 * the wcnt to 42 ? It's definately
                 * what happens on the wire....
                 */
-               set_message(inbuf,outbuf,50,0,True);
-               SCVAL(outbuf,smb_wct,42);
+               reply_outbuf(req, 50, 0);
+               SCVAL(req->outbuf,smb_wct,42);
        } else {
-               set_message(inbuf,outbuf,34,0,True);
+               reply_outbuf(req, 34, 0);
        }
 
-       p = outbuf + smb_vwv2;
+       p = (char *)req->outbuf + smb_vwv2;
        p++;
        SSVAL(p,0,pnum);
        p += 2;
@@ -422,7 +393,7 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                p += 25;
                SIVAL(p,0,FILE_GENERIC_ALL);
-               /* 
+               /*
                 * For pipes W2K3 seems to return
                 * 0x12019B next.
                 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
@@ -432,68 +403,26 @@ static int do_ntcreate_pipe_open(connection_struct *conn,
 
        DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
 
-       return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-/****************************************************************************
- Reply to an NT create and X call for a quota file.
-****************************************************************************/
-
-int reply_ntcreate_and_X_quota(connection_struct *conn,
-                               char *inbuf,
-                               char *outbuf,
-                               int length,
-                               int bufsize,
-                               enum FAKE_FILE_TYPE fake_file_type,
-                               const char *fname)
-{
-       int result;
-       char *p;
-       uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
-       files_struct *fsp;
-       NTSTATUS status;
-
-       status = open_fake_file(conn, fake_file_type, fname, desired_access,
-                               &fsp);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               return ERROR_NT(status);
-       }
-
-       set_message(inbuf,outbuf,34,0,True);
-       
-       p = outbuf + smb_vwv2;
-       
-       /* SCVAL(p,0,NO_OPLOCK_RETURN); */
-       p++;
-       SSVAL(p,0,fsp->fnum);
-
-       DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
-
-       result = chain_reply(inbuf,outbuf,length,bufsize);
-       return result;
+       chain_reply(req);
 }
 
 /****************************************************************************
  Reply to an NT create and X call.
 ****************************************************************************/
 
-int reply_ntcreate_and_X(connection_struct *conn,
-                        char *inbuf,char *outbuf,int length,int bufsize)
-{  
-       int result;
-       pstring fname;
-       uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
-       uint32 access_mask = IVAL(inbuf,smb_ntcreate_DesiredAccess);
-       uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
-       uint32 new_file_attributes;
-       uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
-       uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
-       uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
-       uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
+void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req)
+{
+       char *fname = NULL;
+       uint32 flags;
+       uint32 access_mask;
+       uint32 file_attributes;
+       uint32 share_access;
+       uint32 create_disposition;
+       uint32 create_options;
+       uint16 root_dir_fid;
+       SMB_BIG_UINT allocation_size;
        /* Breakout the oplock request bits so we can set the
           reply bits separately. */
-       int oplock_request = 0;
        uint32 fattr=0;
        SMB_OFF_T file_len = 0;
        SMB_STRUCT_STAT sbuf;
@@ -503,22 +432,55 @@ int reply_ntcreate_and_X(connection_struct *conn,
        struct timespec c_timespec;
        struct timespec a_timespec;
        struct timespec m_timespec;
-       BOOL extended_oplock_granted = False;
        NTSTATUS status;
+       int oplock_request;
+       uint8_t oplock_granted = NO_OPLOCK_RETURN;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBntcreateX);
 
+       if (req->wct < 24) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       flags = IVAL(req->inbuf,smb_ntcreate_Flags);
+       access_mask = IVAL(req->inbuf,smb_ntcreate_DesiredAccess);
+       file_attributes = IVAL(req->inbuf,smb_ntcreate_FileAttributes);
+       share_access = IVAL(req->inbuf,smb_ntcreate_ShareAccess);
+       create_disposition = IVAL(req->inbuf,smb_ntcreate_CreateDisposition);
+       create_options = IVAL(req->inbuf,smb_ntcreate_CreateOptions);
+       root_dir_fid = (uint16)IVAL(req->inbuf,smb_ntcreate_RootDirectoryFid);
+
+       allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,
+                                            smb_ntcreate_AllocationSize);
+#ifdef LARGE_SMB_OFF_T
+       allocation_size |= (((SMB_BIG_UINT)IVAL(
+                                    req->inbuf,
+                                    smb_ntcreate_AllocationSize + 4)) << 32);
+#endif
+
+       srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
+                       smb_buf(req->inbuf), 0, STR_TERMINATE, &status);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               END_PROFILE(SMBntcreateX);
+               return;
+       }
+
        DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
                  "file_attributes = 0x%x, share_access = 0x%x, "
                  "create_disposition = 0x%x create_options = 0x%x "
-                 "root_dir_fid = 0x%x\n",
+                 "root_dir_fid = 0x%x, fname = %s\n",
                        (unsigned int)flags,
                        (unsigned int)access_mask,
                        (unsigned int)file_attributes,
                        (unsigned int)share_access,
                        (unsigned int)create_disposition,
                        (unsigned int)create_options,
-                       (unsigned int)root_dir_fid ));
+                       (unsigned int)root_dir_fid,
+                       fname));
 
        /*
         * If it's an IPC, use the pipe handler.
@@ -526,355 +488,73 @@ int reply_ntcreate_and_X(connection_struct *conn,
 
        if (IS_IPC(conn)) {
                if (lp_nt_pipe_support()) {
+                       do_ntcreate_pipe_open(conn, req);
                        END_PROFILE(SMBntcreateX);
-                       return do_ntcreate_pipe_open(conn,inbuf,outbuf,length,bufsize);
+                       return;
                } else {
+                       reply_doserror(req, ERRDOS, ERRnoaccess);
                        END_PROFILE(SMBntcreateX);
-                       return(ERROR_DOS(ERRDOS,ERRnoaccess));
+                       return;
                }
        }
 
-       if (create_options & FILE_OPEN_BY_FILE_ID) {
-               END_PROFILE(SMBntcreateX);
-               return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+       oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+       if (oplock_request) {
+               oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
+                       ? BATCH_OPLOCK : 0;
        }
 
-       /*
-        * Get the file name.
-        */
-
-       if(root_dir_fid != 0) {
-               /*
-                * This filename is relative to a directory fid.
-                */
-               pstring rel_fname;
-               files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
-               size_t dir_name_len;
-
-               if(!dir_fsp) {
-                       END_PROFILE(SMBntcreateX);
-                       return ERROR_DOS(ERRDOS,ERRbadfid);
-               }
-
-               if(!dir_fsp->is_directory) {
-
-                       srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               END_PROFILE(SMBntcreateX);
-                               return ERROR_NT(status);
-                       }
+       status = create_file(conn, req, root_dir_fid, fname,
+                            access_mask, share_access, create_disposition,
+                            create_options, file_attributes, oplock_request,
+                            allocation_size, NULL, NULL, &fsp, &info, &sbuf);
 
-                       /*
-                        * Check to see if this is a mac fork of some kind.
-                        */
-
-                       if( is_ntfs_stream_name(fname)) {
-                               END_PROFILE(SMBntcreateX);
-                               return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
-                       }
-
-                       /*
-                         we need to handle the case when we get a
-                         relative open relative to a file and the
-                         pathname is blank - this is a reopen!
-                         (hint from demyn plantenberg)
-                       */
-
-                       END_PROFILE(SMBntcreateX);
-                       return(ERROR_DOS(ERRDOS,ERRbadfid));
-               }
-
-               /*
-                * Copy in the base directory name.
-                */
-
-               pstrcpy( fname, dir_fsp->fsp_name );
-               dir_name_len = strlen(fname);
-
-               /*
-                * Ensure it ends in a '\'.
-                */
-
-               if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-                       pstrcat(fname, "/");
-                       dir_name_len++;
-               }
-
-               srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
-               if (!NT_STATUS_IS_OK(status)) {
+       if (!NT_STATUS_IS_OK(status)) {
+               if (open_was_deferred(req->mid)) {
+                       /* We have re-scheduled this call, no error. */
                        END_PROFILE(SMBntcreateX);
-                       return ERROR_NT(status);
+                       return;
                }
-               pstrcat(fname, rel_fname);
-       } else {
-               srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
-               if (!NT_STATUS_IS_OK(status)) {
-                       END_PROFILE(SMBntcreateX);
-                       return ERROR_NT(status);
+               if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
+                       reply_botherror(req, status, ERRDOS, ERRfilexists);
                }
-
-               /*
-                * Check to see if this is a mac fork of some kind.
-                */
-
-               if( is_ntfs_stream_name(fname)) {
-                       enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname);
-                       if (fake_file_type!=FAKE_FILE_TYPE_NONE) {
-                               /*
-                                * Here we go! support for changing the disk quotas --metze
-                                *
-                                * We need to fake up to open this MAGIC QUOTA file 
-                                * and return a valid FID.
-                                *
-                                * w2k close this file directly after openening
-                                * xp also tries a QUERY_FILE_INFO on the file and then close it
-                                */
-                               result = reply_ntcreate_and_X_quota(conn, inbuf, outbuf, length, bufsize,
-                                                               fake_file_type, fname);
-                               END_PROFILE(SMBntcreateX);
-                               return result;
-                       } else {
-                               END_PROFILE(SMBntcreateX);
-                               return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
-                       }
+               else {
+                       reply_nterror(req, status);
                }
-       }
-       
-       /*
-        * Now contruct the smb_open_mode value from the filename, 
-        * desired access and the share access.
-        */
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
-       if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBntcreateX);
-               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
-               }
-               return ERROR_NT(status);
-       }
-
-       oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
-       if (oplock_request) {
-               oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-       }
-
-       /*
-        * Ordinary file or directory.
-        */
-               
-       /*
-        * Check if POSIX semantics are wanted.
-        */
-               
-       new_file_attributes = set_posix_case_semantics(conn, file_attributes);
-               
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
-       if (!NT_STATUS_IS_OK(status)) {
-               restore_case_semantics(conn, file_attributes);
-               END_PROFILE(SMBntcreateX);
-               return ERROR_NT(status);
-       }
-       /* All file access must go through check_name() */
-       status = check_name(conn, fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               restore_case_semantics(conn, file_attributes);
-               END_PROFILE(SMBntcreateX);
-               return ERROR_NT(status);
-       }
-
-       /* This is the correct thing to do (check every time) but can_delete is
-          expensive (it may have to read the parent directory permissions). So
-          for now we're not doing it unless we have a strong hint the client
-          is really going to delete this file. If the client is forcing FILE_CREATE
-          let the filesystem take care of the permissions. */
-
-       /* Setting FILE_SHARE_DELETE is the hint. */
-
-       if (lp_acl_check_permissions(SNUM(conn))
-           && (create_disposition != FILE_CREATE)
-           && (share_access & FILE_SHARE_DELETE)
-           && (access_mask & DELETE_ACCESS)) {
-               if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) ||
-                               !can_delete_file_in_directory(conn, fname)) {
-                       restore_case_semantics(conn, file_attributes);
-                       END_PROFILE(SMBntcreateX);
-                       return ERROR_NT(NT_STATUS_ACCESS_DENIED);
-               }
+               return;
        }
 
        /*
-        * If it's a request for a directory open, deal with it separately.
+        * If the caller set the extended oplock request bit
+        * and we granted one (by whatever means) - set the
+        * correct bit for extended oplock reply.
         */
 
-       if(create_options & FILE_DIRECTORY_FILE) {
-
-               /* Can't open a temp directory. IFS kit test. */
-               if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
-                       END_PROFILE(SMBntcreateX);
-                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
-               }
-
-               oplock_request = 0;
-               status = open_directory(conn, fname, &sbuf,
-                                       access_mask,
-                                       share_access,
-                                       create_disposition,
-                                       create_options,
-                                       new_file_attributes,
-                                       &info, &fsp);
-
-               restore_case_semantics(conn, file_attributes);
-
-               if(!NT_STATUS_IS_OK(status)) {
-                       if (!use_nt_status() && NT_STATUS_EQUAL(
-                                   status, NT_STATUS_OBJECT_NAME_COLLISION)) {
-                               status = NT_STATUS_DOS(ERRDOS, ERRfilexists);
-                       }
-                       END_PROFILE(SMBntcreateX);
-                       return ERROR_NT(status);
-               }
-
-       } else {
+       if (oplock_request &&
+           (lp_fake_oplocks(SNUM(conn))
+            || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
 
                /*
-                * Ordinary file case.
+                * Exclusive oplock granted
                 */
 
-               /* NB. We have a potential bug here. If we
-                * cause an oplock break to ourselves, then we
-                * could end up processing filename related
-                * SMB requests whilst we await the oplock
-                * break response. As we may have changed the
-                * filename case semantics to be POSIX-like,
-                * this could mean a filename request could
-                * fail when it should succeed. This is a rare
-                * condition, but eventually we must arrange
-                * to restore the correct case semantics
-                * before issuing an oplock break request to
-                * our client. JRA.  */
-
-               status = open_file_ntcreate(conn,fname,&sbuf,
-                                       access_mask,
-                                       share_access,
-                                       create_disposition,
-                                       create_options,
-                                       new_file_attributes,
-                                       oplock_request,
-                                       &info, &fsp);
-
-               if (!NT_STATUS_IS_OK(status)) { 
-                       /* We cheat here. There are two cases we
-                        * care about. One is a directory rename,
-                        * where the NT client will attempt to
-                        * open the source directory for
-                        * DELETE access. Note that when the
-                        * NT client does this it does *not*
-                        * set the directory bit in the
-                        * request packet. This is translated
-                        * into a read/write open
-                        * request. POSIX states that any open
-                        * for write request on a directory
-                        * will generate an EISDIR error, so
-                        * we can catch this here and open a
-                        * pseudo handle that is flagged as a
-                        * directory. The second is an open
-                        * for a permissions read only, which
-                        * we handle in the open_file_stat case. JRA.
-                        */
-
-                       if (NT_STATUS_EQUAL(status,
-                                           NT_STATUS_FILE_IS_A_DIRECTORY)) {
-
-                               /*
-                                * Fail the open if it was explicitly a non-directory file.
-                                */
-
-                               if (create_options & FILE_NON_DIRECTORY_FILE) {
-                                       restore_case_semantics(conn, file_attributes);
-                                       END_PROFILE(SMBntcreateX);
-                                       return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
-                               }
-       
-                               oplock_request = 0;
-                               status = open_directory(conn, fname, &sbuf,
-                                                       access_mask,
-                                                       share_access,
-                                                       create_disposition,
-                                                       create_options,
-                                                       new_file_attributes,
-                                                       &info, &fsp);
-
-                               if(!NT_STATUS_IS_OK(status)) {
-                                       restore_case_semantics(conn, file_attributes);
-                                       if (!use_nt_status() && NT_STATUS_EQUAL(
-                                                   status, NT_STATUS_OBJECT_NAME_COLLISION)) {
-                                               status = NT_STATUS_DOS(ERRDOS, ERRfilexists);
-                                       }
-                                       END_PROFILE(SMBntcreateX);
-                                       return ERROR_NT(status);
-                               }
-                       } else {
-                               restore_case_semantics(conn, file_attributes);
-                               END_PROFILE(SMBntcreateX);
-                               if (open_was_deferred(SVAL(inbuf,smb_mid))) {
-                                       /* We have re-scheduled this call. */
-                                       return -1;
-                               }
-                               return ERROR_NT(status);
-                       }
-               } 
+               if (flags & REQUEST_BATCH_OPLOCK) {
+                       oplock_granted = BATCH_OPLOCK_RETURN;
+               } else {
+                       oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
+               }
+       } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
+               oplock_granted = LEVEL_II_OPLOCK_RETURN;
+       } else {
+               oplock_granted = NO_OPLOCK_RETURN;
        }
-               
-       restore_case_semantics(conn, file_attributes);
 
        file_len = sbuf.st_size;
        fattr = dos_mode(conn,fname,&sbuf);
-       if(fattr == 0) {
+       if (fattr == 0) {
                fattr = FILE_ATTRIBUTE_NORMAL;
        }
-       if (!fsp->is_directory && (fattr & aDIR)) {
-               close_file(fsp,ERROR_CLOSE);
-               END_PROFILE(SMBntcreateX);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
-       } 
-       
-       /* Save the requested allocation size. */
-       if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
-               SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize);
-#ifdef LARGE_SMB_OFF_T
-               allocation_size |= (((SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize + 4)) << 32);
-#endif
-               if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
-                       fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
-                       if (fsp->is_directory) {
-                               close_file(fsp,ERROR_CLOSE);
-                               END_PROFILE(SMBntcreateX);
-                               /* Can't set allocation size on a directory. */
-                               return ERROR_NT(NT_STATUS_ACCESS_DENIED);
-                       }
-                       if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
-                               close_file(fsp,ERROR_CLOSE);
-                               END_PROFILE(SMBntcreateX);
-                               return ERROR_NT(NT_STATUS_DISK_FULL);
-                       }
-               } else {
-                       fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)file_len);
-               }
-       }
-
-       /* 
-        * If the caller set the extended oplock request bit
-        * and we granted one (by whatever means) - set the
-        * correct bit for extended oplock reply.
-        */
-
-       if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
-               extended_oplock_granted = True;
-       }
-
-       if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
-               extended_oplock_granted = True;
-       }
 
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                /* This is very strange. We
@@ -882,35 +562,21 @@ int reply_ntcreate_and_X(connection_struct *conn,
                 * the wcnt to 42 ? It's definately
                 * what happens on the wire....
                 */
-               set_message(inbuf,outbuf,50,0,True);
-               SCVAL(outbuf,smb_wct,42);
+               reply_outbuf(req, 50, 0);
+               SCVAL(req->outbuf,smb_wct,42);
        } else {
-               set_message(inbuf,outbuf,34,0,True);
+               reply_outbuf(req, 34, 0);
        }
 
-       p = outbuf + smb_vwv2;
-       
-       /*
-        * Currently as we don't support level II oplocks we just report
-        * exclusive & batch here.
-        */
+       p = (char *)req->outbuf + smb_vwv2;
+
+       SCVAL(p, 0, oplock_granted);
 
-       if (extended_oplock_granted) {
-               if (flags & REQUEST_BATCH_OPLOCK) {
-                       SCVAL(p,0, BATCH_OPLOCK_RETURN);
-               } else {
-                       SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
-               }
-       } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
-               SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
-       } else {
-               SCVAL(p,0,NO_OPLOCK_RETURN);
-       }
-       
        p++;
        SSVAL(p,0,fsp->fnum);
        p += 2;
-       if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
+       if ((create_disposition == FILE_SUPERSEDE)
+           && (info == FILE_WAS_OVERWRITTEN)) {
                SIVAL(p,0,FILE_WAS_SUPERSEDED);
        } else {
                SIVAL(p,0,info);
@@ -918,7 +584,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
        p += 4;
 
        /* Create time. */
-       c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       c_timespec = get_create_timespec(
+               &sbuf,lp_fake_dir_create_times(SNUM(conn)));
        a_timespec = get_atimespec(&sbuf);
        m_timespec = get_mtimespec(&sbuf);
 
@@ -951,7 +618,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                uint32 perms = 0;
                p += 25;
-               if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
+               if (fsp->is_directory
+                   || can_write_to_file(conn, fname, &sbuf)) {
                        perms = FILE_GENERIC_ALL;
                } else {
                        perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -959,30 +627,32 @@ int reply_ntcreate_and_X(connection_struct *conn,
                SIVAL(p,0,perms);
        }
 
-       DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
+       DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n",
+                fsp->fnum, fsp->fsp_name));
 
-       result = chain_reply(inbuf,outbuf,length,bufsize);
+       chain_reply(req);
        END_PROFILE(SMBntcreateX);
-       return result;
+       return;
 }
 
 /****************************************************************************
  Reply to a NT_TRANSACT_CREATE call to open a pipe.
 ****************************************************************************/
 
-static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count)
+static void do_nt_transact_create_pipe(connection_struct *conn,
+                                      struct smb_request *req,
+                                      uint16 **ppsetup, uint32 setup_count,
+                                      char **ppparams, uint32 parameter_count,
+                                      char **ppdata, uint32 data_count)
 {
-       pstring fname;
+       char *fname = NULL;
        char *params = *ppparams;
-       int ret;
        int pnum = -1;
        char *p = NULL;
        NTSTATUS status;
        size_t param_len;
        uint32 flags;
+       TALLOC_CTX *ctx = talloc_tos();
 
        /*
         * Ensure minimum number of parameters sent.
@@ -990,20 +660,27 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
 
        if(parameter_count < 54) {
                DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               reply_doserror(req, ERRDOS, ERRnoaccess);
+               return;
        }
 
        flags = IVAL(params,0);
 
-       srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
+       srvstr_get_path(ctx, params, req->flags2, &fname, params+53,
+                       parameter_count-53, STR_TERMINATE,
+                       &status);
        if (!NT_STATUS_IS_OK(status)) {
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               return;
        }
 
-       if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0) {
-               return ret;
+       nt_open_pipe(fname, conn, req, &pnum);
+
+       if (req->outbuf) {
+               /* Error return */
+               return;
        }
-       
+
        /* Realloc the size of parameters and data we will return */
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                /* Extended response is 32 more byyes. */
@@ -1013,18 +690,19 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
        }
        params = nttrans_realloc(ppparams, param_len);
        if(params == NULL) {
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               reply_doserror(req, ERRDOS, ERRnomem);
+               return;
        }
-       
+
        p = params;
        SCVAL(p,0,NO_OPLOCK_RETURN);
-       
+
        p += 2;
        SSVAL(p,0,pnum);
        p += 2;
        SIVAL(p,0,FILE_WAS_OPENED);
        p += 8;
-       
+
        p += 32;
        SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
        p += 20;
@@ -1033,11 +711,11 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
        /* Device state. */
        SSVAL(p,2, 0x5FF); /* ? */
        p += 4;
-       
+
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                p += 25;
                SIVAL(p,0,FILE_GENERIC_ALL);
-               /* 
+               /*
                 * For pipes W2K3 seems to return
                 * 0x12019B next.
                 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
@@ -1046,11 +724,11 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
        }
 
        DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
-       
+
        /* Send the required number of replies */
-       send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
-       
-       return -1;
+       send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0);
+
+       return;
 }
 
 /****************************************************************************
@@ -1062,8 +740,8 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
        prs_struct pd;
        SEC_DESC *psd = NULL;
        TALLOC_CTX *mem_ctx;
-       BOOL ret;
-       
+       NTSTATUS status;
+
        if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
                return NT_STATUS_OK;
        }
@@ -1083,7 +761,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
         * Setup the prs_struct to point at the memory we just
         * allocated.
         */
-       
+
        prs_give_memory( &pd, data, sd_len, False);
 
        /*
@@ -1094,11 +772,11 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
                DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
                /*
                 * Return access denied for want of a better error message..
-                */ 
+                */
                talloc_destroy(mem_ctx);
                return NT_STATUS_NO_MEMORY;
        }
-       
+
        if (psd->owner_sid==0) {
                security_info_sent &= ~OWNER_SECURITY_INFORMATION;
        }
@@ -1111,23 +789,17 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
        if (psd->dacl==0) {
                security_info_sent &= ~DACL_SECURITY_INFORMATION;
        }
-       
-       ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
-       
-       if (!ret) {
-               talloc_destroy(mem_ctx);
-               return NT_STATUS_ACCESS_DENIED;
-       }
-       
+
+       status = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
+
        talloc_destroy(mem_ctx);
-       
-       return NT_STATUS_OK;
+       return status;
 }
 
 /****************************************************************************
  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
 ****************************************************************************/
-                                                                                                                             
+
 static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
 {
        struct ea_list *ea_list_head = NULL;
@@ -1151,7 +823,7 @@ static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata,
                }
                offset += next_offset;
        }
-                                                                                                                             
+
        return ea_list_head;
 }
 
@@ -1159,41 +831,43 @@ static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata,
  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
 ****************************************************************************/
 
-static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count, uint32 max_data_count)
+static void call_nt_transact_create(connection_struct *conn,
+                                   struct smb_request *req,
+                                   uint16 **ppsetup, uint32 setup_count,
+                                   char **ppparams, uint32 parameter_count,
+                                   char **ppdata, uint32 data_count,
+                                   uint32 max_data_count)
 {
-       pstring fname;
+       char *fname = NULL;
        char *params = *ppparams;
        char *data = *ppdata;
        /* Breakout the oplock request bits so we can set the reply bits separately. */
-       int oplock_request = 0;
        uint32 fattr=0;
        SMB_OFF_T file_len = 0;
        SMB_STRUCT_STAT sbuf;
        int info = 0;
        files_struct *fsp = NULL;
        char *p = NULL;
-       BOOL extended_oplock_granted = False;
        uint32 flags;
        uint32 access_mask;
        uint32 file_attributes;
-       uint32 new_file_attributes;
        uint32 share_access;
        uint32 create_disposition;
        uint32 create_options;
        uint32 sd_len;
+       struct security_descriptor *sd = NULL;
        uint32 ea_len;
        uint16 root_dir_fid;
        struct timespec c_timespec;
        struct timespec a_timespec;
        struct timespec m_timespec;
        struct ea_list *ea_list = NULL;
-       TALLOC_CTX *ctx = NULL;
-       char *pdata = NULL;
        NTSTATUS status;
        size_t param_len;
+       SMB_BIG_UINT allocation_size;
+       int oplock_request;
+       uint8_t oplock_granted;
+       TALLOC_CTX *ctx = talloc_tos();
 
        DEBUG(5,("call_nt_transact_create\n"));
 
@@ -1203,13 +877,15 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
 
        if (IS_IPC(conn)) {
                if (lp_nt_pipe_support()) {
-                       return do_nt_transact_create_pipe(conn, inbuf, outbuf, length, 
-                                       bufsize,
-                                       ppsetup, setup_count,
-                                       ppparams, parameter_count,
-                                       ppdata, data_count);
+                       do_nt_transact_create_pipe(
+                               conn, req,
+                               ppsetup, setup_count,
+                               ppparams, parameter_count,
+                               ppdata, data_count);
+                       return;
                } else {
-                       return ERROR_DOS(ERRDOS,ERRnoaccess);
+                       reply_doserror(req, ERRDOS, ERRnoaccess);
+                       return;
                }
        }
 
@@ -1219,7 +895,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
 
        if(parameter_count < 54) {
                DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
-               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
        }
 
        flags = IVAL(params,0);
@@ -1231,337 +908,126 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        sd_len = IVAL(params,36);
        ea_len = IVAL(params,40);
        root_dir_fid = (uint16)IVAL(params,4);
+       allocation_size = (SMB_BIG_UINT)IVAL(params,12);
+#ifdef LARGE_SMB_OFF_T
+       allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
+#endif
 
-       /* Ensure the data_len is correct for the sd and ea values given. */
-       if ((ea_len + sd_len > data_count) ||
-                       (ea_len > data_count) || (sd_len > data_count) ||
-                       (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
-               DEBUG(10,("call_nt_transact_create - ea_len = %u, sd_len = %u, data_count = %u\n",
-                       (unsigned int)ea_len, (unsigned int)sd_len, (unsigned int)data_count ));
-               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
-       }
-
-       if (ea_len) {
-               if (!lp_ea_support(SNUM(conn))) {
-                       DEBUG(10,("call_nt_transact_create - ea_len = %u but EA's not supported.\n",
-                               (unsigned int)ea_len ));
-                       return ERROR_NT(NT_STATUS_EAS_NOT_SUPPORTED);
-               }
-
-               if (ea_len < 10) {
-                       DEBUG(10,("call_nt_transact_create - ea_len = %u - too small (should be more than 10)\n",
-                               (unsigned int)ea_len ));
-                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
-               }
-       }
-
-       if (create_options & FILE_OPEN_BY_FILE_ID) {
-               return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
-       }
-
-       /*
-        * Get the file name.
-        */
-
-       if(root_dir_fid != 0) {
-               /*
-                * This filename is relative to a directory fid.
-                */
-               files_struct *dir_fsp = file_fsp(params,4);
-               size_t dir_name_len;
-
-               if(!dir_fsp) {
-                       return ERROR_DOS(ERRDOS,ERRbadfid);
-               }
-
-               if(!dir_fsp->is_directory) {
-                       srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               return ERROR_NT(status);
-                       }
-
-                       /*
-                        * Check to see if this is a mac fork of some kind.
-                        */
-
-                       if( is_ntfs_stream_name(fname)) {
-                               return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
-                       }
-
-                       return ERROR_DOS(ERRDOS,ERRbadfid);
-               }
-
-               /*
-                * Copy in the base directory name.
-                */
-
-               pstrcpy( fname, dir_fsp->fsp_name );
-               dir_name_len = strlen(fname);
-
-               /*
-                * Ensure it ends in a '\'.
-                */
-
-               if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
-                       pstrcat(fname, "/");
-                       dir_name_len++;
-               }
-
-               {
-                       pstring tmpname;
-                       srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               return ERROR_NT(status);
-                       }
-                       pstrcat(fname, tmpname);
-               }
-       } else {
-               srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return ERROR_NT(status);
-               }
-
-               /*
-                * Check to see if this is a mac fork of some kind.
-                */
-
-               if( is_ntfs_stream_name(fname)) {
-                       return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
-               }
+       /* Ensure the data_len is correct for the sd and ea values given. */
+       if ((ea_len + sd_len > data_count)
+           || (ea_len > data_count) || (sd_len > data_count)
+           || (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
+               DEBUG(10, ("call_nt_transact_create - ea_len = %u, sd_len = "
+                          "%u, data_count = %u\n", (unsigned int)ea_len,
+                          (unsigned int)sd_len, (unsigned int)data_count));
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
        }
 
-       oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
-       if (oplock_request) {
-               oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-       }
+       if (sd_len) {
+               DEBUG(10, ("call_nt_transact_create - sd_len = %d\n",
+                          sd_len));
 
-       /*
-        * Ordinary file or directory.
-        */
-               
-       /*
-        * Check if POSIX semantics are wanted.
-        */
-               
-       new_file_attributes = set_posix_case_semantics(conn, file_attributes);
-    
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+               status = unmarshall_sec_desc(ctx, (uint8_t *)data, sd_len,
+                                            &sd);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(10, ("call_nt_transact_create: "
+                                  "unmarshall_sec_desc failed: %s\n",
+                                  nt_errstr(status)));
+                       reply_nterror(req, status);
+                       return;
                }
-               return ERROR_NT(status);
        }
 
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
-       if (!NT_STATUS_IS_OK(status)) {
-               restore_case_semantics(conn, file_attributes);
-               return ERROR_NT(status);
-       }
-       /* All file access must go through check_name() */
-       status = check_name(conn, fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               restore_case_semantics(conn, file_attributes);
-               return ERROR_NT(status);
-       }
-
-       /* This is the correct thing to do (check every time) but can_delete is
-          expensive (it may have to read the parent directory permissions). So
-          for now we're not doing it unless we have a strong hint the client
-          is really going to delete this file. If the client is forcing FILE_CREATE
-          let the filesystem take care of the permissions. */
-
-       /* Setting FILE_SHARE_DELETE is the hint. */
-
-       if (lp_acl_check_permissions(SNUM(conn))
-           && (create_disposition != FILE_CREATE)
-           && (share_access & FILE_SHARE_DELETE)
-           && (access_mask & DELETE_ACCESS)) {
-               if ((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY) ||
-                               !can_delete_file_in_directory(conn, fname)) {
-                       restore_case_semantics(conn, file_attributes);
-                       return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+       if (ea_len) {
+               if (!lp_ea_support(SNUM(conn))) {
+                       DEBUG(10, ("call_nt_transact_create - ea_len = %u but "
+                                  "EA's not supported.\n",
+                                  (unsigned int)ea_len));
+                       reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
+                       return;
                }
-       }
 
-       if (ea_len) {
-               pdata = data + sd_len;
+               if (ea_len < 10) {
+                       DEBUG(10,("call_nt_transact_create - ea_len = %u - "
+                                 "too small (should be more than 10)\n",
+                                 (unsigned int)ea_len ));
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return;
+               }
 
                /* We have already checked that ea_len <= data_count here. */
-               ea_list = read_nttrans_ea_list(tmp_talloc_ctx(), pdata,
+               ea_list = read_nttrans_ea_list(talloc_tos(), data + sd_len,
                                               ea_len);
-               if (!ea_list ) {
-                       restore_case_semantics(conn, file_attributes);
-                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               if (ea_list == NULL) {
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return;
                }
        }
 
-       /*
-        * If it's a request for a directory open, deal with it separately.
-        */
-
-       if(create_options & FILE_DIRECTORY_FILE) {
+       srvstr_get_path(ctx, params, req->flags2, &fname,
+                       params+53, parameter_count-53,
+                       STR_TERMINATE, &status);
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               return;
+       }
 
-               /* Can't open a temp directory. IFS kit test. */
-               if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
-                       restore_case_semantics(conn, file_attributes);
-                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
-               }
+       oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+       if (oplock_request) {
+               oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
+                       ? BATCH_OPLOCK : 0;
+       }
 
-               /*
-                * We will get a create directory here if the Win32
-                * app specified a security descriptor in the 
-                * CreateDirectory() call.
-                */
+       status = create_file(conn, req, root_dir_fid, fname,
+                            access_mask, share_access, create_disposition,
+                            create_options, file_attributes, oplock_request,
+                            allocation_size, sd, ea_list, &fsp, &info, &sbuf);
 
-               oplock_request = 0;
-               status = open_directory(conn, fname, &sbuf,
-                                       access_mask,
-                                       share_access,
-                                       create_disposition,
-                                       create_options,
-                                       new_file_attributes,
-                                       &info, &fsp);
-               if(!NT_STATUS_IS_OK(status)) {
-                       restore_case_semantics(conn, file_attributes);
-                       return ERROR_NT(status);
+       if(!NT_STATUS_IS_OK(status)) {
+               if (open_was_deferred(req->mid)) {
+                       /* We have re-scheduled this call, no error. */
+                       return;
                }
-
-       } else {
-
-               /*
-                * Ordinary file case.
-                */
-
-               status = open_file_ntcreate(conn,fname,&sbuf,
-                                       access_mask,
-                                       share_access,
-                                       create_disposition,
-                                       create_options,
-                                       new_file_attributes,
-                                       oplock_request,
-                                       &info, &fsp);
-
-               if (!NT_STATUS_IS_OK(status)) { 
-                       if (NT_STATUS_EQUAL(status,
-                                           NT_STATUS_FILE_IS_A_DIRECTORY)) {
-
-                               /*
-                                * Fail the open if it was explicitly a non-directory file.
-                                */
-
-                               if (create_options & FILE_NON_DIRECTORY_FILE) {
-                                       restore_case_semantics(conn, file_attributes);
-                                       return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
-                               }
-       
-                               oplock_request = 0;
-                               status = open_directory(conn, fname, &sbuf,
-                                                       access_mask,
-                                                       share_access,
-                                                       create_disposition,
-                                                       create_options,
-                                                       new_file_attributes,
-                                                       &info, &fsp);
-                               if(!NT_STATUS_IS_OK(status)) {
-                                       restore_case_semantics(conn, file_attributes);
-                                       return ERROR_NT(status);
-                               }
-                       } else {
-                               restore_case_semantics(conn, file_attributes);
-                               if (open_was_deferred(SVAL(inbuf,smb_mid))) {
-                                       /* We have re-scheduled this call. */
-                                       return -1;
-                               }
-                               return ERROR_NT(status);
-                       }
-               } 
+               if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
+                       reply_botherror(req, status, ERRDOS, ERRfilexists);
+               }
+               else {
+                       reply_nterror(req, status);
+               }
+               return;
        }
 
        /*
-        * According to the MS documentation, the only time the security
-        * descriptor is applied to the opened file is iff we *created* the
-        * file; an existing file stays the same.
-        * 
-        * Also, it seems (from observation) that you can open the file with
-        * any access mask but you can still write the sd. We need to override
-        * the granted access before we call set_sd
-        * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
+        * If the caller set the extended oplock request bit
+        * and we granted one (by whatever means) - set the
+        * correct bit for extended oplock reply.
         */
 
-       if (lp_nt_acl_support(SNUM(conn)) && sd_len && info == FILE_WAS_CREATED) {
-               uint32 saved_access_mask = fsp->access_mask;
-
-               /* We have already checked that sd_len <= data_count here. */
+       if (oplock_request &&
+           (lp_fake_oplocks(SNUM(conn))
+            || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
 
-               fsp->access_mask = FILE_GENERIC_ALL;
+               /*
+                * Exclusive oplock granted
+                */
 
-               status = set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION);
-               if (!NT_STATUS_IS_OK(status)) {
-                       talloc_destroy(ctx);
-                       close_file(fsp,ERROR_CLOSE);
-                       restore_case_semantics(conn, file_attributes);
-                       return ERROR_NT(status);
-               }
-               fsp->access_mask = saved_access_mask;
-       }
-       
-       if (ea_len && (info == FILE_WAS_CREATED)) {
-               status = set_ea(conn, fsp, fname, ea_list);
-               if (!NT_STATUS_IS_OK(status)) {
-                       close_file(fsp,ERROR_CLOSE);
-                       restore_case_semantics(conn, file_attributes);
-                       return ERROR_NT(status);
+               if (flags & REQUEST_BATCH_OPLOCK) {
+                       oplock_granted = BATCH_OPLOCK_RETURN;
+               } else {
+                       oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
                }
+       } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
+               oplock_granted = LEVEL_II_OPLOCK_RETURN;
+       } else {
+               oplock_granted = NO_OPLOCK_RETURN;
        }
 
-       restore_case_semantics(conn, file_attributes);
-
        file_len = sbuf.st_size;
        fattr = dos_mode(conn,fname,&sbuf);
-       if(fattr == 0) {
+       if (fattr == 0) {
                fattr = FILE_ATTRIBUTE_NORMAL;
        }
-       if (!fsp->is_directory && (fattr & aDIR)) {
-               close_file(fsp,ERROR_CLOSE);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
-       } 
-       
-       /* Save the requested allocation size. */
-       if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
-               SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
-#ifdef LARGE_SMB_OFF_T
-               allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
-#endif
-               if (allocation_size && (allocation_size > file_len)) {
-                       fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
-                       if (fsp->is_directory) {
-                               close_file(fsp,ERROR_CLOSE);
-                               /* Can't set allocation size on a directory. */
-                               return ERROR_NT(NT_STATUS_ACCESS_DENIED);
-                       }
-                       if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
-                               close_file(fsp,ERROR_CLOSE);
-                               return ERROR_NT(NT_STATUS_DISK_FULL);
-                       }
-               } else {
-                       fsp->initial_allocation_size = smb_roundup(fsp->conn, (SMB_BIG_UINT)file_len);
-               }
-       }
-
-       /* 
-        * If the caller set the extended oplock request bit
-        * and we granted one (by whatever means) - set the
-        * correct bit for extended oplock reply.
-        */
-
-       if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
-               extended_oplock_granted = True;
-       }
-
-       if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
-               extended_oplock_granted = True;
-       }
 
        /* Realloc the size of parameters and data we will return */
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
@@ -1572,26 +1038,18 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        }
        params = nttrans_realloc(ppparams, param_len);
        if(params == NULL) {
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               reply_doserror(req, ERRDOS, ERRnomem);
+               return;
        }
 
        p = params;
-       if (extended_oplock_granted) {
-               if (flags & REQUEST_BATCH_OPLOCK) {
-                       SCVAL(p,0, BATCH_OPLOCK_RETURN);
-               } else {
-                       SCVAL(p,0, EXCLUSIVE_OPLOCK_RETURN);
-               }
-       } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
-               SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
-       } else {
-               SCVAL(p,0,NO_OPLOCK_RETURN);
-       }
-       
+       SCVAL(p, 0, oplock_granted);
+
        p += 2;
        SSVAL(p,0,fsp->fnum);
        p += 2;
-       if ((create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) {
+       if ((create_disposition == FILE_SUPERSEDE)
+           && (info == FILE_WAS_OVERWRITTEN)) {
                SIVAL(p,0,FILE_WAS_SUPERSEDED);
        } else {
                SIVAL(p,0,info);
@@ -1599,7 +1057,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        p += 8;
 
        /* Create time. */
-       c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+       c_timespec = get_create_timespec(
+               &sbuf,lp_fake_dir_create_times(SNUM(conn)));
        a_timespec = get_atimespec(&sbuf);
        m_timespec = get_mtimespec(&sbuf);
 
@@ -1632,7 +1091,8 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        if (flags & EXTENDED_RESPONSE_REQUIRED) {
                uint32 perms = 0;
                p += 25;
-               if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) {
+               if (fsp->is_directory
+                   || can_write_to_file(conn, fname, &sbuf)) {
                        perms = FILE_GENERIC_ALL;
                } else {
                        perms = FILE_GENERIC_READ|FILE_EXECUTE;
@@ -1643,9 +1103,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
        DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
 
        /* Send the required number of replies */
-       send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len, *ppdata, 0);
+       send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0);
 
-       return -1;
+       return;
 }
 
 /****************************************************************************
@@ -1653,34 +1113,39 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
  conn POINTER CAN BE NULL HERE !
 ****************************************************************************/
 
-int reply_ntcancel(connection_struct *conn,
-                  char *inbuf,char *outbuf,int length,int bufsize)
+void reply_ntcancel(connection_struct *conn, struct smb_request *req)
 {
        /*
         * Go through and cancel any pending change notifies.
         */
-       
-       int mid = SVAL(inbuf,smb_mid);
+
        START_PROFILE(SMBntcancel);
-       remove_pending_change_notify_requests_by_mid(mid);
-       remove_pending_lock_requests_by_mid(mid);
-       srv_cancel_sign_response(mid);
-       
-       DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
+       remove_pending_change_notify_requests_by_mid(req->mid);
+       remove_pending_lock_requests_by_mid(req->mid);
+       srv_cancel_sign_response(req->mid);
+
+       DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid));
 
        END_PROFILE(SMBntcancel);
-       return(-1);
+       return;
 }
 
 /****************************************************************************
  Copy a file.
 ****************************************************************************/
 
-static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *newname, uint32 attrs)
+static NTSTATUS copy_internals(TALLOC_CTX *ctx,
+                               connection_struct *conn,
+                               struct smb_request *req,
+                               const char *oldname_in,
+                               const char *newname_in,
+                               uint32 attrs)
 {
        SMB_STRUCT_STAT sbuf1, sbuf2;
-       pstring last_component_oldname;
-       pstring last_component_newname;
+       char *oldname = NULL;
+       char *newname = NULL;
+       char *last_component_oldname = NULL;
+       char *last_component_newname = NULL;
        files_struct *fsp1,*fsp2;
        uint32 fattr;
        int info;
@@ -1694,7 +1159,8 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
-       status = unix_convert(conn, oldname, False, last_component_oldname, &sbuf1);
+       status = unix_convert(ctx, conn, oldname_in, False, &oldname,
+                       &last_component_oldname, &sbuf1);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -1714,7 +1180,8 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
                return NT_STATUS_NO_SUCH_FILE;
        }
 
-       status = unix_convert(conn, newname, False, last_component_newname, &sbuf2);
+       status = unix_convert(ctx, conn, newname_in, False, &newname,
+                       &last_component_newname, &sbuf2);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -1735,14 +1202,15 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
        }
 
        /* Ensure this is within the share. */
-       status = reduce_name(conn, oldname);
+       status = check_reduced_name(conn, oldname);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
+       DEBUG(10,("copy_internals: doing file copy %s to %s\n",
+                               oldname, newname));
 
-        status = open_file_ntcreate(conn,oldname,&sbuf1,
+        status = open_file_ntcreate(conn, req, oldname, &sbuf1,
                        FILE_READ_DATA, /* Read-only. */
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                        FILE_OPEN,
@@ -1755,7 +1223,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
                return status;
        }
 
-        status = open_file_ntcreate(conn,newname,&sbuf2,
+        status = open_file_ntcreate(conn, req, newname, &sbuf2,
                        FILE_WRITE_DATA, /* Read-only. */
                        FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                        FILE_CREATE,
@@ -1790,7 +1258,7 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
           creates the file. This isn't the correct thing to do in the copy
           case. JRA */
        file_set_dosmode(conn, newname, fattr, &sbuf2,
-                        parent_dirname(newname));
+                        parent_dirname(newname),false);
 
        if (ret < (SMB_OFF_T)sbuf1.st_size) {
                return NT_STATUS_DISK_FULL;
@@ -1807,76 +1275,111 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
  Reply to a NT rename request.
 ****************************************************************************/
 
-int reply_ntrename(connection_struct *conn,
-                  char *inbuf,char *outbuf,int length,int bufsize)
+void reply_ntrename(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = 0;
-       pstring oldname;
-       pstring newname;
+       char *oldname = NULL;
+       char *newname = NULL;
        char *p;
        NTSTATUS status;
-       BOOL src_has_wcard = False;
-       BOOL dest_has_wcard = False;
-       uint32 attrs = SVAL(inbuf,smb_vwv0);
-       uint16 rename_type = SVAL(inbuf,smb_vwv1);
+       bool src_has_wcard = False;
+       bool dest_has_wcard = False;
+       uint32 attrs;
+       uint16 rename_type;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBntrename);
 
-       p = smb_buf(inbuf) + 1;
-       p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &src_has_wcard);
+       if (req->wct < 4) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBntrename);
+               return;
+       }
+
+       attrs = SVAL(req->inbuf,smb_vwv0);
+       rename_type = SVAL(req->inbuf,smb_vwv1);
+
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &oldname, p,
+                                  0, STR_TERMINATE, &status,
+                                  &src_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBntrename);
-               return ERROR_NT(status);
+               return;
        }
 
        if( is_ntfs_stream_name(oldname)) {
                /* Can't rename a stream. */
+               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                END_PROFILE(SMBntrename);
-               return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+               return;
        }
 
        if (ms_has_wild(oldname)) {
+               reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
                END_PROFILE(SMBntrename);
-               return ERROR_NT(NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
+               return;
        }
 
        p++;
-       p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wcard);
+       p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
+                                  0, STR_TERMINATE, &status,
+                                  &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBntrename);
-               return ERROR_NT(status);
+               return;
        }
-       
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, oldname);
+
+       status = resolve_dfspath(ctx, conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               oldname,
+                               &oldname);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBntrename);
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+                       reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
+                                       ERRSRV, ERRbadpath);
+                       END_PROFILE(SMBntrename);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBntrename);
+               return;
        }
 
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname);
+       status = resolve_dfspath(ctx, conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               newname,
+                               &newname);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBntrename);
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+                       reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
+                                       ERRSRV, ERRbadpath);
+                       END_PROFILE(SMBntrename);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBntrename);
+               return;
        }
 
        DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
-       
+
        switch(rename_type) {
                case RENAME_FLAG_RENAME:
-                       status = rename_internals(conn, oldname, newname, attrs, False, src_has_wcard, dest_has_wcard);
+                       status = rename_internals(ctx, conn, req, oldname,
+                                       newname, attrs, False, src_has_wcard,
+                                       dest_has_wcard);
                        break;
                case RENAME_FLAG_HARD_LINK:
                        if (src_has_wcard || dest_has_wcard) {
                                /* No wildcards. */
                                status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
                        } else {
-                               status = hardlink_internals(conn, oldname, newname);
+                               status = hardlink_internals(ctx,
+                                               conn,
+                                               oldname,
+                                               newname);
                        }
                        break;
                case RENAME_FLAG_COPY:
@@ -1884,7 +1387,8 @@ int reply_ntrename(connection_struct *conn,
                                /* No wildcards. */
                                status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
                        } else {
-                               status = copy_internals(conn, oldname, newname, attrs);
+                               status = copy_internals(ctx, conn, req, oldname,
+                                                       newname, attrs);
                        }
                        break;
                case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
@@ -1896,60 +1400,66 @@ int reply_ntrename(connection_struct *conn,
        }
 
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBntrename);
-               if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+               if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       return -1;
+                       END_PROFILE(SMBntrename);
+                       return;
                }
-               return ERROR_NT(status);
+
+               reply_nterror(req, status);
+               END_PROFILE(SMBntrename);
+               return;
        }
 
-       outsize = set_message(inbuf,outbuf,0,0,False);
-  
+       reply_outbuf(req, 0, 0);
+
        END_PROFILE(SMBntrename);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
- Reply to a notify change - queue the request and 
+ Reply to a notify change - queue the request and
  don't allow a directory to be opened.
 ****************************************************************************/
 
-static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
-                                         char *outbuf, int length,
-                                         int bufsize, 
-                                         uint16 **ppsetup, uint32 setup_count,
-                                         char **ppparams,
-                                         uint32 parameter_count,
-                                         char **ppdata, uint32 data_count,
-                                         uint32 max_data_count,
-                                         uint32 max_param_count)
+static void call_nt_transact_notify_change(connection_struct *conn,
+                                          struct smb_request *req,
+                                          uint16 **ppsetup,
+                                          uint32 setup_count,
+                                          char **ppparams,
+                                          uint32 parameter_count,
+                                          char **ppdata, uint32 data_count,
+                                          uint32 max_data_count,
+                                          uint32 max_param_count)
 {
        uint16 *setup = *ppsetup;
        files_struct *fsp;
        uint32 filter;
        NTSTATUS status;
-       BOOL recursive;
+       bool recursive;
 
        if(setup_count < 6) {
-               return ERROR_DOS(ERRDOS,ERRbadfunc);
+               reply_doserror(req, ERRDOS, ERRbadfunc);
+               return;
        }
 
-       fsp = file_fsp((char *)setup,4);
+       fsp = file_fsp(SVAL(setup,4));
        filter = IVAL(setup, 0);
        recursive = (SVAL(setup, 6) != 0) ? True : False;
 
        DEBUG(3,("call_nt_transact_notify_change\n"));
 
        if(!fsp) {
-               return ERROR_DOS(ERRDOS,ERRbadfid);
+               reply_doserror(req, ERRDOS, ERRbadfid);
+               return;
        }
 
        {
                char *filter_string;
 
                if (!(filter_string = notify_filter_string(NULL, filter))) {
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+                       reply_nterror(req,NT_STATUS_NO_MEMORY);
+                       return;
                }
 
                DEBUG(3,("call_nt_transact_notify_change: notify change "
@@ -1960,7 +1470,8 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
        }
 
        if((!fsp->is_directory) || (conn != fsp->conn)) {
-               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
        }
 
        if (fsp->notify == NULL) {
@@ -1970,7 +1481,8 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(10, ("change_notify_create returned %s\n",
                                   nt_errstr(status)));
-                       return ERROR_NT(status);
+                       reply_nterror(req, status);
+                       return;
                }
        }
 
@@ -1985,103 +1497,124 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
                 * here.
                 */
 
-               change_notify_reply(inbuf, fsp->notify);
+               change_notify_reply(req->inbuf, max_param_count, fsp->notify);
 
                /*
                 * change_notify_reply() above has independently sent its
                 * results
                 */
-               return -1;
+               return;
        }
 
        /*
         * No changes pending, queue the request
         */
 
-       status = change_notify_add_request(inbuf, filter, recursive, fsp);
+       status = change_notify_add_request(req->inbuf, max_param_count, filter,
+                       recursive, fsp);
        if (!NT_STATUS_IS_OK(status)) {
-               return ERROR_NT(status);
+               reply_nterror(req, status);
        }
-
-       return -1;
+       return;
 }
 
 /****************************************************************************
  Reply to an NT transact rename command.
 ****************************************************************************/
 
-static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count, uint32 max_data_count)
+static void call_nt_transact_rename(connection_struct *conn,
+                                   struct smb_request *req,
+                                   uint16 **ppsetup, uint32 setup_count,
+                                   char **ppparams, uint32 parameter_count,
+                                   char **ppdata, uint32 data_count,
+                                   uint32 max_data_count)
 {
        char *params = *ppparams;
-       pstring new_name;
+       char *new_name = NULL;
        files_struct *fsp = NULL;
-       BOOL replace_if_exists = False;
-       BOOL dest_has_wcard = False;
+       bool replace_if_exists = False;
+       bool dest_has_wcard = False;
        NTSTATUS status;
+       TALLOC_CTX *ctx = talloc_tos();
 
         if(parameter_count < 5) {
-               return ERROR_DOS(ERRDOS,ERRbadfunc);
+               reply_doserror(req, ERRDOS, ERRbadfunc);
+               return;
        }
 
-       fsp = file_fsp(params, 0);
+       fsp = file_fsp(SVAL(params, 0));
        replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
-       CHECK_FSP(fsp, conn);
-       srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), parameter_count - 4,
-                       STR_TERMINATE, &status, &dest_has_wcard);
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               return;
+       }
+       srvstr_get_path_wcard(ctx, params, req->flags2, &new_name, params+4,
+                             parameter_count - 4,
+                             STR_TERMINATE, &status, &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               return;
        }
 
-       status = rename_internals(conn, fsp->fsp_name,
-                                 new_name, 0, replace_if_exists, False, dest_has_wcard);
+       status = rename_internals(ctx,
+                       conn,
+                       req,
+                       fsp->fsp_name,
+                       new_name,
+                       0,
+                       replace_if_exists,
+                       False,
+                       dest_has_wcard);
 
        if (!NT_STATUS_IS_OK(status)) {
-               if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+               if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       return -1;
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               return;
        }
 
        /*
         * Rename was successful.
         */
-       send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
-       
-       DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n", 
+       send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+
+       DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
                 fsp->fsp_name, new_name));
-       
-       return -1;
+
+       return;
 }
 
 /******************************************************************************
  Fake up a completely empty SD.
 *******************************************************************************/
 
-static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
+static NTSTATUS get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
 {
        size_t sd_size;
 
        *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
        if(!*ppsd) {
                DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
-               sd_size = 0;
+               return NT_STATUS_NO_MEMORY;
        }
 
-       return sd_size;
+       return NT_STATUS_OK;
 }
 
 /****************************************************************************
  Reply to query a security descriptor.
 ****************************************************************************/
 
-static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count, uint32 max_data_count)
+static void call_nt_transact_query_security_desc(connection_struct *conn,
+                                                struct smb_request *req,
+                                                uint16 **ppsetup,
+                                                uint32 setup_count,
+                                                char **ppparams,
+                                                uint32 parameter_count,
+                                                char **ppdata,
+                                                uint32 data_count,
+                                                uint32 max_data_count)
 {
        char *params = *ppparams;
        char *data = *ppdata;
@@ -2091,14 +1624,17 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i
        uint32 security_info_wanted;
        TALLOC_CTX *mem_ctx;
        files_struct *fsp = NULL;
+       NTSTATUS status;
 
         if(parameter_count < 8) {
-               return ERROR_DOS(ERRDOS,ERRbadfunc);
+               reply_doserror(req, ERRDOS, ERRbadfunc);
+               return;
        }
 
-       fsp = file_fsp(params,0);
+       fsp = file_fsp(SVAL(params,0));
        if(!fsp) {
-               return ERROR_DOS(ERRDOS,ERRbadfid);
+               reply_doserror(req, ERRDOS, ERRbadfid);
+               return;
        }
 
        security_info_wanted = IVAL(params,4);
@@ -2108,12 +1644,14 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i
 
        params = nttrans_realloc(ppparams, 4);
        if(params == NULL) {
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               reply_doserror(req, ERRDOS, ERRnomem);
+               return;
        }
 
        if ((mem_ctx = talloc_init("call_nt_transact_query_security_desc")) == NULL) {
                DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               reply_doserror(req, ERRDOS, ERRnomem);
+               return;
        }
 
        /*
@@ -2121,26 +1659,30 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i
         */
 
        if (!lp_nt_acl_support(SNUM(conn))) {
-               sd_size = get_null_nt_acl(mem_ctx, &psd);
+               status = get_null_nt_acl(mem_ctx, &psd);
        } else {
-               sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, security_info_wanted, &psd);
+               status = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd,
+                                            security_info_wanted, &psd);
        }
 
-       if (sd_size == 0) {
+       if (!NT_STATUS_IS_OK(status)) {
                talloc_destroy(mem_ctx);
-               return(UNIXERROR(ERRDOS,ERRnoaccess));
+               reply_nterror(req, status);
+               return;
        }
 
+       sd_size = sec_desc_size(psd);
+
        DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
 
        SIVAL(params,0,(uint32)sd_size);
 
        if(max_data_count < sd_size) {
 
-               send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
+               send_nt_replies(req, NT_STATUS_BUFFER_TOO_SMALL,
                                params, 4, *ppdata, 0);
                talloc_destroy(mem_ctx);
-               return -1;
+               return;
        }
 
        /*
@@ -2150,7 +1692,8 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i
        data = nttrans_realloc(ppdata, sd_size);
        if(data == NULL) {
                talloc_destroy(mem_ctx);
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               reply_doserror(req, ERRDOS, ERRnomem);
+               return;
        }
 
        /*
@@ -2175,9 +1718,10 @@ static int call_nt_transact_query_security_desc(connection_struct *conn, char *i
 security descriptor.\n"));
                /*
                 * Return access denied for want of a better error message..
-                */ 
+                */
                talloc_destroy(mem_ctx);
-               return(UNIXERROR(ERRDOS,ERRnoaccess));
+               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               return;
        }
 
        /*
@@ -2186,19 +1730,23 @@ security descriptor.\n"));
 
        talloc_destroy(mem_ctx);
 
-       send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, 4, data,
-                       (int)sd_size);
-       return -1;
+       send_nt_replies(req, NT_STATUS_OK, params, 4, data, (int)sd_size);
+       return;
 }
 
 /****************************************************************************
  Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
 ****************************************************************************/
 
-static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count, uint32 max_data_count)
+static void call_nt_transact_set_security_desc(connection_struct *conn,
+                                              struct smb_request *req,
+                                              uint16 **ppsetup,
+                                              uint32 setup_count,
+                                              char **ppparams,
+                                              uint32 parameter_count,
+                                              char **ppdata,
+                                              uint32 data_count,
+                                              uint32 max_data_count)
 {
        char *params= *ppparams;
        char *data = *ppdata;
@@ -2207,11 +1755,13 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inb
        NTSTATUS nt_status;
 
        if(parameter_count < 8) {
-               return ERROR_DOS(ERRDOS,ERRbadfunc);
+               reply_doserror(req, ERRDOS, ERRbadfunc);
+               return;
        }
 
-       if((fsp = file_fsp(params,0)) == NULL) {
-               return ERROR_DOS(ERRDOS,ERRbadfid);
+       if((fsp = file_fsp(SVAL(params,0))) == NULL) {
+               reply_doserror(req, ERRDOS, ERRbadfid);
+               return;
        }
 
        if(!lp_nt_acl_support(SNUM(conn))) {
@@ -2224,39 +1774,44 @@ static int call_nt_transact_set_security_desc(connection_struct *conn, char *inb
                (unsigned int)security_info_sent ));
 
        if (data_count == 0) {
-               return ERROR_DOS(ERRDOS, ERRnoaccess);
+               reply_doserror(req, ERRDOS, ERRnoaccess);
+               return;
        }
 
        if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent))) {
-               return ERROR_NT(nt_status);
+               reply_nterror(req, nt_status);
+               return;
        }
 
   done:
 
-       send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
-       return -1;
+       send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+       return;
 }
-   
+
 /****************************************************************************
  Reply to NT IOCTL
 ****************************************************************************/
 
-static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count, uint32 max_data_count)
+static void call_nt_transact_ioctl(connection_struct *conn,
+                                  struct smb_request *req,
+                                  uint16 **ppsetup, uint32 setup_count,
+                                  char **ppparams, uint32 parameter_count,
+                                  char **ppdata, uint32 data_count,
+                                  uint32 max_data_count)
 {
        uint32 function;
        uint16 fidnum;
        files_struct *fsp;
        uint8 isFSctl;
        uint8 compfilter;
-       static BOOL logged_message;
+       static bool logged_message;
        char *pdata = *ppdata;
 
        if (setup_count != 8) {
                DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
-               return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+               reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
+               return;
        }
 
        function = IVAL(*ppsetup, 0);
@@ -2267,7 +1822,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
        DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 
                 function, fidnum, isFSctl, compfilter));
 
-       fsp=file_fsp((char *)*ppsetup, 4);
+       fsp=file_fsp(fidnum);
        /* this check is done in each implemented function case for now
           because I don't want to break anything... --metze
        FSP_BELONGS_CONN(fsp,conn);*/
@@ -2279,10 +1834,9 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                   so we can know if we need to pre-allocate or not */
 
                DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
-               send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL,
-                               0);
-               return -1;
-       
+               send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+               return;
+
        case FSCTL_CREATE_OR_GET_OBJECT_ID:
        {
                unsigned char objid[16];
@@ -2293,16 +1847,22 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
 
                DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fidnum));
 
+               if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
+                       return;
+               }
+
                data_count = 64;
                pdata = nttrans_realloc(ppdata, data_count);
                if (pdata == NULL) {
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       return;
                }
                push_file_id_16(pdata, &fsp->file_id);
                memcpy(pdata+16,create_volume_objectid(conn,objid),16);
                push_file_id_16(pdata+32, &fsp->file_id);
-               send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count);
-               return -1;
+               send_nt_replies(req, NT_STATUS_OK, NULL, 0,
+                               pdata, data_count);
+               return;
        }
 
        case FSCTL_GET_REPARSE_POINT:
@@ -2311,7 +1871,8 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                 */
 
                DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
-               return ERROR_NT(NT_STATUS_NOT_A_REPARSE_POINT);
+               reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT);
+               return;
 
        case FSCTL_SET_REPARSE_POINT:
                /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
@@ -2319,8 +1880,9 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                 */
 
                DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
-               return ERROR_NT(NT_STATUS_NOT_A_REPARSE_POINT);
-                       
+               reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT);
+               return;
+
        case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
        {
                /*
@@ -2335,17 +1897,20 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                 */
                SHADOW_COPY_DATA *shadow_data = NULL;
                TALLOC_CTX *shadow_mem_ctx = NULL;
-               BOOL labels = False;
+               bool labels = False;
                uint32 labels_data_count = 0;
                uint32 i;
                char *cur_pdata;
 
-               FSP_BELONGS_CONN(fsp,conn);
+               if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
+                       return;
+               }
 
                if (max_data_count < 16) {
                        DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
                                max_data_count));
-                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return;
                }
 
                if (max_data_count > 16) {
@@ -2355,18 +1920,20 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
                if (shadow_mem_ctx == NULL) {
                        DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       return;
                }
 
                shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
                if (shadow_data == NULL) {
                        DEBUG(0,("TALLOC_ZERO() failed!\n"));
                        talloc_destroy(shadow_mem_ctx);
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       return;
                }
-               
+
                shadow_data->mem_ctx = shadow_mem_ctx;
-               
+
                /*
                 * Call the VFS routine to actually do the work.
                 */
@@ -2375,11 +1942,13 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                        if (errno == ENOSYS) {
                                DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 
                                        conn->connectpath));
-                               return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+                               reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
+                               return;
                        } else {
                                DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 
                                        conn->connectpath));
-                               return ERROR_NT(NT_STATUS_UNSUCCESSFUL);                        
+                               reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
+                               return;
                        }
                }
 
@@ -2395,14 +1964,16 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                        DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
                                max_data_count,data_count));
                        talloc_destroy(shadow_data->mem_ctx);
-                       return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
+                       reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
+                       return;
                }
 
                pdata = nttrans_realloc(ppdata, data_count);
                if (pdata == NULL) {
                        talloc_destroy(shadow_data->mem_ctx);
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
-               }               
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       return;
+               }
 
                cur_pdata = pdata;
 
@@ -2423,7 +1994,10 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                        shadow_data->num_volumes,fsp->fsp_name));
                if (labels && shadow_data->labels) {
                        for (i=0;i<shadow_data->num_volumes;i++) {
-                               srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
+                               srvstr_push(pdata, req->flags2,
+                                           cur_pdata, shadow_data->labels[i],
+                                           2*sizeof(SHADOW_COPY_LABEL),
+                                           STR_UNICODE|STR_TERMINATE);
                                cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
                                DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
                        }
@@ -2431,16 +2005,16 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
 
                talloc_destroy(shadow_data->mem_ctx);
 
-               send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0,
+               send_nt_replies(req, NT_STATUS_OK, NULL, 0,
                                pdata, data_count);
 
-               return -1;
+               return;
         }
-        
+
        case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
        {
-               /* pretend this succeeded - 
-                * 
+               /* pretend this succeeded -
+                *
                 * we have to send back a list with all files owned by this SID
                 *
                 * but I have to check that --metze
@@ -2448,23 +2022,26 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                DOM_SID sid;
                uid_t uid;
                size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
-               
+
                DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
 
-               FSP_BELONGS_CONN(fsp,conn);
+               if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
+                       return;
+               }
 
                /* unknown 4 bytes: this is not the length of the sid :-(  */
                /*unknown = IVAL(pdata,0);*/
-               
+
                sid_parse(pdata+4,sid_len,&sid);
-               DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
+               DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
 
                if (!sid_to_uid(&sid, &uid)) {
                        DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
-                               sid_string_static(&sid),(unsigned long)sid_len));
+                                sid_string_dbg(&sid),
+                                (unsigned long)sid_len));
                        uid = (-1);
                }
-               
+
                /* we can take a look at the find source :-)
                 *
                 * find ./ -uid $uid  -name '*'   is what we need here
@@ -2477,17 +2054,16 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                 * (maybe we can hang the result anywhere in the fsp struct)
                 *
                 * we don't send all files at once
-                * and at the next we should *not* start from the beginning, 
-                * so we have to cache the result 
+                * and at the next we should *not* start from the beginning,
+                * so we have to cache the result
                 *
                 * --metze
                 */
-               
+
                /* this works for now... */
-               send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0,
-                               NULL, 0);
-               return -1;      
-       }       
+               send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
+               return;
+       }
        default:
                if (!logged_message) {
                        logged_message = True; /* Only print this once... */
@@ -2496,19 +2072,24 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
                }
        }
 
-       return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+       reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
 }
 
 
 #ifdef HAVE_SYS_QUOTAS
 /****************************************************************************
- Reply to get user quota 
+ Reply to get user quota
 ****************************************************************************/
 
-static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count, uint32 max_data_count)
+static void call_nt_transact_get_user_quota(connection_struct *conn,
+                                           struct smb_request *req,
+                                           uint16 **ppsetup,
+                                           uint32 setup_count,
+                                           char **ppparams,
+                                           uint32 parameter_count,
+                                           char **ppdata,
+                                           uint32 data_count,
+                                           uint32 max_data_count)
 {
        NTSTATUS nt_status = NT_STATUS_OK;
        char *params = *ppparams;
@@ -2521,7 +2102,7 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
        uint16 level = 0;
        size_t sid_len;
        DOM_SID sid;
-       BOOL start_enum = True;
+       bool start_enum = True;
        SMB_NTQUOTA_STRUCT qt;
        SMB_NTQUOTA_LIST *tmp_list;
        SMB_NTQUOTA_HANDLE *qt_handle = NULL;
@@ -2532,7 +2113,8 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
        if (current_user.ut.uid != 0) {
                DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
                        lp_servicename(SNUM(conn)),conn->user));
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               reply_doserror(req, ERRDOS, ERRnoaccess);
+               return;
        }
 
        /*
@@ -2541,14 +2123,16 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
 
        if (parameter_count < 4) {
                DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
-               return ERROR_DOS(ERRDOS,ERRinvalidparam);
+               reply_doserror(req, ERRDOS, ERRinvalidparam);
+               return;
        }
-       
+
        /* maybe we can check the quota_fnum */
-       fsp = file_fsp(params,0);
+       fsp = file_fsp(SVAL(params,0));
        if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
                DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
-               return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+               reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+               return;
        }
 
        /* the NULL pointer checking for fsp->fake_file_handle->pd
@@ -2557,16 +2141,16 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
        qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
 
        level = SVAL(params,2);
-       
-       /* unknown 12 bytes leading in params */ 
-       
+
+       /* unknown 12 bytes leading in params */
+
        switch (level) {
                case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
                        /* seems that we should continue with the enum here --metze */
 
-                       if (qt_handle->quota_list!=NULL && 
+                       if (qt_handle->quota_list!=NULL &&
                            qt_handle->tmp_list==NULL) {
-               
+
                                /* free the list */
                                free_ntquota_list(&(qt_handle->quota_list));
 
@@ -2574,7 +2158,8 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
                                param_len = 4;
                                params = nttrans_realloc(ppparams, param_len);
                                if(params == NULL) {
-                                       return ERROR_DOS(ERRDOS,ERRnomem);
+                                       reply_doserror(req, ERRDOS, ERRnomem);
+                                       return;
                                }
 
                                data_len = 0;
@@ -2592,29 +2177,33 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
                                start_enum = True;
                        }
 
-                       if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0)
-                               return ERROR_DOS(ERRSRV,ERRerror);
+                       if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) {
+                               reply_doserror(req, ERRSRV, ERRerror);
+                               return;
+                       }
 
                        /* Realloc the size of parameters and data we will return */
                        param_len = 4;
                        params = nttrans_realloc(ppparams, param_len);
                        if(params == NULL) {
-                               return ERROR_DOS(ERRDOS,ERRnomem);
+                               reply_doserror(req, ERRDOS, ERRnomem);
+                               return;
                        }
 
                        /* we should not trust the value in max_data_count*/
                        max_data_count = MIN(max_data_count,2048);
-                       
+
                        pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
                        if(pdata == NULL) {
-                               return ERROR_DOS(ERRDOS,ERRnomem);
+                               reply_doserror(req, ERRDOS, ERRnomem);
+                               return;
                        }
 
                        entry = pdata;
 
                        /* set params Size of returned Quota Data 4 bytes*/
                        /* but set it later when we know it */
-               
+
                        /* for each entry push the data */
 
                        if (start_enum) {
@@ -2631,28 +2220,28 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
 
                                /* nextoffset entry 4 bytes */
                                SIVAL(entry,0,entry_len);
-               
+
                                /* then the len of the SID 4 bytes */
                                SIVAL(entry,4,sid_len);
-                               
+
                                /* unknown data 8 bytes SMB_BIG_UINT */
                                SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
-                               
+
                                /* the used disk space 8 bytes SMB_BIG_UINT */
                                SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
-                               
+
                                /* the soft quotas 8 bytes SMB_BIG_UINT */
                                SBIG_UINT(entry,24,tmp_list->quotas->softlim);
-                               
+
                                /* the hard quotas 8 bytes SMB_BIG_UINT */
                                SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
-                               
+
                                /* and now the SID */
                                sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
                        }
-                       
+
                        qt_handle->tmp_list = tmp_list;
-                       
+
                        /* overwrite the offset of the last entry */
                        SIVAL(entry-entry_len,0,0);
 
@@ -2663,23 +2252,26 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
                        break;
 
                case TRANSACT_GET_USER_QUOTA_FOR_SID:
-                       
-                       /* unknown 4 bytes IVAL(pdata,0) */     
-                       
+
+                       /* unknown 4 bytes IVAL(pdata,0) */
+
                        if (data_count < 8) {
                                DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
-                               return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
+                               reply_doserror(req, ERRDOS, ERRunknownlevel);
+                               return;
                        }
 
                        sid_len = IVAL(pdata,4);
                        /* Ensure this is less than 1mb. */
                        if (sid_len > (1024*1024)) {
-                               return ERROR_DOS(ERRDOS,ERRnomem);
+                               reply_doserror(req, ERRDOS, ERRnomem);
+                               return;
                        }
 
                        if (data_count < 8+sid_len) {
                                DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
-                               return ERROR_DOS(ERRDOS,ERRunknownlevel);                               
+                               reply_doserror(req, ERRDOS, ERRunknownlevel);
+                               return;
                        }
 
                        data_len = 4+40+sid_len;
@@ -2695,11 +2287,11 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
                        }
 
                        sid_parse(pdata+8,sid_len,&sid);
-               
+
                        if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
                                ZERO_STRUCT(qt);
-                               /* 
-                                * we have to return zero's in all fields 
+                               /*
+                                * we have to return zero's in all fields
                                 * instead of returning an error here
                                 * --metze
                                 */
@@ -2709,37 +2301,39 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
                        param_len = 4;
                        params = nttrans_realloc(ppparams, param_len);
                        if(params == NULL) {
-                               return ERROR_DOS(ERRDOS,ERRnomem);
+                               reply_doserror(req, ERRDOS, ERRnomem);
+                               return;
                        }
 
                        pdata = nttrans_realloc(ppdata, data_len);
                        if(pdata == NULL) {
-                               return ERROR_DOS(ERRDOS,ERRnomem);
+                               reply_doserror(req, ERRDOS, ERRnomem);
+                               return;
                        }
 
                        entry = pdata;
 
                        /* set params Size of returned Quota Data 4 bytes*/
                        SIVAL(params,0,data_len);
-       
+
                        /* nextoffset entry 4 bytes */
                        SIVAL(entry,0,0);
-       
+
                        /* then the len of the SID 4 bytes */
                        SIVAL(entry,4,sid_len);
-                       
+
                        /* unknown data 8 bytes SMB_BIG_UINT */
                        SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
-                       
+
                        /* the used disk space 8 bytes SMB_BIG_UINT */
                        SBIG_UINT(entry,16,qt.usedspace);
-                       
+
                        /* the soft quotas 8 bytes SMB_BIG_UINT */
                        SBIG_UINT(entry,24,qt.softlim);
-                       
+
                        /* the hard quotas 8 bytes SMB_BIG_UINT */
                        SBIG_UINT(entry,32,qt.hardlim);
-                       
+
                        /* and now the SID */
                        sid_linearize(entry+40, sid_len, &sid);
 
@@ -2747,24 +2341,28 @@ static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf,
 
                default:
                        DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
-                       return ERROR_DOS(ERRSRV,ERRerror);
+                       reply_doserror(req, ERRSRV, ERRerror);
+                       return;
                        break;
        }
 
-       send_nt_replies(inbuf, outbuf, bufsize, nt_status, params, param_len,
+       send_nt_replies(req, nt_status, params, param_len,
                        pdata, data_len);
-
-       return -1;
 }
 
 /****************************************************************************
  Reply to set user quota
 ****************************************************************************/
 
-static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, 
-                                  uint16 **ppsetup, uint32 setup_count,
-                                 char **ppparams, uint32 parameter_count,
-                                 char **ppdata, uint32 data_count, uint32 max_data_count)
+static void call_nt_transact_set_user_quota(connection_struct *conn,
+                                           struct smb_request *req,
+                                           uint16 **ppsetup,
+                                           uint32 setup_count,
+                                           char **ppparams,
+                                           uint32 parameter_count,
+                                           char **ppdata,
+                                           uint32 data_count,
+                                           uint32 max_data_count)
 {
        char *params = *ppparams;
        char *pdata = *ppdata;
@@ -2780,7 +2378,8 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf,
        if (current_user.ut.uid != 0) {
                DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
                        lp_servicename(SNUM(conn)),conn->user));
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               reply_doserror(req, ERRDOS, ERRnoaccess);
+               return;
        }
 
        /*
@@ -2789,19 +2388,22 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf,
 
        if (parameter_count < 2) {
                DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
-               return ERROR_DOS(ERRDOS,ERRinvalidparam);
+               reply_doserror(req, ERRDOS, ERRinvalidparam);
+               return;
        }
-       
+
        /* maybe we can check the quota_fnum */
-       fsp = file_fsp(params,0);
+       fsp = file_fsp(SVAL(params,0));
        if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
                DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
-               return ERROR_NT(NT_STATUS_INVALID_HANDLE);
+               reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+               return;
        }
 
        if (data_count < 40) {
                DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
-               return ERROR_DOS(ERRDOS,ERRunknownlevel);               
+               reply_doserror(req, ERRDOS, ERRunknownlevel);
+               return;
        }
 
        /* offset to next quota record.
@@ -2814,10 +2416,11 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf,
 
        if (data_count < 40+sid_len) {
                DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
-               return ERROR_DOS(ERRDOS,ERRunknownlevel);               
+               reply_doserror(req, ERRDOS, ERRunknownlevel);
+               return;
        }
 
-       /* unknown 8 bytes in pdata 
+       /* unknown 8 bytes in pdata
         * maybe its the change time in NTTIME
         */
 
@@ -2830,7 +2433,8 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf,
                ((qt.usedspace != 0xFFFFFFFF)||
                (IVAL(pdata,20)!=0xFFFFFFFF))) {
                /* more than 32 bits? */
-               return ERROR_DOS(ERRDOS,ERRunknownlevel);
+               reply_doserror(req, ERRDOS, ERRunknownlevel);
+               return;
        }
 #endif /* LARGE_SMB_OFF_T */
 
@@ -2843,7 +2447,8 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf,
                ((qt.softlim != 0xFFFFFFFF)||
                (IVAL(pdata,28)!=0xFFFFFFFF))) {
                /* more than 32 bits? */
-               return ERROR_DOS(ERRDOS,ERRunknownlevel);
+               reply_doserror(req, ERRDOS, ERRunknownlevel);
+               return;
        }
 #endif /* LARGE_SMB_OFF_T */
 
@@ -2856,34 +2461,33 @@ static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf,
                ((qt.hardlim != 0xFFFFFFFF)||
                (IVAL(pdata,36)!=0xFFFFFFFF))) {
                /* more than 32 bits? */
-               return ERROR_DOS(ERRDOS,ERRunknownlevel);
+               reply_doserror(req, ERRDOS, ERRunknownlevel);
+               return;
        }
 #endif /* LARGE_SMB_OFF_T */
-       
+
        sid_parse(pdata+40,sid_len,&sid);
-       DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
+       DEBUGADD(8,("SID: %s\n", sid_string_dbg(&sid)));
 
        /* 44 unknown bytes left... */
 
        if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
-               return ERROR_DOS(ERRSRV,ERRerror);      
+               reply_doserror(req, ERRSRV, ERRerror);
+               return;
        }
 
-       send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, params, param_len,
+       send_nt_replies(req, NT_STATUS_OK, params, param_len,
                        pdata, data_len);
-
-       return -1;
 }
 #endif /* HAVE_SYS_QUOTAS */
 
-static int handle_nttrans(connection_struct *conn,
-                         struct trans_state *state,
-                         char *inbuf, char *outbuf, int size, int bufsize)
+static void handle_nttrans(connection_struct *conn,
+                          struct trans_state *state,
+                          struct smb_request *req)
 {
-       int outsize;
-
        if (Protocol >= PROTOCOL_NT1) {
-               SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
+               req->flags2 |= 0x40; /* IS_LONG_NAME */
+               SSVAL(req->inbuf,smb_flg2,req->flags2);
        }
 
        /* Now we must call the relevant NT_TRANS function */
@@ -2891,12 +2495,12 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_CREATE:
                {
                        START_PROFILE(NT_transact_create);
-                       outsize = call_nt_transact_create(conn, inbuf, outbuf,
-                                                         size, bufsize, 
-                                                       &state->setup, state->setup_count,
-                                                       &state->param, state->total_param, 
-                                                       &state->data, state->total_data,
-                                                         state->max_data_return);
+                       call_nt_transact_create(
+                               conn, req,
+                               &state->setup, state->setup_count,
+                               &state->param, state->total_param,
+                               &state->data, state->total_data,
+                               state->max_data_return);
                        END_PROFILE(NT_transact_create);
                        break;
                }
@@ -2904,11 +2508,12 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_IOCTL:
                {
                        START_PROFILE(NT_transact_ioctl);
-                       outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
-                                                        size, bufsize, 
-                                                        &state->setup, state->setup_count,
-                                                        &state->param, state->total_param, 
-                                                        &state->data, state->total_data, state->max_data_return);
+                       call_nt_transact_ioctl(
+                               conn, req,
+                               &state->setup, state->setup_count,
+                               &state->param, state->total_param,
+                               &state->data, state->total_data,
+                               state->max_data_return);
                        END_PROFILE(NT_transact_ioctl);
                        break;
                }
@@ -2916,11 +2521,12 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_SET_SECURITY_DESC:
                {
                        START_PROFILE(NT_transact_set_security_desc);
-                       outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf, 
-                                                        size, bufsize, 
-                                                        &state->setup, state->setup_count,
-                                                        &state->param, state->total_param, 
-                                                        &state->data, state->total_data, state->max_data_return);
+                       call_nt_transact_set_security_desc(
+                               conn, req,
+                               &state->setup, state->setup_count,
+                               &state->param, state->total_param,
+                               &state->data, state->total_data,
+                               state->max_data_return);
                        END_PROFILE(NT_transact_set_security_desc);
                        break;
                }
@@ -2928,10 +2534,10 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_NOTIFY_CHANGE:
                {
                        START_PROFILE(NT_transact_notify_change);
-                       outsize = call_nt_transact_notify_change(
-                               conn, inbuf, outbuf, size, bufsize, 
+                       call_nt_transact_notify_change(
+                               conn, req,
                                &state->setup, state->setup_count,
-                               &state->param, state->total_param, 
+                               &state->param, state->total_param,
                                &state->data, state->total_data,
                                state->max_data_return,
                                state->max_param_return);
@@ -2942,11 +2548,12 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_RENAME:
                {
                        START_PROFILE(NT_transact_rename);
-                       outsize = call_nt_transact_rename(conn, inbuf, outbuf,
-                                                        size, bufsize, 
-                                                        &state->setup, state->setup_count,
-                                                        &state->param, state->total_param, 
-                                                        &state->data, state->total_data, state->max_data_return);
+                       call_nt_transact_rename(
+                               conn, req,
+                               &state->setup, state->setup_count,
+                               &state->param, state->total_param,
+                               &state->data, state->total_data,
+                               state->max_data_return);
                        END_PROFILE(NT_transact_rename);
                        break;
                }
@@ -2954,11 +2561,12 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_QUERY_SECURITY_DESC:
                {
                        START_PROFILE(NT_transact_query_security_desc);
-                       outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf, 
-                                                        size, bufsize, 
-                                                        &state->setup, state->setup_count,
-                                                        &state->param, state->total_param, 
-                                                        &state->data, state->total_data, state->max_data_return);
+                       call_nt_transact_query_security_desc(
+                               conn, req,
+                               &state->setup, state->setup_count,
+                               &state->param, state->total_param,
+                               &state->data, state->total_data,
+                               state->max_data_return);
                        END_PROFILE(NT_transact_query_security_desc);
                        break;
                }
@@ -2967,11 +2575,12 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_GET_USER_QUOTA:
                {
                        START_PROFILE(NT_transact_get_user_quota);
-                       outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf, 
-                                                        size, bufsize, 
-                                                        &state->setup, state->setup_count,
-                                                        &state->param, state->total_param, 
-                                                        &state->data, state->total_data, state->max_data_return);
+                       call_nt_transact_get_user_quota(
+                               conn, req,
+                               &state->setup, state->setup_count,
+                               &state->param, state->total_param,
+                               &state->data, state->total_data,
+                               state->max_data_return);
                        END_PROFILE(NT_transact_get_user_quota);
                        break;
                }
@@ -2979,93 +2588,110 @@ static int handle_nttrans(connection_struct *conn,
                case NT_TRANSACT_SET_USER_QUOTA:
                {
                        START_PROFILE(NT_transact_set_user_quota);
-                       outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf, 
-                                                        size, bufsize, 
-                                                        &state->setup, state->setup_count,
-                                                        &state->param, state->total_param, 
-                                                        &state->data, state->total_data, state->max_data_return);
+                       call_nt_transact_set_user_quota(
+                               conn, req,
+                               &state->setup, state->setup_count,
+                               &state->param, state->total_param,
+                               &state->data, state->total_data,
+                               state->max_data_return);
                        END_PROFILE(NT_transact_set_user_quota);
-                       break;                                  
+                       break;
                }
 #endif /* HAVE_SYS_QUOTAS */
 
                default:
                        /* Error in request */
-                       DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n",
-                                state->call));
-                       return ERROR_DOS(ERRSRV,ERRerror);
+                       DEBUG(0,("handle_nttrans: Unknown request %d in "
+                                "nttrans call\n", state->call));
+                       reply_doserror(req, ERRSRV, ERRerror);
+                       return;
        }
-       return outsize;
+       return;
 }
 
 /****************************************************************************
  Reply to a SMBNTtrans.
 ****************************************************************************/
 
-int reply_nttrans(connection_struct *conn,
-                       char *inbuf,char *outbuf,int size,int bufsize)
+void reply_nttrans(connection_struct *conn, struct smb_request *req)
 {
-       int  outsize = 0;
-       uint32 pscnt = IVAL(inbuf,smb_nt_ParameterCount);
-       uint32 psoff = IVAL(inbuf,smb_nt_ParameterOffset);
-       uint32 dscnt = IVAL(inbuf,smb_nt_DataCount);
-       uint32 dsoff = IVAL(inbuf,smb_nt_DataOffset);
-       
-       uint16 function_code = SVAL( inbuf, smb_nt_Function);
+       uint32 pscnt;
+       uint32 psoff;
+       uint32 dscnt;
+       uint32 dsoff;
+       uint16 function_code;
        NTSTATUS result;
        struct trans_state *state;
+       int size;
 
        START_PROFILE(SMBnttrans);
 
+       if (req->wct < 19) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBnttrans);
+               return;
+       }
+
+       size = smb_len(req->inbuf) + 4;
+       pscnt = IVAL(req->inbuf,smb_nt_ParameterCount);
+       psoff = IVAL(req->inbuf,smb_nt_ParameterOffset);
+       dscnt = IVAL(req->inbuf,smb_nt_DataCount);
+       dsoff = IVAL(req->inbuf,smb_nt_DataOffset);
+       function_code = SVAL(req->inbuf, smb_nt_Function);
+
        if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
+               reply_doserror(req, ERRSRV, ERRaccess);
                END_PROFILE(SMBnttrans);
-               return ERROR_DOS(ERRSRV,ERRaccess);
+               return;
        }
 
-       result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid));
+       result = allow_new_trans(conn->pending_trans, req->mid);
        if (!NT_STATUS_IS_OK(result)) {
                DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
+               reply_nterror(req, result);
                END_PROFILE(SMBnttrans);
-               return ERROR_NT(result);
+               return;
        }
 
        if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
+               reply_doserror(req, ERRSRV, ERRaccess);
                END_PROFILE(SMBnttrans);
-               return ERROR_DOS(ERRSRV,ERRaccess);
+               return;
        }
 
        state->cmd = SMBnttrans;
 
-       state->mid = SVAL(inbuf,smb_mid);
-       state->vuid = SVAL(inbuf,smb_uid);
-       state->total_data = IVAL(inbuf, smb_nt_TotalDataCount);
+       state->mid = req->mid;
+       state->vuid = req->vuid;
+       state->total_data = IVAL(req->inbuf, smb_nt_TotalDataCount);
        state->data = NULL;
-       state->total_param = IVAL(inbuf, smb_nt_TotalParameterCount);
+       state->total_param = IVAL(req->inbuf, smb_nt_TotalParameterCount);
        state->param = NULL;
-       state->max_data_return = IVAL(inbuf,smb_nt_MaxDataCount);       
-       state->max_param_return = IVAL(inbuf,smb_nt_MaxParameterCount);
+       state->max_data_return = IVAL(req->inbuf,smb_nt_MaxDataCount);
+       state->max_param_return = IVAL(req->inbuf,smb_nt_MaxParameterCount);
 
        /* setup count is in *words* */
-       state->setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); 
+       state->setup_count = 2*CVAL(req->inbuf,smb_nt_SetupCount);
        state->setup = NULL;
        state->call = function_code;
 
-       /* 
+       /*
         * All nttrans messages we handle have smb_wct == 19 +
         * state->setup_count.  Ensure this is so as a sanity check.
         */
 
-       if(CVAL(inbuf, smb_wct) != 19 + (state->setup_count/2)) {
+       if(req->wct != 19 + (state->setup_count/2)) {
                DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
-                       CVAL(inbuf, smb_wct), 19 + (state->setup_count/2)));
+                        req->wct, 19 + (state->setup_count/2)));
                goto bad_param;
        }
 
        /* Don't allow more than 128mb for each value. */
        if ((state->total_data > (1024*1024*128)) ||
            (state->total_param > (1024*1024*128))) {
+               reply_doserror(req, ERRDOS, ERRnomem);
                END_PROFILE(SMBnttrans);
-               return ERROR_DOS(ERRDOS,ERRnomem);
+               return;
        }
 
        if ((dscnt > state->total_data) || (pscnt > state->total_param))
@@ -3078,16 +2704,18 @@ int reply_nttrans(connection_struct *conn,
                        DEBUG(0,("reply_nttrans: data malloc fail for %u "
                                 "bytes !\n", (unsigned int)state->total_data));
                        TALLOC_FREE(state);
+                       reply_doserror(req, ERRDOS, ERRnomem);
                        END_PROFILE(SMBnttrans);
-                       return(ERROR_DOS(ERRDOS,ERRnomem));
-               } 
+                       return;
+               }
                if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
                        goto bad_param;
-               if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) ||
-                   (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf)))
+               if ((smb_base(req->inbuf)+dsoff+dscnt
+                    > (char *)req->inbuf + size) ||
+                   (smb_base(req->inbuf)+dsoff+dscnt < smb_base(req->inbuf)))
                        goto bad_param;
 
-               memcpy(state->data,smb_base(inbuf)+dsoff,dscnt);
+               memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
        }
 
        if (state->total_param) {
@@ -3098,16 +2726,18 @@ int reply_nttrans(connection_struct *conn,
                                 "bytes !\n", (unsigned int)state->total_param));
                        SAFE_FREE(state->data);
                        TALLOC_FREE(state);
+                       reply_doserror(req, ERRDOS, ERRnomem);
                        END_PROFILE(SMBnttrans);
-                       return(ERROR_DOS(ERRDOS,ERRnomem));
-               } 
+                       return;
+               }
                if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
                        goto bad_param;
-               if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) ||
-                   (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf)))
+               if ((smb_base(req->inbuf)+psoff+pscnt
+                    > (char *)req->inbuf + size) ||
+                   (smb_base(req->inbuf)+psoff+pscnt < smb_base(req->inbuf)))
                        goto bad_param;
 
-               memcpy(state->param,smb_base(inbuf)+psoff,pscnt);
+               memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
        }
 
        state->received_data  = dscnt;
@@ -3122,8 +2752,9 @@ int reply_nttrans(connection_struct *conn,
                        SAFE_FREE(state->data);
                        SAFE_FREE(state->param);
                        TALLOC_FREE(state);
+                       reply_doserror(req, ERRDOS, ERRnomem);
                        END_PROFILE(SMBnttrans);
-                       return ERROR_DOS(ERRDOS,ERRnomem);
+                       return;
                }
 
                if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
@@ -3134,29 +2765,29 @@ int reply_nttrans(connection_struct *conn,
                        goto bad_param;
                }
 
-               memcpy( state->setup, &inbuf[smb_nt_SetupStart], state->setup_count);
+               memcpy( state->setup, &req->inbuf[smb_nt_SetupStart],
+                       state->setup_count);
                dump_data(10, (uint8 *)state->setup, state->setup_count);
        }
 
        if ((state->received_data == state->total_data) &&
            (state->received_param == state->total_param)) {
-               outsize = handle_nttrans(conn, state, inbuf, outbuf,
-                                        size, bufsize);
+               handle_nttrans(conn, state, req);
                SAFE_FREE(state->param);
                SAFE_FREE(state->data);
                TALLOC_FREE(state);
                END_PROFILE(SMBnttrans);
-               return outsize;
+               return;
        }
 
        DLIST_ADD(conn->pending_trans, state);
 
        /* We need to send an interim response then receive the rest
           of the parameter/data bytes */
-       outsize = set_message(inbuf,outbuf,0,0,False);
-       show_msg(outbuf);
+       reply_outbuf(req, 0, 0);
+       show_msg((char *)req->outbuf);
        END_PROFILE(SMBnttrans);
-       return outsize;
+       return;
 
   bad_param:
 
@@ -3164,57 +2795,69 @@ int reply_nttrans(connection_struct *conn,
        SAFE_FREE(state->data);
        SAFE_FREE(state->param);
        TALLOC_FREE(state);
+       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
        END_PROFILE(SMBnttrans);
-       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       return;
 }
-       
+
 /****************************************************************************
  Reply to a SMBnttranss
  ****************************************************************************/
 
-int reply_nttranss(connection_struct *conn,  char *inbuf,char *outbuf,
-                  int size,int bufsize)
+void reply_nttranss(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = 0;
        unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
        struct trans_state *state;
 
+       int size;
+
        START_PROFILE(SMBnttranss);
 
-       show_msg(inbuf);
+       show_msg((char *)req->inbuf);
+
+       if (req->wct < 18) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBnttranss);
+               return;
+       }
 
        for (state = conn->pending_trans; state != NULL;
             state = state->next) {
-               if (state->mid == SVAL(inbuf,smb_mid)) {
+               if (state->mid == req->mid) {
                        break;
                }
        }
 
        if ((state == NULL) || (state->cmd != SMBnttrans)) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBnttranss);
-               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               return;
        }
 
        /* Revise state->total_param and state->total_data in case they have
           changed downwards */
-       if (IVAL(inbuf, smb_nts_TotalParameterCount) < state->total_param) {
-               state->total_param = IVAL(inbuf, smb_nts_TotalParameterCount);
+       if (IVAL(req->inbuf, smb_nts_TotalParameterCount)
+           < state->total_param) {
+               state->total_param = IVAL(req->inbuf,
+                                         smb_nts_TotalParameterCount);
        }
-       if (IVAL(inbuf, smb_nts_TotalDataCount) < state->total_data) {
-               state->total_data = IVAL(inbuf, smb_nts_TotalDataCount);
+       if (IVAL(req->inbuf, smb_nts_TotalDataCount) < state->total_data) {
+               state->total_data = IVAL(req->inbuf, smb_nts_TotalDataCount);
        }
 
-       pcnt = IVAL(inbuf,smb_nts_ParameterCount);
-       poff = IVAL(inbuf, smb_nts_ParameterOffset);
-       pdisp = IVAL(inbuf, smb_nts_ParameterDisplacement);
+       size = smb_len(req->inbuf) + 4;
+
+       pcnt = IVAL(req->inbuf,smb_nts_ParameterCount);
+       poff = IVAL(req->inbuf, smb_nts_ParameterOffset);
+       pdisp = IVAL(req->inbuf, smb_nts_ParameterDisplacement);
 
-       dcnt = IVAL(inbuf, smb_nts_DataCount);
-       ddisp = IVAL(inbuf, smb_nts_DataDisplacement);
-       doff = IVAL(inbuf, smb_nts_DataOffset);
+       dcnt = IVAL(req->inbuf, smb_nts_DataCount);
+       ddisp = IVAL(req->inbuf, smb_nts_DataDisplacement);
+       doff = IVAL(req->inbuf, smb_nts_DataOffset);
 
        state->received_param += pcnt;
        state->received_data += dcnt;
-               
+
        if ((state->received_data > state->total_data) ||
            (state->received_param > state->total_param))
                goto bad_param;
@@ -3226,13 +2869,15 @@ int reply_nttranss(connection_struct *conn,  char *inbuf,char *outbuf,
                        goto bad_param;
                if (pdisp > state->total_param)
                        goto bad_param;
-               if ((smb_base(inbuf) + poff + pcnt > inbuf + size) ||
-                   (smb_base(inbuf) + poff + pcnt < smb_base(inbuf)))
+               if ((smb_base(req->inbuf) + poff + pcnt
+                    > (char *)req->inbuf + size) ||
+                   (smb_base(req->inbuf) + poff + pcnt
+                    < smb_base(req->inbuf)))
                        goto bad_param;
                if (state->param + pdisp < state->param)
                        goto bad_param;
 
-               memcpy(state->param+pdisp,smb_base(inbuf)+poff,
+               memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,
                       pcnt);
        }
 
@@ -3243,42 +2888,38 @@ int reply_nttranss(connection_struct *conn,  char *inbuf,char *outbuf,
                        goto bad_param;
                if (ddisp > state->total_data)
                        goto bad_param;
-               if ((smb_base(inbuf) + doff + dcnt > inbuf + size) ||
-                   (smb_base(inbuf) + doff + dcnt < smb_base(inbuf)))
+               if ((smb_base(req->inbuf) + doff + dcnt
+                    > (char *)req->inbuf + size) ||
+                   (smb_base(req->inbuf) + doff + dcnt
+                    < smb_base(req->inbuf)))
                        goto bad_param;
                if (state->data + ddisp < state->data)
                        goto bad_param;
 
-               memcpy(state->data+ddisp, smb_base(inbuf)+doff,
-                      dcnt);      
+               memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
+                      dcnt);
        }
 
        if ((state->received_param < state->total_param) ||
            (state->received_data < state->total_data)) {
                END_PROFILE(SMBnttranss);
-               return -1;
+               return;
        }
 
-       /* construct_reply_common has done us the favor to pre-fill the
-        * command field with SMBnttranss which is wrong :-)
+       /*
+        * construct_reply_common will copy smb_com from inbuf to
+        * outbuf. SMBnttranss is wrong here.
         */
-       SCVAL(outbuf,smb_com,SMBnttrans);
+       SCVAL(req->inbuf,smb_com,SMBnttrans);
 
-       outsize = handle_nttrans(conn, state, inbuf, outbuf,
-                                size, bufsize);
+       handle_nttrans(conn, state, req);
 
        DLIST_REMOVE(conn->pending_trans, state);
        SAFE_FREE(state->data);
        SAFE_FREE(state->param);
        TALLOC_FREE(state);
-
-       if (outsize == 0) {
-               END_PROFILE(SMBnttranss);
-               return(ERROR_DOS(ERRSRV,ERRnosupport));
-       }
-       
        END_PROFILE(SMBnttranss);
-       return(outsize);
+       return;
 
   bad_param:
 
@@ -3287,6 +2928,7 @@ int reply_nttranss(connection_struct *conn,  char *inbuf,char *outbuf,
        SAFE_FREE(state->data);
        SAFE_FREE(state->param);
        TALLOC_FREE(state);
+       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
        END_PROFILE(SMBnttranss);
-       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+       return;
 }