From: Stefan Metzmacher Date: Wed, 23 May 2018 10:03:02 +0000 (+0200) Subject: vfs_default: make use of change_to_user_by_fsp() in order to switch between src and... X-Git-Tag: tevent-0.9.37~292 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=506c9b37df1de784fecc6e01cd30f2b3b693a9fd;p=thirdparty%2Fsamba.git 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 Reviewed-by: Ralph Boehme --- diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 58df47ee6b4..baeb285eeb3 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -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);