The branch, master has been updated via 8e63a72 smb2_ioctl: copychunk request max output validation via bf07c33 smb2_ioctl: track copychunk response output state via cb32328 smb2_ioctl: copychunk CHECK_READ and CHECK_WRITE via 456724f torture: copychunk test suite improvements via c3cc51e smb2_ioctl: only pass through to VFS on a valid fsp via bfe7653 torture: replace ioctl failure returns with helper calls via 42a5a6c torture: add locking tests for copychunk via a7c2f13 smb2_ioctl: perform locking around copychunk requests via 7ca8663 smbd: split out file_fsp_get from file_fsp_smb2 via 3619b1a torture: skip FSCTL_SRV_ENUM_SNAPS test when not supported via bc59ebf selftest: enable samba3.smb2.ioctl tests against s3fs via 65983aa smb2_ioctl: remove ioctl error response assumptions via e38d9f7 smb2_ioctl: add support for FSCTL_SRV_COPYCHUNK via ef00eb9 s3-vfs: add copy_chunk vfs hooks via 2bde963 smb2_ioctl: add FSCTL_SRV_REQUEST_RESUME_KEY support via 14bd6c8 smb2_ioctl: split ioctl handler code on device type via 958b21c smb2_ioctl: split ioctl handlers into separate funtions from 9ba44cc build(waf): fix the abi_match for the pdb library
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 8e63a72ec1e9ea9efcbcdf156274afaed9a4b2ea Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:12 2013 +0100 smb2_ioctl: copychunk request max output validation Check that the copychunk ioctl request maximum output specified by the client is large enough to hold copychunk response data. Reviewed by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Thu Jan 17 00:59:44 CET 2013 on sn-devel-104 commit bf07c33dac37442b8f5b49e68653f8ef629ff679 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:11 2013 +0100 smb2_ioctl: track copychunk response output state Treat the response data independent to the status. Reviewed by: Jeremy Allison <j...@samba.org> commit cb323281c1f2b66f2b42527cda722e57ca1f1f23 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:10 2013 +0100 smb2_ioctl: copychunk CHECK_READ and CHECK_WRITE [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request, specifies that the copychunk destination file handle be granted FILE_WRITE_DATA and FILE_READ_DATA access. FILE_READ_DATA access must also be granted on the copychunk source file, which may be done implicitly with execute permission. Reviewed by: Jeremy Allison <j...@samba.org> commit 456724f05d79733fe805a3209231c565d69d2be3 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:09 2013 +0100 torture: copychunk test suite improvements Allow for large files in test_setup_copy_chunk(): Write test data in 1M IOs, rather than attempting to do the whole thing in one go. Add copychunk bad resume key test: Send a copy chunk request with an intentionally bogus resume key (source key handle). Add copychunk src=dest test: Test copychunk requests where the source and destination handles refer to the same file. Add copychunk src=dest overlap test. Add desired access args to test_setup_copy_chunk(). Add copychunk_bad_access test: Open the copychunk source and destination files with differing desired_access values. Confirm copychunk response matches 2k8 and 2k12 behaviour. Add copy_chunk_src_exceed test: Attempts to copy more data than is present in the copychunk source file. Add copy_chunk_src_exceed_multi test: Test whether the first chunk in a multi-chunk copychunk request is written to disk, where the second chunk is invalid due to src file overrun. Add copy_chunk_sparse_dest test: Issue a request where the target offset exceeds the file size, resulting in a sparse region. Add copy_chunk_max_output_sz test. Reviewed by: Jeremy Allison <j...@samba.org> commit c3cc51e8a2f31565c3bac219ea3a78ab4287bcd5 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:08 2013 +0100 smb2_ioctl: only pass through to VFS on a valid fsp A null fsp is dereferenced on VFS call. Reviewed by: Jeremy Allison <j...@samba.org> commit bfe765367e1425fc3ae98e6b8183e6ac5476e97b Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:07 2013 +0100 torture: replace ioctl failure returns with helper calls Also change test_ioctl_get_shadow_copy() to use torture_skip(), and clean up test output. Reviewed by: Jeremy Allison <j...@samba.org> commit 42a5a6c0f61f0c863bac1bf65e7045f1ce086409 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:06 2013 +0100 torture: add locking tests for copychunk Reviewed by: Jeremy Allison <j...@samba.org> commit a7c2f13d7a5646f2a63ce33e8155ce79d10ef696 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:05 2013 +0100 smb2_ioctl: perform locking around copychunk requests For each chunk in a copychunk request, take a read and write lock on the source and destination files respectively. Also change the resume key format to use a combination of the persistent and volatile handles. Thanks to Metze for his help on this. Reviewed by: Jeremy Allison <j...@samba.org> commit 7ca8663e313a55fd6157cf20eb02c2ac8be94a00 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:04 2013 +0100 smbd: split out file_fsp_get from file_fsp_smb2 Obtain the files_struct from smb2req, persistent_id and volatile_id. Reviewed by: Jeremy Allison <j...@samba.org> commit 3619b1a7b2b5a2bfe6fdb13ecb4650ae575ab3e8 Author: David Disseldorp <dd...@suse.de> Date: Tue Jan 15 17:23:03 2013 +0100 torture: skip FSCTL_SRV_ENUM_SNAPS test when not supported If FSCTL_SRV_ENUM_SNAPS fails with NT_STATUS_NOT_SUPPORTED then skip the test, this means we can run the full ioctl test suite as part of autobuild. Reviewed by: Jeremy Allison <j...@samba.org> commit bc59ebf5231b44220598dfdf44c9a2cfcc538711 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:02 2013 +0100 selftest: enable samba3.smb2.ioctl tests against s3fs These tests are now expected to pass with copy-chunk support now implemented. This effectively reverts 632b1042aed94a71d810613fcdbbfecf615a25fa. Reviewed by: Jeremy Allison <j...@samba.org> commit 65983aac12e5ecb12157b39c7bec464388716f27 Author: David Disseldorp <dd...@suse.de> Date: Tue Jan 15 17:23:01 2013 +0100 smb2_ioctl: remove ioctl error response assumptions MS-SMB2 3.3.4.4 documents cases where a ntstatus indicating an error should not be considered a failure. In such a case the output data buffer should be sent to the client rather than an error response packet. Add a new fsctl copy_chunk test to confirm field limits are sent back in response to an oversize chunk request. Reviewed by: Jeremy Allison <j...@samba.org> commit e38d9f71d90e6b20a027d91d4768d91378728621 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:23:00 2013 +0100 smb2_ioctl: add support for FSCTL_SRV_COPYCHUNK SMB2 clients can issue FSCTL_SRV_COPYCHUNK requests in order to copy data between files on the server side only, rather than reading data then writing back from the client. FSCTL_SRV_COPYCHUNK is used by default for Explorer SMB2 file copies on Windows Server 2012. 2.2.32.1 SRV_COPYCHUNK_RESPONSE in [MS-SMB2] describes the requirement for the server to provide maximum copychunk request size limits in ioctl responses carrying STATUS_INVALID_PARAMETER. Reviewed by: Jeremy Allison <j...@samba.org> commit ef00eb90e56dfac2d823582cec92abf1fa9905f1 Author: David Disseldorp <dd...@suse.de> Date: Tue Jan 15 17:22:59 2013 +0100 s3-vfs: add copy_chunk vfs hooks copy_chunk copies n bytes from a source file at a specific offset to a destination file at a given offset. This interface will be used in handling smb2 FSCTL_SRV_COPYCHUNK ioctl requests. Use a pread/pwrite loop in vfs_default, so that requests referring to the same src and dest file are possible. Provide send and receive hooks for copy chunk VFS interface, allowing asynchronous behaviour. Check whether the request source offset + length exceeds the current size. Return STATUS_INVALID_VIEW_SIZE under such a condition, matching Windows server behaviour. Reviewed by: Jeremy Allison <j...@samba.org> commit 2bde9636888067210dc38523b6fafaa0b179ec3b Author: David Disseldorp <dd...@suse.de> Date: Tue Jan 15 17:22:58 2013 +0100 smb2_ioctl: add FSCTL_SRV_REQUEST_RESUME_KEY support Use existing ioctl IDL infrastructure for marshalling. Support for this ioctl is a prerequisite for FSCTL_SRV_COPYCHUNK handling. The client-opaque resume key is constructed using the server side dev/inode file identifier. Reviewed by: Jeremy Allison <j...@samba.org> commit 14bd6c8b0954ad58ac4e3e157835594c26bfa97a Author: David Disseldorp <dd...@suse.de> Date: Tue Jan 15 17:22:57 2013 +0100 smb2_ioctl: split ioctl handler code on device type Add per device type ioctl handler source files for FSCTL_DFS, FSCTL_FILESYSTEM, FSCTL_NAMED_PIPE and FSCTL_NETWORK_FILESYSTEM. Reviewed by: Jeremy Allison <j...@samba.org> commit 958b21c28dacad38cd64e79ca7d77cd8acc20dd0 Author: David Disseldorp <dd...@samba.org> Date: Tue Jan 15 17:22:56 2013 +0100 smb2_ioctl: split ioctl handlers into separate funtions Reviewed by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: docs-xml/manpages/vfs_full_audit.8.xml | 2 + examples/VFS/skel_opaque.c | 42 ++ examples/VFS/skel_transparent.c | 75 +++ libcli/smb/smb_constants.h | 2 + selftest/knownfail | 9 +- selftest/skip | 1 - source3/Makefile.in | 5 + source3/include/vfs.h | 25 +- source3/include/vfs_macros.h | 10 + source3/modules/vfs_default.c | 111 ++++ source3/modules/vfs_full_audit.c | 38 ++ source3/modules/vfs_time_audit.c | 85 +++ source3/smbd/files.c | 34 +- source3/smbd/proto.h | 3 + source3/smbd/smb2_ioctl.c | 426 +++----------- source3/smbd/smb2_ioctl_dfs.c | 158 +++++ source3/smbd/smb2_ioctl_filesys.c | 77 +++ source3/smbd/smb2_ioctl_named_pipe.c | 194 ++++++ source3/smbd/smb2_ioctl_network_fs.c | 628 +++++++++++++++++++ source3/smbd/smb2_ioctl_private.h | 54 ++ source3/smbd/vfs.c | 26 +- source3/wscript_build | 5 + source4/libcli/smb2/ioctl.c | 37 +- source4/torture/smb2/ioctl.c | 1057 +++++++++++++++++++++++++++++++- 24 files changed, 2698 insertions(+), 406 deletions(-) create mode 100644 source3/smbd/smb2_ioctl_dfs.c create mode 100644 source3/smbd/smb2_ioctl_filesys.c create mode 100644 source3/smbd/smb2_ioctl_named_pipe.c create mode 100644 source3/smbd/smb2_ioctl_network_fs.c create mode 100644 source3/smbd/smb2_ioctl_private.h Changeset truncated at 500 lines: diff --git a/docs-xml/manpages/vfs_full_audit.8.xml b/docs-xml/manpages/vfs_full_audit.8.xml index a44924a..312bc25 100644 --- a/docs-xml/manpages/vfs_full_audit.8.xml +++ b/docs-xml/manpages/vfs_full_audit.8.xml @@ -46,6 +46,8 @@ <member>close</member> <member>closedir</member> <member>connect</member> + <member>copy_chunk_send</member> + <member>copy_chunk_recv</member> <member>disconnect</member> <member>disk_free</member> <member>fchmod</member> diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 6948d64..53c64ca 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -22,6 +22,7 @@ */ #include "../source3/include/includes.h" +#include "lib/util/tevent_ntstatus.h" /* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE SAMBA DEVELOPERS GUIDE!!!!!! @@ -488,6 +489,45 @@ static struct file_id skel_file_id_create(vfs_handle_struct *handle, return id; } +struct skel_cc_state { + uint64_t unused; +}; +static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *src_fsp, + off_t src_off, + struct files_struct *dest_fsp, + off_t dest_off, + off_t num) +{ + struct tevent_req *req; + struct skel_cc_state *cc_state; + + req = tevent_req_create(mem_ctx, &cc_state, struct skel_cc_state); + if (req == NULL) { + return NULL; + } + + tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + return tevent_req_post(req, ev); +} + +static NTSTATUS skel_copy_chunk_recv(struct vfs_handle_struct *handle, + struct tevent_req *req, + off_t *copied) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + tevent_req_received(req); + + return NT_STATUS_OK; +} + static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *fname, @@ -825,6 +865,8 @@ struct vfs_fn_pointers skel_opaque_fns = { .notify_watch_fn = skel_notify_watch, .chflags_fn = skel_chflags, .file_id_create_fn = skel_file_id_create, + .copy_chunk_send_fn = skel_copy_chunk_send, + .copy_chunk_recv_fn = skel_copy_chunk_recv, .streaminfo_fn = skel_streaminfo, .get_real_filename_fn = skel_get_real_filename, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 02e8184..99feade 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -23,6 +23,7 @@ #include "../source3/include/includes.h" #include "lib/util/tevent_unix.h" +#include "lib/util/tevent_ntstatus.h" /* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE SAMBA DEVELOPERS GUIDE!!!!!! @@ -572,6 +573,78 @@ static struct file_id skel_file_id_create(vfs_handle_struct *handle, return SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf); } +struct skel_cc_state { + struct vfs_handle_struct *handle; + off_t copied; +}; +static void skel_copy_chunk_done(struct tevent_req *subreq); + +static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *src_fsp, + off_t src_off, + struct files_struct *dest_fsp, + off_t dest_off, + off_t num) +{ + struct tevent_req *req; + struct tevent_req *subreq; + struct skel_cc_state *cc_state; + + req = tevent_req_create(mem_ctx, &cc_state, struct skel_cc_state); + if (req == NULL) { + return NULL; + } + + cc_state->handle = handle; + subreq = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, cc_state, ev, + src_fsp, src_off, + dest_fsp, dest_off, num); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + tevent_req_set_callback(subreq, skel_copy_chunk_done, req); + return req; +} + +static void skel_copy_chunk_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct skel_cc_state *cc_state + = tevent_req_data(req, struct skel_cc_state); + NTSTATUS status; + + status = SMB_VFS_NEXT_COPY_CHUNK_RECV(cc_state->handle, + subreq, + &cc_state->copied); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + +static NTSTATUS skel_copy_chunk_recv(struct vfs_handle_struct *handle, + struct tevent_req *req, + off_t *copied) +{ + struct skel_cc_state *cc_state + = tevent_req_data(req, struct skel_cc_state); + NTSTATUS status; + + *copied = cc_state->copied; + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + tevent_req_received(req); + return NT_STATUS_OK; +} + static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *fname, @@ -898,6 +971,8 @@ struct vfs_fn_pointers skel_transparent_fns = { .notify_watch_fn = skel_notify_watch, .chflags_fn = skel_chflags, .file_id_create_fn = skel_file_id_create, + .copy_chunk_send_fn = skel_copy_chunk_send, + .copy_chunk_recv_fn = skel_copy_chunk_recv, .streaminfo_fn = skel_streaminfo, .get_real_filename_fn = skel_get_real_filename, diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index 8cb3b6e..f1ecbe9 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -367,6 +367,8 @@ enum csc_policy { #define FSCTL_ACCESS_READ 0x00004000 #define FSCTL_ACCESS_WRITE 0x00008000 +#define IOCTL_DEV_TYPE_MASK 0xFFFF0000 + #define FSCTL_DFS 0x00060000 #define FSCTL_DFS_GET_REFERRALS (FSCTL_DFS | FSCTL_ACCESS_ANY | 0x0194 | FSCTL_METHOD_BUFFERED) #define FSCTL_DFS_GET_REFERRALS_EX (FSCTL_DFS | FSCTL_ACCESS_ANY | 0x01B0 | FSCTL_METHOD_BUFFERED) diff --git a/selftest/knownfail b/selftest/knownfail index e3341e9..bdeb92b 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -173,13 +173,8 @@ ^samba3.smb2.durable-v2-open.open-lease ^samba3.smb2.durable-v2-open.persistent-open-lease ^samba3.smb2.durable-v2-open.app-instance -^samba3.smb2.ioctl.shadow_copy -^samba3.smb2.ioctl.req_resume_key -^samba3.smb2.ioctl.copy_chunk_simple -^samba3.smb2.ioctl.copy_chunk_multi -^samba3.smb2.ioctl.copy_chunk_tiny -^samba3.smb2.ioctl.copy_chunk_overwrite -^samba3.smb2.ioctl.copy_chunk_append +^samba4.smb2.ioctl.req_resume_key\(dc\) # not supported by s4 ntvfs server +^samba4.smb2.ioctl.copy_chunk_\w*\(dc\) # not supported by s4 ntvfs server ^samba3.smb2.dir.one ^samba3.smb2.dir.modify ^samba3.smb2.lease.request diff --git a/selftest/skip b/selftest/skip index 4101aa2..43866bb 100644 --- a/selftest/skip +++ b/selftest/skip @@ -103,7 +103,6 @@ bench # don't run benchmarks in our selftest # we should build a samba4ktutil and use that instead ^samba4.blackbox.ktpass # this test isn't portable ... ^samba4.drs.repl_schema.python # flakey test -^samba4.smb2.ioctl # snapshots not supported by default ^samba4.drs.delete_object.python # flakey test ^samba4.rpc.unixinfo # This contains a server-side getpwuid call which hangs the server when nss_winbindd is in use ^samba.tests.dcerpc.unix # This contains a server-side getpwuid call which hangs the server when nss_winbindd is in use diff --git a/source3/Makefile.in b/source3/Makefile.in index 17c8bd2..80cb27c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -973,6 +973,10 @@ SMBD_OBJ_SRV = smbd/server_reload.o \ smbd/smb2_write.o \ smbd/smb2_lock.o \ smbd/smb2_ioctl.o \ + smbd/smb2_ioctl_dfs.o \ + smbd/smb2_ioctl_filesys.o \ + smbd/smb2_ioctl_named_pipe.o \ + smbd/smb2_ioctl_network_fs.o \ smbd/smb2_keepalive.o \ smbd/smb2_find.o \ smbd/smb2_notify.o \ @@ -985,6 +989,7 @@ SMBD_OBJ_SRV = smbd/server_reload.o \ smbd/smbXsrv_tcon.o \ smbd/smbXsrv_open.o \ smbd/durable.o \ + autoconf/librpc/gen_ndr/ndr_ioctl.o \ $(MANGLE_OBJ) @VFS_STATIC@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 2bce1b7..d60cb5e 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -151,6 +151,7 @@ /* Leave at 31 - not yet released. Make struct vuid_cache_entry in connection_struct a pointer. */ /* Leave at 31 - not yet released. Add share_access to vuid_cache_entry. */ +/* Leave at 31 - not yet released. add SMB_VFS_COPY_CHUNK() */ #define SMB_VFS_INTERFACE_VERSION 31 @@ -615,6 +616,17 @@ struct vfs_fn_pointers { int (*chflags_fn)(struct vfs_handle_struct *handle, const char *path, unsigned int flags); struct file_id (*file_id_create_fn)(struct vfs_handle_struct *handle, const SMB_STRUCT_STAT *sbuf); + struct tevent_req *(*copy_chunk_send_fn)(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *src_fsp, + off_t src_off, + struct files_struct *dest_fsp, + off_t dest_off, + off_t num); + NTSTATUS (*copy_chunk_recv_fn)(struct vfs_handle_struct *handle, + struct tevent_req *req, + off_t *copied); NTSTATUS (*streaminfo_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, @@ -1086,7 +1098,18 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle, uint32_t in_len, uint8_t **_out_data, uint32_t max_out_len, - uint32_t *out_len); + uint32_t *out_len); +struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *src_fsp, + off_t src_off, + struct files_struct *dest_fsp, + off_t dest_off, + off_t num); +NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle, + struct tevent_req *req, + off_t *copied); NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 331fe00..364a4ca 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -399,6 +399,16 @@ #define SMB_VFS_NEXT_FSCTL(handle, fsp, ctx, function, req_flags, in_data, in_len, out_data, max_out_len, out_len) \ smb_vfs_call_fsctl((handle)->next, (fsp), (ctx), (function), (req_flags), (in_data), (in_len), (out_data), (max_out_len), (out_len)) +#define SMB_VFS_COPY_CHUNK_SEND(conn, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \ + smb_vfs_call_copy_chunk_send((conn)->vfs_handles, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num)) +#define SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \ + smb_vfs_call_copy_chunk_send((handle)->next, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num)) + +#define SMB_VFS_COPY_CHUNK_RECV(conn, req, copied) \ + smb_vfs_call_copy_chunk_recv((conn)->vfs_handles, (req), (copied)) +#define SMB_VFS_NEXT_COPY_CHUNK_RECV(handle, req, copied) \ + smb_vfs_call_copy_chunk_recv((handle)->next, (req), (copied)) + #define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc) \ smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc)) #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \ diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 0f651dc..d937c4a 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -31,6 +31,7 @@ #include "librpc/gen_ndr/ndr_dfsblobs.h" #include "lib/util/tevent_unix.h" #include "lib/asys/asys.h" +#include "lib/util/tevent_ntstatus.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS @@ -1323,6 +1324,114 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle, return NT_STATUS_NOT_SUPPORTED; } +struct vfs_cc_state { + off_t copied; + uint8_t buf[65536]; +}; + +static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *src_fsp, + off_t src_off, + struct files_struct *dest_fsp, + off_t dest_off, + off_t num) +{ + struct tevent_req *req; + struct vfs_cc_state *vfs_cc_state; + NTSTATUS status; + + DEBUG(10, ("performing server side copy chunk of length %lu\n", + (unsigned long)num)); + + req = tevent_req_create(mem_ctx, &vfs_cc_state, struct vfs_cc_state); + if (req == NULL) { + return NULL; + } + + status = vfs_stat_fsp(src_fsp); + if (tevent_req_nterror(req, status)) { + return tevent_req_post(req, ev); + } + + if (src_fsp->fsp_name->st.st_ex_size < 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 + * the end of file, the server SHOULD<240> treat this as a + * STATUS_END_OF_FILE error. + * ... + * <240> Section 3.3.5.15.6: Windows servers will return + * STATUS_INVALID_VIEW_SIZE instead of STATUS_END_OF_FILE. + */ + tevent_req_nterror(req, NT_STATUS_INVALID_VIEW_SIZE); + return tevent_req_post(req, ev); + } + + /* could use 2.6.33+ sendfile here to do this in kernel */ + while (vfs_cc_state->copied < num) { + ssize_t ret; + off_t this_num = MIN(sizeof(vfs_cc_state->buf), + num - vfs_cc_state->copied); + + ret = SMB_VFS_PREAD(src_fsp, vfs_cc_state->buf, + this_num, src_off); + if (ret == -1) { + tevent_req_nterror(req, map_nt_error_from_unix(errno)); + return tevent_req_post(req, ev); + } + if (ret != this_num) { + /* zero tolerance for short reads */ + tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR); + return tevent_req_post(req, ev); + } + src_off += ret; + + ret = SMB_VFS_PWRITE(dest_fsp, vfs_cc_state->buf, + this_num, dest_off); + if (ret == -1) { + tevent_req_nterror(req, map_nt_error_from_unix(errno)); + return tevent_req_post(req, ev); + } + if (ret != this_num) { + /* zero tolerance for short writes */ + tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR); + return tevent_req_post(req, ev); + } + dest_off += ret; + + vfs_cc_state->copied += this_num; + } + + tevent_req_done(req); + return tevent_req_post(req, ev); +} + +static NTSTATUS vfswrap_copy_chunk_recv(struct vfs_handle_struct *handle, + struct tevent_req *req, + off_t *copied) +{ + struct vfs_cc_state *vfs_cc_state = tevent_req_data(req, + struct vfs_cc_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + DEBUG(2, ("server side copy chunk failed: %s\n", + nt_errstr(status))); + *copied = 0; + tevent_req_received(req); + return status; + } + + *copied = vfs_cc_state->copied; + DEBUG(10, ("server side copy chunk copied %lu\n", + (unsigned long)*copied)); + tevent_req_received(req); + + return NT_STATUS_OK; +} + /******************************************************************** Given a stat buffer return the allocated size on disk, taking into account sparse files. @@ -2367,6 +2476,8 @@ static struct vfs_fn_pointers vfs_default_fns = { .strict_unlock_fn = vfswrap_strict_unlock, .translate_name_fn = vfswrap_translate_name, .fsctl_fn = vfswrap_fsctl, + .copy_chunk_send_fn = vfswrap_copy_chunk_send, + .copy_chunk_recv_fn = vfswrap_copy_chunk_recv, /* NT ACL operations. */ diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index b1fb090..549f55e 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -161,6 +161,8 @@ typedef enum _vfs_op_type { SMB_VFS_OP_STRICT_LOCK, SMB_VFS_OP_STRICT_UNLOCK, SMB_VFS_OP_TRANSLATE_NAME, + SMB_VFS_OP_COPY_CHUNK_SEND, + SMB_VFS_OP_COPY_CHUNK_RECV, /* NT ACL operations. */ @@ -281,6 +283,8 @@ static struct { { SMB_VFS_OP_STRICT_LOCK, "strict_lock" }, { SMB_VFS_OP_STRICT_UNLOCK, "strict_unlock" }, { SMB_VFS_OP_TRANSLATE_NAME, "translate_name" }, + { SMB_VFS_OP_COPY_CHUNK_SEND, "copy_chunk_send" }, + { SMB_VFS_OP_COPY_CHUNK_RECV, "copy_chunk_recv" }, { SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" }, { SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" }, { SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" }, @@ -1732,6 +1736,38 @@ static NTSTATUS smb_full_audit_translate_name(struct vfs_handle_struct *handle, return result; } +static struct tevent_req *smb_full_audit_copy_chunk_send(struct vfs_handle_struct *handle, + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct files_struct *src_fsp, + off_t src_off, + struct files_struct *dest_fsp, + off_t dest_off, + off_t num) +{ + struct tevent_req *req; + + req = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp, + src_off, dest_fsp, dest_off, num); + + do_log(SMB_VFS_OP_COPY_CHUNK_SEND, req, handle, ""); + + return req; +} + -- Samba Shared Repository