From: Ralph Boehme Date: Sat, 14 Sep 2024 17:19:51 +0000 (+0200) Subject: smbd: use delay_for_handle_lease_break_send() for initial delete on close X-Git-Tag: tdb-1.4.13~741 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e13780a8fc48ae8eeda9b14fe72e828166edb3d;p=thirdparty%2Fsamba.git smbd: use delay_for_handle_lease_break_send() for initial delete on close BUG: https://bugzilla.samba.org/show_bug.cgi?id=13458 BUG: https://bugzilla.samba.org/show_bug.cgi?id=15608 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- diff --git a/selftest/knownfail b/selftest/knownfail index 5f64e4edad0..dee099b79c1 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -216,7 +216,6 @@ ^samba3.smb2.setinfo.setinfo ^samba3.smb2.session.*reauth5 # some special anonymous checks? ^samba3.smb2.lock.*replay_broken_windows # This tests the windows behaviour -^samba3.smb2.lease.unlink # we currently do not downgrade RH lease to R after unlink ^samba4.smb2.ioctl.compress_notsup.*\(ad_dc_ntvfs\) ^samba3.raw.session.*reauth2 # maybe fix this? ^samba3.rpc.lsa.secrets.seal # This gives NT_STATUS_LOCAL_USER_SESSION_KEY diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index 996ca8b283c..3e0d2850066 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -263,6 +263,7 @@ struct smbd_smb2_close_state { }; static void smbd_smb2_close_wait_done(struct tevent_req *subreq); +static void smbd_smb2_close_delay_lease_break_done(struct tevent_req *subreq); static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -343,6 +344,56 @@ static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx, return req; } + if (in_fsp->fsp_flags.initial_delete_on_close) { + struct tevent_req *subreq = NULL; + struct share_mode_lock *lck = NULL; + struct timeval timeout; + + lck = get_existing_share_mode_lock(mem_ctx, + in_fsp->file_id); + if (lck == NULL) { + tevent_req_nterror(req, + NT_STATUS_UNSUCCESSFUL); + return tevent_req_post(req, ev); + } + + if (is_delete_on_close_set(lck, in_fsp->name_hash)) { + TALLOC_FREE(lck); + goto do_close; + } + + timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT, 0); + timeout = timeval_sum(&smb2req->request_time, &timeout); + + subreq = delay_for_handle_lease_break_send(req, + ev, + timeout, + in_fsp, + &lck); + if (tevent_req_nomem(subreq, req)) { + TALLOC_FREE(lck); + return tevent_req_post(req, ev); + } + if (tevent_req_is_in_progress(subreq)) { + tevent_req_set_callback( + subreq, + smbd_smb2_close_delay_lease_break_done, + req); + return req; + } + + status = delay_for_handle_lease_break_recv(subreq, + mem_ctx, + &lck); + TALLOC_FREE(subreq); + TALLOC_FREE(lck); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + /* Fall through */ + } + +do_close: status = smbd_smb2_close(smb2req, &state->in_fsp, state->in_flags, @@ -393,6 +444,50 @@ static void smbd_smb2_close_wait_done(struct tevent_req *subreq) tevent_req_done(req); } +static void smbd_smb2_close_delay_lease_break_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); + struct smbd_smb2_close_state *state = tevent_req_data( + req, struct smbd_smb2_close_state); + struct share_mode_lock *lck = NULL; + NTSTATUS status; + bool ok; + + status = delay_for_handle_lease_break_recv(subreq, state, &lck); + TALLOC_FREE(subreq); + TALLOC_FREE(lck); + if (tevent_req_nterror(req, status)) { + return; + } + + /* + * Make sure we run as the user again + */ + ok = change_to_user_and_service( + state->smb2req->tcon->compat, + state->smb2req->session->global->session_wire_id); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return; + } + + status = smbd_smb2_close(state->smb2req, + &state->in_fsp, + state->in_flags, + &state->out_flags, + &state->out_creation_ts, + &state->out_last_access_ts, + &state->out_last_write_ts, + &state->out_change_ts, + &state->out_allocation_size, + &state->out_end_of_file, + &state->out_file_attributes); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + static NTSTATUS smbd_smb2_close_recv(struct tevent_req *req, uint16_t *out_flags, struct timespec *out_creation_ts,