diff options
-rw-r--r-- | source3/include/proto.h | 7 | ||||
-rw-r--r-- | source3/lib/dummysmbd.c | 4 | ||||
-rw-r--r-- | source3/locking/locking.c | 5 | ||||
-rw-r--r-- | source3/smbd/blocking.c | 8 | ||||
-rw-r--r-- | source3/smbd/close.c | 2 | ||||
-rw-r--r-- | source3/smbd/globals.h | 3 | ||||
-rw-r--r-- | source3/smbd/smb2_lock.c | 10 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 8 |
8 files changed, 36 insertions, 11 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index e16cae5b2b..f05f76b961 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3473,7 +3473,8 @@ NTSTATUS do_lock_cancel(files_struct *fsp, enum brl_flavour lock_flav, struct blocking_lock_record *blr); void locking_close_file(struct messaging_context *msg_ctx, - files_struct *fsp); + files_struct *fsp, + enum file_close_type close_type); bool locking_init(void); bool locking_init_readonly(void); bool locking_end(void); @@ -6002,7 +6003,9 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, uint64_t offset, uint64_t count, uint32 blocking_pid); -void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck); +void cancel_pending_lock_requests_by_fid(files_struct *fsp, + struct byte_range_lock *br_lck, + enum file_close_type close_type); void remove_pending_lock_requests_by_mid_smb1(uint64_t mid); bool blocking_lock_was_deferred_smb1(uint64_t mid); struct blocking_lock_record *blocking_lock_cancel_smb1(files_struct *fsp, diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c index a41e6dc033..01a5563306 100644 --- a/source3/lib/dummysmbd.c +++ b/source3/lib/dummysmbd.c @@ -38,7 +38,9 @@ bool conn_snum_used(int snum) return False; } -void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck) +void cancel_pending_lock_requests_by_fid(files_struct *fsp, + struct byte_range_lock *br_lck, + enum file_close_type close_type) { } diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 63bcff17ac..dc43f9e182 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -396,7 +396,8 @@ NTSTATUS do_lock_cancel(files_struct *fsp, ****************************************************************************/ void locking_close_file(struct messaging_context *msg_ctx, - files_struct *fsp) + files_struct *fsp, + enum file_close_type close_type) { struct byte_range_lock *br_lck; @@ -415,7 +416,7 @@ void locking_close_file(struct messaging_context *msg_ctx, br_lck = brl_get_locks(talloc_tos(),fsp); if (br_lck) { - cancel_pending_lock_requests_by_fid(fsp, br_lck); + cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type); brl_close_fnum(msg_ctx, br_lck); TALLOC_FREE(br_lck); } diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index e78d80777e..942237b812 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -571,13 +571,17 @@ static bool blocking_lock_record_process(struct blocking_lock_record *blr) Called when a file is closed. *****************************************************************************/ -void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck) +void cancel_pending_lock_requests_by_fid(files_struct *fsp, + struct byte_range_lock *br_lck, + enum file_close_type close_type) { struct smbd_server_connection *sconn = smbd_server_conn; struct blocking_lock_record *blr, *blr_cancelled, *next = NULL; if (sconn->allow_smb2) { - cancel_pending_lock_requests_by_fid_smb2(fsp, br_lck); + cancel_pending_lock_requests_by_fid_smb2(fsp, + br_lck, + close_type); return; } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 098edacb6d..20fe9e46f1 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -623,7 +623,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, status = ntstatus_keeperror(status, tmp); } - locking_close_file(smbd_messaging_context(), fsp); + locking_close_file(smbd_messaging_context(), fsp, close_type); tmp = fd_close(fsp); status = ntstatus_keeperror(status, tmp); diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 34f8796963..6543ee6f24 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -320,7 +320,8 @@ bool push_blocking_lock_request_smb2( struct byte_range_lock *br_lck, uint32_t blocking_pid); void process_blocking_lock_queue_smb2(struct timeval tv_curr); void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp, - struct byte_range_lock *br_lck); + struct byte_range_lock *br_lck, + enum file_close_type close_type); /* From smbd/smb2_create.c */ int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level); uint8_t map_samba_oplock_levels_to_smb2(int oplock_type); diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index b106c5fad1..9c8964abb8 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -840,7 +840,8 @@ void process_blocking_lock_queue_smb2(struct timeval tv_curr) ****************************************************************************/ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp, - struct byte_range_lock *br_lck) + struct byte_range_lock *br_lck, + enum file_close_type close_type) { struct smbd_server_connection *sconn = smbd_server_conn; struct smbd_smb2_request *smb2req, *nextreq; @@ -904,6 +905,11 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp, blr); /* Finally end the request. */ - tevent_req_nterror(smb2req->subreq, NT_STATUS_RANGE_NOT_LOCKED); + if (close_type == SHUTDOWN_CLOSE) { + tevent_req_done(smb2req->subreq); + } else { + tevent_req_nterror(smb2req->subreq, + NT_STATUS_RANGE_NOT_LOCKED); + } } } diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 243dd40c31..d8e6ba10a3 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1097,10 +1097,18 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) case SMB2_OP_LOCK: if (!NT_STATUS_IS_OK(session_status)) { + /* Too ugly to live ? JRA. */ + if (NT_STATUS_EQUAL(session_status,NT_STATUS_USER_SESSION_DELETED)) { + session_status = NT_STATUS_FILE_CLOSED; + } return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { + /* Too ugly to live ? JRA. */ + if (NT_STATUS_EQUAL(status,NT_STATUS_NETWORK_NAME_DELETED)) { + status = NT_STATUS_FILE_CLOSED; + } return smbd_smb2_request_error(req, status); } return smbd_smb2_request_process_lock(req); |