#define BUFFER_SIZE (0xFFFF)
#define SAFETY_MARGIN 1024
+#define LARGE_WRITEX_HDR_SIZE 65
#define NMB_PORT 137
#define DGRAM_PORT 138
BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
{
- ssize_t len,ret;
+ ssize_t len,ret;
- smb_read_error = 0;
+ smb_read_error = 0;
- memset(buffer,'\0',smb_size + 100);
+ memset(buffer,'\0',smb_size + 100);
- len = read_smb_length_return_keepalive(fd,buffer,timeout);
- if (len < 0)
- {
- DEBUG(10,("receive_smb: length < 0!\n"));
- return(False);
- }
+ len = read_smb_length_return_keepalive(fd,buffer,timeout);
+ if (len < 0) {
+ DEBUG(10,("receive_smb: length < 0!\n"));
+ return(False);
+ }
- if (len > BUFFER_SIZE) {
- DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
- if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
- {
- exit(1);
- }
- }
+ /*
+ * 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 > 0) {
- ret = read_socket_data(fd,buffer+4,len);
- if (ret != len) {
- smb_read_error = READ_ERROR;
- return False;
- }
- }
- return(True);
+ 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);
+ if (ret != len) {
+ smb_read_error = READ_ERROR;
+ return False;
+ }
+ }
+
+ return(True);
}
/****************************************************************************
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);
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;
lp_talloc_free();
main_loop_talloc_free();
- while (!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout)) {
+ while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
return;
num_smbs = 0; /* Reset smb counter. */
{
files_struct *fsp = file_fsp(inbuf,smb_vwv2);
SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
- size_t numtowrite = SVAL(inbuf,smb_vwv10);
+ size_t numtowrite = SVAL(inbuf,smb_vwv10)|(((size_t)SVAL(inbuf,smb_vwv9))<<16);
BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
ssize_t nwritten = -1;
unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
+ unsigned int smblen = smb_len(inbuf);
char *data;
START_PROFILE(SMBwriteX);
CHECK_WRITE(fsp);
CHECK_ERROR(fsp);
- if(smb_doff > smb_len(inbuf)) {
+ if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
END_PROFILE(SMBwriteX);
return(ERROR(ERRDOS,ERRbadmem));
}