summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/smbd/ipc.c16
-rw-r--r--source3/smbd/reply.c9
-rw-r--r--source3/smbd/server.c26
-rw-r--r--source3/smbd/trans2.c16
5 files changed, 61 insertions, 9 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index fceb83b282..9624116f82 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -172,7 +172,7 @@ struct in_addr *iface_ip(struct in_addr ip);
/*The following definitions come from ipc.c */
int get_printerdrivernumber(int snum);
-int reply_trans(char *inbuf,char *outbuf);
+int reply_trans(char *inbuf,char *outbuf, int size, int bufsize);
/*The following definitions come from kanji.c */
@@ -1071,6 +1071,7 @@ int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int
BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval);
BOOL request_oplock_break(share_mode_entry *share_entry,
uint32 dev, uint32 inode);
+BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout);
BOOL snum_used(int snum);
BOOL reload_services(BOOL test);
int setup_groups(char *user, int uid, int gid, int *p_ngroups,
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 741290d2a2..c862ff3b38 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -62,6 +62,8 @@ extern fstring myworkgroup;
#define QNLEN 12 /* queue name maximum length */
extern int Client;
+extern int oplock_sock;
+extern int smb_read_error;
static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
@@ -3203,7 +3205,7 @@ static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name,
/****************************************************************************
reply to a SMBtrans
****************************************************************************/
-int reply_trans(char *inbuf,char *outbuf)
+int reply_trans(char *inbuf,char *outbuf, int size, int bufsize)
{
fstring name;
@@ -3266,12 +3268,18 @@ int reply_trans(char *inbuf,char *outbuf)
/* receive the rest of the trans packet */
while (pscnt < tpscnt || dscnt < tdscnt)
{
+ BOOL ret;
int pcnt,poff,dcnt,doff,pdisp,ddisp;
- if (!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
- CVAL(inbuf, smb_com) != SMBtrans)
+ ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+ if ((ret && (CVAL(inbuf, smb_com) != SMBtrans)) || !ret)
{
- DEBUG(2,("Invalid secondary trans2 packet\n"));
+ if(ret)
+ DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
+ else
+ DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
+ (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
if (params) free(params);
if (data) free(data);
if (setup) free(setup);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 78dad6f02f..0d5f016613 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -3495,7 +3495,14 @@ dev = %x, inode = %x\n",
/* if this is a pure oplock break request then don't send a reply */
if (num_locks == 0 && num_ulocks == 0)
- return -1;
+ {
+ /* Sanity check - ensure a pure oplock break is not a
+ chained request. */
+ if(CVAL(inbuf,smb_vwv0) != 0xff)
+ DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
+ (unsigned int)CVAL(inbuf,smb_vwv0) ));
+ return -1;
+ }
}
/* Data now points at the beginning of the list
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index d51c43c2f7..3f4f6c7034 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -3087,6 +3087,32 @@ oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
}
/****************************************************************************
+Get the next SMB packet, doing the local message processing automatically.
+****************************************************************************/
+
+BOOL receive_next_smb(int smbfd, int oplockfd, char *inbuf, int bufsize, int timeout)
+{
+ BOOL got_smb = False;
+ BOOL ret;
+
+ do
+ {
+ ret = receive_message_or_smb(smbfd,oplockfd,inbuf,bufsize,
+ timeout,&got_smb);
+
+ if(ret && !got_smb)
+ {
+ /* Deal with oplock break requests from other smbd's. */
+ process_local_message(oplock_sock, inbuf, bufsize);
+ continue;
+ }
+ }
+ while(ret && !got_smb);
+
+ return ret;
+}
+
+/****************************************************************************
check if a snum is in use
****************************************************************************/
BOOL snum_used(int snum)
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 6a7fc292fa..0ca678b768 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -30,6 +30,8 @@ extern connection_struct Connections[];
extern files_struct Files[];
extern BOOL case_sensitive;
extern int Client;
+extern int oplock_sock;
+extern int smb_read_error;
/****************************************************************************
Send the required number of replies back.
@@ -1702,11 +1704,19 @@ int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
while( num_data_sofar < total_data || num_params_sofar < total_params)
{
- if(!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
- CVAL(inbuf, smb_com) != SMBtranss2)
+ BOOL ret;
+
+ ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,
+ SMB_SECONDARY_WAIT);
+
+ if((ret && (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret)
{
outsize = set_message(outbuf,0,0,True);
- DEBUG(2,("Invalid secondary trans2 packet\n"));
+ if(ret)
+ DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
+ else
+ DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
+ (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
free(params);
free(data);
return(ERROR(ERRSRV,ERRerror));