uint32_t retry_msecs;
uint16_t lock_count;
struct smbd_lock_element *locks;
+ uint8_t lock_sequence_value;
+ uint8_t *lock_sequence_element;
};
static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
}
}
+static void smbd_smb2_lock_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state);
static void smbd_smb2_lock_try(struct tevent_req *req);
static void smbd_smb2_lock_retry(struct tevent_req *subreq);
static bool smbd_smb2_lock_cancel(struct tevent_req *req);
uint16_t i;
struct smbd_lock_element *locks;
NTSTATUS status;
+ bool check_lock_sequence = false;
+ uint32_t lock_sequence_bucket = 0;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_lock_state);
state->smb2req = smb2req;
smb2req->subreq = req; /* So we can find this when going async. */
+ tevent_req_set_cleanup_fn(req, smbd_smb2_lock_cleanup);
+
state->smb1req = smbd_smb2_fake_smb_request(smb2req);
if (tevent_req_nomem(state->smb1req, req)) {
return tevent_req_post(req, ev);
DEBUG(10,("smbd_smb2_lock_send: %s - %s\n",
fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
+ /*
+ * TODO: Windows sets check_lock_sequence = true
+ * only for resilient and persistent handles
+ *
+ * What about other handles using multi-channel?
+ */
+ if (check_lock_sequence) {
+ state->lock_sequence_value = in_lock_sequence & 0xF;
+ lock_sequence_bucket = in_lock_sequence >> 4;
+ }
+ if ((lock_sequence_bucket > 0) &&
+ (lock_sequence_bucket <= sizeof(fsp->op->global->lock_sequence_array)))
+ {
+ uint32_t idx = lock_sequence_bucket - 1;
+ uint8_t *array = fsp->op->global->lock_sequence_array;
+
+ state->lock_sequence_element = &array[idx];
+ }
+
+ if (state->lock_sequence_element != NULL) {
+ if (*state->lock_sequence_element == state->lock_sequence_value)
+ {
+ DBG_INFO("replayed smb2 lock request detected: "
+ "file %s, value %u, bucket %u\n",
+ fsp_str_dbg(fsp),
+ (unsigned)state->lock_sequence_value,
+ (unsigned)lock_sequence_bucket);
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ }
+ *state->lock_sequence_element = 0xFF;
+ }
+
locks = talloc_array(state, struct smbd_lock_element, in_lock_count);
if (locks == NULL) {
tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return req;
}
+static void smbd_smb2_lock_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state)
+{
+ struct smbd_smb2_lock_state *state = tevent_req_data(
+ req, struct smbd_smb2_lock_state);
+
+ if (req_state != TEVENT_REQ_DONE) {
+ return;
+ }
+
+ if (state->lock_sequence_element != NULL) {
+ *state->lock_sequence_element = state->lock_sequence_value;
+ }
+}
+
static void smbd_smb2_lock_update_retry_msecs(
struct smbd_smb2_lock_state *state)
{