add packages_10.03.2 in preparation for the 10.03.2 interim release
[10.03/packages.git] / net / samba / patches / 250-writex.patch
1 diff -ruN samba-2.0.10.orig/source/include/smb.h samba-2.0.10/source/include/smb.h
2 --- samba-2.0.10.orig/source/include/smb.h      2006-03-06 22:25:53.000000000 +0100
3 +++ samba-2.0.10/source/include/smb.h   2006-03-06 22:27:31.000000000 +0100
4 @@ -24,8 +24,14 @@
5  #ifndef _SMB_H
6  #define _SMB_H
7  
8 +#if defined(LARGE_SMB_OFF_T)
9 +#define BUFFER_SIZE (128*1024)
10 +#else /* no large readwrite possible */
11  #define BUFFER_SIZE (0xFFFF)
12 +#endif
13 +
14  #define SAFETY_MARGIN 1024
15 +#define LARGE_WRITEX_HDR_SIZE 65
16  
17  #define NMB_PORT 137
18  #define DGRAM_PORT 138
19 diff -ruN samba-2.0.10.orig/source/lib/util_sock.c samba-2.0.10/source/lib/util_sock.c
20 --- samba-2.0.10.orig/source/lib/util_sock.c    2000-03-16 23:59:18.000000000 +0100
21 +++ samba-2.0.10/source/lib/util_sock.c 2006-03-06 22:27:31.000000000 +0100
22 @@ -649,19 +649,21 @@
23    memset(buffer,'\0',smb_size + 100);
24  
25    len = read_smb_length_return_keepalive(fd,buffer,timeout);
26 -  if (len < 0)
27 -  {
28 +       if (len < 0) {
29      DEBUG(10,("receive_smb: length < 0!\n"));
30      return(False);
31    }
32  
33 -  if (len > BUFFER_SIZE) {
34 +       /*
35 +        * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
36 +     * of header. Don't print the error if this fits.... JRA.
37 +        */
38 +
39 +       if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
40      DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
41      if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
42 -    {
43         exit(1);
44      }
45 -  }
46  
47    if(len > 0) {
48      ret = read_socket_data(fd,buffer+4,len);
49 diff -ruN samba-2.0.10.orig/source/smbd/oplock.c samba-2.0.10/source/smbd/oplock.c
50 --- samba-2.0.10.orig/source/smbd/oplock.c      2000-04-25 04:32:14.000000000 +0200
51 +++ samba-2.0.10/source/smbd/oplock.c   2006-03-06 22:27:31.000000000 +0100
52 @@ -887,13 +887,13 @@
53       messages crossing on the wire.
54     */
55  
56 -  if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
57 +  if((inbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL)
58    {
59      DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
60      return False;
61    }
62  
63 -  if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
64 +  if((outbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL)
65    {
66      DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
67      free(inbuf);
68 diff -ruN samba-2.0.10.orig/source/smbd/process.c samba-2.0.10/source/smbd/process.c
69 --- samba-2.0.10.orig/source/smbd/process.c     2006-03-06 22:25:28.000000000 +0100
70 +++ samba-2.0.10/source/smbd/process.c  2006-03-06 22:27:31.000000000 +0100
71 @@ -995,8 +995,8 @@
72    time_t last_timeout_processing_time = time(NULL);
73    unsigned int num_smbs = 0;
74  
75 -  InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
76 -  OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
77 +  InBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
78 +  OutBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
79    if ((InBuffer == NULL) || (OutBuffer == NULL)) 
80      return;
81  
82 @@ -1027,7 +1027,7 @@
83      /* free up temporary memory */
84      lp_talloc_free();
85  
86 -    while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb))
87 +    while(!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout,&got_smb))
88      {
89        if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
90          return;
91 diff -ruN samba-2.0.10.orig/source/smbd/reply.c samba-2.0.10/source/smbd/reply.c
92 --- samba-2.0.10.orig/source/smbd/reply.c       2006-03-06 22:25:53.000000000 +0100
93 +++ samba-2.0.10/source/smbd/reply.c    2006-03-06 22:27:31.000000000 +0100
94 @@ -2551,17 +2551,28 @@
95    size_t numtowrite = SVAL(inbuf,smb_vwv10);
96    BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
97    ssize_t nwritten = -1;
98 -  int smb_doff = SVAL(inbuf,smb_vwv11);
99 +  unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
100 +  unsigned int smblen = smb_len(inbuf);
101    char *data;
102 +  BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
103  
104    /* If it's an IPC, pass off the pipe handler. */
105 -  if (IS_IPC(conn))
106 +  if (IS_IPC(conn)) {
107      return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
108 +  }
109  
110    CHECK_FSP(fsp,conn);
111    CHECK_WRITE(fsp);
112    CHECK_ERROR(fsp);
113  
114 +  /* Deal with possible LARGE_WRITEX */
115 +  if (large_writeX)
116 +    numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
117 +
118 +  if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
119 +    return(ERROR(ERRDOS,ERRbadmem));
120 +  }
121 +
122    data = smb_base(inbuf) + smb_doff;
123  
124    if(CVAL(inbuf,smb_wct) == 14) {
125 @@ -2586,8 +2597,9 @@
126  #endif /* LARGE_SMB_OFF_T */
127    }
128  
129 -  if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
130 +  if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
131      return(ERROR(ERRDOS,ERRlock));
132 +  }
133  
134    /* X/Open SMB protocol says that, unlike SMBwrite
135       if the length is zero then NO truncation is
136 @@ -2598,12 +2610,15 @@
137    else
138      nwritten = write_file(fsp,data,startpos,numtowrite);
139    
140 -  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
141 +  if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
142      return(UNIXERROR(ERRDOS,ERRnoaccess));
143 +  }
144  
145    set_message(outbuf,6,0,True);
146    
147    SSVAL(outbuf,smb_vwv2,nwritten);
148 +  if (large_writeX)
149 +    SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
150    
151    if (nwritten < (ssize_t)numtowrite) {
152      CVAL(outbuf,smb_rcls) = ERRHRD;