s3: Change SMB_VFS_CREATE_FILE to take a create_file_flags argument
[kai/samba.git] / source3 / smbd / trans2.c
index 00fee0d34d5a917166604cc7a641ec13ea21478d..f41210b2e19de6417889e4c9159b51c2090d4489 100644 (file)
@@ -768,6 +768,12 @@ void send_trans2_replies(connection_struct *conn,
                reply_outbuf(req, 10, total_sent_thistime + alignment_offset
                             + data_alignment_offset);
 
+               /*
+                * We might have SMBtrans2s in req which was transferred to
+                * the outbuf, fix that.
+                */
+               SCVAL(req->outbuf, smb_com, SMBtrans2);
+
                /* Set total params and data to be sent */
                SSVAL(req->outbuf,smb_tprcnt,paramsize);
                SSVAL(req->outbuf,smb_tdrcnt,datasize);
@@ -1000,22 +1006,24 @@ static void call_trans2open(connection_struct *conn,
                return;
        }
 
-       status = create_file(conn,                      /* conn */
-                            req,                       /* req */
-                            0,                         /* root_dir_fid */
-                            fname,                     /* fname */
-                            access_mask,               /* access_mask */
-                            share_mode,                /* share_access */
-                            create_disposition,        /* create_disposition*/
-                            create_options,            /* create_options */
-                            open_attr,                 /* file_attributes */
-                            oplock_request,            /* oplock_request */
-                            open_size,                 /* allocation_size */
-                            NULL,                      /* sd */
-                            ea_list,                   /* ea_list */
-                            &fsp,                      /* result */
-                            &smb_action,               /* pinfo */
-                            &sbuf);                    /* psbuf */
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               0,                                      /* root_dir_fid */
+               fname,                                  /* fname */
+               CFF_DOS_PATH,                           /* create_file_flags */
+               access_mask,                            /* access_mask */
+               share_mode,                             /* share_access */
+               create_disposition,                     /* create_disposition*/
+               create_options,                         /* create_options */
+               open_attr,                              /* file_attributes */
+               oplock_request,                         /* oplock_request */
+               open_size,                              /* allocation_size */
+               NULL,                                   /* sd */
+               ea_list,                                /* ea_list */
+               &fsp,                                   /* result */
+               &smb_action,                            /* pinfo */
+               &sbuf);                                 /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
@@ -1129,7 +1137,7 @@ static uint32 unix_filetype(mode_t mode)
                return UNIX_TYPE_SOCKET;
 #endif
 
-       DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
+       DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
        return UNIX_TYPE_UNKNOWN;
 }
 
@@ -2183,7 +2191,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        }
 
        DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
-               smb_fn_name(CVAL(req->inbuf,smb_com)),
+               smb_fn_name(req->cmd),
                mask, directory, dirtype, numentries ) );
 
        /*
@@ -2481,7 +2489,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        }
 
        DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
-               smb_fn_name(CVAL(req->inbuf,smb_com)),
+               smb_fn_name(req->cmd),
                mask, directory, dirtype, numentries ) );
 
        /* Check if we can close the dirptr */
@@ -3118,7 +3126,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                            max_data_bytes);
 
        DEBUG( 4, ( "%s info_level = %d\n",
-                   smb_fn_name(CVAL(req->inbuf,smb_com)), info_level) );
+                   smb_fn_name(req->cmd), info_level) );
 
        return;
 }
@@ -3846,7 +3854,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
        files_struct *fsp = NULL;
        struct file_id fileid;
        struct ea_list *ea_list = NULL;
-       uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
        char *lock_data = NULL;
        bool ms_dfs_link = false;
        TALLOC_CTX *ctx = talloc_tos();
@@ -3939,7 +3946,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        pos = fsp->fh->position_information;
                        fileid = vfs_file_id_from_sbuf(conn, &sbuf);
                        get_file_infos(fileid, &delete_pending, &write_time_ts);
-                       access_mask = fsp->access_mask;
                }
 
        } else {
@@ -3995,6 +4001,46 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        return;
                }
 
+               if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
+                   && is_ntfs_stream_name(fname)) {
+                       char *base;
+                       SMB_STRUCT_STAT bsbuf;
+
+                       status = split_ntfs_stream_name(talloc_tos(), fname,
+                                                       &base, NULL);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(10, ("create_file_unixpath: "
+                                       "split_ntfs_stream_name failed: %s\n",
+                                       nt_errstr(status)));
+                               reply_nterror(req, status);
+                               return;
+                       }
+
+                       SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
+
+                       if (INFO_LEVEL_IS_UNIX(info_level)) {
+                               /* Always do lstat for UNIX calls. */
+                               if (SMB_VFS_LSTAT(conn,base,&bsbuf)) {
+                                       DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",base,strerror(errno)));
+                                       reply_unixerror(req,ERRDOS,ERRbadpath);
+                                       return;
+                               }
+                       } else {
+                               if (SMB_VFS_STAT(conn,base,&bsbuf) != 0) {
+                                       DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",base,strerror(errno)));
+                                       reply_unixerror(req,ERRDOS,ERRbadpath);
+                                       return;
+                               }
+                       }
+
+                       fileid = vfs_file_id_from_sbuf(conn, &bsbuf);
+                       get_file_infos(fileid, &delete_pending, NULL);
+                       if (delete_pending) {
+                               reply_nterror(req, NT_STATUS_DELETE_PENDING);
+                               return;
+                       }
+               }
+
                if (INFO_LEVEL_IS_UNIX(info_level)) {
                        /* Always do lstat for UNIX calls. */
                        if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
@@ -4403,7 +4449,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
                case SMB_FILE_ACCESS_INFORMATION:
                        DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
-                       SIVAL(pdata,0,access_mask);
+                       if (fsp) {
+                               SIVAL(pdata,0,fsp->access_mask);
+                       } else {
+                               /* GENERIC_EXECUTE mapping from Windows */
+                               SIVAL(pdata,0,0x12019F);
+                       }
                        data_size = 4;
                        break;
 
@@ -4908,7 +4959,11 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
                          time_to_asc(convert_timespec_to_time_t(ts[1])) ));
 
                if (fsp != NULL) {
-                       set_sticky_write_time_fsp(fsp, ts[1]);
+                       if (fsp->base_fsp) {
+                               set_sticky_write_time_fsp(fsp->base_fsp, ts[1]);
+                       } else {
+                               set_sticky_write_time_fsp(fsp, ts[1]);
+                       }
                } else {
                        set_sticky_write_time_path(conn, fname,
                                            vfs_file_id_from_sbuf(conn, psbuf),
@@ -4918,6 +4973,10 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
 
        DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
 
+       if (fsp && fsp->base_fsp) {
+               fname = fsp->base_fsp->fsp_name;
+       }
+
        if(file_ntimes(conn, fname, ts)!=0) {
                return map_nt_error_from_unix(errno);
        }
@@ -5000,15 +5059,26 @@ static NTSTATUS smb_set_file_size(connection_struct *conn,
                return NT_STATUS_OK;
        }
 
-       status = open_file_ntcreate(conn, req, fname, psbuf,
-                               FILE_WRITE_ATTRIBUTES,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               FORCE_OPLOCK_BREAK_TO_NONE,
-                               NULL, &new_fsp);
-       
+        status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               0,                                      /* root_dir_fid */
+               fname,                                  /* fname */
+               0,                                      /* create_file_flags */
+               FILE_WRITE_ATTRIBUTES,                  /* access_mask */
+               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
+                   FILE_SHARE_DELETE),
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               FORCE_OPLOCK_BREAK_TO_NONE,             /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &new_fsp,                               /* result */
+               NULL,                                   /* pinfo */
+               psbuf);                                 /* psbuf */
+
        if (!NT_STATUS_IS_OK(status)) {
                /* NB. We check for open_was_deferred in the caller. */
                return status;
@@ -5344,26 +5414,42 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                return NT_STATUS_NOT_SUPPORTED;
        }
 
-       /* Create the base directory. */
-       base_name = talloc_strdup(ctx, fname);
-       if (!base_name) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       p = strrchr_m(base_name, '/');
-       if (p) {
-               p[1] = '\0';
+       if (fsp && fsp->base_fsp) {
+               if (newname[0] != ':') {
+                       return NT_STATUS_NOT_SUPPORTED;
+               }
+               base_name = talloc_asprintf(ctx, "%s%s",
+                                          fsp->base_fsp->fsp_name,
+                                          newname);
+               if (!base_name) {
+                       return NT_STATUS_NO_MEMORY;
+               }
        } else {
-               base_name = talloc_strdup(ctx, "./");
+               if (is_ntfs_stream_name(newname)) {
+                       return NT_STATUS_NOT_SUPPORTED;
+               }
+
+               /* Create the base directory. */
+               base_name = talloc_strdup(ctx, fname);
+               if (!base_name) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               p = strrchr_m(base_name, '/');
+               if (p) {
+                       p[1] = '\0';
+               } else {
+                       base_name = talloc_strdup(ctx, "./");
+                       if (!base_name) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+               }
+               /* Append the new name. */
+               base_name = talloc_asprintf_append(base_name,
+                               "%s",
+                               newname);
                if (!base_name) {
                        return NT_STATUS_NO_MEMORY;
                }
-       }
-       /* Append the new name. */
-       base_name = talloc_asprintf_append(base_name,
-                       "%s",
-                       newname);
-       if (!base_name) {
-               return NT_STATUS_NO_MEMORY;
        }
 
        if (fsp) {
@@ -5470,7 +5556,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
 ****************************************************************************/
 
 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
-                               const struct smb_request *req,
+                               struct smb_request *req,
                                const char *pdata,
                                int total_data,
                                files_struct *fsp)
@@ -5753,14 +5839,25 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
 
        /* Pathname or stat or directory file. */
 
-       status = open_file_ntcreate(conn, req, fname, psbuf,
-                               FILE_WRITE_DATA,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               FORCE_OPLOCK_BREAK_TO_NONE,
-                               NULL, &new_fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               0,                                      /* root_dir_fid */
+               fname,                                  /* fname */
+               0,                                      /* create_file_flags */
+               FILE_WRITE_DATA,                        /* access_mask */
+               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
+                   FILE_SHARE_DELETE),
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               FORCE_OPLOCK_BREAK_TO_NONE,             /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &new_fsp,                               /* result */
+               NULL,                                   /* pinfo */
+               psbuf);                                 /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                /* NB. We check for open_was_deferred in the caller. */
@@ -6184,16 +6281,24 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
        DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
                fname, (unsigned int)unixmode ));
 
-       status = open_directory(conn, req,
-                               fname,
-                               psbuf,
-                               FILE_READ_ATTRIBUTES, /* Just a stat open */
-                               FILE_SHARE_NONE, /* Ignored for stat opens */
-                               FILE_CREATE,
-                               0,
-                               mod_unixmode,
-                               &info,
-                               &fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               0,                                      /* root_dir_fid */
+               fname,                                  /* fname */
+               0,                                      /* create_file_flags */
+               FILE_READ_ATTRIBUTES,                   /* access_mask */
+               FILE_SHARE_NONE,                        /* share_access */
+               FILE_CREATE,                            /* create_disposition*/
+               FILE_DIRECTORY_FILE,                    /* create_options */
+               mod_unixmode,                           /* file_attributes */
+               0,                                      /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               &info,                                  /* pinfo */
+               psbuf);                                 /* psbuf */
 
         if (NT_STATUS_IS_OK(status)) {
                 close_file(req, fsp, NORMAL_CLOSE);
@@ -6350,17 +6455,25 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
                (unsigned int)wire_open_mode,
                (unsigned int)unixmode ));
 
-       status = open_file_ntcreate(conn, req,
-                               fname,
-                               psbuf,
-                               access_mask,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-                               create_disp,
-                               0,              /* no create options yet. */
-                               mod_unixmode,
-                               oplock_request,
-                               &info,
-                               &fsp);
+        status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               0,                                      /* root_dir_fid */
+               fname,                                  /* fname */
+               0,                                      /* create_file_flags */
+               access_mask,                            /* access_mask */
+               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
+                   FILE_SHARE_DELETE),
+               create_disp,                            /* create_disposition*/
+               0,                                      /* create_options */
+               mod_unixmode,                           /* file_attributes */
+               oplock_request,                         /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               &info,                                  /* pinfo */
+               psbuf);                                 /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -6445,6 +6558,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
        uint16 flags = 0;
        char del = 1;
        int info = 0;
+       int create_options = 0;
        int i;
        struct share_mode_lock *lck = NULL;
 
@@ -6468,30 +6582,28 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
                fname));
 
        if (VALID_STAT_OF_DIR(*psbuf)) {
-               status = open_directory(conn, req,
-                                       fname,
-                                       psbuf,
-                                       DELETE_ACCESS,
-                                       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-                                       FILE_OPEN,
-                                       0,
-                                       FILE_FLAG_POSIX_SEMANTICS|0777,
-                                       &info,
-                                       &fsp);
-       } else {
-
-               status = open_file_ntcreate(conn, req,
-                               fname,
-                               psbuf,
-                               DELETE_ACCESS,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-                               FILE_OPEN,
-                               0,
-                               FILE_FLAG_POSIX_SEMANTICS|0777,
-                               0, /* No oplock, but break existing ones. */
-                               &info,
-                               &fsp);
-       }
+               create_options |= FILE_DIRECTORY_FILE;
+       }
+
+        status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               0,                                      /* root_dir_fid */
+               fname,                                  /* fname */
+               0,                                      /* create_file_flags */
+               DELETE_ACCESS,                          /* access_mask */
+               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
+                   FILE_SHARE_DELETE),
+               FILE_OPEN,                              /* create_disposition*/
+               create_options,                         /* create_options */
+               FILE_FLAG_POSIX_SEMANTICS|0777,         /* file_attributes */
+               0,                                      /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               &info,                                  /* pinfo */
+               psbuf);                                 /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -7065,10 +7177,11 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
                        reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                        return;
                }
-       } else if (IVAL(pdata,0) != 4) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
        }
+       /* If total_data == 4 Windows doesn't care what values
+        * are placed in that field, it just ignores them.
+        * The System i QNTC IBM SMB client puts bad values here,
+        * so ignore them. */
 
        status = create_directory(conn, req, directory);
 
@@ -7250,7 +7363,7 @@ static void call_trans2ioctl(connection_struct *conn,
                             unsigned int max_data_bytes)
 {
        char *pdata = *ppdata;
-       files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv15));
+       files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
 
        /* check for an invalid fid before proceeding */
 
@@ -7259,8 +7372,8 @@ static void call_trans2ioctl(connection_struct *conn,
                return;
        }
 
-       if ((SVAL(req->inbuf,(smb_setup+4)) == LMCAT_SPL)
-           && (SVAL(req->inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+       if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
+           && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
                *ppdata = (char *)SMB_REALLOC(*ppdata, 32);
                if (*ppdata == NULL) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -7303,7 +7416,7 @@ void reply_findclose(struct smb_request *req)
                return;
        }
 
-       dptr_num = SVALS(req->inbuf,smb_vwv0);
+       dptr_num = SVALS(req->vwv+0, 0);
 
        DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
 
@@ -7333,7 +7446,7 @@ void reply_findnclose(struct smb_request *req)
                return;
        }
        
-       dptr_num = SVAL(req->inbuf,smb_vwv0);
+       dptr_num = SVAL(req->vwv+0, 0);
 
        DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
 
@@ -7523,8 +7636,6 @@ void reply_trans2(struct smb_request *req)
        unsigned int psoff;
        unsigned int pscnt;
        unsigned int tran_call;
-       unsigned int size;
-       unsigned int av_size;
        struct trans_state *state;
        NTSTATUS result;
 
@@ -7536,13 +7647,11 @@ void reply_trans2(struct smb_request *req)
                return;
        }
 
-       dsoff = SVAL(req->inbuf, smb_dsoff);
-       dscnt = SVAL(req->inbuf, smb_dscnt);
-       psoff = SVAL(req->inbuf, smb_psoff);
-       pscnt = SVAL(req->inbuf, smb_pscnt);
-       tran_call = SVAL(req->inbuf, smb_setup0);
-       size = smb_len(req->inbuf) + 4;
-       av_size = smb_len(req->inbuf);
+       dsoff = SVAL(req->vwv+12, 0);
+       dscnt = SVAL(req->vwv+11, 0);
+       psoff = SVAL(req->vwv+10, 0);
+       pscnt = SVAL(req->vwv+9, 0);
+       tran_call = SVAL(req->vwv+14, 0);
 
        result = allow_new_trans(conn->pending_trans, req->mid);
        if (!NT_STATUS_IS_OK(result)) {
@@ -7580,17 +7689,17 @@ void reply_trans2(struct smb_request *req)
 
        state->mid = req->mid;
        state->vuid = req->vuid;
-       state->setup_count = SVAL(req->inbuf, smb_suwcnt);
+       state->setup_count = SVAL(req->vwv+13, 0);
        state->setup = NULL;
-       state->total_param = SVAL(req->inbuf, smb_tpscnt);
+       state->total_param = SVAL(req->vwv+0, 0);
        state->param = NULL;
-       state->total_data =  SVAL(req->inbuf, smb_tdscnt);
+       state->total_data =  SVAL(req->vwv+1, 0);
        state->data = NULL;
-       state->max_param_return = SVAL(req->inbuf, smb_mprcnt);
-       state->max_data_return  = SVAL(req->inbuf, smb_mdrcnt);
-       state->max_setup_return = SVAL(req->inbuf, smb_msrcnt);
-       state->close_on_completion = BITSETW(req->inbuf+smb_vwv5,0);
-       state->one_way = BITSETW(req->inbuf+smb_vwv5,1);
+       state->max_param_return = SVAL(req->vwv+2, 0);
+       state->max_data_return  = SVAL(req->vwv+3, 0);
+       state->max_setup_return = SVAL(req->vwv+4, 0);
+       state->close_on_completion = BITSETW(req->vwv+5, 0);
+       state->one_way = BITSETW(req->vwv+5, 1);
 
        state->call = tran_call;
 
@@ -7607,8 +7716,8 @@ void reply_trans2(struct smb_request *req)
                 */
                if ( (state->setup_count == 4)
                     && (tran_call == TRANSACT2_IOCTL)
-                    && (SVAL(req->inbuf,(smb_setup+4)) == LMCAT_SPL)
-                    && (SVAL(req->inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+                    && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
+                    && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
                        DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
                } else {
                        DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
@@ -7624,6 +7733,12 @@ void reply_trans2(struct smb_request *req)
                goto bad_param;
 
        if (state->total_data) {
+
+               if (trans_oob(state->total_data, 0, dscnt)
+                   || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+                       goto bad_param;
+               }
+
                /* Can't use talloc here, the core routines do realloc on the
                 * params and data. */
                state->data = (char *)SMB_MALLOC(state->total_data);
@@ -7636,21 +7751,16 @@ void reply_trans2(struct smb_request *req)
                        return;
                }
 
-               if (dscnt > state->total_data ||
-                               dsoff+dscnt < dsoff) {
-                       goto bad_param;
-               }
-
-               if (dsoff > av_size ||
-                               dscnt > av_size ||
-                               dsoff+dscnt > av_size) {
-                       goto bad_param;
-               }
-
                memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
        }
 
        if (state->total_param) {
+
+               if (trans_oob(state->total_param, 0, pscnt)
+                   || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+                       goto bad_param;
+               }
+
                /* Can't use talloc here, the core routines do realloc on the
                 * params and data. */
                state->param = (char *)SMB_MALLOC(state->total_param);
@@ -7664,17 +7774,6 @@ void reply_trans2(struct smb_request *req)
                        return;
                } 
 
-               if (pscnt > state->total_param ||
-                               psoff+pscnt < psoff) {
-                       goto bad_param;
-               }
-
-               if (psoff > av_size ||
-                               pscnt > av_size ||
-                               psoff+pscnt > av_size) {
-                       goto bad_param;
-               }
-
                memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
        }
 
@@ -7722,8 +7821,6 @@ void reply_transs2(struct smb_request *req)
        connection_struct *conn = req->conn;
        unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
        struct trans_state *state;
-       unsigned int size;
-       unsigned int av_size;
 
        START_PROFILE(SMBtranss2);
 
@@ -7735,9 +7832,6 @@ void reply_transs2(struct smb_request *req)
                return;
        }
 
-       size = smb_len(req->inbuf)+4;
-       av_size = smb_len(req->inbuf);
-
        for (state = conn->pending_trans; state != NULL;
             state = state->next) {
                if (state->mid == req->mid) {
@@ -7754,18 +7848,18 @@ void reply_transs2(struct smb_request *req)
        /* Revise state->total_param and state->total_data in case they have
           changed downwards */
 
-       if (SVAL(req->inbuf, smb_tpscnt) < state->total_param)
-               state->total_param = SVAL(req->inbuf, smb_tpscnt);
-       if (SVAL(req->inbuf, smb_tdscnt) < state->total_data)
-               state->total_data = SVAL(req->inbuf, smb_tdscnt);
+       if (SVAL(req->vwv+0, 0) < state->total_param)
+               state->total_param = SVAL(req->vwv+0, 0);
+       if (SVAL(req->vwv+1, 0) < state->total_data)
+               state->total_data = SVAL(req->vwv+1, 0);
 
-       pcnt = SVAL(req->inbuf, smb_spscnt);
-       poff = SVAL(req->inbuf, smb_spsoff);
-       pdisp = SVAL(req->inbuf, smb_spsdisp);
+       pcnt = SVAL(req->vwv+2, 0);
+       poff = SVAL(req->vwv+3, 0);
+       pdisp = SVAL(req->vwv+4, 0);
 
-       dcnt = SVAL(req->inbuf, smb_sdscnt);
-       doff = SVAL(req->inbuf, smb_sdsoff);
-       ddisp = SVAL(req->inbuf, smb_sdsdisp);
+       dcnt = SVAL(req->vwv+5, 0);
+       doff = SVAL(req->vwv+6, 0);
+       ddisp = SVAL(req->vwv+7, 0);
 
        state->received_param += pcnt;
        state->received_data += dcnt;
@@ -7775,41 +7869,19 @@ void reply_transs2(struct smb_request *req)
                goto bad_param;
 
        if (pcnt) {
-               if (pdisp > state->total_param ||
-                               pcnt > state->total_param ||
-                               pdisp+pcnt > state->total_param ||
-                               pdisp+pcnt < pdisp) {
-                       goto bad_param;
-               }
-
-               if (poff > av_size ||
-                               pcnt > av_size ||
-                               poff+pcnt > av_size ||
-                               poff+pcnt < poff) {
+               if (trans_oob(state->total_param, pdisp, pcnt)
+                   || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
                        goto bad_param;
                }
-
-               memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,
-                      pcnt);
+               memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
        }
 
        if (dcnt) {
-               if (ddisp > state->total_data ||
-                               dcnt > state->total_data ||
-                               ddisp+dcnt > state->total_data ||
-                               ddisp+dcnt < ddisp) {
-                       goto bad_param;
-               }
-
-               if (ddisp > av_size ||
-                               dcnt > av_size ||
-                               ddisp+dcnt > av_size ||
-                               ddisp+dcnt < ddisp) {
+               if (trans_oob(state->total_data, ddisp, dcnt)
+                   || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
                        goto bad_param;
                }
-
-               memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
-                      dcnt);      
+               memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
        }
 
        if ((state->received_param < state->total_param) ||
@@ -7818,12 +7890,6 @@ void reply_transs2(struct smb_request *req)
                return;
        }
 
-       /*
-        * construct_reply_common will copy smb_com from inbuf to
-        * outbuf. SMBtranss2 is wrong here.
-        */
-       SCVAL(req->inbuf,smb_com,SMBtrans2);
-
        handle_trans2(conn, req, state);
 
        DLIST_REMOVE(conn->pending_trans, state);