smb2_ioctl: add FSCTL_SRV_REQUEST_RESUME_KEY support
authorDavid Disseldorp <ddiss@suse.de>
Tue, 15 Jan 2013 16:22:58 +0000 (17:22 +0100)
committerJeremy Allison <jra@samba.org>
Wed, 16 Jan 2013 22:15:06 +0000 (23:15 +0100)
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@samba.org>

source3/Makefile.in
source3/smbd/smb2_ioctl_network_fs.c
source3/wscript_build

index ae4cf35053e2aa6b87ced9129db22896a1a40354..80cb27c404a21ac05e7a67a81225a9bf82681168 100644 (file)
@@ -989,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) \
index bfc39e3bd5b5d8e59deeaf20913bf408dbae7d36..22eaf57a4b06bdf4c68e16d7664c3867b806761c 100644 (file)
 #include "smbd/globals.h"
 #include "../libcli/smb/smb_common.h"
 #include "../lib/util/tevent_ntstatus.h"
+#include "../lib/ccan/build_assert/build_assert.h"
 #include "include/ntioctl.h"
 #include "../librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/ndr_ioctl.h"
 #include "smb2_ioctl_private.h"
 
 static NTSTATUS fsctl_validate_neg_info(TALLOC_CTX *mem_ctx,
@@ -114,6 +116,41 @@ static NTSTATUS fsctl_validate_neg_info(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS fsctl_srv_req_resume_key(TALLOC_CTX *mem_ctx,
+                                        struct tevent_context *ev,
+                                        struct files_struct *fsp,
+                                        uint32_t in_max_output,
+                                        DATA_BLOB *out_output)
+{
+       struct req_resume_key_rsp rkey_rsp;
+       enum ndr_err_code ndr_ret;
+       DATA_BLOB output;
+
+       if (fsp == NULL) {
+               return NT_STATUS_FILE_CLOSED;
+       }
+
+       ZERO_STRUCT(rkey_rsp);
+       /* use the file id as a copychunk resume key */
+       BUILD_ASSERT(ARRAY_SIZE(rkey_rsp.resume_key) == sizeof(fsp->file_id));
+       memcpy(rkey_rsp.resume_key, &fsp->file_id, sizeof(fsp->file_id));
+
+       ndr_ret = ndr_push_struct_blob(&output, mem_ctx, &rkey_rsp,
+                       (ndr_push_flags_fn_t)ndr_push_req_resume_key_rsp);
+       if (ndr_ret != NDR_ERR_SUCCESS) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       if (in_max_output < output.length) {
+               DEBUG(1, ("max output %u too small for resume key rsp %ld\n",
+                         in_max_output, (long int)output.length));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       *out_output = output;
+
+       return NT_STATUS_OK;
+}
+
 NTSTATUS smb2_ioctl_network_fs(uint32_t ctl_code,
                               struct tevent_context *ev,
                               struct tevent_req *req,
@@ -123,7 +160,6 @@ NTSTATUS smb2_ioctl_network_fs(uint32_t ctl_code,
 
        switch (ctl_code) {
        case FSCTL_VALIDATE_NEGOTIATE_INFO:
-       {
                status = fsctl_validate_neg_info(state, ev,
                                                 state->smbreq->sconn->conn,
                                                 &state->in_input,
@@ -134,7 +170,16 @@ NTSTATUS smb2_ioctl_network_fs(uint32_t ctl_code,
                        tevent_req_done(req);
                }
                return tevent_req_post(req, ev);
-       }
+               break;
+       case FSCTL_SRV_REQUEST_RESUME_KEY:
+               status = fsctl_srv_req_resume_key(state, ev, state->fsp,
+                                                 state->in_max_output,
+                                                 &state->out_output);
+               if (!tevent_req_nterror(req, status)) {
+                       tevent_req_done(req);
+               }
+               return tevent_req_post(req, ev);
+               break;
        default: {
                uint8_t *out_data = NULL;
                uint32_t out_data_len = 0;
index 2f26c0308ae1a134b6663119c7158a54276b689e..2e07fad796847898d5ed2690e81833af51664ae5 100755 (executable)
@@ -981,6 +981,7 @@ bld.SAMBA3_LIBRARY('smbd_base',
                     ccan-hash
                     NDR_SMB_ACL
                     netapi
+                   NDR_IOCTL
                     ''' + bld.env['dmapi_lib'],
                     private_library=True,
                     vars=locals())