summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/libsmb/smb_signing.c41
-rw-r--r--source3/smbd/open.c6
-rw-r--r--source3/smbd/oplock.c4
3 files changed, 46 insertions, 5 deletions
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
@@ -84,6 +84,22 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
}
/***********************************************************
+ 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
************************************************************/
@@ -654,6 +670,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);