OpenPKG CVS Repository
  http://cvs.openpkg.org/
  ____________________________________________________________________________

  Server: cvs.openpkg.org                  Name:   Thomas Lotterer
  Root:   /e/openpkg/cvs                   Email:  [EMAIL PROTECTED]
  Module: openpkg-src                      Date:   17-Mar-2003 20:32:18
  Branch: OPENPKG_1_2_SOLID                Handle: 2003031719321700

  Added files:              (Branch: OPENPKG_1_2_SOLID)
    openpkg-src/samba       samba.patch
  Modified files:           (Branch: OPENPKG_1_2_SOLID)
    openpkg-src/samba       samba.spec

  Log:
    SA-2003.021-samba; CAN-2003-0085, CAN-2003-0086

  Summary:
    Revision    Changes     Path
    1.1.8.1     +1419 -0    openpkg-src/samba/samba.patch
    1.35.2.1.2.2+3  -1      openpkg-src/samba/samba.spec
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: openpkg-src/samba/samba.patch
  ============================================================================
  $ cvs diff -u -r0 -r1.1.8.1 samba.patch
  --- /dev/null 2003-03-17 20:32:17.000000000 +0100
  +++ samba.patch       2003-03-17 20:32:18.000000000 +0100
  @@ -0,0 +1,1419 @@
  +
  +IMPORTANT: Security bugfix for Samba
  +------------------------------------
  +
  +Summary
  +-------
  +
  +The SuSE security audit team, in particular Sebastian Krahmer
  +<[EMAIL PROTECTED]>, has found a flaw in the Samba main smbd code which
  +could allow an external attacker to remotely and anonymously gain
  +Super User (root) privileges on a server running a Samba server.
  +
  +This flaw exists in previous versions of Samba from 2.0.x to 2.2.7a
  +inclusive.  This is a serious problem and all sites should either
  +upgrade to Samba 2.2.8 immediately or prohibit access to TCP ports 139
  +and 445. Advice created by Andrew Tridgell, the leader of the Samba Team,
  +on how to protect an unpatched Samba server is given at the end of this
  +section.
  +
  +The SMB/CIFS protocol implemented by Samba is vulnerable to many
  +attacks, even without specific security holes.  The TCP ports 139 and
  +the new port 445 (used by Win2k and the Samba 3.0 alpha code in
  +particular) should never be exposed to untrusted networks.
  +
  +Description
  +-----------
  +
  +A buffer overrun condition exists in the SMB/CIFS packet fragment
  +re-assembly code in smbd which would allow an attacker to cause smbd
  +to overwrite arbitrary areas of memory in its own process address
  +space. This could allow a skilled attacker to inject binary specific
  +exploit code into smbd.
  +
  +This version of Samba adds explicit overrun and overflow checks on
  +fragment re-assembly of SMB/CIFS packets to ensure that only valid
  +re-assembly is performed by smbd.
  +
  +In addition, the same checks have been added to the re-assembly
  +functions in the client code, making it safe for use in other
  +services.
  +
  +Credit
  +------
  +
  +This security flaw was discovered and reported to the Samba Team by
  +Sebastian Krahmer <[EMAIL PROTECTED]> of the SuSE Security Audit Team.
  +The fix was prepared by Jeremy Allison and reviewed by engineers from
  +the Samba Team, SuSE, HP, SGI, Apple, and the Linux vendor engineers
  +on the Linux Vendor security mailing list.
  +
  +The Samba Team would like to thank SuSE and Sebastian Krahmer for
  +their excellent auditing work and for drawing attention to this flaw.
  +
  +Patch Availability
  +-----------------
  +
  +As this is a security issue, patches for this flaw specific to earlier
  +versions of Samba will be posted on the [EMAIL PROTECTED]
  +mailing list as requested.
  +
  +The patch below was extracted for OpenPKG from the Samba 2.2.7a to 2.2.8
  +differences regarding the following files:
  +    source/include/client.h
  +    source/include/proto.h   changes reduced to functions affected by this patch
  +    source/client/client.c
  +    source/client/clitar.c
  +    source/libsmb/clifile.c
  +    source/libsmb/clilist.c
  +    source/libsmb/clirap.c
  +    source/libsmb/clitrans.c
  +    source/smbd/ipc.c
  +    source/smbd/trans2.c     removed "6)  Fix delete on close semantics to match 
W2K")
  +    source/smbd/nttrans.c    whitespace differences were removed
  +    source/smbd/vfs-wrap.c
  +
  +--- samba-2.2.7a/source/include/client.h     Mon Mar 17 11:00:11 2003
  ++++ samba-2.2.8/source/include/client.h      Fri Mar 14 22:34:47 2003
  +@@ -103,7 +103,7 @@
  +     int max_mux;
  +     char *outbuf;
  +     char *inbuf;
  +-    int bufsize;
  ++    unsigned int bufsize;
  +     int initialised;
  +     int win95;
  +     uint32 capabilities;
  +--- samba-2.2.7a/source/include/proto.h      Mon Mar 17 11:00:16 2003
  ++++ samba-2.2.8-patchedonly/source/include/proto.h   Fri Mar 14 22:34:47 2003
  +@@ -301,7 +301,7 @@
  +             SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type 
lock_type);
  + BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, 
SMB_BIG_UINT len);
  + BOOL cli_getattrE(struct cli_state *cli, int fd, 
  +-              uint16 *attr, size_t *size, 
  ++              uint16 *attr, SMB_BIG_UINT *size, 
  +               time_t *c_time, time_t *a_time, time_t *m_time);
  + BOOL cli_getatr(struct cli_state *cli, const char *fname, 
  +             uint16 *attr, size_t *size, time_t *t);
  +@@ -425,7 +425,7 @@
  + 
  + /* The following definitions come from libsmb/clirap.c  */
  + 
  +-BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, 
  ++BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, 
  +                   uint16 *setup, uint32 setup_count, uint32 max_setup_count,
  +                   char *params, uint32 param_count, uint32 max_param_count,
  +                   char *data, uint32 data_count, uint32 max_data_count,
  +@@ -434,8 +434,8 @@
  + BOOL cli_api(struct cli_state *cli,
  +          char *param, int prcnt, int mprcnt,
  +          char *data, int drcnt, int mdrcnt,
  +-         char **rparam, int *rprcnt,
  +-         char **rdata, int *rdrcnt);
  ++         char **rparam, unsigned int *rprcnt,
  ++         char **rdata, unsigned int *rdrcnt);
  + BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
  + int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, 
const char *, void *), void *state);
  + BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
  +@@ -653,21 +653,21 @@
  + BOOL cli_send_trans(struct cli_state *cli, int trans, 
  +                 const char *pipe_name, 
  +                 int fid, int flags,
  +-                uint16 *setup, int lsetup, int msetup,
  +-                char *param, int lparam, int mparam,
  +-                char *data, int ldata, int mdata);
  ++                uint16 *setup, unsigned int lsetup, unsigned int msetup,
  ++                char *param, unsigned int lparam, unsigned int mparam,
  ++                char *data, unsigned int ldata, unsigned int mdata);
  + BOOL cli_receive_trans(struct cli_state *cli,int trans,
  +-                              char **param, int *param_len,
  +-                              char **data, int *data_len);
  ++                              char **param, unsigned int *param_len,
  ++                              char **data, unsigned int *data_len);
  + BOOL cli_send_nt_trans(struct cli_state *cli, 
  +                    int function, 
  +                    int flags,
  +-                   uint16 *setup, int lsetup, int msetup,
  +-                   char *param, int lparam, int mparam,
  +-                   char *data, int ldata, int mdata);
  ++                   uint16 *setup, unsigned int lsetup, unsigned int msetup,
  ++                   char *param, unsigned int lparam, unsigned int mparam,
  ++                   char *data, unsigned int ldata, unsigned int mdata);
  + BOOL cli_receive_nt_trans(struct cli_state *cli,
  +-                      char **param, int *param_len,
  +-                      char **data, int *data_len);
  ++                      char **param, unsigned int *param_len,
  ++                      char **data, unsigned int *data_len);
  + 
  + /* The following definitions come from libsmb/credentials.c  */
  + 
  +--- samba-2.2.7a/source/libsmb/clifile.c     Mon Mar 17 10:53:21 2003
  ++++ samba-2.2.8/source/libsmb/clifile.c      Fri Mar 14 22:34:48 2003
  +@@ -30,8 +30,8 @@
  + 
  + static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const 
char *fname_dst, BOOL hard_link)
  + {
  +-    int data_len = 0;
  +-    int param_len = 0;
  ++    unsigned int data_len = 0;
  ++    unsigned int param_len = 0;
  +     uint16 setup = TRANSACT2_SETPATHINFO;
  +     char param[sizeof(pstring)+6];
  +     pstring data;
  +@@ -124,8 +124,8 @@
  + 
  + static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char 
*fname, uint32 mode, uint32 uid, uint32 gid)
  + {
  +-    int data_len = 0;
  +-    int param_len = 0;
  ++    unsigned int data_len = 0;
  ++    unsigned int param_len = 0;
  +     uint16 setup = TRANSACT2_SETPATHINFO;
  +     char param[sizeof(pstring)+6];
  +     char data[100];
  +@@ -336,8 +336,8 @@
  + 
  + int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
  + {
  +-    int data_len = 1;
  +-    int param_len = 6;
  ++    unsigned int data_len = 1;
  ++    unsigned int param_len = 6;
  +     uint16 setup = TRANSACT2_SETFILEINFO;
  +     pstring param;
  +     unsigned char data;
  +@@ -802,11 +802,11 @@
  + }
  + 
  + /****************************************************************************
  +- Do a SMBgetattrE call.
  ++ Do a SMBgetattrE call. The size is 32 bits.
  + ****************************************************************************/
  + 
  + BOOL cli_getattrE(struct cli_state *cli, int fd, 
  +-              uint16 *attr, size_t *size, 
  ++              uint16 *attr, SMB_BIG_UINT *size, 
  +               time_t *c_time, time_t *a_time, time_t *m_time)
  + {
  +     memset(cli->outbuf,'\0',smb_size);
  +--- samba-2.2.7a/source/libsmb/clilist.c     Mon Mar 17 11:00:18 2003
  ++++ samba-2.2.8/source/libsmb/clilist.c      Fri Mar 14 22:34:48 2003
  +@@ -152,7 +152,7 @@
  +     int ff_dir_handle=0;
  +     int loop_count = 0;
  +     char *rparam=NULL, *rdata=NULL;
  +-    int param_len, data_len;        
  ++    unsigned int param_len, data_len;       
  +     uint16 setup;
  +     pstring param;
  + 
  +--- samba-2.2.7a/source/libsmb/clirap.c      Mon Mar 17 10:53:23 2003
  ++++ samba-2.2.8/source/libsmb/clirap.c       Fri Mar 14 22:34:48 2003
  +@@ -27,7 +27,7 @@
  + /****************************************************************************
  + Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
  + ****************************************************************************/
  +-BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, 
  ++BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, 
  +                   uint16 *setup, uint32 setup_count, uint32 max_setup_count,
  +                   char *params, uint32 param_count, uint32 max_param_count,
  +                   char *data, uint32 data_count, uint32 max_data_count,
  +@@ -42,8 +42,8 @@
  +                  data, data_count, max_data_count);
  + 
  +   return (cli_receive_trans(cli, SMBtrans, 
  +-                            rparam, (int *)rparam_count,
  +-                            rdata, (int *)rdata_count));
  ++                            rparam, (unsigned int *)rparam_count,
  ++                            rdata, (unsigned int *)rdata_count));
  + }
  + 
  + /****************************************************************************
  +@@ -52,8 +52,8 @@
  + BOOL cli_api(struct cli_state *cli,
  +          char *param, int prcnt, int mprcnt,
  +          char *data, int drcnt, int mdrcnt,
  +-         char **rparam, int *rprcnt,
  +-         char **rdata, int *rdrcnt)
  ++         char **rparam, unsigned int *rprcnt,
  ++         char **rdata, unsigned int *rdrcnt)
  + {
  +   cli_send_trans(cli,SMBtrans,
  +                  PIPE_LANMAN,             /* Name */
  +@@ -176,7 +176,7 @@
  +                                     char *sname = p;
  +                                     int type = SVAL(p,14);
  +                                     int comment_offset = IVAL(p,16) & 0xFFFF;
  +-                                    char *cmnt = 
comment_offset?(rdata+comment_offset-converter):"";
  ++                                    const char *cmnt = 
comment_offset?(rdata+comment_offset-converter):"";
  +                                     pstring s1, s2;
  + 
  +                                     pstrcpy(s1, dos_to_unix_static(sname));
  +@@ -254,7 +254,7 @@
  +                     for (i = 0;i < count;i++, p += 26) {
  +                             char *sname = p;
  +                             int comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
  +-                            char *cmnt = comment_offset?(rdata+comment_offset):"";
  ++                            const char *cmnt = 
comment_offset?(rdata+comment_offset):"";
  +                             pstring s1, s2;
  + 
  +                             if (comment_offset < 0 || comment_offset > rdrcnt) 
continue;
  +@@ -289,8 +289,8 @@
  +   fstring upper_case_new_pw;
  +   unsigned char old_pw_hash[16];
  +   unsigned char new_pw_hash[16];
  +-  int data_len;
  +-  int param_len = 0;
  ++  unsigned int data_len;
  ++  unsigned int param_len = 0;
  +   char *rparam = NULL;
  +   char *rdata = NULL;
  +   int rprcnt, rdrcnt;
  +@@ -372,8 +372,8 @@
  +                time_t *c_time, time_t *a_time, time_t *m_time, 
  +                size_t *size, uint16 *mode)
  + {
  +-    int data_len = 0;
  +-    int param_len = 0;
  ++    unsigned int data_len = 0;
  ++    unsigned int param_len = 0;
  +     uint16 setup = TRANSACT2_QPATHINFO;
  +     pstring param;
  +     char *rparam=NULL, *rdata=NULL;
  +@@ -451,8 +451,8 @@
  +                 time_t *w_time, size_t *size, uint16 *mode,
  +                 SMB_INO_T *ino)
  + {
  +-    int data_len = 0;
  +-    int param_len = 0;
  ++    unsigned int data_len = 0;
  ++    unsigned int param_len = 0;
  +     uint16 setup = TRANSACT2_QPATHINFO;
  +     pstring param;
  +     char *rparam=NULL, *rdata=NULL;
  +@@ -522,8 +522,8 @@
  +                time_t *c_time, time_t *a_time, time_t *m_time, 
  +                time_t *w_time, SMB_INO_T *ino)
  + {
  +-    int data_len = 0;
  +-    int param_len = 0;
  ++    unsigned int data_len = 0;
  ++    unsigned int param_len = 0;
  +     uint16 setup = TRANSACT2_QFILEINFO;
  +     pstring param;
  +     char *rparam=NULL, *rdata=NULL;
  +@@ -590,8 +590,8 @@
  + ****************************************************************************/
  + BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata)
  + {
  +-    int data_len = 0;
  +-    int param_len = 0;
  ++    unsigned int data_len = 0;
  ++    unsigned int param_len = 0;
  +     uint16 setup = TRANSACT2_QFILEINFO;
  +     pstring param;
  +     char *rparam=NULL, *rdata=NULL;
  +@@ -635,8 +635,8 @@
  + 
  + NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring 
alt_name)
  + {
  +-    int data_len = 0;
  +-    int param_len = 0;
  ++    unsigned int data_len = 0;
  ++    unsigned int param_len = 0;
  +     uint16 setup = TRANSACT2_QPATHINFO;
  +     pstring param;
  +     char *rparam=NULL, *rdata=NULL;
  +--- samba-2.2.7a/source/client/client.c      Mon Mar 17 14:49:44 2003
  ++++ samba-2.2.8/source/client/client.c       Mon Mar 17 14:50:19 2003
  +@@ -644,8 +644,9 @@
  +     struct timeval tp_start;
  +     int read_size = io_bufsize;
  +     uint16 attr;
  +-    size_t size;
  +-    off_t nread = 0;
  ++    size_t old_size = 0;
  ++    SMB_BIG_UINT size = 0;
  ++    SMB_BIG_UINT nread = 0;
  + 
  +     GetTimeOfDay(&tp_start);
  + 
  +@@ -671,9 +672,8 @@
  +             return;
  +     }
  + 
  +-
  +     if (!cli_qfileinfo(cli, fnum, 
  +-                       &attr, &size, NULL, NULL, NULL, NULL, NULL) &&
  ++                       &attr, &old_size, NULL, NULL, NULL, NULL, NULL) &&
  +         !cli_getattrE(cli, fnum, 
  +                       &attr, &size, NULL, NULL, NULL)) {
  +             DEBUG(0,("getattrib: %s\n",cli_errstr(cli)));
  +--- samba-2.2.7a/source/client/clitar.c      Mon Mar 17 14:53:27 2003
  ++++ samba-2.2.8/source/client/clitar.c       Mon Mar 17 14:53:58 2003
  +@@ -45,7 +45,7 @@
  + 
  + struct file_info_struct
  + {
  +-  size_t size;
  ++  SMB_BIG_UINT size;
  +   uint16 mode;
  +   int uid;
  +   int gid;
  +@@ -621,7 +621,7 @@
  + static void do_atar(char *rname,char *lname,file_info *finfo1)
  + {
  +   int fnum;
  +-  uint32 nread=0;
  ++  SMB_BIG_UINT nread=0;
  +   char ftype;
  +   file_info2 finfo;
  +   BOOL close_done = False;
  +@@ -643,6 +643,7 @@
  +     finfo.mtime = finfo1 -> mtime;
  +     finfo.atime = finfo1 -> atime;
  +     finfo.ctime = finfo1 -> ctime;
  ++    finfo.name  = finfo1 -> name;
  +   }
  +   else {
  +     finfo.size  = def_finfo.size;
  +@@ -652,13 +653,14 @@
  +     finfo.mtime = def_finfo.mtime;
  +     finfo.atime = def_finfo.atime;
  +     finfo.ctime = def_finfo.ctime;
  ++    finfo.name  = def_finfo.name;
  +   }
  + 
  +   if (dry_run)
  +     {
  +-      DEBUG(3,("skipping file %s of size %d bytes\n",
  ++      DEBUG(3,("skipping file %s of size %12.0f bytes\n",
  +            finfo.name,
  +-           (int)finfo.size));
  ++           (double)finfo.size));
  +       shallitime=0;
  +       ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
  +       ntarf++;
  +@@ -709,9 +711,9 @@
  +     }
  +   else
  +     {
  +-      DEBUG(3,("getting file %s of size %d bytes as a tar file %s",
  ++      DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
  +            finfo.name,
  +-           (int)finfo.size,
  ++           (double)finfo.size,
  +            lname));
  +       
  +       /* write a tar header, don't bother with mode - just set to 100644 */
  +@@ -719,7 +721,7 @@
  + 
  +       while (nread < finfo.size && !close_done)     {
  +           
  +-          DEBUG(3,("nread=%d\n",nread));
  ++          DEBUG(3,("nread=%.0f\n",(double)nread));
  +           
  +           datalen = cli_read(cli, fnum, data, nread, read_size);
  +           
  +@@ -736,7 +738,7 @@
  + 
  +               if (nread > finfo.size) {
  +                     datalen -= nread - finfo.size;
  +-                    DEBUG(0,("File size change - truncating %s to %d bytes\n", 
finfo.name, (int)finfo.size));
  ++                    DEBUG(0,("File size change - truncating %s to %.0f bytes\n", 
finfo.name, (double)finfo.size));
  +               }
  + 
  +           /* add received bits of file to buffer - dotarbuf will
  +@@ -756,7 +758,7 @@
  + 
  +       /* pad tar file with zero's if we couldn't get entire file */
  +       if (nread < finfo.size) {
  +-          DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", 
(int)finfo.size, (int)nread));
  ++          DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%.0f\n", 
(double)finfo.size, (double)nread));
  +           if (padit(data, sizeof(data), finfo.size - nread))
  +                   DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
  +       }
  +@@ -789,8 +791,8 @@
  + 
  +       if (tar_noisy)
  +     {
  +-      DEBUG(0, ("%10d (%7.1f kb/s) %s\n",
  +-           (int)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
  ++      DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
  ++           (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
  +                finfo.name));
  +     }
  + 
  +--- samba-2.2.7a/source/libsmb/clitrans.c    Mon Mar 17 10:53:24 2003
  ++++ samba-2.2.8/source/libsmb/clitrans.c     Fri Mar 14 22:34:48 2003
  +@@ -25,18 +25,19 @@
  + 
  + 
  + /****************************************************************************
  +-  send a SMB trans or trans2 request
  +-  ****************************************************************************/
  ++ Send a SMB trans or trans2 request.
  ++****************************************************************************/
  ++
  + BOOL cli_send_trans(struct cli_state *cli, int trans, 
  +                 const char *pipe_name, 
  +                 int fid, int flags,
  +-                uint16 *setup, int lsetup, int msetup,
  +-                char *param, int lparam, int mparam,
  +-                char *data, int ldata, int mdata)
  ++                uint16 *setup, unsigned int lsetup, unsigned int msetup,
  ++                char *param, unsigned int lparam, unsigned int mparam,
  ++                char *data, unsigned int ldata, unsigned int mdata)
  + {
  +     int i;
  +-    int this_ldata,this_lparam;
  +-    int tot_data=0,tot_param=0;
  ++    unsigned int this_ldata,this_lparam;
  ++    unsigned int tot_data=0,tot_param=0;
  +     char *outdata,*outparam;
  +     char *p;
  +     int pipe_name_len=0;
  +@@ -84,14 +85,13 @@
  +     cli_setup_bcc(cli, outdata+this_ldata);
  + 
  +     show_msg(cli->outbuf);
  +-    cli_send_smb(cli);
  ++    if (!cli_send_smb(cli))
  ++            return False;
  + 
  +     if (this_ldata < ldata || this_lparam < lparam) {
  +             /* receive interim response */
  +-            if (!cli_receive_smb(cli) || 
  +-                cli_is_error(cli)) {
  ++            if (!cli_receive_smb(cli) || cli_is_error(cli))
  +                     return(False);
  +-            }      
  + 
  +             tot_data = this_ldata;
  +             tot_param = this_lparam;
  +@@ -124,7 +124,8 @@
  +                     cli_setup_bcc(cli, outdata+this_ldata);
  +                     
  +                     show_msg(cli->outbuf);
  +-                    cli_send_smb(cli);
  ++                    if (!cli_send_smb(cli))
  ++                            return False;
  +                     
  +                     tot_data += this_ldata;
  +                     tot_param += this_lparam;
  +@@ -134,17 +135,17 @@
  +     return(True);
  + }
  + 
  +-
  + /****************************************************************************
  +-  receive a SMB trans or trans2 response allocating the necessary memory
  +-  ****************************************************************************/
  ++ Receive a SMB trans or trans2 response allocating the necessary memory.
  ++****************************************************************************/
  ++
  + BOOL cli_receive_trans(struct cli_state *cli,int trans,
  +-                              char **param, int *param_len,
  +-                              char **data, int *data_len)
  ++                              char **param, unsigned int *param_len,
  ++                              char **data, unsigned int *data_len)
  + {
  +-    int total_data=0;
  +-    int total_param=0;
  +-    int this_data,this_param;
  ++    unsigned int total_data=0;
  ++    unsigned int total_param=0;
  ++    unsigned int this_data,this_param;
  +     NTSTATUS status;
  +     char *tdata;
  +     char *tparam;
  +@@ -171,9 +172,8 @@
  +      */
  +     status = cli_nt_error(cli);
  +     
  +-    if (NT_STATUS_IS_ERR(status)) {
  ++    if (NT_STATUS_IS_ERR(status))
  +             return False;
  +-    }
  + 
  +     /* parse out the lengths */
  +     total_data = SVAL(cli->inbuf,smb_tdrcnt);
  +@@ -210,21 +210,59 @@
  +                     return False;
  +             }
  + 
  +-            if (this_data)
  +-                    memcpy(*data + SVAL(cli->inbuf,smb_drdisp),
  +-                           smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff),
  +-                           this_data);
  +-            if (this_param)
  +-                    memcpy(*param + SVAL(cli->inbuf,smb_prdisp),
  +-                           smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff),
  +-                           this_param);
  ++            if (this_data + *data_len < this_data ||
  ++                            this_data + *data_len < *data_len ||
  ++                            this_param + *param_len < this_param ||
  ++                            this_param + *param_len < *param_len) {
  ++                    DEBUG(1,("Data overflow in cli_receive_trans\n"));
  ++                    return False;
  ++            }
  ++
  ++            if (this_data) {
  ++                    unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp);
  ++                    unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff);
  ++
  ++                    if (data_offset_out > total_data ||
  ++                                    data_offset_out + this_data > total_data ||
  ++                                    data_offset_out + this_data < data_offset_out 
||
  ++                                    data_offset_out + this_data < this_data) {
  ++                            DEBUG(1,("Data overflow in cli_receive_trans\n"));
  ++                            return False;
  ++                    }
  ++                    if (data_offset_in > cli->bufsize ||
  ++                                    data_offset_in + this_data >  cli->bufsize ||
  ++                                    data_offset_in + this_data < data_offset_in ||
  ++                                    data_offset_in + this_data < this_data) {
  ++                            DEBUG(1,("Data overflow in cli_receive_trans\n"));
  ++                            return False;
  ++                    }
  ++
  ++                    memcpy(*data + data_offset_out, smb_base(cli->inbuf) + 
data_offset_in, this_data);
  ++            }
  ++            if (this_param) {
  ++                    unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp);
  ++                    unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff);
  ++
  ++                    if (param_offset_out > total_param ||
  ++                                    param_offset_out + this_param > total_param ||
  ++                                    param_offset_out + this_param < 
param_offset_out ||
  ++                                    param_offset_out + this_param < this_param) {
  ++                            DEBUG(1,("Param overflow in cli_receive_trans\n"));
  ++                            return False;
  ++                    }
  ++                    if (param_offset_in > cli->bufsize ||
  ++                                    param_offset_in + this_param >  cli->bufsize ||
  ++                                    param_offset_in + this_param < param_offset_in 
||
  ++                                    param_offset_in + this_param < this_param) {
  ++                            DEBUG(1,("Param overflow in cli_receive_trans\n"));
  ++                            return False;
  ++                    }
  ++
  ++                    memcpy(*param + param_offset_out, smb_base(cli->inbuf) + 
param_offset_in, this_param);
  ++            }
  +             *data_len += this_data;
  +             *param_len += this_param;
  + 
  +-            /* parse out the total lengths again - they can shrink! */
  +-            total_data = SVAL(cli->inbuf,smb_tdrcnt);
  +-            total_param = SVAL(cli->inbuf,smb_tprcnt);
  +-            
  +             if (total_data <= *data_len && total_param <= *param_len)
  +                     break;
  +             
  +@@ -243,27 +281,35 @@
  +             if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {
  +                     return(False);
  +             }
  ++
  ++            /* parse out the total lengths again - they can shrink! */
  ++            if (SVAL(cli->inbuf,smb_tdrcnt) < total_data)
  ++                    total_data = SVAL(cli->inbuf,smb_tdrcnt);
  ++            if (SVAL(cli->inbuf,smb_tprcnt) < total_param)
  ++                    total_param = SVAL(cli->inbuf,smb_tprcnt);
  ++            
  ++            if (total_data <= *data_len && total_param <= *param_len)
  ++                    break;
  ++            
  +     }
  +     
  +     return(True);
  + }
  + 
  +-
  +-
  +-
  + /****************************************************************************
  +-  send a SMB nttrans request
  +-  ****************************************************************************/
  ++ Send a SMB nttrans request.
  ++****************************************************************************/
  ++
  + BOOL cli_send_nt_trans(struct cli_state *cli, 
  +                    int function, 
  +                    int flags,
  +-                   uint16 *setup, int lsetup, int msetup,
  +-                   char *param, int lparam, int mparam,
  +-                   char *data, int ldata, int mdata)
  ++                   uint16 *setup, unsigned int lsetup, unsigned int msetup,
  ++                   char *param, unsigned int lparam, unsigned int mparam,
  ++                   char *data, unsigned int ldata, unsigned int mdata)
  + {
  +-    int i;
  +-    int this_ldata,this_lparam;
  +-    int tot_data=0,tot_param=0;
  ++    unsigned int i;
  ++    unsigned int this_ldata,this_lparam;
  ++    unsigned int tot_data=0,tot_param=0;
  +     char *outdata,*outparam;
  + 
  +     this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
  +@@ -302,14 +348,13 @@
  +     cli_setup_bcc(cli, outdata+this_ldata);
  + 
  +     show_msg(cli->outbuf);
  +-    cli_send_smb(cli);
  ++    if (!cli_send_smb(cli))
  ++            return False;
  + 
  +     if (this_ldata < ldata || this_lparam < lparam) {
  +             /* receive interim response */
  +-            if (!cli_receive_smb(cli) || 
  +-                cli_is_error(cli)) {
  ++            if (!cli_receive_smb(cli) || cli_is_error(cli))
  +                     return(False);
  +-            }      
  + 
  +             tot_data = this_ldata;
  +             tot_param = this_lparam;
  +@@ -341,7 +386,8 @@
  +                     cli_setup_bcc(cli, outdata+this_ldata);
  +                     
  +                     show_msg(cli->outbuf);
  +-                    cli_send_smb(cli);
  ++                    if (!cli_send_smb(cli))
  ++                            return False;
  +                     
  +                     tot_data += this_ldata;
  +                     tot_param += this_lparam;
  +@@ -356,13 +402,14 @@
  + /****************************************************************************
  +   receive a SMB nttrans response allocating the necessary memory
  +   ****************************************************************************/
  ++
  + BOOL cli_receive_nt_trans(struct cli_state *cli,
  +-                      char **param, int *param_len,
  +-                      char **data, int *data_len)
  ++                      char **param, unsigned int *param_len,
  ++                      char **data, unsigned int *data_len)
  + {
  +-    int total_data=0;
  +-    int total_param=0;
  +-    int this_data,this_param;
  ++    unsigned int total_data=0;
  ++    unsigned int total_param=0;
  ++    unsigned int this_data,this_param;
  +     uint8 eclass;
  +     uint32 ecode;
  +     char *tdata;
  +@@ -424,25 +471,65 @@
  + 
  +             if (this_data + *data_len > total_data ||
  +                 this_param + *param_len > total_param) {
  +-                    DEBUG(1,("Data overflow in cli_receive_trans\n"));
  ++                    DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
  +                     return False;
  +             }
  + 
  +-            if (this_data)
  +-                    memcpy(*data + SVAL(cli->inbuf,smb_ntr_DataDisplacement),
  +-                           smb_base(cli->inbuf) + 
SVAL(cli->inbuf,smb_ntr_DataOffset),
  +-                           this_data);
  +-            if (this_param)
  +-                    memcpy(*param + SVAL(cli->inbuf,smb_ntr_ParameterDisplacement),
  +-                           smb_base(cli->inbuf) + 
SVAL(cli->inbuf,smb_ntr_ParameterOffset),
  +-                           this_param);
  ++            if (this_data + *data_len < this_data ||
  ++                            this_data + *data_len < *data_len ||
  ++                            this_param + *param_len < this_param ||
  ++                            this_param + *param_len < *param_len) {
  ++                    DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
  ++                    return False;
  ++            }
  ++
  ++            if (this_data) {
  ++                    unsigned int data_offset_out = 
SVAL(cli->inbuf,smb_ntr_DataDisplacement);
  ++                    unsigned int data_offset_in = 
SVAL(cli->inbuf,smb_ntr_DataOffset);
  ++
  ++                    if (data_offset_out > total_data ||
  ++                                    data_offset_out + this_data > total_data ||
  ++                                    data_offset_out + this_data < data_offset_out 
||
  ++                                    data_offset_out + this_data < this_data) {
  ++                            DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
  ++                            return False;
  ++                    }
  ++                    if (data_offset_in > cli->bufsize ||
  ++                                    data_offset_in + this_data >  cli->bufsize ||
  ++                                    data_offset_in + this_data < data_offset_in ||
  ++                                    data_offset_in + this_data < this_data) {
  ++                            DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
  ++                            return False;
  ++                    }
  ++
  ++                    memcpy(*data + data_offset_out, smb_base(cli->inbuf) + 
data_offset_in, this_data);
  ++            }
  ++
  ++            if (this_param) {
  ++                    unsigned int param_offset_out = 
SVAL(cli->inbuf,smb_ntr_ParameterDisplacement);
  ++                    unsigned int param_offset_in = 
SVAL(cli->inbuf,smb_ntr_ParameterOffset);
  ++
  ++                    if (param_offset_out > total_param ||
  ++                                    param_offset_out + this_param > total_param ||
  ++                                    param_offset_out + this_param < 
param_offset_out ||
  ++                                    param_offset_out + this_param < this_param) {
  ++                            DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
  ++                            return False;
  ++                    }
  ++                    if (param_offset_in > cli->bufsize ||
  ++                                    param_offset_in + this_param >  cli->bufsize ||
  ++                                    param_offset_in + this_param < param_offset_in 
||
  ++                                    param_offset_in + this_param < this_param) {
  ++                            DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
  ++                            return False;
  ++                    }
  ++
  ++                    memcpy(*param + param_offset_out, smb_base(cli->inbuf) + 
param_offset_in, this_param);
  ++            }
  ++
  +             *data_len += this_data;
  +             *param_len += this_param;
  + 
  +-            /* parse out the total lengths again - they can shrink! */
  +-            total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount);
  +-            total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount);
  +-            
  +             if (total_data <= *data_len && total_param <= *param_len)
  +                     break;
  +             
  +@@ -463,6 +550,14 @@
  +                            !(eclass == ERRDOS && ecode == ERRmoredata))
  +                             return(False);
  +             }
  ++            /* parse out the total lengths again - they can shrink! */
  ++            if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data)
  ++                    total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount);
  ++            if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param)
  ++                    total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount);
  ++            
  ++            if (total_data <= *data_len && total_param <= *param_len)
  ++                    break;
  +     }
  +     
  +     return(True);
  +--- samba-2.2.7a/source/smbd/ipc.c   Thu Mar 13 23:16:38 2003
  ++++ samba-2.2.8/source/smbd/ipc.c    Fri Mar 14 22:34:49 2003
  +@@ -368,52 +368,69 @@
  +     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);
  +     START_PROFILE(SMBtrans);
  + 
  +     memset(name, '\0',sizeof(name));
  +     fstrcpy(name,smb_buf(inbuf));
  + 
  +-    if (dscnt > tdscnt || pscnt > tpscnt) {
  +-            exit_server("invalid trans parameters\n");
  +-    }
  ++    if (dscnt > tdscnt || pscnt > tpscnt)
  ++            goto bad_param;
  +   
  +     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));
  +                     END_PROFILE(SMBtrans);
  +                     return(ERROR_DOS(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);
  +                     END_PROFILE(SMBtrans);
  +                     return(ERROR_DOS(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))));
  +-              END_PROFILE(SMBtrans);
  +-              return(ERROR_DOS(ERRDOS,ERRnomem));
  +-        } 
  ++                    DEBUG(0,("reply_trans: setup malloc fail for %u bytes !\n", 
(unsigned int)(suwcnt * sizeof(uint16))));
  ++                    SAFE_FREE(data);
  ++                    SAFE_FREE(params);
  ++                    END_PROFILE(SMBtrans);
  ++                    return(ERROR_DOS(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);
  +     }
  +@@ -425,13 +442,13 @@
  +             outsize = set_message(outbuf,0,0,True);
  +             show_msg(outbuf);
  +             if (!send_smb(smbd_server_fd(),outbuf))
  +-                    exit_server("reply_trans: send_smb failed.\n");
  ++                    exit_server("reply_trans: send_smb failed.");
  +     }
  + 
  +     /* 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);
  + 
  +@@ -451,8 +468,11 @@
  + 
  +             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);
  +@@ -465,18 +485,38 @@
  +             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",
  ++    DEBUG(3,("trans <%s> data=%u params=%u setup=%u\n",
  +              name,tdscnt,tpscnt,suwcnt));
  +     
  +     /*
  +@@ -525,4 +565,14 @@
  +     
  +     END_PROFILE(SMBtrans);
  +     return(outsize);
  ++
  ++
  ++  bad_param:
  ++
  ++    DEBUG(0,("reply_trans: invalid trans parameters\n"));
  ++    SAFE_FREE(data);
  ++    SAFE_FREE(params);
  ++    SAFE_FREE(setup);
  ++    END_PROFILE(SMBtrans);
  ++    return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
  + }
  +--- samba-2.2.7a/source/smbd/nttrans.c       Mon Mar 17 10:55:36 2003
  ++++ samba-2.2.8/source/smbd/nttrans.c        Fri Mar 14 22:34:49 2003
  +@@ -28,7 +28,7 @@
  + extern BOOL case_preserve;
  + extern BOOL short_case_preserve;
  + 
  +-static char *known_nt_pipes[] = {
  ++static const char *known_nt_pipes[] = {
  +   "\\LANMAN",
  +   "\\srvsvc",
  +   "\\samr",
  +@@ -1889,8 +1889,7 @@
  +   if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
  +     DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
  +           CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
  +-    END_PROFILE(SMBnttrans);
  +-    return ERROR_DOS(ERRSRV,ERRerror);
  ++  goto bad_param;
  +   }
  +     
  +   /* Allocate the space for the setup, the maximum needed parameters and data */
  +@@ -1904,9 +1903,9 @@
  +  
  +   if ((total_parameter_count && !params)  || (total_data_count && !data) ||
  +       (setup_count && !setup)) {
  +-    safe_free(setup);
  +-    safe_free(params);
  +-    safe_free(data);
  ++   SAFE_FREE(setup);
  ++   SAFE_FREE(params);
  ++   SAFE_FREE(data);
  +     DEBUG(0,("reply_nttrans : Out of memory\n"));
  +     END_PROFILE(SMBnttrans);
  +     return ERROR_DOS(ERRDOS,ERRnomem);
  +@@ -1918,21 +1917,38 @@
  +   num_data_sofar = data_count;
  + 
  +   if (parameter_count > total_parameter_count || data_count > total_data_count)
  +-    exit_server("reply_nttrans: invalid sizes in packet.");
  ++    goto bad_param;
  + 
  +   if(setup) {
  +-    memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
  +     DEBUG(10,("reply_nttrans: setup_count = %d\n", 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);
  +     dump_data(10, setup, setup_count);
  +   }
  +   if(params) {
  +-    memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
  +     DEBUG(10,("reply_nttrans: parameter_count = %d\n", 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);
  +     dump_data(10, params, parameter_count);
  +   }
  +   if(data) {
  +-    memcpy( data, smb_base(inbuf) + data_offset, data_count);
  +     DEBUG(10,("reply_nttrans: data_count = %d\n",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);
  +     dump_data(10, data, data_count);
  +   }
  + 
  +@@ -1945,6 +1961,8 @@
  + 
  +     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);
  + 
  +@@ -1956,27 +1974,59 @@
  +             DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
  +                      (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
  +     }
  +-        SAFE_FREE(params);
  +-        SAFE_FREE(data);
  +-        SAFE_FREE(setup);
  +-    END_PROFILE(SMBnttrans);
  +-        return ERROR_DOS(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");
  +-
  +-      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);
  +-    }
  +-  }
  ++                    /* Revise total_params and total_data in case they have 
changed downwards */
  ++                    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);
  ++                    }
  ++            }
  ++    }
  + 
  +   if (Protocol >= PROTOCOL_NT1)
  +     SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_IS_LONG_NAME);
  +@@ -2051,4 +2101,12 @@
  +   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);
  ++    END_PROFILE(SMBnttrans);
  ++    return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
  + }
  +--- samba-2.2.7a/source/smbd/trans2.c        Mon Mar 17 10:55:35 2003
  ++++ samba-2.2.8-withoutdeleteonclose/source/smbd/trans2.c    Fri Mar 14 22:34:49 
2003
  +@@ -3202,7 +3186,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;
  +     START_PROFILE(SMBtrans2);
  + 
  +     if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
  +@@ -3241,10 +3225,10 @@
  +                             (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
  +                     DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
  +             } else {
  +-                    DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
  ++                    DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",suwcnt));
  +                     DEBUG(2,("Transaction is %d\n",tran_call));
  +                     END_PROFILE(SMBtrans2);
  +-                    return ERROR_DOS(ERRSRV,ERRerror);
  ++                    ERROR_DOS(ERRDOS,ERRinvalidparam);
  +             }
  +     }
  +     
  +@@ -3270,10 +3254,22 @@
  +     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
  +@@ -3285,6 +3281,10 @@
  +             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);
  +                     
  +@@ -3296,25 +3296,55 @@
  +                             else
  +                                     DEBUG(0,("reply_trans2: %s in getting 
secondary trans2 response.\n",
  +                                              (smb_read_error == READ_ERROR) ? 
"error" : "timeout" ));
  +-                            SAFE_FREE(params);
  +-                            SAFE_FREE(data);
  +-                            END_PROFILE(SMBtrans2);
  +-                            return ERROR_DOS(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);
  ++                    }
  +             }
  +     }
  +     
  +@@ -3427,4 +3457,11 @@
  +     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);
  ++    END_PROFILE(SMBtrans2);
  ++    return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
  + }
  +--- samba-2.2.7a/source/smbd/vfs-wrap.c      Mon Mar 17 10:55:37 2003
  ++++ samba-2.2.8/source/smbd/vfs-wrap.c       Fri Mar 14 22:34:49 2003
  +@@ -213,8 +213,9 @@
  + static int copy_reg(const char *source, const char *dest)
  + {
  +     SMB_STRUCT_STAT source_stats;
  +-    int ifd;
  +-    int ofd;
  ++    int saved_errno;
  ++    int ifd = -1;
  ++    int ofd = -1;
  + 
  +     if (sys_lstat (source, &source_stats) == -1)
  +             return -1;
  +@@ -222,42 +223,44 @@
  +     if (!S_ISREG (source_stats.st_mode))
  +             return -1;
  + 
  +-    if (unlink (dest) && errno != ENOENT)
  +-            return -1;
  +-
  +     if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
  +             return -1;
  + 
  +-    if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 ) {
  +-            int saved_errno = errno;
  +-            close (ifd);
  +-            errno = saved_errno;
  ++    if (unlink (dest) && errno != ENOENT)
  +             return -1;
  +-    }
  + 
  +-    if (transfer_file(ifd, ofd, (size_t)-1) == -1) {
  +-            int saved_errno = errno;
  +-            close (ifd);
  +-            close (ofd);
  +-            unlink (dest);
  +-            errno = saved_errno;
  +-            return -1;
  +-    }
  ++#ifdef O_NOFOLLOW
  ++    if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 
0 )
  ++#else
  ++    if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
  ++#endif
  ++            goto err;
  + 
  +-    if (close (ifd) == -1) {
  +-            int saved_errno = errno;
  +-            close (ofd);
  +-            errno = saved_errno;
  +-            return -1;
  +-    }
  +-    if (close (ofd) == -1) 
  +-            return -1;
  ++    if (transfer_file(ifd, ofd, (size_t)-1) == -1)
  ++            goto err;
  ++
  ++    /*
  ++     * Try to preserve ownership.  For non-root it might fail, but that's ok.
  ++     * But root probably wants to know, e.g. if NFS disallows it.
  ++     */
  ++
  ++    if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != 
EPERM))
  ++            goto err;
  + 
  +     /*
  +-     * chown turns off set[ug]id bits for non-root,
  ++     * fchown turns off set[ug]id bits for non-root,
  +      * so do the chmod last.
  +      */
  + 
  ++    if (fchmod (ofd, source_stats.st_mode & 07777))
  ++            goto err;
  ++
  ++    if (close (ifd) == -1)
  ++            goto err;
  ++
  ++    if (close (ofd) == -1) 
  ++            return -1;
  ++
  +     /* Try to copy the old file's modtime and access time.  */
  +     {
  +             struct utimbuf tv;
  +@@ -267,21 +270,19 @@
  +             utime (dest, &tv);
  +     }
  + 
  +-    /*
  +-     * Try to preserve ownership.  For non-root it might fail, but that's ok.
  +-     * But root probably wants to know, e.g. if NFS disallows it.
  +-     */
  +-
  +-    if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != 
EPERM))
  +-            return -1;
  +-
  +-    if (chmod (dest, source_stats.st_mode & 07777))
  +-            return -1;
  +-
  +     if (unlink (source) == -1)
  +             return -1;
  + 
  +     return 0;
  ++
  ++  err:
  ++    saved_errno = errno;
  ++    if (ifd != -1)
  ++            close(ifd);
  ++    if (ofd != -1)
  ++            close(ofd);
  ++    errno = saved_errno;
  ++    return -1;
  + }
  + 
  + int vfswrap_rename(connection_struct *conn, const char *oldname, const char 
*newname)
  @@ .
  patch -p0 <<'@@ .'
  Index: openpkg-src/samba/samba.spec
  ============================================================================
  $ cvs diff -u -r1.35.2.1.2.1 -r1.35.2.1.2.2 samba.spec
  --- openpkg-src/samba/samba.spec      18 Jan 2003 17:22:36 -0000      1.35.2.1.2.1
  +++ openpkg-src/samba/samba.spec      17 Mar 2003 19:32:17 -0000      1.35.2.1.2.2
  @@ -33,7 +33,7 @@
   Group:        Filesystem
   License:      GPL
   Version:      2.2.7a
  -Release:      1.2.0
  +Release:      1.2.1
   
   #   package options
   %option       with_pam  no
  @@ -43,6 +43,7 @@
   Source1:      smb.conf
   Source2:      smb.hosts
   Source3:      rc.samba
  +Patch0:       samba.patch
   
   #   build information
   Prefix:       %{l_prefix}
  @@ -62,6 +63,7 @@
   
   %prep
       %setup -q
  +    %patch -p1
   
   %build
       ( cd source
  @@ .
______________________________________________________________________
The OpenPKG Project                                    www.openpkg.org
CVS Repository Commit List                     [EMAIL PROTECTED]

Reply via email to