From: Stefan Metzmacher Date: Mon, 19 Aug 2019 10:04:43 +0000 (+0200) Subject: s3:blocking: maintain state->deny_status X-Git-Tag: talloc-2.3.1~968 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aba0ee46258f3dd910421facb742fce3318a6946;p=thirdparty%2Fsamba.git 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 Reviewed-by: Volker Lendecke --- 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);