#define DEFAULT_PIPE_TIMEOUT 10000000 /* Ten seconds */
#endif
+/* how long to wait for secondary SMB packets (seconds) */
+#define SMB_SECONDARY_WAIT 30
+
/* debugging code */
#ifndef SYSLOG
#define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(Debug1 body):0)
if (msg_type == 0x85)
{
- DEBUG(5,( "Got keepalive packet\n"));
+ DEBUG(5,("Got keepalive packet\n"));
ok = False;
}
}
****************************************************************************/
BOOL receive_smb(int fd,char *buffer,int timeout)
{
- int len;
- BOOL ok;
+ int len,ret;
bzero(buffer,smb_size + 100);
return(False);
if (len > BUFFER_SIZE) {
- DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
+ DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
exit(1);
}
- ok = (read_data(fd,buffer+4,len) == len);
-
- if (!ok)
- {
- close_sockets();
- exit(1);
- }
+ ret = read_data(fd,buffer+4,len);
+ if (ret != len) {
+ DEBUG(0,("ERROR: Invalid SMB length. Expected %d got %d\n",len,ret));
+ return False;
+ }
return(True);
}
while (pscnt < tpscnt || dscnt < tdscnt)
{
int pcnt,poff,dcnt,doff,pdisp,ddisp;
-
- receive_smb(Client,inbuf, 0);
- show_msg(inbuf);
-
- /* Ensure this is still a trans packet (sanity check) */
- if(CVAL(inbuf, smb_com) != SMBtrans)
+
+ if (!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT*1000) ||
+ CVAL(inbuf, smb_com) != SMBtrans)
{
DEBUG(2,("Invalid secondary trans2 packet\n"));
if (params) free(params);
if (setup) free(setup);
return(ERROR(ERRSRV,ERRerror));
}
+
+ show_msg(inbuf);
tpscnt = SVAL(inbuf,smb_vwv0);
tdscnt = SVAL(inbuf,smb_vwv1);
CVAL(outbuf,0) = 0x81;
send_smb(password_client,outbuf);
- receive_smb(password_client,inbuf,5000);
+
- if (CVAL(inbuf,0) != 0x82) {
+ if (!receive_smb(password_client,inbuf,5000) ||
+ CVAL(inbuf,0) != 0x82) {
DEBUG(1,("%s rejected the session\n",pserver));
close(password_client); password_client = -1;
return(False);
send_smb(Client,outbuf);
/* Now read the raw data into the buffer and write it */
- if(read_smb_length(Client,inbuf,0) == -1) {
+ if (read_smb_length(Client,inbuf,SMB_SECONDARY_WAIT) == -1) {
exit_server("secondary writebraw failed");
}
t = time(NULL);
+ {
+ /* the following bit of code was added to combat smbd
+ looping chewing lots of CPU time. It should never
+ actually be needed, but it seems that some systems
+ don't set error correctly, which is used to distinguish
+ a select() timeout from a read error
+
+ we exit if receive_smb() returns false 3 times in one second.
+ */
+ static int error_count=0;
+ static time_t error_time=0;
+ if (error_count==0) {
+ error_time = t;
+ } else if (error_time != t) {
+ error_count = 0;
+ } else if (error_count++ > 2) {
+ exit_server("looping in process()\n");
+ }
+ }
+
+
/* become root again if waiting */
unbecome_user();
while( num_data_sofar < total_data || num_params_sofar < total_params)
{
- receive_smb(Client,inbuf, 0);
-
- /* Ensure this is still a trans2 packet (sanity check) */
- if(CVAL(inbuf, smb_com) != SMBtranss2)
+ if(!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT*1000) ||
+ CVAL(inbuf, smb_com) != SMBtranss2)
{
outsize = set_message(outbuf,0,0,True);
DEBUG(2,("Invalid secondary trans2 packet\n"));