+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:53.000000000 +0100
++++ samba-2.0.10/source/include/smb.h 2006-03-06 22:27:31.000000000 +0100
+@@ -24,8 +24,14 @@
+ #ifndef _SMB_H
+ #define _SMB_H
+
++#if defined(LARGE_SMB_OFF_T)
++#define BUFFER_SIZE (128*1024)
++#else /* no large readwrite possible */
+ #define BUFFER_SIZE (0xFFFF)
++#endif
++
+ #define SAFETY_MARGIN 1024
++#define LARGE_WRITEX_HDR_SIZE 65
+
+ #define NMB_PORT 137
+ #define DGRAM_PORT 138
+diff -ruN samba-2.0.10.orig/source/lib/util_sock.c samba-2.0.10/source/lib/util_sock.c
+--- samba-2.0.10.orig/source/lib/util_sock.c 2000-03-16 23:59:18.000000000 +0100
++++ samba-2.0.10/source/lib/util_sock.c 2006-03-06 22:27:31.000000000 +0100
+@@ -649,19 +649,21 @@
+ memset(buffer,'\0',smb_size + 100);
+
+ len = read_smb_length_return_keepalive(fd,buffer,timeout);
+- if (len < 0)
+- {
++ if (len < 0) {
+ DEBUG(10,("receive_smb: length < 0!\n"));
+ return(False);
+ }
+
+- if (len > BUFFER_SIZE) {
++ /*
++ * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
++ * of header. Don't print the error if this fits.... JRA.
++ */
++
++ if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
+ DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
+ if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
+- {
+ exit(1);
+ }
+- }
+
+ if(len > 0) {
+ ret = read_socket_data(fd,buffer+4,len);
+diff -ruN samba-2.0.10.orig/source/smbd/oplock.c samba-2.0.10/source/smbd/oplock.c
+--- samba-2.0.10.orig/source/smbd/oplock.c 2000-04-25 04:32:14.000000000 +0200
++++ samba-2.0.10/source/smbd/oplock.c 2006-03-06 22:27:31.000000000 +0100
+@@ -887,13 +887,13 @@
+ messages crossing on the wire.
+ */
+
+- if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
++ if((inbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL)
+ {
+ DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
+ return False;
+ }
+
+- if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
++ if((outbuf = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN))==NULL)
+ {
+ DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
+ free(inbuf);
+diff -ruN samba-2.0.10.orig/source/smbd/process.c samba-2.0.10/source/smbd/process.c
+--- samba-2.0.10.orig/source/smbd/process.c 2006-03-06 22:25:28.000000000 +0100
++++ samba-2.0.10/source/smbd/process.c 2006-03-06 22:27:31.000000000 +0100
+@@ -995,8 +995,8 @@
+ time_t last_timeout_processing_time = time(NULL);
+ unsigned int num_smbs = 0;
+
+- InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+- OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
++ InBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
++ OutBuffer = (char *)malloc(BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
+ if ((InBuffer == NULL) || (OutBuffer == NULL))
+ return;
+
+@@ -1027,7 +1027,7 @@
+ /* free up temporary memory */
+ lp_talloc_free();
+
+- while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb))
++ while(!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout,&got_smb))
+ {
+ if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+ return;
+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:53.000000000 +0100
++++ samba-2.0.10/source/smbd/reply.c 2006-03-06 22:27:31.000000000 +0100
+@@ -2551,17 +2551,28 @@
+ size_t numtowrite = SVAL(inbuf,smb_vwv10);
+ BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
+ ssize_t nwritten = -1;
+- int smb_doff = SVAL(inbuf,smb_vwv11);
++ unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
++ unsigned int smblen = smb_len(inbuf);
+ char *data;
++ BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
+
+ /* If it's an IPC, pass off the pipe handler. */
+- if (IS_IPC(conn))
++ if (IS_IPC(conn)) {
+ return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
++ }
+
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
+ CHECK_ERROR(fsp);
+
++ /* Deal with possible LARGE_WRITEX */
++ if (large_writeX)
++ numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
++
++ if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
++ return(ERROR(ERRDOS,ERRbadmem));
++ }
++
+ data = smb_base(inbuf) + smb_doff;
+
+ if(CVAL(inbuf,smb_wct) == 14) {
+@@ -2586,8 +2597,9 @@
+ #endif /* LARGE_SMB_OFF_T */
+ }
+
+- if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
++ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ return(ERROR(ERRDOS,ERRlock));
++ }
+
+ /* X/Open SMB protocol says that, unlike SMBwrite
+ if the length is zero then NO truncation is
+@@ -2598,12 +2610,15 @@
+ else
+ nwritten = write_file(fsp,data,startpos,numtowrite);
+
+- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
++ if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
++ }
+
+ set_message(outbuf,6,0,True);
+
+ SSVAL(outbuf,smb_vwv2,nwritten);
++ if (large_writeX)
++ SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
+
+ if (nwritten < (ssize_t)numtowrite) {
+ CVAL(outbuf,smb_rcls) = ERRHRD;