[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Jan 16 17:00:03 MST 2013


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 <ddiss at 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 <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Jan 17 00:59:44 CET 2013 on sn-devel-104

commit bf07c33dac37442b8f5b49e68653f8ef629ff679
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit cb323281c1f2b66f2b42527cda722e57ca1f1f23
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 456724f05d79733fe805a3209231c565d69d2be3
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit c3cc51e8a2f31565c3bac219ea3a78ab4287bcd5
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit bfe765367e1425fc3ae98e6b8183e6ac5476e97b
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 42a5a6c0f61f0c863bac1bf65e7045f1ce086409
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Jan 15 17:23:06 2013 +0100

    torture: add locking tests for copychunk
    
    Reviewed by: Jeremy Allison <jra at samba.org>

commit a7c2f13d7a5646f2a63ce33e8155ce79d10ef696
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 7ca8663e313a55fd6157cf20eb02c2ac8be94a00
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 3619b1a7b2b5a2bfe6fdb13ecb4650ae575ab3e8
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit bc59ebf5231b44220598dfdf44c9a2cfcc538711
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 65983aac12e5ecb12157b39c7bec464388716f27
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit e38d9f71d90e6b20a027d91d4768d91378728621
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit ef00eb90e56dfac2d823582cec92abf1fa9905f1
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 2bde9636888067210dc38523b6fafaa0b179ec3b
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 14bd6c8b0954ad58ac4e3e157835594c26bfa97a
Author: David Disseldorp <ddiss at 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 <jra at samba.org>

commit 958b21c28dacad38cd64e79ca7d77cd8acc20dd0
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Jan 15 17:22:56 2013 +0100

    smb2_ioctl: split ioctl handlers into separate funtions
    
    Reviewed by: Jeremy Allison <jra at 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


More information about the samba-cvs mailing list