srv_cancel_sign_response(xconn);
remove_pending_change_notify_requests_by_mid(sconn, req->mid);
remove_pending_lock_requests_by_mid_smb1(sconn, req->mid);
+ cancel_deferred_open_message_smb(xconn, req->mid);
DEBUG(3,("reply_ntcancel: cancel called on mid = %llu.\n",
(unsigned long long)req->mid));
struct deferred_open_record {
bool delayed_for_oplocks;
bool async_open;
+ bool cancelled;
struct file_id id;
/*
return rec->async_open;
}
+bool cancel_open_async(struct deferred_open_record *rec)
+{
+ if (rec->cancelled) {
+ return false;
+ }
+
+ if (is_deferred_open_async(rec)) {
+ /* Can't cancel an async create. */
+ return false;
+ }
+
+ rec->cancelled = true;
+ return true;
+}
+
static bool clear_ads(uint32_t create_disposition)
{
bool ret = false;
/* Ensure we don't reprocess this message. */
remove_deferred_open_message_smb(req->xconn, req->mid);
+ if (open_rec->cancelled) {
+ return NT_STATUS_CANCELLED;
+ }
+
first_open_attempt = false;
}
}
return false;
}
+/****************************************************************************
+ Function to cancel a sharing violation open message by mid.
+****************************************************************************/
+
+void cancel_deferred_open_message_smb(struct smbXsrv_connection *xconn,
+ uint64_t mid)
+{
+ struct smbd_server_connection *sconn = xconn->client->sconn;
+ struct pending_message_list *pml;
+ int i = 0;
+
+ if (sconn->using_smb2) {
+ return;
+ }
+
+ for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
+ uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
+ struct tevent_timer *te = NULL;
+ bool ok;
+
+ DBG_DEBUG("[%d] msg_mid = %llu\n",
+ i++, (unsigned long long)msg_mid);
+
+ if (mid != msg_mid) {
+ continue;
+ }
+
+ if (pml->processed) {
+ /* A processed message should not be
+ * rescheduled. */
+ DBG_WARNING("LOGIC ERROR message mid %llu was "
+ "already processed\n",
+ (unsigned long long)msg_mid);
+ return;
+ }
+
+ ok = cancel_open_async(pml->open_rec);
+ if (!ok) {
+ DBG_DEBUG("Request not cancelable, "
+ "skipping mid %llu\n",
+ (unsigned long long)msg_mid);
+ return;
+ }
+
+ DBG_DEBUG("canceling deferred open mid %llu\n",
+ (unsigned long long)mid);
+
+ te = tevent_add_timer(pml->sconn->ev_ctx,
+ pml,
+ timeval_zero(),
+ smbd_deferred_open_timer,
+ pml);
+ if (te == NULL) {
+ DBG_ERR("tevent_add_timer() failed, "
+ "skipping mid %llu\n",
+ (unsigned long long)msg_mid);
+ return;
+ }
+
+ TALLOC_FREE(pml->te);
+ pml->te = te;
+ DLIST_PROMOTE(sconn->deferred_open_queue, pml);
+ return;
+ }
+
+ DBG_DEBUG("failed to find message mid %llu\n",
+ (unsigned long long)mid);
+ return;
+}
+
/****************************************************************************
Return true if this mid is on the deferred queue and was not yet processed.
****************************************************************************/
uint16_t break_to);
struct deferred_open_record;
bool is_deferred_open_async(const struct deferred_open_record *rec);
+bool cancel_open_async(struct deferred_open_record *rec);
NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
struct smb_filename *smb_dname);
void msg_file_was_renamed(struct messaging_context *msg,
uint64_t mid);
bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
uint64_t mid);
+void cancel_deferred_open_message_smb(struct smbXsrv_connection *xconn,
+ uint64_t mid);
bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid);
bool get_deferred_open_message_state(struct smb_request *smbreq,
struct timeval *p_request_time,