r25055: Add file_id_string_tos
[samba.git] / source3 / smbd / reply.c
index 40b9630ecfc0d48f03719ed5d9a094fa0296db7a..e3c3e8dff02478ac96f8e2907f1a084378f05ca2 100644 (file)
@@ -285,11 +285,10 @@ size_t srvstr_get_path(const char *inbuf, uint16 smb_flags2, char *dest,
 }
 
 /****************************************************************************
- Check if we have a correct fsp pointing to a file. Replacement for the
- CHECK_FSP macro.
+ Check if we have a correct fsp pointing to a file. Basic check for open fsp.
 ****************************************************************************/
 
-BOOL check_fsp(connection_struct *conn, struct smb_request *req,
+BOOL check_fsp_open(connection_struct *conn, struct smb_request *req,
               files_struct *fsp, struct current_user *user)
 {
        if (!(fsp) || !(conn)) {
@@ -300,6 +299,20 @@ BOOL check_fsp(connection_struct *conn, struct smb_request *req,
                reply_nterror(req, NT_STATUS_INVALID_HANDLE);
                return False;
        }
+       return True;
+}
+
+/****************************************************************************
+ Check if we have a correct fsp pointing to a file. Replacement for the
+ CHECK_FSP macro.
+****************************************************************************/
+
+BOOL check_fsp(connection_struct *conn, struct smb_request *req,
+              files_struct *fsp, struct current_user *user)
+{
+       if (!check_fsp_open(conn, req, fsp, user)) {
+               return False;
+       }
        if ((fsp)->is_directory) {
                reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
                return False;
@@ -429,16 +442,12 @@ void reply_special(char *inbuf)
  conn POINTER CAN BE NULL HERE !
 ****************************************************************************/
 
-int reply_tcon(connection_struct *conn,
-              char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_tcon(connection_struct *conn, struct smb_request *req)
 {
-       TALLOC_CTX *ctx;
        const char *service;
        char *service_buf = NULL;
        char *password = NULL;
        char *dev = NULL;
-       int outsize = 0;
-       uint16 vuid = SVAL(inbuf,smb_uid);
        int pwlen=0;
        NTSTATUS nt_status;
        char *p;
@@ -446,25 +455,25 @@ int reply_tcon(connection_struct *conn,
 
        START_PROFILE(SMBtcon);
 
-       ctx = talloc_init("reply_tcon");
-       if (!ctx) {
+       if (smb_buflen(req->inbuf) < 4) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBtcon);
-               return ERROR_NT(NT_STATUS_NO_MEMORY);
+               return;
        }
 
-       p = smb_buf(inbuf)+1;
-       p += srvstr_pull_buf_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2),
-                       &service_buf, p, STR_TERMINATE) + 1;
-       pwlen = srvstr_pull_buf_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2),
-                       &password, p, STR_TERMINATE) + 1;
+       p = smb_buf(req->inbuf)+1;
+       p += srvstr_pull_buf_talloc(req, req->inbuf, req->flags2,
+                                   &service_buf, p, STR_TERMINATE) + 1;
+       pwlen = srvstr_pull_buf_talloc(req, req->inbuf, req->flags2,
+                                      &password, p, STR_TERMINATE) + 1;
        p += pwlen;
-       p += srvstr_pull_buf_talloc(ctx, inbuf, SVAL(inbuf, smb_flg2),
-                       &dev, p, STR_TERMINATE) + 1;
+       p += srvstr_pull_buf_talloc(req, req->inbuf, req->flags2,
+                                   &dev, p, STR_TERMINATE) + 1;
 
        if (service_buf == NULL || password == NULL || dev == NULL) {
-               TALLOC_FREE(ctx);
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBtcon);
-               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+               return;
        }
        p = strrchr_m(service_buf,'\\');
        if (p) {
@@ -475,27 +484,26 @@ int reply_tcon(connection_struct *conn,
 
        password_blob = data_blob(password, pwlen+1);
 
-       conn = make_connection(service,password_blob,dev,vuid,&nt_status);
+       conn = make_connection(service,password_blob,dev,req->vuid,&nt_status);
 
        data_blob_clear_free(&password_blob);
 
        if (!conn) {
-               TALLOC_FREE(ctx);
+               reply_nterror(req, nt_status);
                END_PROFILE(SMBtcon);
-               return ERROR_NT(nt_status);
+               return;
        }
 
-       outsize = set_message(inbuf,outbuf,2,0,True);
-       SSVAL(outbuf,smb_vwv0,max_recv);
-       SSVAL(outbuf,smb_vwv1,conn->cnum);
-       SSVAL(outbuf,smb_tid,conn->cnum);
+       reply_outbuf(req, 2, 0);
+       SSVAL(req->outbuf,smb_vwv0,max_recv);
+       SSVAL(req->outbuf,smb_vwv1,conn->cnum);
+       SSVAL(req->outbuf,smb_tid,conn->cnum);
 
-       DEBUG(3,("tcon service=%s cnum=%d\n", 
+       DEBUG(3,("tcon service=%s cnum=%d\n",
                 service, conn->cnum));
 
        END_PROFILE(SMBtcon);
-       TALLOC_FREE(ctx);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -692,7 +700,7 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
        TALLOC_FREE(ctx);
        END_PROFILE(SMBtconX);
 
-       chain_reply_new(req);
+       chain_reply(req);
        return;
 }
 
@@ -724,56 +732,73 @@ void reply_unknown_new(struct smb_request *req, uint8 type)
  conn POINTER CAN BE NULL HERE !
 ****************************************************************************/
 
-int reply_ioctl(connection_struct *conn,
-               char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_ioctl(connection_struct *conn, struct smb_request *req)
 {
-       uint16 device     = SVAL(inbuf,smb_vwv1);
-       uint16 function   = SVAL(inbuf,smb_vwv2);
-       uint32 ioctl_code = (device << 16) + function;
-       int replysize, outsize;
+       uint16 device;
+       uint16 function;
+       uint32 ioctl_code;
+       int replysize;
        char *p;
+
        START_PROFILE(SMBioctl);
 
+       if (req->wct < 3) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBioctl);
+               return;
+       }
+
+       device     = SVAL(req->inbuf,smb_vwv1);
+       function   = SVAL(req->inbuf,smb_vwv2);
+       ioctl_code = (device << 16) + function;
+
        DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
 
        switch (ioctl_code) {
            case IOCTL_QUERY_JOB_INFO:
-               replysize = 32;
-               break;
+                   replysize = 32;
+                   break;
            default:
-               END_PROFILE(SMBioctl);
-               return(ERROR_DOS(ERRSRV,ERRnosupport));
+                   reply_doserror(req, ERRSRV, ERRnosupport);
+                   END_PROFILE(SMBioctl);
+                   return;
        }
 
-       outsize = set_message(inbuf,outbuf,8,replysize+1,True);
-       SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
-       SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
-       SSVAL(outbuf,smb_vwv6,52);        /* Offset to data */
-       p = smb_buf(outbuf) + 1;          /* Allow for alignment */
+       reply_outbuf(req, 8, replysize+1);
+       SSVAL(req->outbuf,smb_vwv1,replysize); /* Total data bytes returned */
+       SSVAL(req->outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
+       SSVAL(req->outbuf,smb_vwv6,52);        /* Offset to data */
+       p = smb_buf(req->outbuf);
+       memset(p, '\0', replysize+1); /* valgrind-safe. */
+       p += 1;          /* Allow for alignment */
 
        switch (ioctl_code) {
                case IOCTL_QUERY_JOB_INFO:                  
                {
-                       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+                       files_struct *fsp = file_fsp(SVAL(req->inbuf,
+                                                         smb_vwv0));
                        if (!fsp) {
+                               reply_doserror(req, ERRDOS, ERRbadfid);
                                END_PROFILE(SMBioctl);
-                               return(UNIXERROR(ERRDOS,ERRbadfid));
+                               return;
                        }
                        SSVAL(p,0,fsp->rap_print_jobid);             /* Job number */
-                       srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p+2,
+                       srvstr_push((char *)req->outbuf, req->flags2, p+2,
                                    global_myname(), 15,
                                    STR_TERMINATE|STR_ASCII);
                        if (conn) {
-                               srvstr_push(outbuf, SVAL(outbuf, smb_flg2),
+                               srvstr_push((char *)req->outbuf, req->flags2,
                                            p+18, lp_servicename(SNUM(conn)),
                                            13, STR_TERMINATE|STR_ASCII);
+                       } else {
+                               memset(p+18, 0, 13);
                        }
                        break;
                }
        }
 
        END_PROFILE(SMBioctl);
-       return outsize;
+       return;
 }
 
 /****************************************************************************
@@ -798,14 +823,15 @@ static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
 
 void reply_checkpath(connection_struct *conn, struct smb_request *req)
 {
-       pstring name;
+       pstring name_in;
+       char *name = NULL;
        SMB_STRUCT_STAT sbuf;
        NTSTATUS status;
 
        START_PROFILE(SMBcheckpath);
 
-       srvstr_get_path((char *)req->inbuf, req->flags2, name,
-                       smb_buf(req->inbuf) + 1, sizeof(name), 0,
+       srvstr_get_path((char *)req->inbuf, req->flags2, name_in,
+                       smb_buf(req->inbuf) + 1, sizeof(name_in), 0,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                status = map_checkpath_error((char *)req->inbuf, status);
@@ -814,7 +840,7 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name);
+       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name_in);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -825,9 +851,9 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
                goto path_err;
        }
 
-       DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
+       DEBUG(3,("reply_checkpath %s mode=%d\n", name_in, (int)SVAL(req->inbuf,smb_vwv0)));
 
-       status = unix_convert(conn, name, False, NULL, &sbuf);
+       status = unix_convert(conn, name_in, False, &name, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                goto path_err;
        }
@@ -886,10 +912,10 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
  Reply to a getatr.
 ****************************************************************************/
 
-int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_getatr(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
-       int outsize = 0;
+       pstring fname_in;
+       char *fname = NULL;
        SMB_STRUCT_STAT sbuf;
        int mode=0;
        SMB_OFF_T size=0;
@@ -899,26 +925,32 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
        START_PROFILE(SMBgetatr);
 
-       p = smb_buf(inbuf) + 1;
-       p += srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, p,
-                            sizeof(fname), 0, STR_TERMINATE, &status);
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, p,
+                            sizeof(fname_in), 0, STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBgetatr);
-               return ERROR_NT(status);
+               return;
        }
 
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                fname_in);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBgetatr);
                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(SMBgetatr);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBgetatr);
+               return;
        }
   
        /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
                under WfWg - weird! */
-       if (*fname == '\0') {
+       if (*fname_in == '\0') {
                mode = aHIDDEN | aDIR;
                if (!CAN_WRITE(conn)) {
                        mode |= aRONLY;
@@ -926,20 +958,24 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                size = 0;
                mtime = 0;
        } else {
-               status = unix_convert(conn, fname, False, NULL,&sbuf);
+               status = unix_convert(conn, fname_in, False, &fname, NULL,&sbuf);
                if (!NT_STATUS_IS_OK(status)) {
+                       reply_nterror(req, status);
                        END_PROFILE(SMBgetatr);
-                       return ERROR_NT(status);
+                       return;
                }
                status = check_name(conn, fname);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
+                       reply_nterror(req, status);
                        END_PROFILE(SMBgetatr);
-                       return ERROR_NT(status);
+                       return;
                }
                if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn,fname,&sbuf) != 0)) {
                        DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",fname,strerror(errno)));
-                       return UNIXERROR(ERRDOS,ERRbadfile);
+                       reply_unixerror(req, ERRDOS,ERRbadfile);
+                       END_PROFILE(SMBgetatr);
+                       return;
                }
 
                mode = dos_mode(conn,fname,&sbuf);
@@ -949,35 +985,36 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                        size = 0;
                }
        }
-  
-       outsize = set_message(inbuf,outbuf,10,0,True);
 
-       SSVAL(outbuf,smb_vwv0,mode);
+       reply_outbuf(req, 10, 0);
+
+       SSVAL(req->outbuf,smb_vwv0,mode);
        if(lp_dos_filetime_resolution(SNUM(conn)) ) {
-               srv_put_dos_date3(outbuf,smb_vwv1,mtime & ~1);
+               srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime & ~1);
        } else {
-               srv_put_dos_date3(outbuf,smb_vwv1,mtime);
+               srv_put_dos_date3((char *)req->outbuf,smb_vwv1,mtime);
        }
-       SIVAL(outbuf,smb_vwv3,(uint32)size);
+       SIVAL(req->outbuf,smb_vwv3,(uint32)size);
 
        if (Protocol >= PROTOCOL_NT1) {
-               SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
+               SSVAL(req->outbuf, smb_flg2,
+                     SVAL(req->outbuf, smb_flg2) | FLAGS2_IS_LONG_NAME);
        }
   
        DEBUG(3,("reply_getatr: name=%s mode=%d size=%u\n", fname, mode, (unsigned int)size ) );
   
        END_PROFILE(SMBgetatr);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
  Reply to a setatr.
 ****************************************************************************/
 
-int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_setatr(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
-       int outsize = 0;
+       pstring fname_in;
+       char *fname = NULL;
        int mode;
        time_t mtime;
        SMB_STRUCT_STAT sbuf;
@@ -986,33 +1023,46 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
        START_PROFILE(SMBsetatr);
 
-       p = smb_buf(inbuf) + 1;
-       p += srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, p,
-                            sizeof(fname), 0, STR_TERMINATE, &status);
+       if (req->wct < 2) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path((char *)req->inbuf, req->flags2, fname_in, p,
+                            sizeof(fname_in), 0, STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBsetatr);
-               return ERROR_NT(status);
+               return;
        }
 
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                fname_in);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBsetatr);
                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(SMBsetatr);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBsetatr);
+               return;
        }
   
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
+       status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBsetatr);
-               return ERROR_NT(status);
+               return;
        }
 
        status = check_name(conn, fname);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBsetatr);
-               return ERROR_NT(status);
+               return;
        }
 
        if (fname[0] == '.' && fname[1] == '\0') {
@@ -1020,12 +1070,13 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                 * Not sure here is the right place to catch this
                 * condition. Might be moved to somewhere else later -- vl
                 */
+               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                END_PROFILE(SMBsetatr);
-               return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+               return;
        }
 
-       mode = SVAL(inbuf,smb_vwv0);
-       mtime = srv_make_unix_date3(inbuf+smb_vwv1);
+       mode = SVAL(req->inbuf,smb_vwv0);
+       mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
   
        if (mode != FILE_ATTRIBUTE_NORMAL) {
                if (VALID_STAT_OF_DIR(sbuf))
@@ -1034,22 +1085,24 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                        mode &= ~aDIR;
 
                if (file_set_dosmode(conn,fname,mode,&sbuf,False) != 0) {
+                       reply_unixerror(req, ERRDOS, ERRnoaccess);
                        END_PROFILE(SMBsetatr);
-                       return UNIXERROR(ERRDOS, ERRnoaccess);
+                       return;
                }
        }
 
        if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) {
+               reply_unixerror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBsetatr);
-               return UNIXERROR(ERRDOS, ERRnoaccess);
+               return;
        }
+
+       reply_outbuf(req, 0, 0);
  
-       outsize = set_message(inbuf,outbuf,0,0,False);
-  
        DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
   
        END_PROFILE(SMBsetatr);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -1108,16 +1161,15 @@ void reply_dskattr(connection_struct *conn, struct smb_request *req)
  Can be called from SMBsearch, SMBffirst or SMBfunique.
 ****************************************************************************/
 
-int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_search(connection_struct *conn, struct smb_request *req)
 {
        pstring mask;
-       pstring directory;
+       char *directory = NULL;
        pstring fname;
        SMB_OFF_T size;
        uint32 mode;
        time_t date;
        uint32 dirtype;
-       int outsize = 0;
        unsigned int numentries = 0;
        unsigned int maxentries = 0;
        BOOL finished = False;
@@ -1130,41 +1182,55 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        BOOL expect_close = False;
        NTSTATUS nt_status;
        BOOL mask_contains_wcard = False;
-       BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
+       BOOL allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
 
        START_PROFILE(SMBsearch);
 
+       if (req->wct < 2) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBsearch);
+               return;
+       }
+
        if (lp_posix_pathnames()) {
+               reply_unknown_new(req, CVAL(req->inbuf, smb_com));
                END_PROFILE(SMBsearch);
-               return reply_unknown(inbuf, outbuf);
+               return;
        }
 
-       *mask = *directory = *fname = 0;
+       *mask = *fname = 0;
 
        /* If we were called as SMBffirst then we must expect close. */
-       if(CVAL(inbuf,smb_com) == SMBffirst) {
+       if(CVAL(req->inbuf,smb_com) == SMBffirst) {
                expect_close = True;
        }
-  
-       outsize = set_message(inbuf,outbuf,1,3,True);
-       maxentries = SVAL(inbuf,smb_vwv0); 
-       dirtype = SVAL(inbuf,smb_vwv1);
-       p = smb_buf(inbuf) + 1;
-       p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), path, p,
+
+       reply_outbuf(req, 1, 3);
+       maxentries = SVAL(req->inbuf,smb_vwv0);
+       dirtype = SVAL(req->inbuf,smb_vwv1);
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, path, p,
                                   sizeof(path), 0, STR_TERMINATE, &nt_status,
                                   &mask_contains_wcard);
        if (!NT_STATUS_IS_OK(nt_status)) {
+               reply_nterror(req, nt_status);
                END_PROFILE(SMBsearch);
-               return ERROR_NT(nt_status);
+               return;
        }
 
-       nt_status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, path, &mask_contains_wcard);
+       nt_status = resolve_dfspath_wcard(conn,
+                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                         path, &mask_contains_wcard);
        if (!NT_STATUS_IS_OK(nt_status)) {
-               END_PROFILE(SMBsearch);
                if (NT_STATUS_EQUAL(nt_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(SMBsearch);
+                       return;
                }
-               return ERROR_NT(nt_status);
+               reply_nterror(req, nt_status);
+               END_PROFILE(SMBsearch);
+               return;
        }
   
        p++;
@@ -1176,33 +1242,60 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        if (status_len == 0) {
                SMB_STRUCT_STAT sbuf;
 
-               pstrcpy(directory,path);
-               nt_status = unix_convert(conn, directory, True, NULL, &sbuf);
+               nt_status = unix_convert(conn, path, True, &directory, NULL, &sbuf);
                if (!NT_STATUS_IS_OK(nt_status)) {
+                       reply_nterror(req, nt_status);
                        END_PROFILE(SMBsearch);
-                       return ERROR_NT(nt_status);
+                       return;
                }
 
                nt_status = check_name(conn, directory);
                if (!NT_STATUS_IS_OK(nt_status)) {
+                       reply_nterror(req, nt_status);
                        END_PROFILE(SMBsearch);
-                       return ERROR_NT(nt_status);
+                       return;
                }
 
                p = strrchr_m(directory,'/');
                if (!p) {
                        pstrcpy(mask,directory);
-                       pstrcpy(directory,".");
+                       directory = talloc_strdup(talloc_tos(),".");
+                       if (!directory) {
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
+                               END_PROFILE(SMBsearch);
+                               return;
+                       }
                } else {
                        *p = 0;
                        pstrcpy(mask,p+1);
                }
 
                if (*directory == '\0') {
-                       pstrcpy(directory,".");
+                       directory = talloc_strdup(talloc_tos(),".");
+                       if (!directory) {
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
+                               END_PROFILE(SMBsearch);
+                               return;
+                       }
                }
                memset((char *)status,'\0',21);
                SCVAL(status,0,(dirtype & 0x1F));
+
+               nt_status = dptr_create(conn,
+                                       directory,
+                                       True,
+                                       expect_close,
+                                       req->smbpid,
+                                       mask,
+                                       mask_contains_wcard,
+                                       dirtype,
+                                       &conn->dirptr);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       reply_nterror(req, nt_status);
+                       END_PROFILE(SMBsearch);
+                       return;
+               }
+               dptr_num = dptr_dnum(conn->dirptr);
        } else {
                int status_dirtype;
 
@@ -1212,7 +1305,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                        dirtype = status_dirtype;
                }
 
-               conn->dirptr = dptr_fetch(status+12,&dptr_num);      
+               conn->dirptr = dptr_fetch(status+12,&dptr_num);
                if (!conn->dirptr) {
                        goto SearchEmpty;
                }
@@ -1223,44 +1316,36 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                 * check from the initial saved string.
                 */
                mask_contains_wcard = ms_has_wild(mask);
-       }
-
-       p = smb_buf(outbuf) + 3;
-     
-       if (status_len == 0) {
-               nt_status = dptr_create(conn,
-                                       directory,
-                                       True,
-                                       expect_close,
-                                       SVAL(inbuf,smb_pid),
-                                       mask,
-                                       mask_contains_wcard,
-                                       dirtype,
-                                       &conn->dirptr);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       return ERROR_NT(nt_status);
-               }
-               dptr_num = dptr_dnum(conn->dirptr);
-       } else {
                dirtype = dptr_attr(dptr_num);
        }
 
        DEBUG(4,("dptr_num is %d\n",dptr_num));
 
-       if ((dirtype&0x1F) == aVOLID) {   
-               memcpy(p,status,21);
-               make_dir_struct(p,"???????????",volume_label(SNUM(conn)),
+       if ((dirtype&0x1F) == aVOLID) {
+               char buf[DIR_STRUCT_SIZE];
+               memcpy(buf,status,21);
+               make_dir_struct(buf,"???????????",volume_label(SNUM(conn)),
                                0,aVOLID,0,!allow_long_path_components);
-               dptr_fill(p+12,dptr_num);
-               if (dptr_zero(p+12) && (status_len==0)) {
+               dptr_fill(buf+12,dptr_num);
+               if (dptr_zero(buf+12) && (status_len==0)) {
                        numentries = 1;
                } else {
                        numentries = 0;
                }
-               p += DIR_STRUCT_SIZE;
+               if (message_push_blob(&req->outbuf,
+                                     data_blob_const(buf, sizeof(buf)))
+                   == -1) {
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       END_PROFILE(SMBsearch);
+                       return;
+               }
        } else {
                unsigned int i;
-               maxentries = MIN(maxentries, ((BUFFER_SIZE - (p - outbuf))/DIR_STRUCT_SIZE));
+               maxentries = MIN(
+                       maxentries,
+                       ((BUFFER_SIZE -
+                         ((uint8 *)smb_buf(req->outbuf) + 3 - req->outbuf))
+                        /DIR_STRUCT_SIZE));
 
                DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
                        conn->dirpath,lp_dontdescend(SNUM(conn))));
@@ -1271,14 +1356,21 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                for (i=numentries;(i<maxentries) && !finished;i++) {
                        finished = !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
                        if (!finished) {
-                               memcpy(p,status,21);
-                               make_dir_struct(p,mask,fname,size, mode,date,
+                               char buf[DIR_STRUCT_SIZE];
+                               memcpy(buf,status,21);
+                               make_dir_struct(buf,mask,fname,size, mode,date,
                                                !allow_long_path_components);
-                               if (!dptr_fill(p+12,dptr_num)) {
+                               if (!dptr_fill(buf+12,dptr_num)) {
                                        break;
                                }
+                               if (message_push_blob(&req->outbuf,
+                                                     data_blob_const(buf, sizeof(buf)))
+                                   == -1) {
+                                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                                       END_PROFILE(SMBsearch);
+                                       return;
+                               }
                                numentries++;
-                               p += DIR_STRUCT_SIZE;
                        }
                }
        }
@@ -1297,49 +1389,56 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        }
 
        /* If we were called as SMBfunique, then we can close the dirptr now ! */
-       if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique) {
+       if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
                dptr_close(&dptr_num);
        }
 
        if ((numentries == 0) && !mask_contains_wcard) {
-               return ERROR_BOTH(STATUS_NO_MORE_FILES,ERRDOS,ERRnofiles);
+               reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
+               END_PROFILE(SMBsearch);
+               return;
        }
 
-       SSVAL(outbuf,smb_vwv0,numentries);
-       SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
-       SCVAL(smb_buf(outbuf),0,5);
-       SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
+       SSVAL(req->outbuf,smb_vwv0,numentries);
+       SSVAL(req->outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
+       SCVAL(smb_buf(req->outbuf),0,5);
+       SSVAL(smb_buf(req->outbuf),1,numentries*DIR_STRUCT_SIZE);
 
        /* The replies here are never long name. */
-       SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
+       SSVAL(req->outbuf, smb_flg2,
+             SVAL(req->outbuf, smb_flg2) & (~FLAGS2_IS_LONG_NAME));
        if (!allow_long_path_components) {
-               SSVAL(outbuf,smb_flg2,SVAL(outbuf, smb_flg2) & (~FLAGS2_LONG_PATH_COMPONENTS));
+               SSVAL(req->outbuf, smb_flg2,
+                     SVAL(req->outbuf, smb_flg2)
+                     & (~FLAGS2_LONG_PATH_COMPONENTS));
        }
 
        /* This SMB *always* returns ASCII names. Remove the unicode bit in flags2. */
-       SSVAL(outbuf,smb_flg2, (SVAL(outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
-         
-       outsize += DIR_STRUCT_SIZE*numentries;
-       smb_setlen(inbuf,outbuf,outsize - 4);
-  
-       if ((! *directory) && dptr_path(dptr_num))
-               slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
+       SSVAL(req->outbuf, smb_flg2,
+             (SVAL(req->outbuf, smb_flg2) & (~FLAGS2_UNICODE_STRINGS)));
+
+       if (!directory) {
+               directory = dptr_path(dptr_num);
+       }
 
-       DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%u of %u\n",
-               smb_fn_name(CVAL(inbuf,smb_com)), 
-               mask, directory, dirtype, numentries, maxentries ) );
+       DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
+               smb_fn_name(CVAL(req->inbuf,smb_com)),
+               mask,
+               directory ? directory : "./",
+               dirtype,
+               numentries,
+               maxentries ));
 
        END_PROFILE(SMBsearch);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
  Reply to a fclose (stop directory search).
 ****************************************************************************/
 
-int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_fclose(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = 0;
        int status_len;
        pstring path;
        char status[21];
@@ -1351,26 +1450,28 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        START_PROFILE(SMBfclose);
 
        if (lp_posix_pathnames()) {
+               reply_unknown_new(req, CVAL(req->inbuf, smb_com));
                END_PROFILE(SMBfclose);
-               return reply_unknown(inbuf, outbuf);
+               return;
        }
 
-       outsize = set_message(inbuf,outbuf,1,0,True);
-       p = smb_buf(inbuf) + 1;
-       p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), path, p,
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, path, p,
                                   sizeof(path), 0, STR_TERMINATE, &err,
                                   &path_contains_wcard);
        if (!NT_STATUS_IS_OK(err)) {
+               reply_nterror(req, err);
                END_PROFILE(SMBfclose);
-               return ERROR_NT(err);
+               return;
        }
        p++;
        status_len = SVAL(p,0);
        p += 2;
 
        if (status_len == 0) {
+               reply_doserror(req, ERRSRV, ERRsrverror);
                END_PROFILE(SMBfclose);
-               return ERROR_DOS(ERRSRV,ERRsrverror);
+               return;
        }
 
        memcpy(status,p,21);
@@ -1380,12 +1481,13 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
                dptr_close(&dptr_num);
        }
 
-       SSVAL(outbuf,smb_vwv0,0);
+       reply_outbuf(req, 1, 0);
+       SSVAL(req->outbuf,smb_vwv0,0);
 
        DEBUG(3,("search close\n"));
 
        END_PROFILE(SMBfclose);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -1394,7 +1496,8 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
 
 void reply_open(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
+       pstring fname_in;
+       char *fname = NULL;
        uint32 fattr=0;
        SMB_OFF_T size = 0;
        time_t mtime=0;
@@ -1422,8 +1525,8 @@ void reply_open(connection_struct *conn, struct smb_request *req)
        deny_mode = SVAL(req->inbuf,smb_vwv0);
        dos_attr = SVAL(req->inbuf,smb_vwv1);
 
-       srvstr_get_path((char *)req->inbuf, req->flags2, fname,
-                       smb_buf(req->inbuf)+1, sizeof(fname), 0,
+       srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
+                       smb_buf(req->inbuf)+1, sizeof(fname_in), 0,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -1432,7 +1535,7 @@ void reply_open(connection_struct *conn, struct smb_request *req)
        }
 
        status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                fname);
+                                fname_in);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1445,7 +1548,7 @@ void reply_open(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
+       status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBopen);
@@ -1477,11 +1580,11 @@ void reply_open(connection_struct *conn, struct smb_request *req)
 
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
-                       /* We have re-scheduled this call. */
                        END_PROFILE(SMBopen);
+                       /* We have re-scheduled this call. */
                        return;
                }
-               reply_nterror(req, status);
+               reply_openerror(req, status);
                END_PROFILE(SMBopen);
                return;
        }
@@ -1528,7 +1631,8 @@ void reply_open(connection_struct *conn, struct smb_request *req)
 
 void reply_open_and_X(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
+       pstring fname_in;
+       char *fname = NULL;
        uint16 open_flags;
        int deny_mode;
        uint32 smb_attr;
@@ -1584,8 +1688,8 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
        }
 
        /* XXXX we need to handle passed times, sattr and flags */
-       srvstr_get_path((char *)req->inbuf, req->flags2, fname,
-                       smb_buf(req->inbuf), sizeof(fname), 0, STR_TERMINATE,
+       srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
+                       smb_buf(req->inbuf), sizeof(fname_in), 0, STR_TERMINATE,
                        &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -1594,7 +1698,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
        }
 
        status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                fname);
+                                fname_in);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBopenX);
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1606,7 +1710,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
+       status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBopenX);
@@ -1638,14 +1742,14 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
                        smb_attr,
                        oplock_request,
                        &smb_action, &fsp);
-      
+
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBopenX);
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
                        return;
                }
-               reply_nterror(req, status);
+               reply_openerror(req, status);
                return;
        }
 
@@ -1728,7 +1832,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
        }
 
        END_PROFILE(SMBopenX);
-       chain_reply_new(req);
+       chain_reply(req);
        return;
 }
 
@@ -1763,7 +1867,7 @@ void reply_ulogoffX(connection_struct *conn, struct smb_request *req)
        DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
 
        END_PROFILE(SMBulogoffX);
-       chain_reply_new(req);
+       chain_reply(req);
 }
 
 /****************************************************************************
@@ -1772,7 +1876,8 @@ void reply_ulogoffX(connection_struct *conn, struct smb_request *req)
 
 void reply_mknew(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
+       pstring fname_in;
+       char *fname = NULL;
        int com;
        uint32 fattr = 0;
        struct timespec ts[2];
@@ -1801,9 +1906,9 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
                        srv_make_unix_date3(req->inbuf + smb_vwv1));
                        /* mtime. */
 
-       srvstr_get_path((char *)req->inbuf, req->flags2, fname,
-                        smb_buf(req->inbuf) + 1, sizeof(fname), 0,
-                       STR_TERMINATE, &status);
+       srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
+                        smb_buf(req->inbuf) + 1, sizeof(fname_in), 0,
+                       STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBcreate);
@@ -1811,7 +1916,7 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
        }
 
        status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
-                       fname);
+                       fname_in);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBcreate);
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1823,7 +1928,7 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
+       status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBcreate);
@@ -1874,7 +1979,6 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
        file_ntimes(conn, fname, ts);
 
        reply_outbuf(req, 1, 0);
-
        SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
 
        if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
@@ -1899,67 +2003,82 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
  Reply to a create temporary file.
 ****************************************************************************/
 
-int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_ctemp(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
-       int outsize = 0;
-       uint32 fattr = SVAL(inbuf,smb_vwv0);
+       pstring fname_in;
+       char *fname = NULL;
+       uint32 fattr;
        files_struct *fsp;
-       int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+       int oplock_request;
        int tmpfd;
        SMB_STRUCT_STAT sbuf;
-       char *p, *s;
+       char *s;
        NTSTATUS status;
-       unsigned int namelen;
-       struct smb_request req;
 
        START_PROFILE(SMBctemp);
 
-       init_smb_request(&req, (uint8 *)inbuf);
+       if (req->wct < 3) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBctemp);
+               return;
+       }
+
+       fattr = SVAL(req->inbuf,smb_vwv0);
+       oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
 
-       srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, smb_buf(inbuf)+1,
-                       sizeof(fname), 0, STR_TERMINATE, &status);
+       srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
+                       smb_buf(req->inbuf)+1, sizeof(fname_in), 0, STR_TERMINATE,
+                       &status);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBctemp);
-               return ERROR_NT(status);
+               return;
        }
-       if (*fname) {
-               pstrcat(fname,"/TMXXXXXX");
+       if (*fname_in) {
+               pstrcat(fname_in,"/TMXXXXXX");
        } else {
-               pstrcat(fname,"TMXXXXXX");
+               pstrcat(fname_in,"TMXXXXXX");
        }
 
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                fname_in);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBctemp);
                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(SMBctemp);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBctemp);
+               return;
        }
 
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
+       status = unix_convert(conn, fname_in, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBctemp);
-               return ERROR_NT(status);
+               return;
        }
 
        status = check_name(conn, fname);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBctemp);
-               return ERROR_NT(status);
+               return;
        }
   
        tmpfd = smb_mkstemp(fname);
        if (tmpfd == -1) {
+               reply_unixerror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBctemp);
-               return(UNIXERROR(ERRDOS,ERRnoaccess));
+               return;
        }
 
        SMB_VFS_STAT(conn,fname,&sbuf);
 
        /* We should fail if file does not exist. */
-       status = open_file_ntcreate(conn, &req, fname, &sbuf,
+       status = open_file_ntcreate(conn, req, fname, &sbuf,
                                FILE_GENERIC_READ | FILE_GENERIC_WRITE,
                                FILE_SHARE_READ|FILE_SHARE_WRITE,
                                FILE_OPEN,
@@ -1972,16 +2091,18 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        close(tmpfd);
 
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBctemp);
-               if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+               if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       return -1;
+                       END_PROFILE(SMBctemp);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_openerror(req, status);
+               END_PROFILE(SMBctemp);
+               return;
        }
 
-       outsize = set_message(inbuf,outbuf,1,0,True);
-       SSVAL(outbuf,smb_vwv0,fsp->fnum);
+       reply_outbuf(req, 1, 0);
+       SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
 
        /* the returned filename is relative to the directory */
        s = strrchr_m(fname, '/');
@@ -1991,23 +2112,26 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                s++;
        }
 
-       p = smb_buf(outbuf);
 #if 0
        /* Tested vs W2K3 - this doesn't seem to be here - null terminated filename is the only
           thing in the byte section. JRA */
        SSVALS(p, 0, -1); /* what is this? not in spec */
 #endif
-       namelen = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p, s, -1,
-                             STR_ASCII|STR_TERMINATE);
-       p += namelen;
-       outsize = set_message_end(inbuf,outbuf, p);
+       if (message_push_string(&req->outbuf, s, STR_ASCII|STR_TERMINATE)
+           == -1) {
+               reply_nterror(req, NT_STATUS_NO_MEMORY);
+               END_PROFILE(SMBctemp);
+               return;
+       }
 
        if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
-               SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+               SCVAL(req->outbuf, smb_flg,
+                     CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
        }
   
        if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
-               SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+               SCVAL(req->outbuf, smb_flg,
+                     CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
        }
 
        DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
@@ -2015,7 +2139,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                        (unsigned int)sbuf.st_mode ) );
 
        END_PROFILE(SMBctemp);
-       return(outsize);
+       return;
 }
 
 /*******************************************************************
@@ -2174,22 +2298,23 @@ static NTSTATUS do_unlink(connection_struct *conn, struct smb_request *req,
 ****************************************************************************/
 
 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
-                         uint32 dirtype, char *name, BOOL has_wild)
+                         uint32 dirtype, const char *name_in, BOOL has_wild)
 {
        pstring directory;
        pstring mask;
+       char *name = NULL;
        char *p;
        int count=0;
        NTSTATUS status = NT_STATUS_OK;
        SMB_STRUCT_STAT sbuf;
-       
+
        *directory = *mask = 0;
-       
-       status = unix_convert(conn, name, has_wild, NULL, &sbuf);
+
+       status = unix_convert(conn, name_in, has_wild, &name, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
-       
+
        p = strrchr_m(name,'/');
        if (!p) {
                pstrcpy(directory,".");
@@ -2199,7 +2324,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
                pstrcpy(directory,name);
                pstrcpy(mask,p+1);
        }
-       
+
        /*
         * We should only check the mangled cache
         * here if unix_convert failed. This means
@@ -2208,10 +2333,18 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
         * for a possible mangle. This patch from
         * Tine Smukavec <valentin.smukavec@hermes.si>.
         */
-       
-       if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params))
-               mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
-       
+
+       if (!VALID_STAT(sbuf) && mangle_is_mangled(mask,conn->params)) {
+               char *new_mask = NULL;
+               mangle_lookup_name_from_8_3(talloc_tos(),
+                               mask,
+                               &new_mask,
+                               conn->params );
+               if (new_mask) {
+                       pstrcpy(mask, new_mask);
+               }
+       }
+
        if (!has_wild) {
                pstrcat(directory,"/");
                pstrcat(directory,mask);
@@ -2234,7 +2367,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
                struct smb_Dir *dir_hnd = NULL;
                long offset = 0;
                const char *dname;
-               
+
                if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) {
                        return NT_STATUS_OBJECT_NAME_INVALID;
                }
@@ -2577,7 +2710,7 @@ void reply_readbraw(connection_struct *conn, struct smb_request *req)
 
        fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
 
-       /* 
+       /*
         * We have to do a check_fsp by hand here, as
         * we must always return 4 zero bytes on error,
         * not a NTSTATUS.
@@ -2669,7 +2802,7 @@ void reply_readbraw(connection_struct *conn, struct smb_request *req)
        if (startpos >= size) {
                nread = 0;
        } else {
-               nread = MIN(maxcount,(size - startpos));          
+               nread = MIN(maxcount,(size - startpos));
        }
 
 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
@@ -2697,31 +2830,48 @@ void reply_readbraw(connection_struct *conn, struct smb_request *req)
  Reply to a lockread (core+ protocol).
 ****************************************************************************/
 
-int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz)
+void reply_lockread(connection_struct *conn, struct smb_request *req)
 {
        ssize_t nread = -1;
        char *data;
-       int outsize = 0;
        SMB_OFF_T startpos;
        size_t numtoread;
        NTSTATUS status;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
        struct byte_range_lock *br_lck = NULL;
+       char *p = NULL;
+
        START_PROFILE(SMBlockread);
 
-       CHECK_FSP(fsp,conn);
-       if (!CHECK_READ(fsp,inbuf)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
+       if (req->wct < 5) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBlockread);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBlockread);
+               return;
+       }
+
+       if (!CHECK_READ(fsp,req->inbuf)) {
+               reply_doserror(req, ERRDOS, ERRbadaccess);
+               END_PROFILE(SMBlockread);
+               return;
        }
 
        release_level_2_oplocks_on_change(fsp);
 
-       numtoread = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-  
-       outsize = set_message(inbuf,outbuf,5,3,True);
-       numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
-       data = smb_buf(outbuf) + 3;
+       numtoread = SVAL(req->inbuf,smb_vwv1);
+       startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+
+       numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
+
+       reply_outbuf(req, 5, numtoread + 3);
+
+       data = smb_buf(req->outbuf) + 3;
        
        /*
         * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
@@ -2733,7 +2883,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
        
        br_lck = do_lock(smbd_messaging_context(),
                        fsp,
-                       (uint32)SVAL(inbuf,smb_pid), 
+                       req->smbpid,
                        (SMB_BIG_UINT)numtoread,
                        (SMB_BIG_UINT)startpos,
                        WRITE_LOCK,
@@ -2744,8 +2894,9 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
        TALLOC_FREE(br_lck);
 
        if (NT_STATUS_V(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBlockread);
-               return ERROR_NT(status);
+               return;
        }
 
        /*
@@ -2761,20 +2912,24 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
        nread = read_file(fsp,data,startpos,numtoread);
 
        if (nread < 0) {
+               reply_unixerror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBlockread);
-               return(UNIXERROR(ERRDOS,ERRnoaccess));
+               return;
        }
        
-       outsize += nread;
-       SSVAL(outbuf,smb_vwv0,nread);
-       SSVAL(outbuf,smb_vwv5,nread+3);
-       SSVAL(smb_buf(outbuf),1,nread);
+       set_message(NULL, (char *)req->outbuf, 5, nread+3, False);
+
+       SSVAL(req->outbuf,smb_vwv0,nread);
+       SSVAL(req->outbuf,smb_vwv5,nread+3);
+       p = smb_buf(req->outbuf);
+       SCVAL(p,0,0); /* pad byte. */
+       SSVAL(p,1,nread);
        
        DEBUG(3,("lockread fnum=%d num=%d nread=%d\n",
                 fsp->fnum, (int)numtoread, (int)nread));
 
        END_PROFILE(SMBlockread);
-       return(outsize);
+       return;
 }
 
 #undef DBGC_CLASS
@@ -2784,26 +2939,41 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
  Reply to a read.
 ****************************************************************************/
 
-int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_read(connection_struct *conn, struct smb_request *req)
 {
        size_t numtoread;
        ssize_t nread = 0;
        char *data;
        SMB_OFF_T startpos;
        int outsize = 0;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
+
        START_PROFILE(SMBread);
 
-       CHECK_FSP(fsp,conn);
-       if (!CHECK_READ(fsp,inbuf)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
+       if (req->wct < 3) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBread);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBread);
+               return;
+       }
+
+       if (!CHECK_READ(fsp,req->inbuf)) {
+               reply_doserror(req, ERRDOS, ERRbadaccess);
+               END_PROFILE(SMBread);
+               return;
        }
 
-       numtoread = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
+       numtoread = SVAL(req->inbuf,smb_vwv1);
+       startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
 
-       outsize = set_message(inbuf,outbuf,5,3,True);
        numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
+
        /*
         * The requested read size cannot be greater than max_recv. JRA.
         */
@@ -2814,32 +2984,38 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
                numtoread = MIN(numtoread,max_recv);
        }
 
-       data = smb_buf(outbuf) + 3;
+       reply_outbuf(req, 5, numtoread+3);
+
+       data = smb_buf(req->outbuf) + 3;
   
-       if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+       if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtoread,
+                     (SMB_BIG_UINT)startpos, READ_LOCK)) {
+               reply_doserror(req, ERRDOS,ERRlock);
                END_PROFILE(SMBread);
-               return ERROR_DOS(ERRDOS,ERRlock);
+               return;
        }
 
        if (numtoread > 0)
                nread = read_file(fsp,data,startpos,numtoread);
 
        if (nread < 0) {
+               reply_unixerror(req, ERRDOS,ERRnoaccess);
                END_PROFILE(SMBread);
-               return(UNIXERROR(ERRDOS,ERRnoaccess));
+               return;
        }
-  
-       outsize += nread;
-       SSVAL(outbuf,smb_vwv0,nread);
-       SSVAL(outbuf,smb_vwv5,nread+3);
-       SCVAL(smb_buf(outbuf),0,1);
-       SSVAL(smb_buf(outbuf),1,nread);
+
+       set_message(NULL, (char *)req->outbuf, 5, nread+3, False);
+
+       SSVAL(req->outbuf,smb_vwv0,nread);
+       SSVAL(req->outbuf,smb_vwv5,nread+3);
+       SCVAL(smb_buf(req->outbuf),0,1);
+       SSVAL(smb_buf(req->outbuf),1,nread);
   
        DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
                fsp->fnum, (int)numtoread, (int)nread ) );
 
        END_PROFILE(SMBread);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -2957,7 +3133,6 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                TALLOC_FREE(req->outbuf);
                return;
        }
-
 #endif
 
 normal_read:
@@ -2998,7 +3173,7 @@ normal_read:
                DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
                        fsp->fnum, (int)smb_maxcnt, (int)nread ) );
 
-               chain_reply_new(req);
+               chain_reply(req);
 
                return;
        }
@@ -3110,7 +3285,6 @@ void reply_read_and_X(connection_struct *conn, struct smb_request *req)
        if (!big_readX
            && schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
                END_PROFILE(SMBreadX);
-               reply_post_legacy(req, -1);
                return;
        }
 
@@ -3120,12 +3294,28 @@ void reply_read_and_X(connection_struct *conn, struct smb_request *req)
        return;
 }
 
+/****************************************************************************
+ Error replies to writebraw must have smb_wct == 1. Fix this up.
+****************************************************************************/
+
+void error_to_writebrawerr(struct smb_request *req)
+{
+       uint8 *old_outbuf = req->outbuf;
+
+       reply_outbuf(req, 1, 0);
+
+       memcpy(req->outbuf, old_outbuf, smb_size);
+       TALLOC_FREE(old_outbuf);
+}
+
 /****************************************************************************
  Reply to a writebraw (core+ or LANMAN1.0 protocol).
 ****************************************************************************/
 
-int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_writebraw(connection_struct *conn, struct smb_request *req)
 {
+       int outsize = 0;
+       char *buf = NULL;
        ssize_t nwritten=0;
        ssize_t total_written=0;
        size_t numtowrite=0;
@@ -3133,140 +3323,212 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
        SMB_OFF_T startpos;
        char *data=NULL;
        BOOL write_through;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
-       int outsize = 0;
+       files_struct *fsp;
        NTSTATUS status;
+
        START_PROFILE(SMBwritebraw);
 
+       /*
+        * If we ever reply with an error, it must have the SMB command
+        * type of SMBwritec, not SMBwriteBraw, as this tells the client
+        * we're finished.
+        */
+       SCVAL(req->inbuf,smb_com,SMBwritec);
+
        if (srv_is_signing_active()) {
-               exit_server_cleanly("reply_writebraw: SMB signing is active - raw reads/writes are disallowed.");
+               END_PROFILE(SMBwritebraw);
+               exit_server_cleanly("reply_writebraw: SMB signing is active - "
+                               "raw reads/writes are disallowed.");
+       }
+
+       if (req->wct < 12) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               error_to_writebrawerr(req);
+               END_PROFILE(SMBwritebraw);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               error_to_writebrawerr(req);
+               END_PROFILE(SMBwritebraw);
+               return;
        }
 
-       CHECK_FSP(fsp,conn);
        if (!CHECK_WRITE(fsp)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
+               reply_doserror(req, ERRDOS, ERRbadaccess);
+               error_to_writebrawerr(req);
+               END_PROFILE(SMBwritebraw);
+               return;
        }
-  
-       tcount = IVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
-       write_through = BITSETW(inbuf+smb_vwv7,0);
+
+       tcount = IVAL(req->inbuf,smb_vwv1);
+       startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
+       write_through = BITSETW(req->inbuf+smb_vwv7,0);
 
        /* We have to deal with slightly different formats depending
                on whether we are using the core+ or lanman1.0 protocol */
 
        if(Protocol <= PROTOCOL_COREPLUS) {
-               numtowrite = SVAL(smb_buf(inbuf),-2);
-               data = smb_buf(inbuf);
+               numtowrite = SVAL(smb_buf(req->inbuf),-2);
+               data = smb_buf(req->inbuf);
        } else {
-               numtowrite = SVAL(inbuf,smb_vwv10);
-               data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
+               numtowrite = SVAL(req->inbuf,smb_vwv10);
+               data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
        }
 
-       /* force the error type */
-       SCVAL(inbuf,smb_com,SMBwritec);
-       SCVAL(outbuf,smb_com,SMBwritec);
+       /* Ensure we don't write bytes past the end of this packet. */
+       if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               error_to_writebrawerr(req);
+               END_PROFILE(SMBwritebraw);
+               return;
+       }
 
-       if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+       if (is_locked(fsp,(uint32)req->smbpid,(SMB_BIG_UINT)tcount,
+                               (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+               reply_doserror(req, ERRDOS, ERRlock);
+               error_to_writebrawerr(req);
                END_PROFILE(SMBwritebraw);
-               return(ERROR_DOS(ERRDOS,ERRlock));
+               return;
        }
 
-       if (numtowrite>0)
+       if (numtowrite>0) {
                nwritten = write_file(fsp,data,startpos,numtowrite);
-  
-       DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
-               fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
+       }
+
+       DEBUG(3,("reply_writebraw: initial write fnum=%d start=%.0f num=%d "
+                       "wrote=%d sync=%d\n",
+               fsp->fnum, (double)startpos, (int)numtowrite,
+               (int)nwritten, (int)write_through));
 
        if (nwritten < (ssize_t)numtowrite)  {
+               reply_unixerror(req, ERRHRD, ERRdiskfull);
+               error_to_writebrawerr(req);
                END_PROFILE(SMBwritebraw);
-               return(UNIXERROR(ERRHRD,ERRdiskfull));
+               return;
        }
 
        total_written = nwritten;
 
-       /* Return a message to the redirector to tell it to send more bytes */
-       SCVAL(outbuf,smb_com,SMBwritebraw);
-       SSVALS(outbuf,smb_vwv0,-1);
-       outsize = set_message(inbuf,outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
-       show_msg(outbuf);
-       if (!send_smb(smbd_server_fd(),outbuf))
-               exit_server_cleanly("reply_writebraw: send_smb failed.");
-  
+       /* Allocate a buffer of 64k + length. */
+       buf = TALLOC_ARRAY(NULL, char, 65540);
+       if (!buf) {
+               reply_doserror(req, ERRDOS, ERRnomem);
+               error_to_writebrawerr(req);
+               END_PROFILE(SMBwritebraw);
+               return;
+       }
+
+       /* Return a SMBwritebraw message to the redirector to tell
+        * it to send more bytes */
+
+       memcpy(buf, req->inbuf, smb_size);
+       outsize = set_message(NULL,buf,
+                       Protocol>PROTOCOL_COREPLUS?1:0,0,True);
+       SCVAL(buf,smb_com,SMBwritebraw);
+       SSVALS(buf,smb_vwv0,0xFFFF);
+       show_msg(buf);
+       if (!send_smb(smbd_server_fd(),buf)) {
+               exit_server_cleanly("reply_writebraw: send_smb "
+                       "failed.");
+       }
+
        /* Now read the raw data into the buffer and write it */
-       if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
+       if (read_smb_length(smbd_server_fd(),buf,SMB_SECONDARY_WAIT) == -1) {
                exit_server_cleanly("secondary writebraw failed");
        }
-  
-       /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
-       numtowrite = smb_len(inbuf);
 
-       /* Set up outbuf to return the correct return */
-       outsize = set_message(inbuf,outbuf,1,0,True);
-       SCVAL(outbuf,smb_com,SMBwritec);
+       /*
+        * Even though this is not an smb message,
+        * smb_len returns the generic length of a packet.
+        */
+
+       numtowrite = smb_len(buf);
+
+       /* Set up outbuf to return the correct size */
+       reply_outbuf(req, 1, 0);
 
        if (numtowrite != 0) {
 
-               if (numtowrite > BUFFER_SIZE) {
-                       DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
+               if (numtowrite > 0xFFFF) {
+                       DEBUG(0,("reply_writebraw: Oversize secondary write "
+                               "raw requested (%u). Terminating\n",
                                (unsigned int)numtowrite ));
                        exit_server_cleanly("secondary writebraw failed");
                }
 
                if (tcount > nwritten+numtowrite) {
-                       DEBUG(3,("Client overestimated the write %d %d %d\n",
+                       DEBUG(3,("reply_writebraw: Client overestimated the "
+                               "write %d %d %d\n",
                                (int)tcount,(int)nwritten,(int)numtowrite));
                }
 
-               if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
-                       DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
+               if (read_data(smbd_server_fd(), buf+4, numtowrite)
+                                       != numtowrite ) {
+                       DEBUG(0,("reply_writebraw: Oversize secondary write "
+                               "raw read failed (%s). Terminating\n",
                                strerror(errno) ));
                        exit_server_cleanly("secondary writebraw failed");
                }
 
-               nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
+               nwritten = write_file(fsp,buf+4,startpos+nwritten,numtowrite);
                if (nwritten == -1) {
+                       TALLOC_FREE(buf);
+                       reply_unixerror(req, ERRHRD, ERRdiskfull);
+                       error_to_writebrawerr(req);
                        END_PROFILE(SMBwritebraw);
-                       return(UNIXERROR(ERRHRD,ERRdiskfull));
+                       return;
                }
 
                if (nwritten < (ssize_t)numtowrite) {
-                       SCVAL(outbuf,smb_rcls,ERRHRD);
-                       SSVAL(outbuf,smb_err,ERRdiskfull);      
+                       SCVAL(req->outbuf,smb_rcls,ERRHRD);
+                       SSVAL(req->outbuf,smb_err,ERRdiskfull);
                }
 
-               if (nwritten > 0)
+               if (nwritten > 0) {
                        total_written += nwritten;
+               }
        }
-       SSVAL(outbuf,smb_vwv0,total_written);
+
+       TALLOC_FREE(buf);
+       SSVAL(req->outbuf,smb_vwv0,total_written);
 
        status = sync_file(conn, fsp, write_through);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
                        fsp->fsp_name, nt_errstr(status) ));
+               reply_nterror(req, status);
+               error_to_writebrawerr(req);
                END_PROFILE(SMBwritebraw);
-               return ERROR_NT(status);
+               return;
        }
 
-       DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
-               fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
+       DEBUG(3,("reply_writebraw: secondart write fnum=%d start=%.0f num=%d "
+               "wrote=%d\n",
+               fsp->fnum, (double)startpos, (int)numtowrite,
+               (int)total_written));
 
-       /* we won't return a status if write through is not selected - this follows what WfWg does */
+       /* We won't return a status if write through is not selected - this
+        * follows what WfWg does */
        END_PROFILE(SMBwritebraw);
+
        if (!write_through && total_written==tcount) {
 
 #if RABBIT_PELLET_FIX
                /*
                 * Fix for "rabbit pellet" mode, trigger an early TCP ack by
-                * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
+                * sending a SMBkeepalive. Thanks to DaveCB at Sun for this.
+                * JRA.
                 */
-               if (!send_keepalive(smbd_server_fd()))
-                       exit_server_cleanly("reply_writebraw: send of keepalive failed");
+               if (!send_keepalive(smbd_server_fd())) {
+                       exit_server_cleanly("reply_writebraw: send of "
+                               "keepalive failed");
+               }
 #endif
-               return(-1);
+               TALLOC_FREE(req->outbuf);
        }
-
-       return(outsize);
+       return;
 }
 
 #undef DBGC_CLASS
@@ -3276,30 +3538,46 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
  Reply to a writeunlock (core+).
 ****************************************************************************/
 
-int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, 
-                     int size, int dum_buffsize)
+void reply_writeunlock(connection_struct *conn, struct smb_request *req)
 {
        ssize_t nwritten = -1;
        size_t numtowrite;
        SMB_OFF_T startpos;
        char *data;
        NTSTATUS status = NT_STATUS_OK;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
-       int outsize = 0;
+       files_struct *fsp;
+
        START_PROFILE(SMBwriteunlock);
+
+       if (req->wct < 5) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBwriteunlock);
+               return;
+       }
        
-       CHECK_FSP(fsp,conn);
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBwriteunlock);
+               return;
+       }
+
        if (!CHECK_WRITE(fsp)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
+               reply_doserror(req, ERRDOS,ERRbadaccess);
+               END_PROFILE(SMBwriteunlock);
+               return;
        }
 
-       numtowrite = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-       data = smb_buf(inbuf) + 3;
+       numtowrite = SVAL(req->inbuf,smb_vwv1);
+       startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+       data = smb_buf(req->inbuf) + 3;
   
-       if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+       if (numtowrite
+           && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
+                        (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+               reply_doserror(req, ERRDOS, ERRlock);
                END_PROFILE(SMBwriteunlock);
-               return ERROR_DOS(ERRDOS,ERRlock);
+               return;
        }
 
        /* The special X/Open SMB protocol handling of
@@ -3313,40 +3591,43 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
   
        status = sync_file(conn, fsp, False /* write through */);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBwriteunlock);
                DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
                        fsp->fsp_name, nt_errstr(status) ));
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBwriteunlock);
+               return;
        }
 
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+               reply_unixerror(req, ERRHRD, ERRdiskfull);
                END_PROFILE(SMBwriteunlock);
-               return(UNIXERROR(ERRHRD,ERRdiskfull));
+               return;
        }
 
        if (numtowrite) {
                status = do_unlock(smbd_messaging_context(),
                                fsp,
-                               (uint32)SVAL(inbuf,smb_pid),
+                               req->smbpid,
                                (SMB_BIG_UINT)numtowrite, 
                                (SMB_BIG_UINT)startpos,
                                WINDOWS_LOCK);
 
                if (NT_STATUS_V(status)) {
+                       reply_nterror(req, status);
                        END_PROFILE(SMBwriteunlock);
-                       return ERROR_NT(status);
+                       return;
                }
        }
+
+       reply_outbuf(req, 1, 0);
        
-       outsize = set_message(inbuf,outbuf,1,0,True);
-       
-       SSVAL(outbuf,smb_vwv0,nwritten);
+       SSVAL(req->outbuf,smb_vwv0,nwritten);
        
        DEBUG(3,("writeunlock fnum=%d num=%d wrote=%d\n",
                 fsp->fnum, (int)numtowrite, (int)nwritten));
        
        END_PROFILE(SMBwriteunlock);
-       return outsize;
+       return;
 }
 
 #undef DBGC_CLASS
@@ -3356,36 +3637,52 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
  Reply to a write.
 ****************************************************************************/
 
-int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
+void reply_write(connection_struct *conn, struct smb_request *req)
 {
        size_t numtowrite;
        ssize_t nwritten = -1;
        SMB_OFF_T startpos;
        char *data;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
-       int outsize = 0;
+       files_struct *fsp;
        NTSTATUS status;
+
        START_PROFILE(SMBwrite);
 
+       if (req->wct < 5) {
+               END_PROFILE(SMBwrite);
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
        /* If it's an IPC, pass off the pipe handler. */
        if (IS_IPC(conn)) {
+               reply_pipe_write(req);
+               END_PROFILE(SMBwrite);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
                END_PROFILE(SMBwrite);
-               return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
+               return;
        }
 
-       CHECK_FSP(fsp,conn);
        if (!CHECK_WRITE(fsp)) {
+               reply_doserror(req, ERRDOS, ERRbadaccess);
                END_PROFILE(SMBwrite);
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
+               return;
        }
 
-       numtowrite = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-       data = smb_buf(inbuf) + 3;
+       numtowrite = SVAL(req->inbuf,smb_vwv1);
+       startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+       data = smb_buf(req->inbuf) + 3;
   
-       if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+       if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
+                     (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+               reply_doserror(req, ERRDOS, ERRlock);
                END_PROFILE(SMBwrite);
-               return ERROR_DOS(ERRDOS,ERRlock);
+               return;
        }
 
        /*
@@ -3400,43 +3697,47 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
                 */
                nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
                if (nwritten < 0) {
+                       reply_nterror(req, NT_STATUS_DISK_FULL);
                        END_PROFILE(SMBwrite);
-                       return ERROR_NT(NT_STATUS_DISK_FULL);
+                       return;
                }
                nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
                if (nwritten < 0) {
+                       reply_nterror(req, NT_STATUS_DISK_FULL);
                        END_PROFILE(SMBwrite);
-                       return ERROR_NT(NT_STATUS_DISK_FULL);
+                       return;
                }
        } else
                nwritten = write_file(fsp,data,startpos,numtowrite);
   
        status = sync_file(conn, fsp, False);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBwrite);
                DEBUG(5,("reply_write: sync_file for %s returned %s\n",
                        fsp->fsp_name, nt_errstr(status) ));
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBwrite);
+               return;
        }
 
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+               reply_unixerror(req, ERRHRD, ERRdiskfull);
                END_PROFILE(SMBwrite);
-               return(UNIXERROR(ERRHRD,ERRdiskfull));
+               return;
        }
 
-       outsize = set_message(inbuf,outbuf,1,0,True);
+       reply_outbuf(req, 1, 0);
   
-       SSVAL(outbuf,smb_vwv0,nwritten);
+       SSVAL(req->outbuf,smb_vwv0,nwritten);
 
        if (nwritten < (ssize_t)numtowrite) {
-               SCVAL(outbuf,smb_rcls,ERRHRD);
-               SSVAL(outbuf,smb_err,ERRdiskfull);      
+               SCVAL(req->outbuf,smb_rcls,ERRHRD);
+               SSVAL(req->outbuf,smb_err,ERRdiskfull);
        }
   
        DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten));
 
        END_PROFILE(SMBwrite);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -3584,7 +3885,7 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
        }
 
        END_PROFILE(SMBwriteX);
-       chain_reply_new(req);
+       chain_reply(req);
        return;
 }
 
@@ -3592,22 +3893,32 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
  Reply to a lseek.
 ****************************************************************************/
 
-int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_lseek(connection_struct *conn, struct smb_request *req)
 {
        SMB_OFF_T startpos;
        SMB_OFF_T res= -1;
        int mode,umode;
-       int outsize = 0;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
+
        START_PROFILE(SMBlseek);
 
-       CHECK_FSP(fsp,conn);
+       if (req->wct < 4) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBlseek);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               return;
+       }
 
        flush_write_cache(fsp, SEEK_FLUSH);
 
-       mode = SVAL(inbuf,smb_vwv1) & 3;
+       mode = SVAL(req->inbuf,smb_vwv1) & 3;
        /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
-       startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
+       startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
 
        switch (mode) {
                case 0:
@@ -3634,8 +3945,10 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
                                SMB_STRUCT_STAT sbuf;
 
                                if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) {
+                                       reply_unixerror(req, ERRDOS,
+                                                       ERRnoaccess);
                                        END_PROFILE(SMBlseek);
-                                       return(UNIXERROR(ERRDOS,ERRnoaccess));
+                                       return;
                                }
 
                                current_pos += sbuf.st_size;
@@ -3645,21 +3958,22 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
                }
 
                if(res == -1) {
+                       reply_unixerror(req, ERRDOS, ERRnoaccess);
                        END_PROFILE(SMBlseek);
-                       return(UNIXERROR(ERRDOS,ERRnoaccess));
+                       return;
                }
        }
 
        fsp->fh->pos = res;
-  
-       outsize = set_message(inbuf,outbuf,2,0,True);
-       SIVAL(outbuf,smb_vwv0,res);
+
+       reply_outbuf(req, 2, 0);
+       SIVAL(req->outbuf,smb_vwv0,res);
   
        DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
                fsp->fnum, (double)startpos, (double)res, mode));
 
        END_PROFILE(SMBlseek);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -3806,32 +4120,48 @@ void reply_close(connection_struct *conn, struct smb_request *req)
  Reply to a writeclose (Core+ protocol).
 ****************************************************************************/
 
-int reply_writeclose(connection_struct *conn,
-                    char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_writeclose(connection_struct *conn, struct smb_request *req)
 {
        size_t numtowrite;
        ssize_t nwritten = -1;
-       int outsize = 0;
        NTSTATUS close_status = NT_STATUS_OK;
        SMB_OFF_T startpos;
        char *data;
        struct timespec mtime;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
+
        START_PROFILE(SMBwriteclose);
 
-       CHECK_FSP(fsp,conn);
+       if (req->wct < 6) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBwriteclose);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBwriteclose);
+               return;
+       }
        if (!CHECK_WRITE(fsp)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
+               reply_doserror(req, ERRDOS,ERRbadaccess);
+               END_PROFILE(SMBwriteclose);
+               return;
        }
 
-       numtowrite = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-       mtime = convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv4));
-       data = smb_buf(inbuf) + 1;
+       numtowrite = SVAL(req->inbuf,smb_vwv1);
+       startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+       mtime = convert_time_t_to_timespec(srv_make_unix_date3(
+                                                  req->inbuf+smb_vwv4));
+       data = smb_buf(req->inbuf) + 1;
   
-       if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+       if (numtowrite
+           && is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite,
+                        (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+               reply_doserror(req, ERRDOS,ERRlock);
                END_PROFILE(SMBwriteclose);
-               return ERROR_DOS(ERRDOS,ERRlock);
+               return;
        }
   
        nwritten = write_file(fsp,data,startpos,numtowrite);
@@ -3854,20 +4184,22 @@ int reply_writeclose(connection_struct *conn,
                 conn->num_files_open));
   
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                END_PROFILE(SMBwriteclose);
-               return(UNIXERROR(ERRHRD,ERRdiskfull));
+               return;
        }
  
        if(!NT_STATUS_IS_OK(close_status)) {
+               reply_nterror(req, close_status);
                END_PROFILE(SMBwriteclose);
-               return ERROR_NT(close_status);
+               return;
        }
-       outsize = set_message(inbuf,outbuf,1,0,True);
+
+       reply_outbuf(req, 1, 0);
   
-       SSVAL(outbuf,smb_vwv0,nwritten);
+       SSVAL(req->outbuf,smb_vwv0,nwritten);
        END_PROFILE(SMBwriteclose);
-       return(outsize);
+       return;
 }
 
 #undef DBGC_CLASS
@@ -3877,30 +4209,39 @@ int reply_writeclose(connection_struct *conn,
  Reply to a lock.
 ****************************************************************************/
 
-int reply_lock(connection_struct *conn,
-              char *inbuf,char *outbuf, int length, int dum_buffsize)
+void reply_lock(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = set_message(inbuf,outbuf,0,0,False);
        SMB_BIG_UINT count,offset;
        NTSTATUS status;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
        struct byte_range_lock *br_lck = NULL;
 
        START_PROFILE(SMBlock);
 
-       CHECK_FSP(fsp,conn);
+       if (req->wct < 5) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBlock);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBlock);
+               return;
+       }
 
        release_level_2_oplocks_on_change(fsp);
 
-       count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
-       offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
+       count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
+       offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
 
        DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
                 fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
 
        br_lck = do_lock(smbd_messaging_context(),
                        fsp,
-                       (uint32)SVAL(inbuf,smb_pid),
+                       req->smbpid,
                        count,
                        offset,
                        WRITE_LOCK,
@@ -3912,49 +4253,65 @@ int reply_lock(connection_struct *conn,
        TALLOC_FREE(br_lck);
 
        if (NT_STATUS_V(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBlock);
-               return ERROR_NT(status);
+               return;
        }
 
+       reply_outbuf(req, 0, 0);
+
        END_PROFILE(SMBlock);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
  Reply to a unlock.
 ****************************************************************************/
 
-int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, 
-                int dum_buffsize)
+void reply_unlock(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = set_message(inbuf,outbuf,0,0,False);
        SMB_BIG_UINT count,offset;
        NTSTATUS status;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
+
        START_PROFILE(SMBunlock);
 
-       CHECK_FSP(fsp,conn);
-       
-       count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
-       offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
+       if (req->wct < 5) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBunlock);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBunlock);
+               return;
+       }
+       
+       count = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv1);
+       offset = (SMB_BIG_UINT)IVAL(req->inbuf,smb_vwv3);
        
        status = do_unlock(smbd_messaging_context(),
                        fsp,
-                       (uint32)SVAL(inbuf,smb_pid),
+                       req->smbpid,
                        count,
                        offset,
                        WINDOWS_LOCK);
 
        if (NT_STATUS_V(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBunlock);
-               return ERROR_NT(status);
+               return;
        }
 
        DEBUG( 3, ( "unlock fd=%d fnum=%d offset=%.0f count=%.0f\n",
                    fsp->fh->fd, fsp->fnum, (double)offset, (double)count ) );
-       
+
+       reply_outbuf(req, 0, 0);
+
        END_PROFILE(SMBunlock);
-       return(outsize);
+       return;
 }
 
 #undef DBGC_CLASS
@@ -4047,55 +4404,72 @@ void reply_echo(connection_struct *conn, struct smb_request *req)
  Reply to a printopen.
 ****************************************************************************/
 
-int reply_printopen(connection_struct *conn, 
-                   char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_printopen(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = 0;
        files_struct *fsp;
        NTSTATUS status;
        
        START_PROFILE(SMBsplopen);
-       
+
+       if (req->wct < 2) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBsplopen);
+               return;
+       }
+
        if (!CAN_PRINT(conn)) {
+               reply_doserror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBsplopen);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return;
        }
 
        /* Open for exclusive use, write only. */
        status = print_fsp_open(conn, NULL, &fsp);
 
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBsplopen);
-               return(ERROR_NT(status));
+               return;
        }
 
-       outsize = set_message(inbuf,outbuf,1,0,True);
-       SSVAL(outbuf,smb_vwv0,fsp->fnum);
+       reply_outbuf(req, 1, 0);
+       SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
   
        DEBUG(3,("openprint fd=%d fnum=%d\n",
                 fsp->fh->fd, fsp->fnum));
 
        END_PROFILE(SMBsplopen);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
  Reply to a printclose.
 ****************************************************************************/
 
-int reply_printclose(connection_struct *conn,
-                    char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_printclose(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = set_message(inbuf,outbuf,0,0,False);
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
        NTSTATUS status;
+
        START_PROFILE(SMBsplclose);
 
-       CHECK_FSP(fsp,conn);
+       if (req->wct < 3) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBsplclose);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBsplclose);
+                return;
+        }
 
        if (!CAN_PRINT(conn)) {
+               reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
                END_PROFILE(SMBsplclose);
-               return ERROR_NT(NT_STATUS_DOS(ERRSRV, ERRerror));
+               return;
        }
   
        DEBUG(3,("printclose fd=%d fnum=%d\n",
@@ -4104,39 +4478,50 @@ int reply_printclose(connection_struct *conn,
        status = close_file(fsp,NORMAL_CLOSE);
 
        if(!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBsplclose);
-               return ERROR_NT(status);
+               return;
        }
 
        END_PROFILE(SMBsplclose);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
  Reply to a printqueue.
 ****************************************************************************/
 
-int reply_printqueue(connection_struct *conn,
-                    char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_printqueue(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = set_message(inbuf,outbuf,2,3,True);
-       int max_count = SVAL(inbuf,smb_vwv0);
-       int start_index = SVAL(inbuf,smb_vwv1);
+       int max_count;
+       int start_index;
+
        START_PROFILE(SMBsplretq);
 
+       if (req->wct < 2) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBsplretq);
+               return;
+       }
+
+       max_count = SVAL(req->inbuf,smb_vwv0);
+       start_index = SVAL(req->inbuf,smb_vwv1);
+
        /* we used to allow the client to get the cnum wrong, but that
           is really quite gross and only worked when there was only
           one printer - I think we should now only accept it if they
           get it right (tridge) */
        if (!CAN_PRINT(conn)) {
+               reply_doserror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBsplretq);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return;
        }
 
-       SSVAL(outbuf,smb_vwv0,0);
-       SSVAL(outbuf,smb_vwv1,0);
-       SCVAL(smb_buf(outbuf),0,1);
-       SSVAL(smb_buf(outbuf),1,0);
+       reply_outbuf(req, 2, 3);
+       SSVAL(req->outbuf,smb_vwv0,0);
+       SSVAL(req->outbuf,smb_vwv1,0);
+       SCVAL(smb_buf(req->outbuf),0,1);
+       SSVAL(smb_buf(req->outbuf),1,0);
   
        DEBUG(3,("printqueue start_index=%d max_count=%d\n",
                 start_index, max_count));
@@ -4144,7 +4529,6 @@ int reply_printqueue(connection_struct *conn,
        {
                print_queue_struct *queue = NULL;
                print_status_struct status;
-               char *p = smb_buf(outbuf) + 3;
                int count = print_queue_status(SNUM(conn), &queue, &status);
                int num_to_get = ABS(max_count);
                int first = (max_count>0?start_index:start_index+max_count+1);
@@ -4157,22 +4541,33 @@ int reply_printqueue(connection_struct *conn,
     
 
                for (i=first;i<first+num_to_get;i++) {
+                       char blob[28];
+                       char *p = blob;
+
                        srv_put_dos_date2(p,0,queue[i].time);
                        SCVAL(p,4,(queue[i].status==LPQ_PRINTING?2:3));
                        SSVAL(p,5, queue[i].job);
                        SIVAL(p,7,queue[i].size);
                        SCVAL(p,11,0);
-                       srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p+12,
+                       srvstr_push(blob, req->flags2, p+12,
                                    queue[i].fs_user, 16, STR_ASCII);
-                       p += 28;
+
+                       if (message_push_blob(
+                                   &req->outbuf,
+                                   data_blob_const(
+                                           blob, sizeof(blob))) == -1) {
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
+                               END_PROFILE(SMBsplretq);
+                               return;
+                       }
                }
 
                if (count > 0) {
-                       outsize = set_message(inbuf,outbuf,2,28*count+3,False); 
-                       SSVAL(outbuf,smb_vwv0,count);
-                       SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
-                       SCVAL(smb_buf(outbuf),0,1);
-                       SSVAL(smb_buf(outbuf),1,28*count);
+                       SSVAL(req->outbuf,smb_vwv0,count);
+                       SSVAL(req->outbuf,smb_vwv1,
+                             (max_count>0?first+count:first-1));
+                       SCVAL(smb_buf(req->outbuf),0,1);
+                       SSVAL(smb_buf(req->outbuf),1,28*count);
                }
 
                SAFE_FREE(queue);
@@ -4181,44 +4576,66 @@ int reply_printqueue(connection_struct *conn,
        }
   
        END_PROFILE(SMBsplretq);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
  Reply to a printwrite.
 ****************************************************************************/
 
-int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_printwrite(connection_struct *conn, struct smb_request *req)
 {
        int numtowrite;
-       int outsize = set_message(inbuf,outbuf,0,0,False);
        char *data;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
 
        START_PROFILE(SMBsplwr);
+
+       if (req->wct < 1) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBsplwr);
+               return;
+       }
   
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBsplwr);
+                return;
+        }
+
        if (!CAN_PRINT(conn)) {
+               reply_doserror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBsplwr);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return;
        }
 
-       CHECK_FSP(fsp,conn);
        if (!CHECK_WRITE(fsp)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
+               reply_doserror(req, ERRDOS, ERRbadaccess);
+               END_PROFILE(SMBsplwr);
+               return;
        }
 
-       numtowrite = SVAL(smb_buf(inbuf),1);
-       data = smb_buf(inbuf) + 3;
-  
+       numtowrite = SVAL(smb_buf(req->inbuf),1);
+
+       if (smb_buflen(req->inbuf) < numtowrite + 3) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBsplwr);
+               return;
+       }
+
+       data = smb_buf(req->inbuf) + 3;
+
        if (write_file(fsp,data,-1,numtowrite) != numtowrite) {
+               reply_unixerror(req, ERRHRD, ERRdiskfull);
                END_PROFILE(SMBsplwr);
-               return(UNIXERROR(ERRHRD,ERRdiskfull));
+               return;
        }
 
        DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
   
        END_PROFILE(SMBsplwr);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -4227,14 +4644,15 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
 
 void reply_mkdir(connection_struct *conn, struct smb_request *req)
 {
-       pstring directory;
+       pstring directory_in;
+       char *directory = NULL;
        NTSTATUS status;
        SMB_STRUCT_STAT sbuf;
 
        START_PROFILE(SMBmkdir);
  
-       srvstr_get_path((char *)req->inbuf, req->flags2, directory,
-                       smb_buf(req->inbuf) + 1, sizeof(directory), 0,
+       srvstr_get_path((char *)req->inbuf, req->flags2, directory_in,
+                       smb_buf(req->inbuf) + 1, sizeof(directory_in), 0,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -4244,7 +4662,7 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
 
        status = resolve_dfspath(conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                directory);
+                                directory_in);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -4257,7 +4675,7 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = unix_convert(conn, directory, False, NULL, &sbuf);
+       status = unix_convert(conn, directory_in, False, &directory, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBmkdir);
@@ -4270,7 +4688,7 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
                END_PROFILE(SMBmkdir);
                return;
        }
-  
+
        status = create_directory(conn, directory);
 
        DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
@@ -4480,13 +4898,14 @@ NTSTATUS rmdir_internals(connection_struct *conn, const char *directory)
 
 void reply_rmdir(connection_struct *conn, struct smb_request *req)
 {
-       pstring directory;
+       pstring directory_in;
+       char *directory = NULL;
        SMB_STRUCT_STAT sbuf;
        NTSTATUS status;
        START_PROFILE(SMBrmdir);
 
-       srvstr_get_path((char *)req->inbuf, req->flags2, directory,
-                       smb_buf(req->inbuf) + 1, sizeof(directory), 0,
+       srvstr_get_path((char *)req->inbuf, req->flags2, directory_in,
+                       smb_buf(req->inbuf) + 1, sizeof(directory_in), 0,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -4496,7 +4915,7 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
 
        status = resolve_dfspath(conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                directory);
+                                directory_in);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -4509,7 +4928,8 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = unix_convert(conn, directory, False, NULL, &sbuf);
+       status = unix_convert(conn, directory_in, False, &directory,
+                       NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBrmdir);
@@ -4541,87 +4961,129 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
 
 /*******************************************************************
  Resolve wildcards in a filename rename.
- Note that name is in UNIX charset and thus potentially can be more
- than fstring buffer (255 bytes) especially in default UTF-8 case.
- Therefore, we use pstring inside and all calls should ensure that
- name2 is at least pstring-long (they do already)
 ********************************************************************/
 
-static BOOL resolve_wildcards(const char *name1, char *name2)
+static BOOL resolve_wildcards(TALLOC_CTX *ctx,
+                               const char *name1,
+                               const char *name2,
+                               char **pp_newname)
 {
-       pstring root1,root2;
-       pstring ext1,ext2;
+       char *name2_copy = NULL;
+       char *root1 = NULL;
+       char *root2 = NULL;
+       char *ext1 = NULL;
+       char *ext2 = NULL;
        char *p,*p2, *pname1, *pname2;
-       int available_space, actual_space;
        
+       name2_copy = talloc_strdup(ctx, name2);
+       if (!name2_copy) {
+               return False;
+       }
+
        pname1 = strrchr_m(name1,'/');
-       pname2 = strrchr_m(name2,'/');
+       pname2 = strrchr_m(name2_copy,'/');
 
-       if (!pname1 || !pname2)
-               return(False);
+       if (!pname1 || !pname2) {
+               return False;
+       }
   
-       pstrcpy(root1,pname1);
-       pstrcpy(root2,pname2);
+       /* Truncate the copy of name2 at the last '/' */
+       *pname2 = '\0';
+
+       /* Now go past the '/' */
+       pname1++;
+       pname2++;
+
+       root1 = talloc_strdup(ctx, pname1);
+       root2 = talloc_strdup(ctx, pname2);
+
+       if (!root1 || !root2) {
+               return False;
+       }
+
        p = strrchr_m(root1,'.');
        if (p) {
                *p = 0;
-               pstrcpy(ext1,p+1);
+               ext1 = talloc_strdup(ctx, p+1);
        } else {
-               pstrcpy(ext1,"");    
+               ext1 = talloc_strdup(ctx, "");
        }
        p = strrchr_m(root2,'.');
        if (p) {
                *p = 0;
-               pstrcpy(ext2,p+1);
+               ext2 = talloc_strdup(ctx, p+1);
        } else {
-               pstrcpy(ext2,"");    
+               ext2 = talloc_strdup(ctx, "");
+       }
+
+       if (!ext1 || !ext2) {
+               return False;
        }
 
        p = root1;
        p2 = root2;
        while (*p2) {
                if (*p2 == '?') {
+                       /* Hmmm. Should this be mb-aware ? */
                        *p2 = *p;
                        p2++;
                } else if (*p2 == '*') {
-                       pstrcpy(p2, p);
+                       *p2 = '\0';
+                       root2 = talloc_asprintf(ctx, "%s%s",
+                                               root2,
+                                               p);
+                       if (!root2) {
+                               return False;
+                       }
                        break;
                } else {
                        p2++;
                }
-               if (*p)
+               if (*p) {
                        p++;
+               }
        }
 
        p = ext1;
        p2 = ext2;
        while (*p2) {
                if (*p2 == '?') {
+                       /* Hmmm. Should this be mb-aware ? */
                        *p2 = *p;
                        p2++;
                } else if (*p2 == '*') {
-                       pstrcpy(p2, p);
+                       *p2 = '\0';
+                       ext2 = talloc_asprintf(ctx, "%s%s",
+                                               ext2,
+                                               p);
+                       if (!ext2) {
+                               return False;
+                       }
                        break;
                } else {
                        p2++;
                }
-               if (*p)
+               if (*p) {
                        p++;
+               }
        }
 
-       available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
-       
-       if (ext2[0]) {
-               actual_space = snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
-               if (actual_space >= available_space - 1) {
-                       DEBUG(1,("resolve_wildcards: can't fit resolved name into specified buffer (overrun by %d bytes)\n",
-                               actual_space - available_space));
-               }
+       if (*ext2) {
+               *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
+                               name2_copy,
+                               root2,
+                               ext2);
        } else {
-               pstrcpy_base(pname2, root2, name2);
+               *pp_newname = talloc_asprintf(ctx, "%s/%s",
+                               name2_copy,
+                               root2);
+       }
+
+       if (!*pp_newname) {
+               return False;
        }
 
-       return(True);
+       return True;
 }
 
 /****************************************************************************
@@ -4646,7 +5108,7 @@ static void rename_open_files(connection_struct *conn,
                        continue;
                }
                DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
-                         fsp->fnum, file_id_static_string(&fsp->file_id),
+                         fsp->fnum, file_id_string_tos(&fsp->file_id),
                        fsp->fsp_name, newname ));
                string_set(&fsp->fsp_name, newname);
                did_rename = True;
@@ -4654,7 +5116,7 @@ static void rename_open_files(connection_struct *conn,
 
        if (!did_rename) {
                DEBUG(10,("rename_open_files: no open files on file_id %s for %s\n",
-                         file_id_static_string(&lck->id), newname ));
+                         file_id_string_tos(&lck->id), newname ));
        }
 
        /* Send messages to all smbd's (not ourself) that the name has changed. */
@@ -4737,36 +5199,34 @@ static void notify_rename(connection_struct *conn, BOOL is_dir,
  Rename an open file - given an fsp.
 ****************************************************************************/
 
-NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstring newname, uint32 attrs, BOOL replace_if_exists)
+NTSTATUS rename_internals_fsp(connection_struct *conn,
+                       files_struct *fsp,
+                       char *newname,
+                       const char *newname_last_component,
+                       uint32 attrs,
+                       BOOL replace_if_exists)
 {
+       TALLOC_CTX *ctx = talloc_tos();
        SMB_STRUCT_STAT sbuf, sbuf1;
-       pstring newname_last_component;
        NTSTATUS status = NT_STATUS_OK;
        struct share_mode_lock *lck = NULL;
        BOOL dst_exists;
 
        ZERO_STRUCT(sbuf);
 
-       status = unix_convert(conn, newname, False, newname_last_component, &sbuf);
-
-       /* If an error we expect this to be NT_STATUS_OBJECT_PATH_NOT_FOUND */
-
-       if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND, status)) {
-               return status;
-       }
-
        status = check_name(conn, newname);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
-  
+
        /* Ensure newname contains a '/' */
        if(strrchr_m(newname,'/') == 0) {
-               pstring tmpstr;
-               
-               pstrcpy(tmpstr, "./");
-               pstrcat(tmpstr, newname);
-               pstrcpy(newname, tmpstr);
+               newname = talloc_asprintf(ctx,
+                                       "./%s",
+                                       newname);
+               if (!newname) {
+                       return NT_STATUS_NO_MEMORY;
+               }
        }
 
        /*
@@ -4780,7 +5240,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin
        if((conn->case_sensitive == False) && (conn->case_preserve == True) &&
                        strequal(newname, fsp->fsp_name)) {
                char *p;
-               pstring newname_modified_last_component;
+               char *newname_modified_last_component = NULL;
 
                /*
                 * Get the last component of the modified name.
@@ -4788,15 +5248,23 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin
                 * character above.
                 */
                p = strrchr_m(newname,'/');
-               pstrcpy(newname_modified_last_component,p+1);
-                       
-               if(strcsequal(newname_modified_last_component, 
+               newname_modified_last_component = talloc_strdup(ctx,
+                                               p+1);
+               if (!newname_modified_last_component) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               if(strcsequal(newname_modified_last_component,
                              newname_last_component) == False) {
                        /*
                         * Replace the modified last component with
                         * the original.
                         */
-                       pstrcpy(p+1, newname_last_component);
+                       *p = '\0'; /* Truncate at the '/' */
+                       newname = talloc_asprintf(ctx,
+                                       "%s/%s",
+                                       newname,
+                                       newname_last_component);
                }
        }
 
@@ -4896,7 +5364,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin
                        }
                }
                TALLOC_FREE(lck);
-               return NT_STATUS_OK;    
+               return NT_STATUS_OK;
        }
 
        TALLOC_FREE(lck);
@@ -4906,7 +5374,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin
        } else {
                status = map_nt_error_from_unix(errno);
        }
-               
+
        DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
                nt_errstr(status), fsp->fsp_name,newname));
 
@@ -4919,8 +5387,8 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin
 ****************************************************************************/
 
 NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
-                               pstring name,
-                               pstring newname,
+                               const char *name_in,
+                               const char *newname_in,
                                uint32 attrs,
                                BOOL replace_if_exists,
                                BOOL src_has_wild,
@@ -4928,8 +5396,10 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
 {
        pstring directory;
        pstring mask;
-       pstring last_component_src;
-       pstring last_component_dest;
+       char *last_component_src = NULL;
+       char *last_component_dest = NULL;
+       char *name = NULL;
+       char *newname = NULL;
        char *p;
        int count=0;
        NTSTATUS status = NT_STATUS_OK;
@@ -4944,12 +5414,14 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
        ZERO_STRUCT(sbuf1);
        ZERO_STRUCT(sbuf2);
 
-       status = unix_convert(conn, name, src_has_wild, last_component_src, &sbuf1);
+       status = unix_convert(conn, name_in, src_has_wild, &name,
+                       &last_component_src, &sbuf1);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       status = unix_convert(conn, newname, dest_has_wild, last_component_dest, &sbuf2);
+       status = unix_convert(conn, newname_in, dest_has_wild, &newname,
+                       &last_component_dest, &sbuf2);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -4984,7 +5456,14 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
         */
 
        if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
-               mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
+               char *new_mask = NULL;
+               mangle_lookup_name_from_8_3(talloc_tos(),
+                                       mask,
+                                       &new_mask,
+                                       conn->params );
+               if (new_mask) {
+                       pstrcpy(mask, new_mask);
+               }
        }
 
        if (!src_has_wild) {
@@ -4998,16 +5477,17 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
                /* Add a terminating '/' to the directory name. */
                pstrcat(directory,"/");
                pstrcat(directory,mask);
-               
+
                /* Ensure newname contains a '/' also */
                if(strrchr_m(newname,'/') == 0) {
-                       pstring tmpstr;
-                       
-                       pstrcpy(tmpstr, "./");
-                       pstrcat(tmpstr, newname);
-                       pstrcpy(newname, tmpstr);
+                       newname = talloc_asprintf(talloc_tos(),
+                                               "./%s",
+                                               newname);
+                       if (!newname) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
                }
-               
+
                DEBUG(3, ("rename_internals: case_sensitive = %d, "
                          "case_preserve = %d, short case preserve = %d, "
                          "directory = %s, newname = %s, "
@@ -5018,11 +5498,14 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
 
                /* The dest name still may have wildcards. */
                if (dest_has_wild) {
-                       if (!resolve_wildcards(directory,newname)) {
+                       char *mod_newname = NULL;
+                       if (!resolve_wildcards(talloc_tos(),
+                                       directory,newname,&mod_newname)) {
                                DEBUG(6, ("rename_internals: resolve_wildcards %s %s failed\n", 
                                          directory,newname));
                                return NT_STATUS_NO_MEMORY;
                        }
+                       newname = mod_newname;
                }
                                
                ZERO_STRUCT(sbuf1);
@@ -5046,8 +5529,9 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
                        return status;
                }
 
-               status = rename_internals_fsp(conn, fsp, newname, attrs,
-                                             replace_if_exists);
+               status = rename_internals_fsp(conn, fsp, newname,
+                                             last_component_dest,
+                                             attrs, replace_if_exists);
 
                close_file(fsp, NORMAL_CLOSE);
 
@@ -5084,6 +5568,7 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
                files_struct *fsp;
                pstring fname;
                BOOL sysdir_entry = False;
+               char *mod_destname = NULL;
 
                pstrcpy(fname,dname);
                                
@@ -5115,11 +5600,13 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
 
                pstrcpy(destname,newname);
                        
-               if (!resolve_wildcards(fname,destname)) {
+               if (!resolve_wildcards(talloc_tos(),
+                               fname,destname,&mod_destname)) {
                        DEBUG(6, ("resolve_wildcards %s %s failed\n", 
                                  fname, destname));
                        continue;
                }
+               pstrcpy(destname,mod_destname);
                                
                ZERO_STRUCT(sbuf1);
                SMB_VFS_STAT(conn, fname, &sbuf1);
@@ -5143,8 +5630,8 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
                        break;
                }
 
-               status = rename_internals_fsp(conn, fsp, destname, attrs,
-                                             replace_if_exists);
+               status = rename_internals_fsp(conn, fsp, destname, dname,
+                                             attrs, replace_if_exists);
 
                close_file(fsp, NORMAL_CLOSE);
 
@@ -5173,75 +5660,94 @@ NTSTATUS rename_internals(connection_struct *conn, struct smb_request *req,
  Reply to a mv.
 ****************************************************************************/
 
-int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, 
-            int dum_buffsize)
+void reply_mv(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = 0;
        pstring name;
        pstring newname;
        char *p;
-       uint32 attrs = SVAL(inbuf,smb_vwv0);
+       uint32 attrs;
        NTSTATUS status;
        BOOL src_has_wcard = False;
        BOOL dest_has_wcard = False;
-       struct smb_request req;
 
        START_PROFILE(SMBmv);
 
-       init_smb_request(&req, (uint8 *)inbuf);
+       if (req->wct < 1) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBmv);
+               return;
+       }
 
-       p = smb_buf(inbuf) + 1;
-       p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), name, p,
+       attrs = SVAL(req->inbuf,smb_vwv0);
+
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name, p,
                                   sizeof(name), 0, STR_TERMINATE, &status,
                                   &src_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBmv);
-               return ERROR_NT(status);
+               return;
        }
        p++;
-       p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), newname, p,
+       p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname, p,
                                   sizeof(newname), 0, STR_TERMINATE, &status,
                                   &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBmv);
-               return ERROR_NT(status);
+               return;
        }
        
-       status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &src_has_wcard);
+       status = resolve_dfspath_wcard(conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      name, &src_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBmv);
                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(SMBmv);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBmv);
+               return;
        }
 
-       status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wcard);
+       status = resolve_dfspath_wcard(conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      newname, &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBmv);
                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(SMBmv);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBmv);
+               return;
        }
        
        DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
        
-       status = rename_internals(conn, &req, name, newname, attrs, False,
+       status = rename_internals(conn, req, name, newname, attrs, False,
                                  src_has_wcard, dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBmv);
-               if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+               if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       return -1;
+                       END_PROFILE(SMBmv);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBmv);
+               return;
        }
 
-       outsize = set_message(inbuf,outbuf,0,0,False);
+       reply_outbuf(req, 0, 0);
   
        END_PROFILE(SMBmv);
-       return(outsize);
+       return;
 }
 
 /*******************************************************************
@@ -5367,100 +5873,133 @@ NTSTATUS copy_file(connection_struct *conn,
  Reply to a file copy.
 ****************************************************************************/
 
-int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_copy(connection_struct *conn, struct smb_request *req)
 {
-       int outsize = 0;
-       pstring name;
+       pstring name_in;
+       char *name = NULL;
+       pstring newname_in;
+       char *newname = NULL;
        pstring directory;
-       pstring mask,newname;
+       pstring mask;
        char *p;
        int count=0;
        int error = ERRnoaccess;
        int err = 0;
-       int tid2 = SVAL(inbuf,smb_vwv0);
-       int ofun = SVAL(inbuf,smb_vwv1);
-       int flags = SVAL(inbuf,smb_vwv2);
+       int tid2;
+       int ofun;
+       int flags;
        BOOL target_is_directory=False;
        BOOL source_has_wild = False;
        BOOL dest_has_wild = False;
        SMB_STRUCT_STAT sbuf1, sbuf2;
        NTSTATUS status;
+
        START_PROFILE(SMBcopy);
 
+       if (req->wct < 3) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBcopy);
+               return;
+       }
+
+       tid2 = SVAL(req->inbuf,smb_vwv0);
+       ofun = SVAL(req->inbuf,smb_vwv1);
+       flags = SVAL(req->inbuf,smb_vwv2);
+
        *directory = *mask = 0;
 
-       p = smb_buf(inbuf);
-       p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), name, p,
-                                  sizeof(name), 0, STR_TERMINATE, &status,
+       p = smb_buf(req->inbuf);
+       p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name_in, p,
+                                  sizeof(name_in), 0, STR_TERMINATE, &status,
                                   &source_has_wild);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBcopy);
-               return ERROR_NT(status);
+               return;
        }
-       p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), newname, p,
-                                  sizeof(newname), 0, STR_TERMINATE, &status,
+       p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname_in, p,
+                                  sizeof(newname_in), 0, STR_TERMINATE, &status,
                                   &dest_has_wild);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBcopy);
-               return ERROR_NT(status);
+               return;
        }
    
-       DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
+       DEBUG(3,("reply_copy : %s -> %s\n",name_in,newname_in));
    
        if (tid2 != conn->cnum) {
                /* can't currently handle inter share copies XXXX */
                DEBUG(3,("Rejecting inter-share copy\n"));
+               reply_doserror(req, ERRSRV, ERRinvdevice);
                END_PROFILE(SMBcopy);
-               return ERROR_DOS(ERRSRV,ERRinvdevice);
+               return;
        }
 
-       status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &source_has_wild);
+       status = resolve_dfspath_wcard(conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      name_in, &source_has_wild);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBcopy);
                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(SMBcopy);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBcopy);
+               return;
        }
 
-       status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wild);
+       status = resolve_dfspath_wcard(conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      newname_in, &dest_has_wild);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBcopy);
                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(SMBcopy);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBcopy);
+               return;
        }
 
-       status = unix_convert(conn, name, source_has_wild, NULL, &sbuf1);
+       status = unix_convert(conn, name_in, source_has_wild, &name, NULL, &sbuf1);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBcopy);
-               return ERROR_NT(status);
+               return;
        }
 
-       status = unix_convert(conn, newname, dest_has_wild, NULL, &sbuf2);
+       status = unix_convert(conn, newname_in, dest_has_wild, &newname, NULL, &sbuf2);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBcopy);
-               return ERROR_NT(status);
+               return;
        }
 
        target_is_directory = VALID_STAT_OF_DIR(sbuf2);
 
        if ((flags&1) && target_is_directory) {
+               reply_doserror(req, ERRDOS, ERRbadfile);
                END_PROFILE(SMBcopy);
-               return ERROR_DOS(ERRDOS,ERRbadfile);
+               return;
        }
 
        if ((flags&2) && !target_is_directory) {
+               reply_doserror(req, ERRDOS, ERRbadpath);
                END_PROFILE(SMBcopy);
-               return ERROR_DOS(ERRDOS,ERRbadpath);
+               return;
        }
 
        if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
                /* wants a tree copy! XXXX */
                DEBUG(3,("Rejecting tree copy\n"));
+               reply_doserror(req, ERRSRV, ERRerror);
                END_PROFILE(SMBcopy);
-               return ERROR_DOS(ERRSRV,ERRerror);
+               return;
        }
 
        p = strrchr_m(name,'/');
@@ -5483,35 +6022,51 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
         */
 
        if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
-               mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
+               char *new_mask = NULL;
+               mangle_lookup_name_from_8_3( talloc_tos(),
+                                       mask,
+                                       &new_mask,
+                                       conn->params );
+               if (new_mask) {
+                       pstrcpy(mask, new_mask);
+               }
        }
 
        if (!source_has_wild) {
                pstrcat(directory,"/");
                pstrcat(directory,mask);
                if (dest_has_wild) {
-                       if (!resolve_wildcards(directory,newname)) {
+                       char *mod_newname = NULL;
+                       if (!resolve_wildcards(talloc_tos(),
+                                       directory,newname,&mod_newname)) {
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
                                END_PROFILE(SMBcopy);
-                               return ERROR_NT(NT_STATUS_NO_MEMORY);
+                               return;
                        }
+                       newname = mod_newname;
                }
 
                status = check_name(conn, directory);
                if (!NT_STATUS_IS_OK(status)) {
-                       return ERROR_NT(status);
+                       reply_nterror(req, status);
+                       END_PROFILE(SMBcopy);
+                       return;
                }
                
                status = check_name(conn, newname);
                if (!NT_STATUS_IS_OK(status)) {
-                       return ERROR_NT(status);
+                       reply_nterror(req, status);
+                       END_PROFILE(SMBcopy);
+                       return;
                }
                
                status = copy_file(conn,directory,newname,ofun,
                                        count,target_is_directory);
 
                if(!NT_STATUS_IS_OK(status)) {
+                       reply_nterror(req, status);
                        END_PROFILE(SMBcopy);
-                       return ERROR_NT(status);
+                       return;
                } else {
                        count++;
                }
@@ -5526,18 +6081,23 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
                status = check_name(conn, directory);
                if (!NT_STATUS_IS_OK(status)) {
-                       return ERROR_NT(status);
+                       reply_nterror(req, status);
+                       END_PROFILE(SMBcopy);
+                       return;
                }
                
                dir_hnd = OpenDir(conn, directory, mask, 0);
                if (dir_hnd == NULL) {
                        status = map_nt_error_from_unix(errno);
-                       return ERROR_NT(status);
+                       reply_nterror(req, status);
+                       END_PROFILE(SMBcopy);
+                       return;
                }
 
                error = ERRbadfile;
 
                while ((dname = ReadDirName(dir_hnd, &offset))) {
+                       char *mod_destname = NULL;
                        pstring fname;
                        pstrcpy(fname,dname);
     
@@ -5552,18 +6112,24 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                        error = ERRnoaccess;
                        slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
                        pstrcpy(destname,newname);
-                       if (!resolve_wildcards(fname,destname)) {
+                       if (!resolve_wildcards(talloc_tos(),
+                                       fname,destname,&mod_destname)) {
                                continue;
                        }
+                       pstrcpy(destname,mod_destname);
 
                        status = check_name(conn, fname);
                        if (!NT_STATUS_IS_OK(status)) {
-                               return ERROR_NT(status);
+                               reply_nterror(req, status);
+                               END_PROFILE(SMBcopy);
+                               return;
                        }
                
                        status = check_name(conn, destname);
                        if (!NT_STATUS_IS_OK(status)) {
-                               return ERROR_NT(status);
+                               reply_nterror(req, status);
+                               END_PROFILE(SMBcopy);
+                               return;
                        }
                
                        DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
@@ -5581,72 +6147,21 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                if(err) {
                        /* Error on close... */
                        errno = err;
+                       reply_unixerror(req, ERRHRD, ERRgeneral);
                        END_PROFILE(SMBcopy);
-                       return(UNIXERROR(ERRHRD,ERRgeneral));
+                       return;
                }
 
+               reply_doserror(req, ERRDOS, error);
                END_PROFILE(SMBcopy);
-               return ERROR_DOS(ERRDOS,error);
-       }
-  
-       outsize = set_message(inbuf,outbuf,1,0,True);
-       SSVAL(outbuf,smb_vwv0,count);
-
-       END_PROFILE(SMBcopy);
-       return(outsize);
-}
-
-/****************************************************************************
- Reply to a setdir.
-****************************************************************************/
-
-int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
-{
-       int snum;
-       int outsize = 0;
-       pstring newdir;
-       NTSTATUS status;
-
-       START_PROFILE(pathworks_setdir);
-  
-       snum = SNUM(conn);
-       if (!CAN_SETDIR(snum)) {
-               END_PROFILE(pathworks_setdir);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
-       }
-
-       srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), newdir,
-                       smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE,
-                       &status);
-       if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(pathworks_setdir);
-               return ERROR_NT(status);
-       }
-  
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newdir);
-       if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(pathworks_setdir);
-               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
-               }
-               return ERROR_NT(status);
+               return;
        }
 
-       if (strlen(newdir) != 0) {
-               if (!vfs_directory_exist(conn,newdir,NULL)) {
-                       END_PROFILE(pathworks_setdir);
-                       return ERROR_DOS(ERRDOS,ERRbadpath);
-               }
-               set_conn_connectpath(conn,newdir);
-       }
-  
-       outsize = set_message(inbuf,outbuf,0,0,False);
-       SCVAL(outbuf,smb_reh,CVAL(inbuf,smb_reh));
-  
-       DEBUG(3,("setdir %s\n", newdir));
+       reply_outbuf(req, 1, 0);
+       SSVAL(req->outbuf,smb_vwv0,count);
 
-       END_PROFILE(pathworks_setdir);
-       return(outsize);
+       END_PROFILE(SMBcopy);
+       return;
 }
 
 #undef DBGC_CLASS
@@ -5871,7 +6386,6 @@ void reply_lockingX(connection_struct *conn, struct smb_request *req)
                         * send a reply */
                        if (num_locks == 0 && num_ulocks == 0) {
                                END_PROFILE(SMBlockingX);
-                               reply_post_legacy(req, -1);
                                return;
                        } else {
                                END_PROFILE(SMBlockingX);
@@ -6078,7 +6592,6 @@ void reply_lockingX(connection_struct *conn, struct smb_request *req)
                                                        block_smbpid)) {
                                        TALLOC_FREE(br_lck);
                                        END_PROFILE(SMBlockingX);
-                                       reply_post_legacy(req, -1);
                                        return;
                                }
                        }
@@ -6138,7 +6651,7 @@ void reply_lockingX(connection_struct *conn, struct smb_request *req)
                  fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
        
        END_PROFILE(SMBlockingX);
-       chain_reply_new(req);
+       chain_reply(req);
 }
 
 #undef DBGC_CLASS
@@ -6146,108 +6659,70 @@ void reply_lockingX(connection_struct *conn, struct smb_request *req)
 
 /****************************************************************************
  Reply to a SMBreadbmpx (read block multiplex) request.
+ Always reply with an error, if someone has a platform really needs this,
+ please contact vl@samba.org
 ****************************************************************************/
 
-int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+void reply_readbmpx(connection_struct *conn, struct smb_request *req)
 {
-       ssize_t nread = -1;
-       ssize_t total_read;
-       char *data;
-       SMB_OFF_T startpos;
-       int outsize;
-       size_t maxcount;
-       int max_per_packet;
-       size_t tcount;
-       int pad;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
        START_PROFILE(SMBreadBmpx);
+       reply_doserror(req, ERRSRV, ERRuseSTD);
+       END_PROFILE(SMBreadBmpx);
+       return;
+}
 
-       /* this function doesn't seem to work - disable by default */
-       if (!lp_readbmpx()) {
-               END_PROFILE(SMBreadBmpx);
-               return ERROR_DOS(ERRSRV,ERRuseSTD);
-       }
-
-       outsize = set_message(inbuf,outbuf,8,0,True);
-
-       CHECK_FSP(fsp,conn);
-       if (!CHECK_READ(fsp,inbuf)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
-       }
-
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
-       maxcount = SVAL(inbuf,smb_vwv3);
-
-       data = smb_buf(outbuf);
-       pad = ((long)data)%4;
-       if (pad)
-               pad = 4 - pad;
-       data += pad;
-
-       max_per_packet = bufsize-(outsize+pad);
-       tcount = maxcount;
-       total_read = 0;
-
-       if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
-               END_PROFILE(SMBreadBmpx);
-               return ERROR_DOS(ERRDOS,ERRlock);
-       }
-
-       do {
-               size_t N = MIN(max_per_packet,tcount-total_read);
-  
-               nread = read_file(fsp,data,startpos,N);
-
-               if (nread <= 0)
-                       nread = 0;
-
-               if (nread < (ssize_t)N)
-                       tcount = total_read + nread;
-
-               set_message(inbuf,outbuf,8,nread+pad,False);
-               SIVAL(outbuf,smb_vwv0,startpos);
-               SSVAL(outbuf,smb_vwv2,tcount);
-               SSVAL(outbuf,smb_vwv6,nread);
-               SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
-
-               show_msg(outbuf);
-               if (!send_smb(smbd_server_fd(),outbuf))
-                       exit_server_cleanly("reply_readbmpx: send_smb failed.");
-
-               total_read += nread;
-               startpos += nread;
-       } while (total_read < (ssize_t)tcount);
+/****************************************************************************
+ Reply to a SMBreadbs (read block multiplex secondary) request.
+ Always reply with an error, if someone has a platform really needs this,
+ please contact vl@samba.org
+****************************************************************************/
 
-       END_PROFILE(SMBreadBmpx);
-       return(-1);
+void reply_readbs(connection_struct *conn, struct smb_request *req)
+{
+       START_PROFILE(SMBreadBs);
+       reply_doserror(req, ERRSRV, ERRuseSTD);
+       END_PROFILE(SMBreadBs);
+       return;
 }
 
 /****************************************************************************
  Reply to a SMBsetattrE.
 ****************************************************************************/
 
-int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_setattrE(connection_struct *conn, struct smb_request *req)
 {
        struct timespec ts[2];
-       int outsize = 0;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
+
        START_PROFILE(SMBsetattrE);
 
-       outsize = set_message(inbuf,outbuf,0,0,False);
+       if (req->wct < 7) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBsetattrE);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
 
        if(!fsp || (fsp->conn != conn)) {
+               reply_doserror(req, ERRDOS, ERRbadfid);
                END_PROFILE(SMBsetattrE);
-               return ERROR_DOS(ERRDOS,ERRbadfid);
+               return;
        }
 
+
        /*
         * Convert the DOS times into unix times. Ignore create
         * time as UNIX can't set this.
         */
 
-       ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv3)); /* atime. */
-       ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv5)); /* mtime. */
+       ts[0] = convert_time_t_to_timespec(
+               srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
+       ts[1] = convert_time_t_to_timespec(
+               srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
   
+       reply_outbuf(req, 0, 0);
+
        /* 
         * Patch from Ray Frush <frush@engr.colostate.edu>
         * Sometimes times are sent as zero - ignore them.
@@ -6260,7 +6735,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
                        dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
                }
                END_PROFILE(SMBsetattrE);
-               return(outsize);
+               return;
        } else if (!null_timespec(ts[0]) && null_timespec(ts[1])) {
                /* set modify time = to access time if modify time was unset */
                ts[1] = ts[0];
@@ -6269,8 +6744,9 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
        /* Set the date on this file */
        /* Should we set pending modtime here ? JRA */
        if(file_ntimes(conn, fsp->fsp_name, ts)) {
+               reply_doserror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBsetattrE);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return;
        }
   
        DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
@@ -6279,7 +6755,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
                (unsigned int)ts[1].tv_sec));
 
        END_PROFILE(SMBsetattrE);
-       return(outsize);
+       return;
 }
 
 
@@ -6287,233 +6763,63 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
 
 /****************************************************************************
  Reply to a SMBwritebmpx (write block multiplex primary) request.
+ Always reply with an error, if someone has a platform really needs this,
+ please contact vl@samba.org
 ****************************************************************************/
 
-int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_writebmpx(connection_struct *conn, struct smb_request *req)
 {
-       size_t numtowrite;
-       ssize_t nwritten = -1;
-       int outsize = 0;
-       SMB_OFF_T startpos;
-       size_t tcount;
-       BOOL write_through;
-       int smb_doff;
-       char *data;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
-       NTSTATUS status;
        START_PROFILE(SMBwriteBmpx);
-
-       CHECK_FSP(fsp,conn);
-       if (!CHECK_WRITE(fsp)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
-       }
-       if (HAS_CACHED_ERROR(fsp)) {
-               return(CACHED_ERROR(fsp));
-       }
-
-       tcount = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
-       write_through = BITSETW(inbuf+smb_vwv7,0);
-       numtowrite = SVAL(inbuf,smb_vwv10);
-       smb_doff = SVAL(inbuf,smb_vwv11);
-
-       data = smb_base(inbuf) + smb_doff;
-
-       /* If this fails we need to send an SMBwriteC response,
-               not an SMBwritebmpx - set this up now so we don't forget */
-       SCVAL(outbuf,smb_com,SMBwritec);
-
-       if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
-               END_PROFILE(SMBwriteBmpx);
-               return(ERROR_DOS(ERRDOS,ERRlock));
-       }
-
-       nwritten = write_file(fsp,data,startpos,numtowrite);
-
-       status = sync_file(conn, fsp, write_through);
-       if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBwriteBmpx);
-               DEBUG(5,("reply_writebmpx: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
-               return ERROR_NT(status);
-       }
-  
-       if(nwritten < (ssize_t)numtowrite) {
-               END_PROFILE(SMBwriteBmpx);
-               return(UNIXERROR(ERRHRD,ERRdiskfull));
-       }
-
-       /* If the maximum to be written to this file
-               is greater than what we just wrote then set
-               up a secondary struct to be attached to this
-               fd, we will use this to cache error messages etc. */
-
-       if((ssize_t)tcount > nwritten) {
-               write_bmpx_struct *wbms;
-               if(fsp->wbmpx_ptr != NULL)
-                       wbms = fsp->wbmpx_ptr; /* Use an existing struct */
-               else
-                       wbms = SMB_MALLOC_P(write_bmpx_struct);
-               if(!wbms) {
-                       DEBUG(0,("Out of memory in reply_readmpx\n"));
-                       END_PROFILE(SMBwriteBmpx);
-                       return(ERROR_DOS(ERRSRV,ERRnoresource));
-               }
-               wbms->wr_mode = write_through;
-               wbms->wr_discard = False; /* No errors yet */
-               wbms->wr_total_written = nwritten;
-               wbms->wr_errclass = 0;
-               wbms->wr_error = 0;
-               fsp->wbmpx_ptr = wbms;
-       }
-
-       /* We are returning successfully, set the message type back to
-               SMBwritebmpx */
-       SCVAL(outbuf,smb_com,SMBwriteBmpx);
-  
-       outsize = set_message(inbuf,outbuf,1,0,True);
-  
-       SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
-  
-       DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
-                       fsp->fnum, (int)numtowrite, (int)nwritten ) );
-
-       if (write_through && tcount==nwritten) {
-               /* We need to send both a primary and a secondary response */
-               smb_setlen(inbuf,outbuf,outsize - 4);
-               show_msg(outbuf);
-               if (!send_smb(smbd_server_fd(),outbuf))
-                       exit_server_cleanly("reply_writebmpx: send_smb failed.");
-
-               /* Now the secondary */
-               outsize = set_message(inbuf,outbuf,1,0,True);
-               SCVAL(outbuf,smb_com,SMBwritec);
-               SSVAL(outbuf,smb_vwv0,nwritten);
-       }
-
+       reply_doserror(req, ERRSRV, ERRuseSTD);
        END_PROFILE(SMBwriteBmpx);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
  Reply to a SMBwritebs (write block multiplex secondary) request.
+ Always reply with an error, if someone has a platform really needs this,
+ please contact vl@samba.org
 ****************************************************************************/
 
-int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_writebs(connection_struct *conn, struct smb_request *req)
 {
-       size_t numtowrite;
-       ssize_t nwritten = -1;
-       int outsize = 0;
-       SMB_OFF_T startpos;
-       size_t tcount;
-       BOOL write_through;
-       int smb_doff;
-       char *data;
-       write_bmpx_struct *wbms;
-       BOOL send_response = False; 
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
-       NTSTATUS status;
        START_PROFILE(SMBwriteBs);
-
-       CHECK_FSP(fsp,conn);
-       if (!CHECK_WRITE(fsp)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
-       }
-
-       tcount = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-       numtowrite = SVAL(inbuf,smb_vwv6);
-       smb_doff = SVAL(inbuf,smb_vwv7);
-
-       data = smb_base(inbuf) + smb_doff;
-
-       /* We need to send an SMBwriteC response, not an SMBwritebs */
-       SCVAL(outbuf,smb_com,SMBwritec);
-
-       /* This fd should have an auxiliary struct attached,
-               check that it does */
-       wbms = fsp->wbmpx_ptr;
-       if(!wbms) {
-               END_PROFILE(SMBwriteBs);
-               return(-1);
-       }
-
-       /* If write through is set we can return errors, else we must cache them */
-       write_through = wbms->wr_mode;
-
-       /* Check for an earlier error */
-       if(wbms->wr_discard) {
-               END_PROFILE(SMBwriteBs);
-               return -1; /* Just discard the packet */
-       }
-
-       nwritten = write_file(fsp,data,startpos,numtowrite);
-
-       status = sync_file(conn, fsp, write_through);
-  
-       if (nwritten < (ssize_t)numtowrite || !NT_STATUS_IS_OK(status)) {
-               if(write_through) {
-                       /* We are returning an error - we can delete the aux struct */
-                       if (wbms)
-                               free((char *)wbms);
-                       fsp->wbmpx_ptr = NULL;
-                       END_PROFILE(SMBwriteBs);
-                       return(ERROR_DOS(ERRHRD,ERRdiskfull));
-               }
-               wbms->wr_errclass = ERRHRD;
-               wbms->wr_error = ERRdiskfull;
-               wbms->wr_status = NT_STATUS_DISK_FULL;
-               wbms->wr_discard = True;
-               END_PROFILE(SMBwriteBs);
-               return -1;
-       }
-
-       /* Increment the total written, if this matches tcount
-               we can discard the auxiliary struct (hurrah !) and return a writeC */
-       wbms->wr_total_written += nwritten;
-       if(wbms->wr_total_written >= tcount) {
-               if (write_through) {
-                       outsize = set_message(inbuf,outbuf,1,0,True);
-                       SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);    
-                       send_response = True;
-               }
-
-               free((char *)wbms);
-               fsp->wbmpx_ptr = NULL;
-       }
-
-       if(send_response) {
-               END_PROFILE(SMBwriteBs);
-               return(outsize);
-       }
-
+       reply_doserror(req, ERRSRV, ERRuseSTD);
        END_PROFILE(SMBwriteBs);
-       return(-1);
+       return;
 }
 
 /****************************************************************************
  Reply to a SMBgetattrE.
 ****************************************************************************/
 
-int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_getattrE(connection_struct *conn, struct smb_request *req)
 {
        SMB_STRUCT_STAT sbuf;
-       int outsize = 0;
        int mode;
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       files_struct *fsp;
+
        START_PROFILE(SMBgetattrE);
 
-       outsize = set_message(inbuf,outbuf,11,0,True);
+       if (req->wct < 1) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBgetattrE);
+               return;
+       }
+
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
 
        if(!fsp || (fsp->conn != conn)) {
+               reply_doserror(req, ERRDOS, ERRbadfid);
                END_PROFILE(SMBgetattrE);
-               return ERROR_DOS(ERRDOS,ERRbadfid);
+               return;
        }
 
        /* Do an fstat on this file */
        if(fsp_stat(fsp, &sbuf)) {
+               reply_unixerror(req, ERRDOS, ERRnoaccess);
                END_PROFILE(SMBgetattrE);
-               return(UNIXERROR(ERRDOS,ERRnoaccess));
+               return;
        }
   
        mode = dos_mode(conn,fsp->fsp_name,&sbuf);
@@ -6524,23 +6830,27 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
         * this.
         */
 
-       srv_put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
-       srv_put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
+       reply_outbuf(req, 11, 0);
+
+       srv_put_dos_date2((char *)req->outbuf, smb_vwv0,
+                         get_create_time(&sbuf,
+                                         lp_fake_dir_create_times(SNUM(conn))));
+       srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime);
        /* Should we check pending modtime here ? JRA */
-       srv_put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
+       srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime);
 
        if (mode & aDIR) {
-               SIVAL(outbuf,smb_vwv6,0);
-               SIVAL(outbuf,smb_vwv8,0);
+               SIVAL(req->outbuf, smb_vwv6, 0);
+               SIVAL(req->outbuf, smb_vwv8, 0);
        } else {
                uint32 allocation_size = get_allocation_size(conn,fsp, &sbuf);
-               SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
-               SIVAL(outbuf,smb_vwv8,allocation_size);
+               SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size);
+               SIVAL(req->outbuf, smb_vwv8, allocation_size);
        }
-       SSVAL(outbuf,smb_vwv10, mode);
+       SSVAL(req->outbuf,smb_vwv10, mode);
   
        DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
   
        END_PROFILE(SMBgetattrE);
-       return(outsize);
+       return;
 }