r25111: Move to talloced pathnames on most code paths.
[tprouty/samba.git] / source / smbd / reply.c
index 48b100764a9069708bef11e80c27a1083ba6588d..7ac6c4699fb3573d7f2a7a6342830b5f52c59aa9 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    Main SMB reply routines
    Copyright (C) Andrew Tridgell 1992-1998
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -208,27 +208,46 @@ NTSTATUS check_path_syntax_posix(char *path)
  Pull a string and check the path allowing a wilcard - provide for error return.
 ****************************************************************************/
 
-size_t srvstr_get_path_wcard(const char *inbuf, uint16 smb_flags2, char *dest,
-                            const char *src, size_t dest_len, size_t src_len,
-                            int flags, NTSTATUS *err, BOOL *contains_wcard)
+size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
+                       const char *inbuf,
+                       uint16 smb_flags2,
+                       char **pp_dest,
+                       const char *src,
+                       size_t src_len,
+                       int flags,
+                       NTSTATUS *err,
+                       BOOL *contains_wcard)
 {
        size_t ret;
-#ifdef DEVELOPER
-       SMB_ASSERT(dest_len == sizeof(pstring));
-#endif
+
+       *pp_dest = NULL;
 
        if (src_len == 0) {
-               ret = srvstr_pull_buf(inbuf, smb_flags2, dest, src,
-                                     dest_len, flags);
+               ret = srvstr_pull_buf_talloc(ctx,
+                               inbuf,
+                               smb_flags2,
+                               pp_dest,
+                               src,
+                               flags);
        } else {
-               ret = srvstr_pull(inbuf, smb_flags2, dest, src,
-                                 dest_len, src_len, flags);
+               ret = srvstr_pull_talloc(ctx,
+                               inbuf,
+                               smb_flags2,
+                               pp_dest,
+                               src,
+                               src_len,
+                               flags);
+       }
+
+       if (!*pp_dest) {
+               *err = NT_STATUS_INVALID_PARAMETER;
+               return ret;
        }
 
        *contains_wcard = False;
 
        if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
-               /* 
+               /*
                 * For a DFS path the function parse_dfs_path()
                 * will do the path processing, just make a copy.
                 */
@@ -237,9 +256,9 @@ size_t srvstr_get_path_wcard(const char *inbuf, uint16 smb_flags2, char *dest,
        }
 
        if (lp_posix_pathnames()) {
-               *err = check_path_syntax_posix(dest);
+               *err = check_path_syntax_posix(*pp_dest);
        } else {
-               *err = check_path_syntax_wcard(dest, contains_wcard);
+               *err = check_path_syntax_wcard(*pp_dest, contains_wcard);
        }
 
        return ret;
@@ -249,25 +268,43 @@ size_t srvstr_get_path_wcard(const char *inbuf, uint16 smb_flags2, char *dest,
  Pull a string and check the path - provide for error return.
 ****************************************************************************/
 
-size_t srvstr_get_path(const char *inbuf, uint16 smb_flags2, char *dest,
-                      const char *src, size_t dest_len, size_t src_len,
-                      int flags, NTSTATUS *err)
+size_t srvstr_get_path(TALLOC_CTX *ctx,
+                       const char *inbuf,
+                       uint16 smb_flags2,
+                       char **pp_dest,
+                       const char *src,
+                       size_t src_len,
+                       int flags,
+                       NTSTATUS *err)
 {
        size_t ret;
-#ifdef DEVELOPER
-       SMB_ASSERT(dest_len == sizeof(pstring));
-#endif
+
+       *pp_dest = NULL;
 
        if (src_len == 0) {
-               ret = srvstr_pull_buf(inbuf, smb_flags2, dest, src,
-                                     dest_len, flags);
+               ret = srvstr_pull_buf_talloc(ctx,
+                                       inbuf,
+                                       smb_flags2,
+                                       pp_dest,
+                                       src,
+                                       flags);
        } else {
-               ret = srvstr_pull(inbuf, smb_flags2, dest, src,
-                                 dest_len, src_len, flags);
+               ret = srvstr_pull_talloc(ctx,
+                               inbuf,
+                               smb_flags2,
+                               pp_dest,
+                               src,
+                               src_len,
+                               flags);
+       }
+
+       if (!*pp_dest) {
+               *err = NT_STATUS_INVALID_PARAMETER;
+               return ret;
        }
 
        if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
-               /* 
+               /*
                 * For a DFS path the function parse_dfs_path()
                 * will do the path processing, just make a copy.
                 */
@@ -276,19 +313,19 @@ size_t srvstr_get_path(const char *inbuf, uint16 smb_flags2, char *dest,
        }
 
        if (lp_posix_pathnames()) {
-               *err = check_path_syntax_posix(dest);
+               *err = check_path_syntax_posix(*pp_dest);
        } else {
-               *err = check_path_syntax(dest);
+               *err = check_path_syntax(*pp_dest);
        }
 
        return ret;
 }
 
 /****************************************************************************
- 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)) {
@@ -299,6 +336,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;
@@ -428,42 +479,39 @@ 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;
        DATA_BLOB password_blob;
+       TALLOC_CTX *ctx = talloc_tos();
 
        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(ctx, req->inbuf, req->flags2,
+                                   &service_buf, p, STR_TERMINATE) + 1;
+       pwlen = srvstr_pull_buf_talloc(ctx, 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(ctx, 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) {
@@ -474,27 +522,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;
 }
 
 /****************************************************************************
@@ -506,8 +553,7 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
 {
        char *service = NULL;
        DATA_BLOB password;
-
-       TALLOC_CTX *ctx = NULL;
+       TALLOC_CTX *ctx = talloc_tos();
        /* what the cleint thinks the device is */
        char *client_devicetype = NULL;
        /* what the server tells the client the share represents */
@@ -558,19 +604,11 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
                p = smb_buf(req->inbuf) + passlen + 1;
        }
 
-       ctx = talloc_init("reply_tcon_and_X");
-       if (!ctx) {
-               data_blob_clear_free(&password);
-               reply_nterror(req, NT_STATUS_NO_MEMORY);
-               END_PROFILE(SMBtconX);
-               return;
-       }
        p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
                             STR_TERMINATE);
 
        if (path == NULL) {
                data_blob_clear_free(&password);
-               TALLOC_FREE(ctx);
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBtconX);
                return;
@@ -584,7 +622,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
                q = strchr_m(path+2,'\\');
                if (!q) {
                        data_blob_clear_free(&password);
-                       TALLOC_FREE(ctx);
                        reply_doserror(req, ERRDOS, ERRnosuchshare);
                        END_PROFILE(SMBtconX);
                        return;
@@ -600,7 +637,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
 
        if (client_devicetype == NULL) {
                data_blob_clear_free(&password);
-               TALLOC_FREE(ctx);
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBtconX);
                return;
@@ -614,7 +650,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
        data_blob_clear_free(&password);
 
        if (!conn) {
-               TALLOC_FREE(ctx);
                reply_nterror(req, nt_status);
                END_PROFILE(SMBtconX);
                return;
@@ -631,7 +666,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
                reply_outbuf(req, 2, 0);
                if (message_push_string(&req->outbuf, server_devicetype,
                                        STR_TERMINATE|STR_ASCII) == -1) {
-                       TALLOC_FREE(ctx);
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
                        END_PROFILE(SMBtconX);
                        return;
@@ -666,7 +700,6 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
                                         STR_TERMINATE|STR_ASCII) == -1)
                    || (message_push_string(&req->outbuf, fstype,
                                            STR_TERMINATE) == -1)) {
-                       TALLOC_FREE(ctx);
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
                        END_PROFILE(SMBtconX);
                        return;
@@ -688,10 +721,9 @@ void reply_tcon_and_X(connection_struct *conn, struct smb_request *req)
        SSVAL(req->inbuf,smb_tid,conn->cnum);
        SSVAL(req->outbuf,smb_tid,conn->cnum);
 
-       TALLOC_FREE(ctx);
        END_PROFILE(SMBtconX);
 
-       chain_reply_new(req);
+       chain_reply(req);
        return;
 }
 
@@ -723,56 +755,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;
 }
 
 /****************************************************************************
@@ -790,21 +839,22 @@ static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
        }
        return status;
 }
-       
+
 /****************************************************************************
  Reply to a checkpath.
 ****************************************************************************/
 
 void reply_checkpath(connection_struct *conn, struct smb_request *req)
 {
-       pstring name;
+       char *name = NULL;
        SMB_STRUCT_STAT sbuf;
        NTSTATUS status;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBcheckpath);
 
-       srvstr_get_path((char *)req->inbuf, req->flags2, name,
-                       smb_buf(req->inbuf) + 1, sizeof(name), 0,
+       srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
+                       smb_buf(req->inbuf) + 1, 0,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                status = map_checkpath_error((char *)req->inbuf, status);
@@ -813,7 +863,10 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES, name);
+       status = resolve_dfspath(ctx, conn,
+                       req->flags2 & FLAGS2_DFS_PATHNAMES,
+                       name,
+                       &name);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -826,7 +879,7 @@ void reply_checkpath(connection_struct *conn, struct smb_request *req)
 
        DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
 
-       status = unix_convert(conn, name, False, NULL, &sbuf);
+       status = unix_convert(conn, name, False, &name, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                goto path_err;
        }
@@ -885,36 +938,44 @@ 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;
+       char *fname = NULL;
        SMB_STRUCT_STAT sbuf;
        int mode=0;
        SMB_OFF_T size=0;
        time_t mtime=0;
        char *p;
        NTSTATUS status;
+       TALLOC_CTX *ctx = talloc_tos();
 
        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(ctx, (char *)req->inbuf, req->flags2, &fname, p,
+                            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(ctx, conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               fname,
+                               &fname);
        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') {
@@ -925,20 +986,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, 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);
@@ -948,70 +1013,86 @@ 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;
+       char *fname = NULL;
        int mode;
        time_t mtime;
        SMB_STRUCT_STAT sbuf;
        char *p;
        NTSTATUS status;
+       TALLOC_CTX *ctx = talloc_tos();
 
        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(ctx, (char *)req->inbuf, req->flags2, &fname, p,
+                               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(ctx, conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               fname,
+                               &fname);
        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, 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') {
@@ -1019,12 +1100,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))
@@ -1033,22 +1115,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;
 }
 
 /****************************************************************************
@@ -1107,101 +1191,150 @@ 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;
        char *p;
        int status_len;
-       pstring path;
+       char *path = NULL;
        char status[21];
        int dptr_num= -1;
        BOOL check_descend = False;
        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;
+       TALLOC_CTX *ctx = talloc_tos();
 
        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,
-                                  sizeof(path), 0, STR_TERMINATE, &nt_status,
-                                  &mask_contains_wcard);
+
+       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(ctx,
+                               (char *)req->inbuf,
+                               req->flags2,
+                               &path,
+                               p,
+                               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(ctx, conn,
+                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                         path,
+                                         &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++;
        status_len = SVAL(p, 0);
        p += 2;
-  
+
        /* dirtype &= ~aDIR; */
 
        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;
 
@@ -1211,7 +1344,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;
                }
@@ -1222,44 +1355,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))));
@@ -1270,14 +1395,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;
                        }
                }
        }
@@ -1296,80 +1428,96 @@ 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];
        int dptr_num= -2;
        char *p;
+       char *path = NULL;
        NTSTATUS err;
        BOOL path_contains_wcard = False;
+       TALLOC_CTX *ctx = talloc_tos();
 
        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,
-                                  sizeof(path), 0, STR_TERMINATE, &err,
-                                  &path_contains_wcard);
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path_wcard(ctx,
+                               (char *)req->inbuf,
+                               req->flags2,
+                               &path,
+                               p,
+                               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);
@@ -1379,79 +1527,97 @@ 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;
 }
 
 /****************************************************************************
  Reply to an open.
 ****************************************************************************/
 
-int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_open(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
-       int outsize = 0;
+       char *fname = NULL;
        uint32 fattr=0;
        SMB_OFF_T size = 0;
        time_t mtime=0;
        int info;
        SMB_STRUCT_STAT sbuf;
        files_struct *fsp;
-       int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+       int oplock_request;
        int deny_mode;
-       uint32 dos_attr = SVAL(inbuf,smb_vwv1);
+       uint32 dos_attr;
        uint32 access_mask;
        uint32 share_mode;
        uint32 create_disposition;
        uint32 create_options = 0;
        NTSTATUS status;
-       struct smb_request req;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBopen);
 
-       init_smb_request(&req, (uint8 *)inbuf);
-       deny_mode = SVAL(inbuf,smb_vwv0);
+       if (req->wct < 2) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBopen);
+               return;
+       }
 
-       srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, smb_buf(inbuf)+1,
-                       sizeof(fname), 0, STR_TERMINATE, &status);
+       oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
+       deny_mode = SVAL(req->inbuf,smb_vwv0);
+       dos_attr = SVAL(req->inbuf,smb_vwv1);
+
+       srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
+                       smb_buf(req->inbuf)+1, 0,
+                       STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBopen);
-               return ERROR_NT(status);
+               return;
        }
 
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+       status = resolve_dfspath(ctx, conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               fname,
+                               &fname);
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBopen);
                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(SMBopen);
+                       return;
                }
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               END_PROFILE(SMBopen);
+               return;
        }
 
-       status = unix_convert(conn, fname, False, NULL, &sbuf);
+       status = unix_convert(conn, fname, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBopen);
-               return ERROR_NT(status);
+               return;
        }
     
        status = check_name(conn, fname);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(SMBopen);
-               return ERROR_NT(status);
+               return;
        }
 
        if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
                        &access_mask, &share_mode, &create_disposition, &create_options)) {
+               reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
                END_PROFILE(SMBopen);
-               return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
+               return;
        }
 
-       status = open_file_ntcreate(conn, &req, fname, &sbuf,
+       status = open_file_ntcreate(conn, req, fname, &sbuf,
                        access_mask,
                        share_mode,
                        create_disposition,
@@ -1461,12 +1627,14 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                        &info, &fsp);
 
        if (!NT_STATUS_IS_OK(status)) {
-               END_PROFILE(SMBopen);
-               if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+               if (open_was_deferred(req->mid)) {
+                       END_PROFILE(SMBopen);
                        /* We have re-scheduled this call. */
-                       return -1;
+                       return;
                }
-               return ERROR_NT(status);
+               reply_openerror(req, status);
+               END_PROFILE(SMBopen);
+               return;
        }
 
        size = sbuf.st_size;
@@ -1476,30 +1644,33 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
        if (fattr & aDIR) {
                DEBUG(3,("attempt to open a directory %s\n",fname));
                close_file(fsp,ERROR_CLOSE);
+               reply_doserror(req, ERRDOS,ERRnoaccess);
                END_PROFILE(SMBopen);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return;
        }
-  
-       outsize = set_message(inbuf,outbuf,7,0,True);
-       SSVAL(outbuf,smb_vwv0,fsp->fnum);
-       SSVAL(outbuf,smb_vwv1,fattr);
+
+       reply_outbuf(req, 7, 0);
+       SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
+       SSVAL(req->outbuf,smb_vwv1,fattr);
        if(lp_dos_filetime_resolution(SNUM(conn)) ) {
-               srv_put_dos_date3(outbuf,smb_vwv2,mtime & ~1);
+               srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime & ~1);
        } else {
-               srv_put_dos_date3(outbuf,smb_vwv2,mtime);
+               srv_put_dos_date3((char *)req->outbuf,smb_vwv2,mtime);
        }
-       SIVAL(outbuf,smb_vwv4,(uint32)size);
-       SSVAL(outbuf,smb_vwv6,deny_mode);
+       SIVAL(req->outbuf,smb_vwv4,(uint32)size);
+       SSVAL(req->outbuf,smb_vwv6,deny_mode);
 
        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);
        }
        END_PROFILE(SMBopen);
-       return(outsize);
+       return;
 }
 
 /****************************************************************************
@@ -1508,7 +1679,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
 void reply_open_and_X(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
+       char *fname = NULL;
        uint16 open_flags;
        int deny_mode;
        uint32 smb_attr;
@@ -1534,6 +1705,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
        uint32 share_mode;
        uint32 create_disposition;
        uint32 create_options = 0;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBopenX);
 
@@ -1564,8 +1736,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(ctx, (char *)req->inbuf, req->flags2, &fname,
+                       smb_buf(req->inbuf), 0, STR_TERMINATE,
                        &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -1573,8 +1745,10 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                fname);
+       status = resolve_dfspath(ctx, conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               fname,
+                               &fname);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBopenX);
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1586,7 +1760,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, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBopenX);
@@ -1618,14 +1792,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;
        }
 
@@ -1708,7 +1882,7 @@ void reply_open_and_X(connection_struct *conn, struct smb_request *req)
        }
 
        END_PROFILE(SMBopenX);
-       chain_reply_new(req);
+       chain_reply(req);
        return;
 }
 
@@ -1743,7 +1917,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);
 }
 
 /****************************************************************************
@@ -1752,7 +1926,7 @@ void reply_ulogoffX(connection_struct *conn, struct smb_request *req)
 
 void reply_mknew(connection_struct *conn, struct smb_request *req)
 {
-       pstring fname;
+       char *fname = NULL;
        int com;
        uint32 fattr = 0;
        struct timespec ts[2];
@@ -1764,6 +1938,7 @@ void reply_mknew(connection_struct *conn, struct smb_request *req)
        uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
        uint32 create_disposition;
        uint32 create_options = 0;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBcreate);
 
@@ -1781,17 +1956,19 @@ 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(ctx, (char *)req->inbuf, req->flags2, &fname,
+                        smb_buf(req->inbuf) + 1, 0,
+                       STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBcreate);
                return;
        }
 
-       status = resolve_dfspath(conn, req->flags2 & FLAGS2_DFS_PATHNAMES,
-                       fname);
+       status = resolve_dfspath(ctx, conn,
+                       req->flags2 & FLAGS2_DFS_PATHNAMES,
+                       fname,
+                       &fname);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBcreate);
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1803,7 +1980,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, False, &fname, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBcreate);
@@ -1854,7 +2031,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))) {
@@ -1879,67 +2055,92 @@ 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);
+       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;
+       TALLOC_CTX *ctx = talloc_tos();
 
        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(ctx, (char *)req->inbuf, req->flags2, &fname,
+                       smb_buf(req->inbuf)+1, 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");
+               fname = talloc_asprintf(ctx,
+                               "%s/TMXXXXXX",
+                               fname);
        } else {
-               pstrcat(fname,"TMXXXXXX");
+               fname = talloc_strdup(ctx, "TMXXXXXX");
        }
 
-       status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
-       if (!NT_STATUS_IS_OK(status)) {
+       if (!fname) {
+               reply_nterror(req, NT_STATUS_NO_MEMORY);
                END_PROFILE(SMBctemp);
+               return;
+       }
+
+       status = resolve_dfspath(ctx, conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               fname,
+                               &fname);
+       if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+                       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, 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);
+       status = check_name(conn, CONST_DISCARD(char *,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,
@@ -1952,16 +2153,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, '/');
@@ -1971,23 +2174,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 ) );
@@ -1995,7 +2201,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;
 }
 
 /*******************************************************************
@@ -2154,22 +2360,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,".");
@@ -2179,7 +2386,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
@@ -2188,10 +2395,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);
@@ -2214,7 +2429,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;
                }
@@ -2293,10 +2508,11 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
 
 void reply_unlink(connection_struct *conn, struct smb_request *req)
 {
-       pstring name;
+       char *name = NULL;
        uint32 dirtype;
        NTSTATUS status;
        BOOL path_contains_wcard = False;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBunlink);
 
@@ -2307,9 +2523,9 @@ void reply_unlink(connection_struct *conn, struct smb_request *req)
        }
 
        dirtype = SVAL(req->inbuf,smb_vwv0);
-       
-       srvstr_get_path_wcard((char *)req->inbuf, req->flags2, name,
-                             smb_buf(req->inbuf) + 1, sizeof(name), 0,
+
+       srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
+                             smb_buf(req->inbuf) + 1, 0,
                              STR_TERMINATE, &status, &path_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -2317,9 +2533,11 @@ void reply_unlink(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath_wcard(conn,
+       status = resolve_dfspath_wcard(ctx, conn,
                                       req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      name, &path_contains_wcard);
+                                      name,
+                                      &name,
+                                      &path_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -2331,9 +2549,9 @@ void reply_unlink(connection_struct *conn, struct smb_request *req)
                END_PROFILE(SMBunlink);
                return;
        }
-       
+
        DEBUG(3,("reply_unlink : %s\n",name));
-       
+
        status = unlink_internals(conn, req, dirtype, name,
                                  path_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
@@ -2418,13 +2636,30 @@ static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
        return (ssize_t)nread;
 }
 
+/****************************************************************************
+ Return a readbraw error (4 bytes of zero).
+****************************************************************************/
+
+static void reply_readbraw_error(void)
+{
+       char header[4];
+       SIVAL(header,0,0);
+       if (write_data(smbd_server_fd(),header,4) != 4) {
+               fail_readraw();
+       }
+}
+
 /****************************************************************************
  Use sendfile in readbraw.
 ****************************************************************************/
 
-void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
-               ssize_t mincount, char *outbuf, int out_buffsize)
+void send_file_readbraw(connection_struct *conn,
+                       files_struct *fsp,
+                       SMB_OFF_T startpos,
+                       size_t nread,
+                       ssize_t mincount)
 {
+       char *outbuf = NULL;
        ssize_t ret=0;
 
 #if defined(WITH_SENDFILE)
@@ -2437,15 +2672,16 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
 
        if ( (chain_size == 0) && (nread > 0) &&
            (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
-               DATA_BLOB header;
+               char header[4];
+               DATA_BLOB header_blob;
 
-               _smb_setlen(outbuf,nread);
-               header.data = (uint8 *)outbuf;
-               header.length = 4;
-               header.free = NULL;
+               _smb_setlen(header,nread);
+               header_blob = data_blob_const(header, 4);
 
-               if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) {
-                       /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+               if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd,
+                               &header_blob, startpos, nread) == -1) {
+                       /* Returning ENOSYS means no data at all was sent.
+                        * Do this as a normal read. */
                        if (errno == ENOSYS) {
                                goto normal_readbraw;
                        }
@@ -2479,6 +2715,14 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
 
 normal_readbraw:
 
+       outbuf = TALLOC_ARRAY(NULL, char, nread+4);
+       if (!outbuf) {
+               DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
+                       (unsigned)(nread+4)));
+               reply_readbraw_error();
+               return;
+       }
+
        if (nread > 0) {
                ret = read_file(fsp,outbuf+4,startpos,nread);
 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
@@ -2493,23 +2737,34 @@ normal_readbraw:
        _smb_setlen(outbuf,ret);
        if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
                fail_readraw();
+
+       TALLOC_FREE(outbuf);
 }
 
 /****************************************************************************
  Reply to a readbraw (core+ protocol).
 ****************************************************************************/
 
-int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
+void reply_readbraw(connection_struct *conn, struct smb_request *req)
 {
        ssize_t maxcount,mincount;
        size_t nread = 0;
        SMB_OFF_T startpos;
-       char *header = outbuf;
        files_struct *fsp;
+       SMB_STRUCT_STAT st;
+       SMB_OFF_T size = 0;
+
        START_PROFILE(SMBreadbraw);
 
        if (srv_is_signing_active()) {
-               exit_server_cleanly("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
+               exit_server_cleanly("reply_readbraw: SMB signing is active - "
+                       "raw reads/writes are disallowed.");
+       }
+
+       if (req->wct < 8) {
+               reply_readbraw_error();
+               END_PROFILE(SMBreadbraw);
+               return;
        }
 
        /*
@@ -2518,32 +2773,49 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
         * return a zero length response here.
         */
 
-       fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+       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.
+        */
 
-       if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
+       if (!fsp || !conn || conn != fsp->conn ||
+                       current_user.vuid != fsp->vuid ||
+                       fsp->is_directory || fsp->fh->fd == -1) {
                /*
                 * fsp could be NULL here so use the value from the packet. JRA.
                 */
-               DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
-               _smb_setlen(header,0);
-               if (write_data(smbd_server_fd(),header,4) != 4)
-                       fail_readraw();
+               DEBUG(3,("reply_readbraw: fnum %d not valid "
+                       "- cache prime?\n",
+                       (int)SVAL(req->inbuf,smb_vwv0)));
+               reply_readbraw_error();
                END_PROFILE(SMBreadbraw);
-               return(-1);
+               return;
        }
 
-       CHECK_FSP(fsp,conn);
+       /* Do a "by hand" version of CHECK_READ. */
+       if (!(fsp->can_read ||
+                       ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
+                               (fsp->access_mask & FILE_EXECUTE)))) {
+               DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
+                               (int)SVAL(req->inbuf,smb_vwv0)));
+               reply_readbraw_error();
+               END_PROFILE(SMBreadbraw);
+               return;
+       }
 
        flush_write_cache(fsp, READRAW_FLUSH);
 
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
-       if(CVAL(inbuf,smb_wct) == 10) {
+       startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
+       if(req->wct == 10) {
                /*
                 * This is a large offset (64 bit) read.
                 */
 #ifdef LARGE_SMB_OFF_T
 
-               startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
+               startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
 
 #else /* !LARGE_SMB_OFF_T */
 
@@ -2551,46 +2823,51 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
                 * Ensure we haven't been sent a >32 bit offset.
                 */
 
-               if(IVAL(inbuf,smb_vwv8) != 0) {
-                       DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
-64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
-                       _smb_setlen(header,0);
-                       if (write_data(smbd_server_fd(),header,4) != 4)
-                               fail_readraw();
+               if(IVAL(req->inbuf,smb_vwv8) != 0) {
+                       DEBUG(0,("reply_readbraw: large offset "
+                               "(%x << 32) used and we don't support "
+                               "64 bit offsets.\n",
+                       (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
+                       reply_readbraw_error();
                        END_PROFILE(SMBreadbraw);
-                       return(-1);
+                       return;
                }
 
 #endif /* LARGE_SMB_OFF_T */
 
                if(startpos < 0) {
-                       DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
-                       _smb_setlen(header,0);
-                       if (write_data(smbd_server_fd(),header,4) != 4)
-                               fail_readraw();
+                       DEBUG(0,("reply_readbraw: negative 64 bit "
+                               "readraw offset (%.0f) !\n",
+                               (double)startpos ));
+                       reply_readbraw_error();
                        END_PROFILE(SMBreadbraw);
-                       return(-1);
+                       return;
                }      
        }
-       maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
-       mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
+
+       maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
+       mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
 
        /* ensure we don't overrun the packet size */
        maxcount = MIN(65535,maxcount);
 
-       if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
-               SMB_STRUCT_STAT st;
-               SMB_OFF_T size = 0;
-  
-               if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
-                       size = st.st_size;
-               }
+       if (is_locked(fsp,(uint32)req->smbpid,
+                       (SMB_BIG_UINT)maxcount,
+                       (SMB_BIG_UINT)startpos,
+                       READ_LOCK)) {
+               reply_readbraw_error();
+               END_PROFILE(SMBreadbraw);
+               return;
+       }
 
-               if (startpos >= size) {
-                       nread = 0;
-               } else {
-                       nread = MIN(maxcount,(size - startpos));          
-               }
+       if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
+               size = st.st_size;
+       }
+
+       if (startpos >= size) {
+               nread = 0;
+       } else {
+               nread = MIN(maxcount,(size - startpos));
        }
 
 #if 0 /* mincount appears to be ignored in a W2K server. JRA. */
@@ -2598,14 +2875,17 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
                nread = 0;
 #endif
   
-       DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp->fnum, (double)startpos,
-                               (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) );
+       DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
+               "min=%lu nread=%lu\n",
+               fsp->fnum, (double)startpos,
+               (unsigned long)maxcount,
+               (unsigned long)mincount,
+               (unsigned long)nread ) );
   
-       send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
+       send_file_readbraw(conn, fsp, startpos, nread, mincount);
 
-       DEBUG(5,("readbraw finished\n"));
+       DEBUG(5,("reply_readbraw finished\n"));
        END_PROFILE(SMBreadbraw);
-       return -1;
 }
 
 #undef DBGC_CLASS
@@ -2615,31 +2895,48 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
  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+
@@ -2651,7 +2948,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,
@@ -2662,8 +2959,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;
        }
 
        /*
@@ -2679,20 +2977,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
@@ -2702,26 +3004,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.
         */
@@ -2732,32 +3049,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;
 }
 
 /****************************************************************************
@@ -2875,7 +3198,6 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                TALLOC_FREE(req->outbuf);
                return;
        }
-
 #endif
 
 normal_read:
@@ -2916,7 +3238,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;
        }
@@ -3028,7 +3350,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;
        }
 
@@ -3038,12 +3359,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;
@@ -3051,140 +3388,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
@@ -3194,30 +3603,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);
-       
-       CHECK_FSP(fsp,conn);
-       if (!CHECK_WRITE(fsp)) {
-               return(ERROR_DOS(ERRDOS,ERRbadaccess));
-       }
 
-       numtowrite = SVAL(inbuf,smb_vwv1);
-       startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
-       data = smb_buf(inbuf) + 3;
-  
-       if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+       if (req->wct < 5) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBwriteunlock);
+               return;
+       }
+       
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBwriteunlock);
+               return;
+       }
+
+       if (!CHECK_WRITE(fsp)) {
+               reply_doserror(req, ERRDOS,ERRbadaccess);
+               END_PROFILE(SMBwriteunlock);
+               return;
+       }
+
+       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)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
@@ -3231,40 +3656,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
@@ -3274,36 +3702,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;
        }
 
        /*
@@ -3318,43 +3762,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;
 }
 
 /****************************************************************************
@@ -3502,7 +3950,7 @@ void reply_write_and_X(connection_struct *conn, struct smb_request *req)
        }
 
        END_PROFILE(SMBwriteX);
-       chain_reply_new(req);
+       chain_reply(req);
        return;
 }
 
@@ -3510,22 +3958,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:
@@ -3552,8 +4010,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;
@@ -3563,21 +4023,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;
 }
 
 /****************************************************************************
@@ -3724,32 +4185,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);
@@ -3772,20 +4249,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
@@ -3795,30 +4274,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,
@@ -3830,49 +4318,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);
+       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(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);
        
        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
@@ -3965,55 +4469,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",
@@ -4022,39 +4543,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));
@@ -4062,7 +4594,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);
@@ -4075,22 +4606,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);
@@ -4099,44 +4641,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;
 }
 
 /****************************************************************************
@@ -4145,14 +4709,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;
+       char *directory = NULL;
        NTSTATUS status;
        SMB_STRUCT_STAT sbuf;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBmkdir);
-       srvstr_get_path((char *)req->inbuf, req->flags2, directory,
-                       smb_buf(req->inbuf) + 1, sizeof(directory), 0,
+
+       srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
+                       smb_buf(req->inbuf) + 1, 0,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -4160,9 +4725,10 @@ void reply_mkdir(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(conn,
+       status = resolve_dfspath(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                directory);
+                                directory,
+                                &directory);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -4175,7 +4741,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, False, &directory, NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBmkdir);
@@ -4188,7 +4754,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)));
@@ -4398,13 +4964,15 @@ NTSTATUS rmdir_internals(connection_struct *conn, const char *directory)
 
 void reply_rmdir(connection_struct *conn, struct smb_request *req)
 {
-       pstring directory;
+       char *directory = NULL;
        SMB_STRUCT_STAT sbuf;
        NTSTATUS status;
+       TALLOC_CTX *ctx = talloc_tos();
+
        START_PROFILE(SMBrmdir);
 
-       srvstr_get_path((char *)req->inbuf, req->flags2, directory,
-                       smb_buf(req->inbuf) + 1, sizeof(directory), 0,
+       srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
+                       smb_buf(req->inbuf) + 1, 0,
                        STR_TERMINATE, &status);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -4412,9 +4980,10 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(conn,
+       status = resolve_dfspath(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                directory);
+                                directory,
+                                &directory);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -4427,13 +4996,14 @@ void reply_rmdir(connection_struct *conn, struct smb_request *req)
                return;
        }
 
-       status = unix_convert(conn, directory, False, NULL, &sbuf);
+       status = unix_convert(conn, directory, False, &directory,
+                       NULL, &sbuf);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBrmdir);
                return;
        }
-  
+
        status = check_name(conn, directory);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -4459,88 +5029,130 @@ 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);
        }
 
-       return(True);
-}
+       if (!*pp_newname) {
+               return False;
+       }
+
+       return True;
+}
 
 /****************************************************************************
  Ensure open files have their names updated. Updated to notify other smbd's
@@ -4564,7 +5176,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;
@@ -4572,7 +5184,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. */
@@ -4655,36 +5267,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;
+               }
        }
 
        /*
@@ -4698,7 +5308,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.
@@ -4706,15 +5316,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);
                }
        }
 
@@ -4814,7 +5432,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);
@@ -4824,7 +5442,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));
 
@@ -4837,8 +5455,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,
@@ -4846,8 +5464,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;
@@ -4862,12 +5482,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;
        }
@@ -4902,7 +5524,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) {
@@ -4916,16 +5545,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, "
@@ -4936,11 +5566,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);
@@ -4964,8 +5597,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);
 
@@ -5002,6 +5636,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);
                                
@@ -5033,11 +5668,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);
@@ -5061,8 +5698,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);
 
@@ -5091,75 +5728,99 @@ 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 *name = NULL;
+       char *newname = NULL;
        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;
+       TALLOC_CTX *ctx = talloc_tos();
 
        START_PROFILE(SMBmv);
 
-       init_smb_request(&req, (uint8 *)inbuf);
+       if (req->wct < 1) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBmv);
+               return;
+       }
+
+       attrs = SVAL(req->inbuf,smb_vwv0);
 
-       p = smb_buf(inbuf) + 1;
-       p += srvstr_get_path_wcard(inbuf, SVAL(inbuf,smb_flg2), name, p,
-                                  sizeof(name), 0, STR_TERMINATE, &status,
+       p = smb_buf(req->inbuf) + 1;
+       p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
+                                  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,
-                                  sizeof(newname), 0, STR_TERMINATE, &status,
+       p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
+                                  0, STR_TERMINATE, &status,
                                   &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
                END_PROFILE(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(ctx, conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      name,
+                                      &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(ctx, conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      newname,
+                                      &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;
 }
 
 /*******************************************************************
@@ -5285,100 +5946,136 @@ 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;
+       char *name = NULL;
+       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;
+       TALLOC_CTX *ctx = talloc_tos();
+
        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(ctx, (char *)req->inbuf, req->flags2, &name, p,
+                                  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(ctx, (char *)req->inbuf, req->flags2, &newname, p,
+                                  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));
-   
+
        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(ctx, conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      name,
+                                      &name,
+                                      &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(ctx, conn,
+                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                      newname,
+                                      &newname,
+                                      &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, 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, 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,'/');
@@ -5401,35 +6098,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++;
                }
@@ -5444,18 +6157,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);
     
@@ -5470,18 +6188,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));
@@ -5499,72 +6223,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
@@ -5707,35 +6380,52 @@ SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_forma
  Reply to a lockingX request.
 ****************************************************************************/
 
-int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
-                  int length, int bufsize)
+void reply_lockingX(connection_struct *conn, struct smb_request *req)
 {
-       files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv2));
-       unsigned char locktype = CVAL(inbuf,smb_vwv3);
-       unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
-       uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
-       uint16 num_locks = SVAL(inbuf,smb_vwv7);
+       files_struct *fsp;
+       unsigned char locktype;
+       unsigned char oplocklevel;
+       uint16 num_ulocks;
+       uint16 num_locks;
        SMB_BIG_UINT count = 0, offset = 0;
        uint32 lock_pid;
-       int32 lock_timeout = IVAL(inbuf,smb_vwv4);
+       int32 lock_timeout;
        int i;
        char *data;
-       BOOL large_file_format =
-               (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
+       BOOL large_file_format;
        BOOL err;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 
        START_PROFILE(SMBlockingX);
+
+       if (req->wct < 8) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBlockingX);
+               return;
+       }
        
-       CHECK_FSP(fsp,conn);
+       fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
+       locktype = CVAL(req->inbuf,smb_vwv3);
+       oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
+       num_ulocks = SVAL(req->inbuf,smb_vwv6);
+       num_locks = SVAL(req->inbuf,smb_vwv7);
+       lock_timeout = IVAL(req->inbuf,smb_vwv4);
+       large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
+
+       if (!check_fsp(conn, req, fsp, &current_user)) {
+               END_PROFILE(SMBlockingX);
+               return;
+       }
        
-       data = smb_buf(inbuf);
+       data = smb_buf(req->inbuf);
 
        if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
                /* we don't support these - and CANCEL_LOCK makes w2k
                   and XP reboot so I don't really want to be
                   compatible! (tridge) */
-               return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
+               reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
+               END_PROFILE(SMBlockingX);
+               return;
        }
        
        /* Check if this is an oplock break on a file
@@ -5772,10 +6462,11 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                         * send a reply */
                        if (num_locks == 0 && num_ulocks == 0) {
                                END_PROFILE(SMBlockingX);
-                               return -1;
+                               return;
                        } else {
                                END_PROFILE(SMBlockingX);
-                               return ERROR_DOS(ERRDOS,ERRlock);
+                               reply_doserror(req, ERRDOS, ERRlock);
+                               return;
                        }
                }
 
@@ -5800,12 +6491,13 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                if (num_locks == 0 && num_ulocks == 0) {
                        /* Sanity check - ensure a pure oplock break is not a
                           chained request. */
-                       if(CVAL(inbuf,smb_vwv0) != 0xff)
+                       if(CVAL(req->inbuf,smb_vwv0) != 0xff)
                                DEBUG(0,("reply_lockingX: Error : pure oplock "
                                         "break is a chained %d request !\n",
-                                        (unsigned int)CVAL(inbuf,smb_vwv0) ));
+                                        (unsigned int)CVAL(req->inbuf,
+                                                           smb_vwv0) ));
                        END_PROFILE(SMBlockingX);
-                       return -1;
+                       return;
                }
        }
 
@@ -5815,6 +6507,13 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
         */
        
        release_level_2_oplocks_on_change(fsp);
+
+       if (smb_buflen(req->inbuf) <
+           (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               END_PROFILE(SMBlockingX);
+               return;
+       }
        
        /* Data now points at the beginning of the list
           of smb_unlkrng structs */
@@ -5828,7 +6527,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                 */
                if(err) {
                        END_PROFILE(SMBlockingX);
-                       return ERROR_DOS(ERRDOS,ERRnoaccess);
+                       reply_doserror(req, ERRDOS, ERRnoaccess);
+                       return;
                }
 
                DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
@@ -5844,7 +6544,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
 
                if (NT_STATUS_V(status)) {
                        END_PROFILE(SMBlockingX);
-                       return ERROR_NT(status);
+                       reply_nterror(req, status);
+                       return;
                }
        }
 
@@ -5872,7 +6573,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                 */
                if(err) {
                        END_PROFILE(SMBlockingX);
-                       return ERROR_DOS(ERRDOS,ERRnoaccess);
+                       reply_doserror(req, ERRDOS, ERRnoaccess);
+                       return;
                }
                
                DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
@@ -5895,7 +6597,12 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                                                locktype,
                                                NT_STATUS_FILE_LOCK_CONFLICT)) {
                                        END_PROFILE(SMBlockingX);
-                                       return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRcancelviolation));
+                                       reply_nterror(
+                                               req,
+                                               NT_STATUS_DOS(
+                                                       ERRDOS,
+                                                       ERRcancelviolation));
+                                       return;
                                }
                        }
                        /* Remove a matching pending lock. */
@@ -5948,7 +6655,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                                 * onto the blocking lock queue.
                                 */
                                if(push_blocking_lock_request(br_lck,
-                                                       inbuf, length,
+                                                       (char *)req->inbuf,
+                                                       smb_len(req->inbuf)+4,
                                                        fsp,
                                                        lock_timeout,
                                                        i,
@@ -5960,7 +6668,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                                                        block_smbpid)) {
                                        TALLOC_FREE(br_lck);
                                        END_PROFILE(SMBlockingX);
-                                       return -1;
+                                       return;
                                }
                        }
 
@@ -5969,7 +6677,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
 
                if (NT_STATUS_V(status)) {
                        END_PROFILE(SMBlockingX);
-                       return ERROR_NT(status);
+                       reply_nterror(req, status);
+                       return;
                }
        }
        
@@ -5996,7 +6705,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                         */
                        if(err) {
                                END_PROFILE(SMBlockingX);
-                               return ERROR_DOS(ERRDOS,ERRnoaccess);
+                               reply_doserror(req, ERRDOS, ERRnoaccess);
+                               return;
                        }
                        
                        do_unlock(smbd_messaging_context(),
@@ -6007,16 +6717,17 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
                                WINDOWS_LOCK);
                }
                END_PROFILE(SMBlockingX);
-               return ERROR_NT(status);
+               reply_nterror(req, status);
+               return;
        }
 
-       set_message(inbuf,outbuf,2,0,True);
+       reply_outbuf(req, 2, 0);
        
        DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
                  fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
        
        END_PROFILE(SMBlockingX);
-       return chain_reply(inbuf,&outbuf,length,bufsize);
+       chain_reply(req);
 }
 
 #undef DBGC_CLASS
@@ -6024,108 +6735,70 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
 
 /****************************************************************************
  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.
@@ -6138,7 +6811,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];
@@ -6147,8 +6820,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",
@@ -6157,7 +6831,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;
 }
 
 
@@ -6165,233 +6839,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);
@@ -6402,23 +6906,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;
 }