move old kamikaze out of trunk - will put buildroot-ng in there as soon as all the...
[openwrt/staging/dedeckeh.git] / openwrt / package / samba / patches / 200-security.patch
diff --git a/openwrt/package/samba/patches/200-security.patch b/openwrt/package/samba/patches/200-security.patch
deleted file mode 100644 (file)
index 8e51549..0000000
+++ /dev/null
@@ -1,606 +0,0 @@
-diff -ruN samba-2.0.10.orig/source/include/smb.h samba-2.0.10/source/include/smb.h
---- samba-2.0.10.orig/source/include/smb.h     2006-03-06 22:25:08.000000000 +0100
-+++ samba-2.0.10/source/include/smb.h  2006-03-06 22:25:53.000000000 +0100
-@@ -272,6 +272,7 @@
- #define ERRlock 33 /* Lock request conflicts with existing lock */
- #define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */
- #define ERRfilexists 80 /* File in operation already exists */
-+#define ERRinvalidparam 87
- #define ERRcannotopen 110 /* Cannot open the file specified */
- #define ERRunknownlevel 124
- #define ERRrename 183
-@@ -1911,4 +1912,7 @@
- #define SAFE_NETBIOS_CHARS ". -_"
-+#ifndef SAFE_FREE
-+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
-+#endif
- #endif /* _SMB_H */
-diff -ruN samba-2.0.10.orig/source/include/version.h samba-2.0.10/source/include/version.h
---- samba-2.0.10.orig/source/include/version.h 2001-06-23 15:23:59.000000000 +0200
-+++ samba-2.0.10/source/include/version.h      2006-03-06 22:25:53.000000000 +0100
-@@ -1 +1 @@
--#define VERSION "2.0.10"
-+#define VERSION "2.0.10-security-rollup"
-diff -ruN samba-2.0.10.orig/source/smbd/filename.c samba-2.0.10/source/smbd/filename.c
---- samba-2.0.10.orig/source/smbd/filename.c   2000-03-16 23:59:44.000000000 +0100
-+++ samba-2.0.10/source/smbd/filename.c        2006-03-06 22:25:53.000000000 +0100
-@@ -172,7 +172,7 @@
-    * StrnCpy always null terminates.
-    */
--  StrnCpy(orig_name, full_orig_name, namelen);
-+  StrnCpy(orig_name, full_orig_name, MIN(namelen, sizeof(orig_name)-1));
-   if(!case_sensitive)
-     strupper( orig_name );
-diff -ruN samba-2.0.10.orig/source/smbd/ipc.c samba-2.0.10/source/smbd/ipc.c
---- samba-2.0.10.orig/source/smbd/ipc.c        2006-03-06 22:25:08.000000000 +0100
-+++ samba-2.0.10/source/smbd/ipc.c     2006-03-06 22:25:53.000000000 +0100
-@@ -3556,18 +3556,18 @@
-       uint16 *setup=NULL;
-       int outsize = 0;
-       uint16 vuid = SVAL(inbuf,smb_uid);
--      int tpscnt = SVAL(inbuf,smb_vwv0);
--      int tdscnt = SVAL(inbuf,smb_vwv1);
--      int mprcnt = SVAL(inbuf,smb_vwv2);
--      int mdrcnt = SVAL(inbuf,smb_vwv3);
--      int msrcnt = CVAL(inbuf,smb_vwv4);
-+      unsigned int tpscnt = SVAL(inbuf,smb_vwv0);
-+      unsigned int tdscnt = SVAL(inbuf,smb_vwv1);
-+      unsigned int mprcnt = SVAL(inbuf,smb_vwv2);
-+      unsigned int mdrcnt = SVAL(inbuf,smb_vwv3);
-+      unsigned int msrcnt = CVAL(inbuf,smb_vwv4);
-       BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
-       BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
--      int pscnt = SVAL(inbuf,smb_vwv9);
--      int psoff = SVAL(inbuf,smb_vwv10);
--      int dscnt = SVAL(inbuf,smb_vwv11);
--      int dsoff = SVAL(inbuf,smb_vwv12);
--      int suwcnt = CVAL(inbuf,smb_vwv13);
-+      unsigned int pscnt = SVAL(inbuf,smb_vwv9);
-+      unsigned int psoff = SVAL(inbuf,smb_vwv10);
-+      unsigned int dscnt = SVAL(inbuf,smb_vwv11);
-+      unsigned int dsoff = SVAL(inbuf,smb_vwv12);
-+      unsigned int suwcnt = CVAL(inbuf,smb_vwv13);
-       memset(name, '\0',sizeof(name));
-       fstrcpy(name,smb_buf(inbuf));
-@@ -3578,26 +3578,44 @@
-   
-       if (tdscnt)  {
-               if((data = (char *)malloc(tdscnt)) == NULL) {
--                      DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n", tdscnt));
-+                      DEBUG(0,("reply_trans: data malloc fail for %u bytes !\n", tdscnt));
-                       return(ERROR(ERRDOS,ERRnomem));
-               } 
-+              if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
-+                      goto bad_param;
-+              if (smb_base(inbuf)+dsoff+dscnt > inbuf + size)
-+                      goto bad_param;
-+
-               memcpy(data,smb_base(inbuf)+dsoff,dscnt);
-       }
-       if (tpscnt) {
-               if((params = (char *)malloc(tpscnt)) == NULL) {
--                      DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n", tpscnt));
-+                      DEBUG(0,("reply_trans: param malloc fail for %u bytes !\n", tpscnt));
-+                      SAFE_FREE(data);
-                       return(ERROR(ERRDOS,ERRnomem));
-               } 
-+              if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
-+                      goto bad_param;
-+              if (smb_base(inbuf)+psoff+pscnt > inbuf + size)
-+                      goto bad_param;
-+
-               memcpy(params,smb_base(inbuf)+psoff,pscnt);
-       }
-       if (suwcnt) {
-               int i;
-               if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
--          DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt * sizeof(uint16))));
--                return(ERROR(ERRDOS,ERRnomem));
--        } 
-+                      DEBUG(0,("reply_trans: setup malloc fail for %u bytes !\n", (unsigned int)(suwcnt * sizeof(uint16))));
-+                      SAFE_FREE(data);
-+                      SAFE_FREE(params);
-+                      return(ERROR(ERRDOS,ERRnomem));
-+              } 
-+              if (inbuf+smb_vwv14+(suwcnt*SIZEOFWORD) > inbuf + size)
-+                      goto bad_param;
-+              if ((smb_vwv14+(suwcnt*SIZEOFWORD) < smb_vwv14) || (smb_vwv14+(suwcnt*SIZEOFWORD) < (suwcnt*SIZEOFWORD)))
-+                      goto bad_param;
-+
-               for (i=0;i<suwcnt;i++)
-                       setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
-       }
-@@ -3614,7 +3632,7 @@
-       /* receive the rest of the trans packet */
-       while (pscnt < tpscnt || dscnt < tdscnt) {
-               BOOL ret;
--              int pcnt,poff,dcnt,doff,pdisp,ddisp;
-+              unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
-       
-               ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
-@@ -3625,19 +3643,19 @@
-                               DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
-                                        (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
-                       }
--                      if (params)
--                              free(params);
--                      if (data)
--                              free(data);
--                      if (setup)
--                              free(setup);
-+                      SAFE_FREE(params);
-+                      SAFE_FREE(data);
-+                      SAFE_FREE(setup);
-                       return(ERROR(ERRSRV,ERRerror));
-               }
-               show_msg(inbuf);
-       
--              tpscnt = SVAL(inbuf,smb_vwv0);
--              tdscnt = SVAL(inbuf,smb_vwv1);
-+              /* Revise total_params and total_data in case they have changed downwards */
-+              if (SVAL(inbuf,smb_vwv0) < tpscnt)
-+                      tpscnt = SVAL(inbuf,smb_vwv0);
-+              if (SVAL(inbuf,smb_vwv1) < tdscnt)
-+                      tdscnt = SVAL(inbuf,smb_vwv1);
-               pcnt = SVAL(inbuf,smb_vwv2);
-               poff = SVAL(inbuf,smb_vwv3);
-@@ -3650,17 +3668,36 @@
-               pscnt += pcnt;
-               dscnt += dcnt;
-               
--              if (dscnt > tdscnt || pscnt > tpscnt) {
--                      exit_server("invalid trans parameters\n");
--              }
-+              if (dscnt > tdscnt || pscnt > tpscnt)
-+                      goto bad_param;
-               
--              if (pcnt)
-+              if (pcnt) {
-+                      if (pdisp+pcnt >= tpscnt)
-+                              goto bad_param;
-+                      if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
-+                              goto bad_param;
-+                      if (smb_base(inbuf) + poff + pcnt >= inbuf + bufsize)
-+                              goto bad_param;
-+                      if (params + pdisp < params)
-+                              goto bad_param;
-+
-                       memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
--              if (dcnt)
-+              }
-+
-+              if (dcnt) {
-+                      if (ddisp+dcnt >= tdscnt)
-+                              goto bad_param;
-+                      if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
-+                              goto bad_param;
-+                      if (smb_base(inbuf) + doff + dcnt >= inbuf + bufsize)
-+                              goto bad_param;
-+                      if (data + ddisp < data)
-+                              goto bad_param;
-+
-                       memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);      
-+              }
-       }
--      
--      
-+
-       DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
-                name,tdscnt,tpscnt,suwcnt));
-       
-@@ -3700,4 +3737,12 @@
-               return(ERROR(ERRSRV,ERRnosupport));
-       
-       return(outsize);
-+
-+  bad_param:
-+
-+      DEBUG(0,("reply_trans: invalid trans parameters\n"));
-+      SAFE_FREE(data);
-+      SAFE_FREE(params);
-+      SAFE_FREE(setup);
-+      return(ERROR(ERRSRV,ERRerror));
- }
-diff -ruN samba-2.0.10.orig/source/smbd/nttrans.c samba-2.0.10/source/smbd/nttrans.c
---- samba-2.0.10.orig/source/smbd/nttrans.c    2000-04-24 19:27:30.000000000 +0200
-+++ samba-2.0.10/source/smbd/nttrans.c 2006-03-06 22:25:53.000000000 +0100
-@@ -2575,11 +2575,14 @@
-     params = (char *)malloc(total_parameter_count);
-   if (total_data_count > 0)
-     data = (char *)malloc(total_data_count);
-- 
-+
-   if ((total_parameter_count && !params)  || (total_data_count && !data) ||
-       (setup_count && !setup)) {
-+    SAFE_FREE(setup);
-+    SAFE_FREE(params);
-+    SAFE_FREE(data);
-     DEBUG(0,("reply_nttrans : Out of memory\n"));
--    return(ERROR(ERRDOS,ERRnomem));
-+    return ERROR(ERRDOS,ERRnomem);
-   }
-   /* Copy the param and data bytes sent with this request into
-@@ -2588,64 +2591,112 @@
-   num_data_sofar = data_count;
-   if (parameter_count > total_parameter_count || data_count > total_data_count)
--    exit_server("reply_nttrans: invalid sizes in packet.\n");
-+    goto bad_param;
-   if(setup) {
--    memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
-     DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
--    dump_data(10, setup, setup_count);
-+    if ((smb_nt_SetupStart + setup_count < smb_nt_SetupStart) ||
-+      (smb_nt_SetupStart + setup_count < setup_count))
-+      goto bad_param;
-+    if (smb_nt_SetupStart + setup_count > length)
-+      goto bad_param;
-+    
-+    memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
-   }
-   if(params) {
--    memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
-     DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
--    dump_data(10, params, parameter_count);
-+    if ((parameter_offset + parameter_count < parameter_offset) ||
-+      (parameter_offset + parameter_count < parameter_count))
-+      goto bad_param;
-+    if (smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)
-+      goto bad_param;
-+    
-+    memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
-   }
-   if(data) {
--    memcpy( data, smb_base(inbuf) + data_offset, data_count);
-     DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
--    dump_data(10, data, data_count);
-+    if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count))
-+      goto bad_param;
-+    if (smb_base(inbuf) + data_offset + data_count > inbuf + length)
-+      goto bad_param;
-+    
-+    memcpy( data, smb_base(inbuf) + data_offset, data_count);
-+
-   }
-   if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
-     /* We need to send an interim response then receive the rest
-        of the parameter/data bytes */
-     outsize = set_message(outbuf,0,0,True);
--    send_smb(Client,outbuf);
-+    if (!send_smb(Client,outbuf))
-+      exit_server("reply_nttrans: send_smb failed.");
-     while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
-       BOOL ret;
--
-+      uint32 parameter_displacement;
-+      uint32 data_displacement;
-+      
-       ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
--
-+      
-       if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
--        outsize = set_message(outbuf,0,0,True);
--        if(ret) {
--              DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
--        } else {
--              DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
--                       (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
-+      outsize = set_message(outbuf,0,0,True);
-+      if(ret) {
-+        DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
-+      } else {
-+        DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
-+                 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
-       }
--        if(params)
--          free(params);
--        if(data)
--          free(data);
--        if(setup)
--          free(setup);
--        return(ERROR(ERRSRV,ERRerror));
-+      goto bad_param;
-       }
-       
-       /* Revise total_params and total_data in case they have changed downwards */
--      total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
--      total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
--      num_params_sofar += (parameter_count = IVAL(inbuf,smb_nts_ParameterCount));
--      num_data_sofar += ( data_count = IVAL(inbuf, smb_nts_DataCount));
--      if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count)
--        exit_server("reply_nttrans2: data overflow in secondary nttrans packet\n");
--
--      memcpy( &params[ IVAL(inbuf, smb_nts_ParameterDisplacement)], 
--              smb_base(inbuf) + IVAL(inbuf, smb_nts_ParameterOffset), parameter_count);
--      memcpy( &data[IVAL(inbuf, smb_nts_DataDisplacement)],
--              smb_base(inbuf)+ IVAL(inbuf, smb_nts_DataOffset), data_count);
-+      if (IVAL(inbuf, smb_nts_TotalParameterCount) < total_parameter_count)
-+      total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
-+      if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count)
-+      total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
-+      
-+      parameter_count = IVAL(inbuf,smb_nts_ParameterCount);
-+      parameter_offset = IVAL(inbuf, smb_nts_ParameterOffset);
-+      parameter_displacement = IVAL(inbuf, smb_nts_ParameterDisplacement);
-+      num_params_sofar += parameter_count;
-+      
-+      data_count = IVAL(inbuf, smb_nts_DataCount);
-+      data_displacement = IVAL(inbuf, smb_nts_DataDisplacement);
-+      data_offset = IVAL(inbuf, smb_nts_DataOffset);
-+      num_data_sofar += data_count;
-+
-+      if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count) {
-+      DEBUG(0,("reply_nttrans2: data overflow in secondary nttrans packet"));
-+      goto bad_param;
-+      }
-+
-+      if (parameter_count) {
-+      if (parameter_displacement + parameter_count >= total_parameter_count)
-+        goto bad_param;
-+      if ((parameter_displacement + parameter_count < parameter_displacement) ||
-+          (parameter_displacement + parameter_count < parameter_count))
-+        goto bad_param;
-+      if (smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize)
-+        goto bad_param;
-+      if (params + parameter_displacement < params)
-+        goto bad_param;
-+      
-+      memcpy( &params[parameter_displacement], smb_base(inbuf) + parameter_offset, parameter_count);
-+      }
-+      
-+      if (data_count) {
-+      if (data_displacement + data_count >= total_data_count)
-+        goto bad_param;
-+      if ((data_displacement + data_count < data_displacement) ||
-+          (data_displacement + data_count < data_count))
-+        goto bad_param;
-+      if (smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize)
-+        goto bad_param;
-+      if (data + data_displacement < data)
-+        goto bad_param;
-+      
-+      memcpy( &data[data_displacement], smb_base(inbuf)+ data_offset, data_count);
-+      }
-     }
-   }
-@@ -2714,4 +2765,10 @@
-   return outsize; /* If a correct response was needed the call_nt_transact_xxxx 
-                    calls have already sent it. If outsize != -1 then it is
-                    returning an error packet. */
-+ bad_param:
-+
-+  SAFE_FREE(params);
-+  SAFE_FREE(data);
-+  SAFE_FREE(setup);
-+  return ERROR(ERRDOS,ERRinvalidparam);
- }
-diff -ruN samba-2.0.10.orig/source/smbd/password.c samba-2.0.10/source/smbd/password.c
---- samba-2.0.10.orig/source/smbd/password.c   2006-03-06 22:25:08.000000000 +0100
-+++ samba-2.0.10/source/smbd/password.c        2006-03-06 22:25:53.000000000 +0100
-@@ -770,7 +770,7 @@
-       if (!ok && lp_username(snum)) {
-       char *auser;
-       pstring user_list;
--      StrnCpy(user_list,lp_username(snum),sizeof(pstring));
-+      StrnCpy(user_list,lp_username(snum),sizeof(pstring)-1);
-       pstring_sub(user_list,"%S",lp_servicename(snum));
-         
-diff -ruN samba-2.0.10.orig/source/smbd/reply.c samba-2.0.10/source/smbd/reply.c
---- samba-2.0.10.orig/source/smbd/reply.c      2006-03-06 22:25:08.000000000 +0100
-+++ samba-2.0.10/source/smbd/reply.c   2006-03-06 22:25:53.000000000 +0100
-@@ -1413,6 +1413,9 @@
-         for (i=numentries;(i<maxentries) && !finished;i++)
-         {
-+        /* check to make sure we have room in the buffer */
-+        if ( ((PTR_DIFF(p, outbuf))+DIR_STRUCT_SIZE) > BUFFER_SIZE )
-+              break;
-           finished = 
-             !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
-           if (!finished)
-@@ -3122,6 +3125,9 @@
-     
-               for (i=first;i<first+num_to_get;i++) {
-+                      /* check to make sure we have room in the buffer */
-+                      if ( (PTR_DIFF(p, outbuf)+28) > BUFFER_SIZE )
-+                              break;
-                       put_dos_date2(p,0,queue[i].time);
-                       CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
-                       SSVAL(p,5,printjob_encode(SNUM(conn), 
-diff -ruN samba-2.0.10.orig/source/smbd/trans2.c samba-2.0.10/source/smbd/trans2.c
---- samba-2.0.10.orig/source/smbd/trans2.c     2000-04-24 19:27:31.000000000 +0200
-+++ samba-2.0.10/source/smbd/trans2.c  2006-03-06 22:25:53.000000000 +0100
-@@ -201,7 +201,6 @@
-   int16 open_ofun = SVAL(params,12);
-   int32 open_size = IVAL(params,14);
-   char *pname = &params[28];
--  int16 namelen = strlen(pname)+1;
-   pstring fname;
-   mode_t unixmode;
-@@ -213,7 +212,7 @@
-   BOOL bad_path = False;
-   files_struct *fsp;
--  StrnCpy(fname,pname,namelen);
-+  pstrcpy(fname,pname);
-   DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
-          fname,open_mode, open_attr, open_ofun, open_size));
-@@ -2185,7 +2184,7 @@
-       unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
-       unsigned int tran_call = SVAL(inbuf, smb_setup0);
-       char *params = NULL, *data = NULL;
--      int num_params, num_params_sofar, num_data, num_data_sofar;
-+      unsigned int num_params, num_params_sofar, num_data, num_data_sofar;
-       if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
-               /* Queue this open message as we are the process of an
-@@ -2203,8 +2202,9 @@
-       /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
-          is so as a sanity check */
-       if (suwcnt != 1) {
--              DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
--              return(ERROR(ERRSRV,ERRerror));
-+              DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
-+              DEBUG(2,("Transaction is %d\n",tran_call));
-+              ERROR(ERRDOS,ERRinvalidparam);
-       }
-     
-       /* Allocate the space for the maximum needed parameters and data */
-@@ -2215,11 +2215,9 @@
-   
-       if ((total_params && !params)  || (total_data && !data)) {
-               DEBUG(2,("Out of memory in reply_trans2\n"));
--        if(params)
--          free(params);
--        if(data)
--          free(data); 
--              return(ERROR(ERRDOS,ERRnomem));
-+              SAFE_FREE(params);
-+              SAFE_FREE(data); 
-+              return ERROR(ERRDOS,ERRnomem);
-       }
-       /* Copy the param and data bytes sent with this request into
-@@ -2230,20 +2228,37 @@
-       if (num_params > total_params || num_data > total_data)
-               exit_server("invalid params in reply_trans2");
--      if(params)
--              memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
--      if(data)
--              memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
-+      if(params) {
-+              unsigned int psoff = SVAL(inbuf, smb_psoff);
-+              if ((psoff + num_params < psoff) || (psoff + num_params < num_params))
-+                      goto bad_param;
-+              if (smb_base(inbuf) + psoff + num_params > inbuf + length)
-+                      goto bad_param;
-+              memcpy( params, smb_base(inbuf) + psoff, num_params);
-+      }
-+      if(data) {
-+              unsigned int dsoff = SVAL(inbuf, smb_dsoff);
-+              if ((dsoff + num_data < dsoff) || (dsoff + num_data < num_data))
-+                      goto bad_param;
-+              if (smb_base(inbuf) + dsoff + num_data > inbuf + length)
-+                      goto bad_param;
-+              memcpy( data, smb_base(inbuf) + dsoff, num_data);
-+      }
-       if(num_data_sofar < total_data || num_params_sofar < total_params)  {
-               /* We need to send an interim response then receive the rest
-                  of the parameter/data bytes */
-               outsize = set_message(outbuf,0,0,True);
--              send_smb(Client,outbuf);
-+              if (!send_smb(Client,outbuf))
-+                      exit_server("reply_trans2: send_smb failed.");
-               while (num_data_sofar < total_data || 
-                      num_params_sofar < total_params) {
-                       BOOL ret;
-+                      unsigned int param_disp;
-+                      unsigned int param_off;
-+                      unsigned int data_disp;
-+                      unsigned int data_off;
-                       ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
-                       
-@@ -2255,26 +2270,55 @@
-                               else
-                                       DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
-                                                (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
--                              if(params)
--                                      free(params);
--                              if(data)
--                                      free(data);
--                              return(ERROR(ERRSRV,ERRerror));
-+                              goto bad_param;
-                       }
-       
-                       /* Revise total_params and total_data in case
-                            they have changed downwards */
--                      total_params = SVAL(inbuf, smb_tpscnt);
--                      total_data = SVAL(inbuf, smb_tdscnt);
--                      num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
--                      num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
-+                      if (SVAL(inbuf, smb_tpscnt) < total_params)
-+                              total_params = SVAL(inbuf, smb_tpscnt);
-+                      if (SVAL(inbuf, smb_tdscnt) < total_data)
-+                              total_data = SVAL(inbuf, smb_tdscnt);
-+
-+                      num_params = SVAL(inbuf,smb_spscnt);
-+                      param_off = SVAL(inbuf, smb_spsoff);
-+                      param_disp = SVAL(inbuf, smb_spsdisp);
-+                      num_params_sofar += num_params;
-+
-+                      num_data = SVAL(inbuf, smb_sdscnt);
-+                      data_off = SVAL(inbuf, smb_sdsoff);
-+                      data_disp = SVAL(inbuf, smb_sdsdisp);
-+                      num_data_sofar += num_data;
-+
-                       if (num_params_sofar > total_params || num_data_sofar > total_data)
--                              exit_server("data overflow in trans2");
-+                              goto bad_param;
-                       
--                      memcpy( &params[ SVAL(inbuf, smb_spsdisp)], 
--                              smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
--                      memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
--                              smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
-+                      if (num_params) {
-+                              if (param_disp + num_params >= total_params)
-+                                      goto bad_param;
-+                              if ((param_disp + num_params < param_disp) ||
-+                                              (param_disp + num_params < num_params))
-+                                      goto bad_param;
-+                              if (smb_base(inbuf) + param_off + num_params >= inbuf + bufsize)
-+                                      goto bad_param;
-+                              if (params + param_disp < params)
-+                                      goto bad_param;
-+
-+                              memcpy( &params[param_disp], smb_base(inbuf) + param_off, num_params);
-+                      }
-+                      if (num_data) {
-+                              if (data_disp + num_data >= total_data)
-+                                      goto bad_param;
-+                              if ((data_disp + num_data < data_disp) ||
-+                                              (data_disp + num_data < num_data))
-+                                      goto bad_param;
-+                              if (smb_base(inbuf) + data_off + num_data >= inbuf + bufsize)
-+                                      goto bad_param;
-+                              if (data + data_disp < data)
-+                                      goto bad_param;
-+
-+                              memcpy( &data[data_disp], smb_base(inbuf) + data_off, num_data);
-+                      }
-               }
-       }
-       
-@@ -2367,4 +2411,10 @@
-       return outsize; /* If a correct response was needed the
-                          call_trans2xxx calls have already sent
-                          it. If outsize != -1 then it is returning */
-+
-+  bad_param:
-+
-+      SAFE_FREE(params);
-+      SAFE_FREE(data);
-+      return (ERROR(ERRDOS,ERRinvalidparam));
- }