From 3bbe9c0869ea8653f684afa9a1345f6fa2f80b4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Aug 2003 05:36:08 +0000 Subject: An oplock break reply from the client causes the sequence number to be updated by 2 if there is no open reply outstanding, else by one.... Yes - this makes no sense.... Jeremy. (This used to be commit b43ce1ff6109f6422a621329ceb713b42df40040) --- source3/libsmb/smb_signing.c | 41 ++++++++++++++++++++++++++++++++++++++++- source3/smbd/open.c | 6 ++++++ source3/smbd/oplock.c | 4 ---- 3 files changed, 46 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4b12f36eba..afacfc7a93 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -83,6 +83,22 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return False; } +/*********************************************************** + A reply is pending if there is a non-deferred packet on the queue. +************************************************************/ + +static BOOL is_reply_pending(struct outstanding_packet_lookup *list) +{ + for (; list; list = list->next) { + if (!list->deferred_packet) { + DEBUG(10,("is_reply_pending: True.\n")); + return True; + } + } + DEBUG(10,("is_reply_pending: False.\n")); + return False; +} + /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ @@ -653,6 +669,22 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) } } +/*********************************************************** + Is an incoming packet an oplock break reply ? +************************************************************/ + +static BOOL is_oplock_break(char *inbuf) +{ + if (CVAL(inbuf,smb_com) != SMBlockingX) + return False; + + if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) + return False; + + DEBUG(10,("is_oplock_break: Packet is oplock break\n")); + return True; +} + /*********************************************************** SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ @@ -684,6 +716,13 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { /* We always increment the sequence number. */ data->send_seq_num++; + + /* If we get an asynchronous oplock break reply and there + * isn't a reply pending we need to re-sync the sequence + * number. + */ + if (is_oplock_break(inbuf) && !is_reply_pending(data->outstanding_packet_list)) + data->send_seq_num++; } saved_seq = reply_seq_number; @@ -718,7 +757,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) #endif /* JRATEST */ } else { - DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 5f49640aa4..2c9d3290d8 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -626,6 +626,12 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode)); + /* Ensure the reply for the open uses the correct sequence number. */ + /* This isn't a real deferred packet as it's response will also increment + * the sequence. + */ + srv_defer_sign_response(get_current_mid(), False); + /* Oplock break - unlock to request it. */ unlock_share_entry(conn, dev, inode); diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 49a1b7d8cf..19e6956d9e 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -743,10 +743,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, /* Remember if we just sent a break to level II on this file. */ fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT; - /* Ensure the reply for the open uses the correct sequence number. */ - /* This isn't a real deferred packet as it's response will also increment - * the sequence. */ - srv_defer_sign_response(get_current_mid(), False); /* Save the server smb signing state. */ sign_state = srv_oplock_set_signing(False); -- cgit