summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2019-08-19 12:04:43 +0200
committerStefan Metzmacher <metze@samba.org>2019-09-09 16:04:29 +0000
commitb56bb2ac59dd190cdf3c726a7becf2ae9d296657 (patch)
treeb9bdc28bed7c7e904a56f6f122c5a3e1c09e345f
parent85b9b5f04fdf7fa432f7260b27f77342f27dddbb (diff)
downloadsamba-b56bb2ac59dd190cdf3c726a7becf2ae9d296657.tar.gz
s3:blocking: maintain state->deny_status
For Windows locks we start with LOCK_NOT_GRANTED and use FILE_LOCK_CONFLICT if we retried after a timeout. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org> (cherry picked from commit aba0ee46258f3dd910421facb742fce3318a6946)
-rw-r--r--selftest/knownfail.d/samba3posixtimedlock1
-rw-r--r--source3/smbd/blocking.c33
2 files changed, 28 insertions, 6 deletions
diff --git a/selftest/knownfail.d/samba3posixtimedlock b/selftest/knownfail.d/samba3posixtimedlock
deleted file mode 100644
index 56d2d349e1e..00000000000
--- a/selftest/knownfail.d/samba3posixtimedlock
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.raw.samba3posixtimedlock.samba3posixtimedlock
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 50e1d436eb7..a87d62d910a 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -109,6 +109,7 @@ struct smbd_smb1_do_locks_state {
uint16_t num_locks;
struct smbd_lock_element *locks;
uint16_t blocker;
+ NTSTATUS deny_status;
};
static void smbd_smb1_do_locks_try(struct tevent_req *req);
@@ -176,6 +177,16 @@ struct tevent_req *smbd_smb1_do_locks_send(
state->num_locks = num_locks;
state->locks = locks;
+ if (lock_flav == POSIX_LOCK) {
+ /*
+ * SMB1 posix locks always use
+ * NT_STATUS_FILE_LOCK_CONFLICT.
+ */
+ state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT;
+ } else {
+ state->deny_status = NT_STATUS_LOCK_NOT_GRANTED;
+ }
+
DBG_DEBUG("state=%p, state->smbreq=%p\n", state, state->smbreq);
if (num_locks == 0) {
@@ -245,10 +256,19 @@ struct tevent_req *smbd_smb1_do_locks_send(
state->timeout,
blocking_smblctx);
+ /*
+ * If the endtime is not elapsed yet,
+ * it means we'll retry after a timeout.
+ * In that case we'll have to return
+ * NT_STATUS_FILE_LOCK_CONFLICT
+ * instead of NT_STATUS_LOCK_NOT_GRANTED.
+ */
if (state->timeout == 0) {
+ status = state->deny_status;
tevent_req_nterror(req, status);
goto done;
}
+ state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT;
subreq = dbwrap_watched_watch_send(
state, state->ev, lck->data->record, blocking_pid);
@@ -379,16 +399,19 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req)
* Otherwise keep waiting either waiting
* for changes in locking.tdb or the polling
* mode timers waiting for posix locks.
+ *
+ * If the endtime is not expired yet,
+ * it means we'll retry after a timeout.
+ * In that case we'll have to return
+ * NT_STATUS_FILE_LOCK_CONFLICT
+ * instead of NT_STATUS_LOCK_NOT_GRANTED.
*/
elapsed = timeval_elapsed(&state->endtime);
if (elapsed > 0) {
- /*
- * On timeout we always return
- * NT_STATUS_FILE_LOCK_CONFLICT
- */
- status = NT_STATUS_FILE_LOCK_CONFLICT;
+ status = state->deny_status;
goto done;
}
+ state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT;
subreq = dbwrap_watched_watch_send(
state, state->ev, lck->data->record, blocking_pid);