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
************************************************************/
}
}
+/***********************************************************
+ 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.
************************************************************/
} 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;
#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);
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);
/* 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);