From 2bde9636888067210dc38523b6fafaa0b179ec3b Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Tue, 15 Jan 2013 17:22:58 +0100 Subject: 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 --- source3/Makefile.in | 1 + source3/smbd/smb2_ioctl_network_fs.c | 49 ++++++++++++++++++++++++++++++++++-- source3/wscript_build | 1 + 3 files changed, 49 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index ae4cf35053..80cb27c404 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -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) \ diff --git a/source3/smbd/smb2_ioctl_network_fs.c b/source3/smbd/smb2_ioctl_network_fs.c index bfc39e3bd5..22eaf57a4b 100644 --- a/source3/smbd/smb2_ioctl_network_fs.c +++ b/source3/smbd/smb2_ioctl_network_fs.c @@ -23,8 +23,10 @@ #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; diff --git a/source3/wscript_build b/source3/wscript_build index 2f26c0308a..2e07fad796 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -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()) -- cgit