From 1c7a60ef41d76526384d6b9e4ba03d3df251fe06 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 May 2010 15:39:21 -0700 Subject: Fix cancel by close lock test. Jeremy. --- source3/smbd/smb2_lock.c | 60 +++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 24 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 63e43fa832..b106c5fad1 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -3,6 +3,7 @@ Core SMB2 server Copyright (C) Stefan Metzmacher 2009 + Copyright (C) Jeremy Allison 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,6 +30,16 @@ struct smbd_smb2_lock_element { uint32_t flags; }; +struct smbd_smb2_lock_state { + struct smbd_smb2_request *smb2req; + struct smb_request *smb1req; + struct blocking_lock_record *blr; + uint16_t lock_count; + struct smbd_lock_element *locks; +}; + +static void remove_pending_lock(TALLOC_CTX *mem_ctx, struct blocking_lock_record *blr); + static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbd_smb2_request *smb2req, @@ -130,22 +141,32 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req) static void smbd_smb2_request_lock_done(struct tevent_req *subreq) { - struct smbd_smb2_request *req = tevent_req_callback_data(subreq, + struct smbd_smb2_request *smb2req = tevent_req_callback_data(subreq, struct smbd_smb2_request); DATA_BLOB outbody; NTSTATUS status; NTSTATUS error; /* transport error */ - if (req->cancelled) { + if (smb2req->cancelled) { const uint8_t *inhdr = (const uint8_t *) - req->in.vector[req->current_idx].iov_base; + smb2req->in.vector[smb2req->current_idx].iov_base; uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID); + struct smbd_smb2_lock_state *state; DEBUG(10,("smbd_smb2_request_lock_done: cancelled mid %llu\n", (unsigned long long)mid )); - error = smbd_smb2_request_error(req, NT_STATUS_CANCELLED); + + state = tevent_req_data(smb2req->subreq, + struct smbd_smb2_lock_state); + + SMB_ASSERT(state); + SMB_ASSERT(state->blr); + + remove_pending_lock(state, state->blr); + + error = smbd_smb2_request_error(smb2req, NT_STATUS_CANCELLED); if (!NT_STATUS_IS_OK(error)) { - smbd_server_connection_terminate(req->sconn, + smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } @@ -155,20 +176,20 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq) status = smbd_smb2_lock_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - error = smbd_smb2_request_error(req, status); + error = smbd_smb2_request_error(smb2req, status); if (!NT_STATUS_IS_OK(error)) { - smbd_server_connection_terminate(req->sconn, + smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } return; } - outbody = data_blob_talloc(req->out.vector, NULL, 0x04); + outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x04); if (outbody.data == NULL) { - error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); + error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { - smbd_server_connection_terminate(req->sconn, + smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } @@ -178,22 +199,14 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq) SSVAL(outbody.data, 0x00, 0x04); /* struct size */ SSVAL(outbody.data, 0x02, 0); /* reserved */ - error = smbd_smb2_request_done(req, outbody, NULL); + error = smbd_smb2_request_done(smb2req, outbody, NULL); if (!NT_STATUS_IS_OK(error)) { - smbd_server_connection_terminate(req->sconn, + smbd_server_connection_terminate(smb2req->sconn, nt_errstr(error)); return; } } -struct smbd_smb2_lock_state { - struct smbd_smb2_request *smb2req; - struct smb_request *smb1req; - struct blocking_lock_record *blr; - uint16_t lock_count; - struct smbd_lock_element *locks; -}; - static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct smbd_smb2_request *smb2req, @@ -853,7 +866,7 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp, } inhdr = (const uint8_t *)smb2req->in.vector[i].iov_base; - if (IVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_LOCK) { + if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_LOCK) { /* Not a lock call. */ continue; } @@ -890,8 +903,7 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp, blr->lock_flav, blr); - /* Finally cancel the request. */ - smb2req->cancelled = true; - tevent_req_cancel(smb2req->subreq); + /* Finally end the request. */ + tevent_req_nterror(smb2req->subreq, NT_STATUS_RANGE_NOT_LOCKED); } } -- cgit