summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h7
-rw-r--r--source3/lib/dummysmbd.c4
-rw-r--r--source3/locking/locking.c5
-rw-r--r--source3/smbd/blocking.c8
-rw-r--r--source3/smbd/close.c2
-rw-r--r--source3/smbd/globals.h3
-rw-r--r--source3/smbd/smb2_lock.c10
-rw-r--r--source3/smbd/smb2_server.c8
8 files changed, 36 insertions, 11 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e16cae5b2b7..f05f76b9615 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 a41e6dc033a..01a55633068 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 63bcff17acb..dc43f9e182f 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 e78d80777e0..942237b812f 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 098edacb6d5..20fe9e46f1f 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 34f8796963c..6543ee6f24c 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 b106c5fad10..9c8964abb8e 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 243dd40c31a..d8e6ba10a3e 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);