1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

s3/vfs: make SMB_VFS_OFFLOAD_WRITE_SEND offload token based

Remove the source fsp argument and instead pass the offload token
generated with SMB_VFS_OFFLOAD_READ_SEND/RECV.

An actual offload fsctl is not implemented yet, neither in the VFS nor
at the SMB ioctl layer, and returns NT_STATUS_NOT_IMPLEMENTED

With these changes we now pass the copy-chunk-across-shares test.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Ralph Boehme 2017-06-09 13:02:49 +02:00
parent d50f307e97
commit 3645f83a3c
15 changed files with 242 additions and 134 deletions

View File

@ -585,8 +585,9 @@ struct skel_cc_state {
static struct tevent_req *skel_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,

View File

@ -719,8 +719,9 @@ static void skel_offload_write_done(struct tevent_req *subreq);
static struct tevent_req *skel_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,
@ -737,7 +738,7 @@ static struct tevent_req *skel_offload_write_send(struct vfs_handle_struct *hand
state->handle = handle;
subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, state, ev,
src_fsp, src_off,
fsctl, token, transfer_offset,
dest_fsp, dest_off, num, flags);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);

View File

@ -1,2 +0,0 @@
^samba3.smb2.ioctl.copy_chunk_across_shares
^samba3.smb2.ioctl fs_specific.copy_chunk_across_shares

View File

@ -799,8 +799,9 @@ struct vfs_fn_pointers {
struct tevent_req *(*offload_write_send_fn)(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t to_copy,
@ -1379,8 +1380,9 @@ NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,

View File

@ -425,10 +425,10 @@
#define SMB_VFS_NEXT_OFFLOAD_READ_RECV(req, handle, mem_ctx, token_blob) \
smb_vfs_call_offload_read_recv((req), (handle)->next, (mem_ctx), (token_blob))
#define SMB_VFS_OFFLOAD_WRITE_SEND(conn, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num, flags) \
smb_vfs_call_offload_write_send((conn)->vfs_handles, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num), (flags))
#define SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num, flags) \
smb_vfs_call_offload_write_send((handle)->next, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num), (flags))
#define SMB_VFS_OFFLOAD_WRITE_SEND(conn, mem_ctx, ev, fsctl, token, transfer_offset, dest_fsp, dest_off, num, flags) \
smb_vfs_call_offload_write_send((conn)->vfs_handles, (mem_ctx), (ev), (fsctl), (token), (transfer_offset), (dest_fsp), (dest_off), (num), (flags))
#define SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, mem_ctx, ev, fsctl, token, transfer_offset, dest_fsp, dest_off, num, flags) \
smb_vfs_call_offload_write_send((handle)->next, (mem_ctx), (ev), (fsctl), (token), (transfer_offset), (dest_fsp), (dest_off), (num), (flags))
#define SMB_VFS_OFFLOAD_WRITE_RECV(conn, req, copied) \
smb_vfs_call_offload_write_recv((conn)->vfs_handles, (req), (copied))

View File

@ -20,6 +20,7 @@
#include "includes.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/security/security.h"
#include "dbwrap/dbwrap.h"
#include "dbwrap/dbwrap_rbt.h"
#include "dbwrap/dbwrap_open.h"
@ -220,3 +221,92 @@ NTSTATUS vfs_offload_token_create_blob(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
NTSTATUS vfs_offload_token_check_handles(uint32_t fsctl,
files_struct *src_fsp,
files_struct *dst_fsp)
{
if (src_fsp->vuid != dst_fsp->vuid) {
DBG_INFO("copy chunk handles not in the same session.\n");
return NT_STATUS_ACCESS_DENIED;
}
if (!NT_STATUS_IS_OK(src_fsp->op->status)) {
DBG_INFO("copy chunk source handle invalid: %s\n",
nt_errstr(src_fsp->op->status));
return NT_STATUS_ACCESS_DENIED;
}
if (!NT_STATUS_IS_OK(dst_fsp->op->status)) {
DBG_INFO("copy chunk destination handle invalid: %s\n",
nt_errstr(dst_fsp->op->status));
return NT_STATUS_ACCESS_DENIED;
}
if (src_fsp->deferred_close != NULL) {
DBG_INFO("copy chunk src handle with deferred close.\n");
return NT_STATUS_ACCESS_DENIED;
}
if (dst_fsp->deferred_close != NULL) {
DBG_INFO("copy chunk dst handle with deferred close.\n");
return NT_STATUS_ACCESS_DENIED;
}
if (src_fsp->is_directory) {
DBG_INFO("copy chunk no read on src directory handle (%s).\n",
smb_fname_str_dbg(src_fsp->fsp_name));
return NT_STATUS_ACCESS_DENIED;
}
if (dst_fsp->is_directory) {
DBG_INFO("copy chunk no read on dst directory handle (%s).\n",
smb_fname_str_dbg(dst_fsp->fsp_name));
return NT_STATUS_ACCESS_DENIED;
}
if (IS_IPC(src_fsp->conn) || IS_IPC(dst_fsp->conn)) {
DBG_INFO("copy chunk no access on IPC$ handle.\n");
return NT_STATUS_ACCESS_DENIED;
}
if (IS_PRINT(src_fsp->conn) || IS_PRINT(dst_fsp->conn)) {
DBG_INFO("copy chunk no access on PRINT handle.\n");
return NT_STATUS_ACCESS_DENIED;
}
/*
* [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
* The server MUST fail the request with STATUS_ACCESS_DENIED if any of
* the following are true:
* - The Open.GrantedAccess of the destination file does not include
* FILE_WRITE_DATA or FILE_APPEND_DATA.
*
* A non writable dst handle also doesn't make sense for other fsctls.
*/
if (!CHECK_WRITE(dst_fsp)) {
DBG_INFO("dest handle not writable (%s).\n",
smb_fname_str_dbg(dst_fsp->fsp_name));
return NT_STATUS_ACCESS_DENIED;
}
/*
* - The Open.GrantedAccess of the destination file does not include
* FILE_READ_DATA, and the CtlCode is FSCTL_SRV_COPYCHUNK.
*/
if ((fsctl == FSCTL_SRV_COPYCHUNK) && !CHECK_READ_IOCTL(dst_fsp)) {
DBG_INFO("copy chunk no read on dest handle (%s).\n",
smb_fname_str_dbg(dst_fsp->fsp_name));
return NT_STATUS_ACCESS_DENIED;
}
/*
* - The Open.GrantedAccess of the source file does not include
* FILE_READ_DATA access.
*/
if (!CHECK_READ_SMB2(src_fsp)) {
DBG_INFO("src handle not readable (%s).\n",
smb_fname_str_dbg(src_fsp->fsp_name));
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
}

View File

@ -34,4 +34,7 @@ NTSTATUS vfs_offload_token_create_blob(TALLOC_CTX *mem_ctx,
const files_struct *fsp,
uint32_t fsctl,
DATA_BLOB *token_blob);
NTSTATUS vfs_offload_token_check_handles(uint32_t fsctl,
files_struct *src_fsp,
files_struct *dst_fsp);
#endif

View File

@ -206,8 +206,9 @@ static void btrfs_offload_write_done(struct tevent_req *subreq);
static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,
@ -218,7 +219,10 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
struct btrfs_ioctl_clone_range_args cr_args;
struct lock_struct src_lck;
struct lock_struct dest_lck;
off_t src_off = transfer_offset;
files_struct *src_fsp = NULL;
int ret;
bool handle_offload_write = true;
NTSTATUS status;
req = tevent_req_create(mem_ctx, &cc_state, struct btrfs_cc_state);
@ -233,16 +237,38 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
cc_state->handle = handle;
status = vfs_offload_token_db_fetch_fsp(btrfs_offload_ctx,
token, &src_fsp);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
switch (fsctl) {
case FSCTL_SRV_COPYCHUNK:
case FSCTL_SRV_COPYCHUNK_WRITE:
case FSCTL_DUP_EXTENTS_TO_FILE:
break;
default:
handle_offload_write = false;
break;
}
if (num == 0) {
/*
* With a @src_length of zero, BTRFS_IOC_CLONE_RANGE clones
* all data from @src_offset->EOF! This is certainly not what
* the caller expects, and not what vfs_default does.
*/
handle_offload_write = false;
}
if (!handle_offload_write) {
cc_state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
cc_state, ev,
src_fsp,
src_off,
fsctl,
token,
transfer_offset,
dest_fsp,
dest_off,
num, flags);
@ -255,6 +281,13 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
return req;
}
status = vfs_offload_token_check_handles(
fsctl, src_fsp, dest_fsp);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
status = vfs_stat_fsp(src_fsp);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
@ -323,8 +356,9 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han
(unsigned long long)cr_args.dest_offset));
cc_state->subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
cc_state, ev,
src_fsp,
src_off,
fsctl,
token,
transfer_offset,
dest_fsp,
dest_off,
num, flags);

View File

@ -1689,6 +1689,7 @@ struct vfswrap_offload_write_state {
struct lock_struct read_lck;
bool write_lck_locked;
struct lock_struct write_lck;
DATA_BLOB *token;
struct files_struct *src_fsp;
off_t src_off;
struct files_struct *dst_fsp;
@ -1705,8 +1706,9 @@ static struct tevent_req *vfswrap_offload_write_send(
struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t to_copy,
@ -1715,10 +1717,9 @@ static struct tevent_req *vfswrap_offload_write_send(
struct tevent_req *req;
struct vfswrap_offload_write_state *state = NULL;
size_t num = MIN(to_copy, COPYCHUNK_MAX_TOTAL_LEN);
files_struct *src_fsp = NULL;
NTSTATUS status;
DBG_DEBUG("server side copy chunk of length %" PRIu64 "\n", to_copy);
req = tevent_req_create(mem_ctx, &state,
struct vfswrap_offload_write_state);
if (req == NULL) {
@ -1738,8 +1739,8 @@ static struct tevent_req *vfswrap_offload_write_send(
*state = (struct vfswrap_offload_write_state) {
.ev = ev,
.src_fsp = src_fsp,
.src_off = src_off,
.token = token,
.src_off = transfer_offset,
.dst_fsp = dest_fsp,
.dst_off = dest_off,
.to_copy = to_copy,
@ -1747,11 +1748,44 @@ static struct tevent_req *vfswrap_offload_write_send(
.flags = flags,
};
switch (fsctl) {
case FSCTL_SRV_COPYCHUNK:
case FSCTL_SRV_COPYCHUNK_WRITE:
break;
case FSCTL_OFFLOAD_WRITE:
tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
return tevent_req_post(req, ev);
default:
tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
return tevent_req_post(req, ev);
}
/*
* From here on we assume a copy-chunk fsctl
*/
if (to_copy == 0) {
tevent_req_done(req);
return tevent_req_post(req, ev);
}
status = vfs_offload_token_db_fetch_fsp(vfswrap_offload_ctx,
token, &src_fsp);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
state->src_fsp = src_fsp;
DBG_DEBUG("server side copy chunk of length %" PRIu64 "\n", to_copy);
status = vfs_offload_token_check_handles(fsctl, src_fsp, dest_fsp);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
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);
@ -1762,7 +1796,7 @@ static struct tevent_req *vfswrap_offload_write_send(
return tevent_req_post(req, ev);
}
if (src_fsp->fsp_name->st.st_ex_size < src_off + num) {
if (src_fsp->fsp_name->st.st_ex_size < state->src_off + num) {
/*
* [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
* If the SourceOffset or SourceOffset + Length extends beyond

View File

@ -5485,8 +5485,9 @@ static void fruit_offload_write_done(struct tevent_req *subreq);
static struct tevent_req *fruit_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,
@ -5496,6 +5497,8 @@ static struct tevent_req *fruit_offload_write_send(struct vfs_handle_struct *han
struct fruit_offload_write_state *state;
NTSTATUS status;
struct fruit_config_data *config;
off_t src_off = transfer_offset;
files_struct *src_fsp = NULL;
off_t to_copy = num;
DEBUG(10,("soff: %ju, doff: %ju, len: %ju\n",
@ -5511,9 +5514,22 @@ static struct tevent_req *fruit_offload_write_send(struct vfs_handle_struct *han
return NULL;
}
state->handle = handle;
state->src_fsp = src_fsp;
state->dst_fsp = dest_fsp;
switch (fsctl) {
case FSCTL_SRV_COPYCHUNK:
case FSCTL_SRV_COPYCHUNK_WRITE:
status = vfs_offload_token_db_fetch_fsp(fruit_offload_ctx,
token, &src_fsp);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
state->src_fsp = src_fsp;
break;
default:
break;
}
/*
* Check if this a OS X copyfile style copychunk request with
* a requested chunk count of 0 that was translated to a
@ -5521,7 +5537,7 @@ static struct tevent_req *fruit_offload_write_send(struct vfs_handle_struct *han
* = dest_off = num = 0.
*/
if ((src_off == 0) && (dest_off == 0) && (num == 0) &&
src_fsp->aapl_copyfile_supported &&
src_fsp != NULL && src_fsp->aapl_copyfile_supported &&
dest_fsp->aapl_copyfile_supported)
{
status = vfs_stat_fsp(src_fsp);
@ -5536,8 +5552,9 @@ static struct tevent_req *fruit_offload_write_send(struct vfs_handle_struct *han
subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle,
mem_ctx,
ev,
src_fsp,
src_off,
fsctl,
token,
transfer_offset,
dest_fsp,
dest_off,
to_copy,

View File

@ -1944,8 +1944,9 @@ static NTSTATUS smb_full_audit_offload_read_recv(
static struct tevent_req *smb_full_audit_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,
@ -1953,8 +1954,9 @@ static struct tevent_req *smb_full_audit_offload_write_send(struct vfs_handle_st
{
struct tevent_req *req;
req = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, mem_ctx, ev, src_fsp,
src_off, dest_fsp, dest_off, num,
req = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, mem_ctx, ev,
fsctl, token, transfer_offset,
dest_fsp, dest_off, num,
flags);
do_log(SMB_VFS_OP_OFFLOAD_WRITE_SEND, req, handle, "");

View File

@ -2005,8 +2005,9 @@ static void smb_time_audit_offload_write_done(struct tevent_req *subreq);
static struct tevent_req *smb_time_audit_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,
@ -2025,7 +2026,7 @@ static struct tevent_req *smb_time_audit_offload_write_send(struct vfs_handle_st
state->handle = handle;
clock_gettime_mono(&state->ts_send);
subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, state, ev,
src_fsp, src_off,
fsctl, token, transfer_offset,
dest_fsp, dest_off, num, flags);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);

View File

@ -161,7 +161,6 @@ static NTSTATUS fsctl_dup_extents_check_sparse(struct files_struct *src_fsp,
struct fsctl_dup_extents_state {
struct tevent_context *ev;
struct connection_struct *conn;
struct files_struct *src_fsp;
struct files_struct *dst_fsp;
struct fsctl_dup_extents_to_file dup_extents;
};
@ -234,7 +233,6 @@ static struct tevent_req *fsctl_dup_extents_send(TALLOC_CTX *mem_ctx,
tevent_req_nterror(req, NT_STATUS_INVALID_HANDLE);
return tevent_req_post(req, ev);
}
state->src_fsp = src_fsp;
status = fsctl_dup_extents_check_lengths(src_fsp, dst_fsp,
&state->dup_extents);
@ -279,11 +277,11 @@ static void fsctl_dup_extents_offload_read_done(struct tevent_req *subreq)
subreq, struct tevent_req);
struct fsctl_dup_extents_state *state = tevent_req_data(
req, struct fsctl_dup_extents_state);
DATA_BLOB token_blob;
DATA_BLOB token;
NTSTATUS status;
status = SMB_VFS_OFFLOAD_READ_RECV(subreq, state->dst_fsp->conn,
state, &token_blob);
state, &token);
if (tevent_req_nterror(req, status)) {
return;
}
@ -292,7 +290,8 @@ static void fsctl_dup_extents_offload_read_done(struct tevent_req *subreq)
subreq = SMB_VFS_OFFLOAD_WRITE_SEND(state->dst_fsp->conn,
state,
state->ev,
state->src_fsp,
FSCTL_DUP_EXTENTS_TO_FILE,
&token,
state->dup_extents.source_off,
state->dst_fsp,
state->dup_extents.target_off,

View File

@ -82,6 +82,8 @@ struct fsctl_srv_copychunk_state {
uint32_t current_chunk;
NTSTATUS status;
off_t total_written;
uint32_t ctl_code;
DATA_BLOB token;
struct files_struct *src_fsp;
struct files_struct *dst_fsp;
enum {
@ -93,67 +95,6 @@ struct fsctl_srv_copychunk_state {
};
static void fsctl_srv_copychunk_vfs_done(struct tevent_req *subreq);
static NTSTATUS copychunk_check_handles(uint32_t ctl_code,
struct files_struct *src_fsp,
struct files_struct *dst_fsp)
{
/*
* [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
* The server MUST fail the request with STATUS_ACCESS_DENIED if any of
* the following are true:
* - The Open.GrantedAccess of the destination file does not include
* FILE_WRITE_DATA or FILE_APPEND_DATA.
*/
if (!CHECK_WRITE(dst_fsp)) {
DEBUG(5, ("copy chunk no write on dest handle (%s).\n",
smb_fname_str_dbg(dst_fsp->fsp_name) ));
return NT_STATUS_ACCESS_DENIED;
}
/*
* - The Open.GrantedAccess of the destination file does not include
* FILE_READ_DATA, and the CtlCode is FSCTL_SRV_COPYCHUNK.
*/
if ((ctl_code == FSCTL_SRV_COPYCHUNK) &&
!CHECK_READ_IOCTL(dst_fsp)) {
DEBUG(5, ("copy chunk no read on dest handle (%s).\n",
smb_fname_str_dbg(dst_fsp->fsp_name) ));
return NT_STATUS_ACCESS_DENIED;
}
/*
* - The Open.GrantedAccess of the source file does not include
* FILE_READ_DATA access.
*/
if (!CHECK_READ_SMB2(src_fsp)) {
DEBUG(5, ("copy chunk no read on src handle (%s).\n",
smb_fname_str_dbg(src_fsp->fsp_name) ));
return NT_STATUS_ACCESS_DENIED;
}
if (src_fsp->is_directory) {
DEBUG(5, ("copy chunk no read on src directory handle (%s).\n",
smb_fname_str_dbg(src_fsp->fsp_name) ));
return NT_STATUS_ACCESS_DENIED;
}
if (dst_fsp->is_directory) {
DEBUG(5, ("copy chunk no read on dst directory handle (%s).\n",
smb_fname_str_dbg(dst_fsp->fsp_name) ));
return NT_STATUS_ACCESS_DENIED;
}
if (IS_IPC(src_fsp->conn) || IS_IPC(dst_fsp->conn)) {
DEBUG(5, ("copy chunk no access on IPC$ handle.\n"));
return NT_STATUS_ACCESS_DENIED;
}
if (IS_PRINT(src_fsp->conn) || IS_PRINT(dst_fsp->conn)) {
DEBUG(5, ("copy chunk no access on PRINT handle.\n"));
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
}
static NTSTATUS fsctl_srv_copychunk_loop(struct tevent_req *req);
static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
@ -166,8 +107,6 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
{
struct tevent_req *req = NULL;
struct fsctl_srv_copychunk_state *state = NULL;
uint64_t src_persistent_h;
uint64_t src_volatile_h;
enum ndr_err_code ndr_ret;
NTSTATUS status;
@ -183,6 +122,8 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
*state = (struct fsctl_srv_copychunk_state) {
.conn = dst_fsp->conn,
.ev = ev,
.ctl_code = ctl_code,
.dst_fsp = dst_fsp,
};
if (in_max_output < sizeof(struct srv_copychunk_rsp)) {
@ -203,26 +144,8 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
/* persistent/volatile keys sent as the resume key */
src_persistent_h = BVAL(state->cc_copy.source_key, 0);
src_volatile_h = BVAL(state->cc_copy.source_key, 8);
state->src_fsp = file_fsp_get(smb2req, src_persistent_h, src_volatile_h);
if (state->src_fsp == NULL) {
DEBUG(3, ("invalid resume key in copy chunk req\n"));
state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
tevent_req_nterror(req, state->status);
return tevent_req_post(req, ev);
}
state->dst_fsp = dst_fsp;
state->status = copychunk_check_handles(ctl_code,
state->src_fsp,
state->dst_fsp);
if (!NT_STATUS_IS_OK(state->status)) {
tevent_req_nterror(req, state->status);
return tevent_req_post(req, ev);
}
state->token = data_blob_const(state->cc_copy.source_key,
sizeof(state->cc_copy.source_key));
state->status = copychunk_check_limits(&state->cc_copy);
if (!NT_STATUS_IS_OK(state->status)) {
@ -272,7 +195,8 @@ static NTSTATUS fsctl_srv_copychunk_loop(struct tevent_req *req)
subreq = SMB_VFS_OFFLOAD_WRITE_SEND(state->dst_fsp->conn,
state,
state->ev,
state->src_fsp,
state->ctl_code,
&state->token,
source_off,
state->dst_fsp,
target_off,

View File

@ -2377,16 +2377,18 @@ NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct files_struct *src_fsp,
off_t src_off,
uint32_t fsctl,
DATA_BLOB *token,
off_t transfer_offset,
struct files_struct *dest_fsp,
off_t dest_off,
off_t num,
uint32_t flags)
{
VFS_FIND(offload_write_send);
return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, src_fsp,
src_off, dest_fsp, dest_off, num,
return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
token, transfer_offset,
dest_fsp, dest_off, num,
flags);
}