1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

vfs_default: make use of change_to_user_by_fsp() in order to switch between src and dst fsp

This may matter if at least one share uses "force user".

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Stefan Metzmacher 2018-05-23 12:03:02 +02:00
parent 2d75da9f61
commit 506c9b37df

View File

@ -1598,6 +1598,22 @@ struct vfswrap_offload_write_state {
size_t next_io_size;
};
static void vfswrap_offload_write_cleanup(struct tevent_req *req,
enum tevent_req_state req_state)
{
struct vfswrap_offload_write_state *state = tevent_req_data(
req, struct vfswrap_offload_write_state);
bool ok;
if (state->dst_fsp == NULL) {
return;
}
ok = change_to_user_by_fsp(state->dst_fsp);
SMB_ASSERT(ok);
state->dst_fsp = NULL;
}
static NTSTATUS vfswrap_offload_write_loop(struct tevent_req *req);
static struct tevent_req *vfswrap_offload_write_send(
@ -1616,6 +1632,7 @@ static struct tevent_req *vfswrap_offload_write_send(
size_t num = MIN(to_copy, COPYCHUNK_MAX_TOTAL_LEN);
files_struct *src_fsp = NULL;
NTSTATUS status;
bool ok;
req = tevent_req_create(mem_ctx, &state,
struct vfswrap_offload_write_state);
@ -1633,6 +1650,8 @@ static struct tevent_req *vfswrap_offload_write_send(
.remaining = to_copy,
};
tevent_req_set_cleanup_fn(req, vfswrap_offload_write_cleanup);
switch (fsctl) {
case FSCTL_SRV_COPYCHUNK:
case FSCTL_SRV_COPYCHUNK_WRITE:
@ -1676,6 +1695,12 @@ static struct tevent_req *vfswrap_offload_write_send(
return tevent_req_post(req, ev);
}
ok = change_to_user_by_fsp(src_fsp);
if (!ok) {
tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
return tevent_req_post(req, ev);
}
state->buf = talloc_array(state, uint8_t, num);
if (tevent_req_nomem(state->buf, req)) {
return tevent_req_post(req, ev);
@ -1719,6 +1744,10 @@ static NTSTATUS vfswrap_offload_write_loop(struct tevent_req *req)
struct lock_struct read_lck;
bool ok;
/*
* This is called under the context of state->src_fsp.
*/
state->next_io_size = MIN(state->remaining, talloc_array_length(state->buf));
init_strict_lock_struct(state->src_fsp,
@ -1778,6 +1807,12 @@ static void vfswrap_offload_write_read_done(struct tevent_req *subreq)
state->src_off += nread;
ok = change_to_user_by_fsp(state->dst_fsp);
if (!ok) {
tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
return;
}
init_strict_lock_struct(state->dst_fsp,
state->dst_fsp->op->global->open_persistent_id,
state->dst_off,
@ -1815,6 +1850,7 @@ static void vfswrap_offload_write_write_done(struct tevent_req *subreq)
struct vfs_aio_state aio_state;
ssize_t nwritten;
NTSTATUS status;
bool ok;
nwritten = SMB_VFS_PWRITE_RECV(subreq, &aio_state);
TALLOC_FREE(subreq);
@ -1842,6 +1878,12 @@ static void vfswrap_offload_write_write_done(struct tevent_req *subreq)
return;
}
ok = change_to_user_by_fsp(state->src_fsp);
if (!ok) {
tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
return;
}
status = vfswrap_offload_write_loop(req);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);