The branch, master has been updated via c11c4df s3:smb2_ioctl: allow functions to disconnect the smb connection via 7e7c4ba libcli/smb/smb_constants: add FSCTL_VALIDATE_NEGOTIATE_INFO* via 739bd25 s3:smb2_ioctl: FSCTL_SRV_ENUMERATE_SNAPSHOTS is handles in SMB_VFS_FSCTL() via 5e998b8 s3:smb2_ioctl: call SMB_VFS_FSCTL() as fallback for non SMB2 specific functions from 61546b5 samba4: When running samba_dnsupdate during tests, use the test smb.conf.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit c11c4df762fd9e17bc8c5a422528bb80eae85e21 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 10 13:47:46 2012 +0200 s3:smb2_ioctl: allow functions to disconnect the smb connection metze Autobuild-User: Stefan Metzmacher <me...@samba.org> Autobuild-Date: Fri May 11 20:15:37 CEST 2012 on sn-devel-104 commit 7e7c4ba6f856488e4efc2c654b0073dbd8cc264a Author: Stefan Metzmacher <me...@samba.org> Date: Wed May 9 21:32:33 2012 +0200 libcli/smb/smb_constants: add FSCTL_VALIDATE_NEGOTIATE_INFO* metze commit 739bd25fe0ac2ecfb26a39ffb13cd7b5f84f8e49 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 10 18:33:12 2012 +0200 s3:smb2_ioctl: FSCTL_SRV_ENUMERATE_SNAPSHOTS is handles in SMB_VFS_FSCTL() metze commit 5e998b805ffb03c8cde1f81fd79e6763f061d1b6 Author: Stefan Metzmacher <me...@samba.org> Date: Thu May 10 17:43:36 2012 +0200 s3:smb2_ioctl: call SMB_VFS_FSCTL() as fallback for non SMB2 specific functions metze ----------------------------------------------------------------------- Summary of changes: libcli/smb/smb_constants.h | 8 ++ source3/smbd/smb2_ioctl.c | 159 +++++++++++--------------------------------- 2 files changed, 47 insertions(+), 120 deletions(-) Changeset truncated at 500 lines: diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index 3b53dab..4b7d1f2 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -394,4 +394,12 @@ enum csc_policy { #define FSCTL_SRV_READ_HASH (FSCTL_NETWORK_FILESYSTEM | FSCTL_ACCESS_READ| 0x01B8 | FSCTL_METHOD_NEITHER) #define FSCTL_LMR_REQ_RESILIENCY (FSCTL_NETWORK_FILESYSTEM | FSCTL_ACCESS_ANY | 0x01D4 | FSCTL_METHOD_BUFFERED) +/* + * FSCTL_VALIDATE_NEGOTIATE_INFO_224 was used used in + * Windows 8 server beta with SMB 2.24 + */ +#define FSCTL_VALIDATE_NEGOTIATE_INFO_224 \ + (FSCTL_NETWORK_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0200 | FSCTL_METHOD_BUFFERED) +#define FSCTL_VALIDATE_NEGOTIATE_INFO (FSCTL_NETWORK_FILESYSTEM | FSCTL_ACCESS_ANY | 0x0204 | FSCTL_METHOD_BUFFERED) + #endif /* _SMB_CONSTANTS_H */ diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c index d537a87..4bbb8ae 100644 --- a/source3/smbd/smb2_ioctl.c +++ b/source3/smbd/smb2_ioctl.c @@ -36,7 +36,8 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx, uint32_t in_flags); static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - DATA_BLOB *out_output); + DATA_BLOB *out_output, + bool *disconnect); static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq); NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req) @@ -129,8 +130,11 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq) DATA_BLOB out_output_buffer = data_blob_null; NTSTATUS status; NTSTATUS error; /* transport error */ + bool disconnect = false; - status = smbd_smb2_ioctl_recv(subreq, req, &out_output_buffer); + status = smbd_smb2_ioctl_recv(subreq, req, + &out_output_buffer, + &disconnect); DEBUG(10,("smbd_smb2_request_ioctl_done: smbd_smb2_ioctl_recv returned " "%u status %s\n", @@ -138,6 +142,13 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq) nt_errstr(status) )); TALLOC_FREE(subreq); + if (disconnect) { + error = status; + smbd_server_connection_terminate(req->sconn, + nt_errstr(error)); + return; + } + if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { /* also ok */ } else if (!NT_STATUS_IS_OK(status)) { @@ -211,6 +222,7 @@ struct smbd_smb2_ioctl_state { DATA_BLOB in_input; uint32_t in_max_output; DATA_BLOB out_output; + bool disconnect; }; static void smbd_smb2_ioctl_pipe_write_done(struct tevent_req *subreq); @@ -377,24 +389,9 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx, req); return req; - case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */ - { - /* - * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots) - * and return their volume names. If max_data_count is 16, then it is just - * asking for the number of volumes and length of the combined names. - * - * pdata is the data allocated by our caller, but that uses - * total_data_count (which is 0 in our case) rather than max_data_count. - * Allocate the correct amount and return the pointer to let - * it be deallocated when we return. - */ - struct shadow_copy_data *shadow_data = NULL; - bool labels = False; - uint32_t labels_data_count = 0; - uint32_t data_count; - uint32_t i; - char *pdata; + default: { + uint8_t *out_data = NULL; + uint32_t out_data_len = 0; NTSTATUS status; if (fsp == NULL) { @@ -402,114 +399,33 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - if (in_max_output < 16) { - DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " - "in_max_output(%u) < 16 is invalid!\n", - in_max_output)); - tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); - return tevent_req_post(req, ev); - } - - if (in_max_output > 16) { - labels = True; - } - - shadow_data = talloc_zero(talloc_tos(), - struct shadow_copy_data); - if (tevent_req_nomem(shadow_data, req)) { - DEBUG(0,("TALLOC_ZERO() failed!\n")); + status = SMB_VFS_FSCTL(fsp, + state, + in_ctl_code, + smbreq->flags2, + in_input.data, + in_input.length, + &out_data, + in_max_output, + &out_data_len); + state->out_output = data_blob_const(out_data, out_data_len); + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); return tevent_req_post(req, ev); } - /* - * Call the VFS routine to actually do the work. - */ - if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels) - != 0) { - if (errno == ENOSYS) { - DEBUG(5, ("FSCTL_GET_SHADOW_COPY_DATA: " - "connectpath %s, not supported.\n", - smbreq->conn->connectpath)); - status = NT_STATUS_NOT_SUPPORTED; + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + if (IS_IPC(smbreq->conn)) { + status = NT_STATUS_FS_DRIVER_REQUIRED; } else { - DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " - "connectpath %s, failed.\n", - smbreq->conn->connectpath)); - status = map_nt_error_from_unix(errno); - } - TALLOC_FREE(shadow_data); - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - - labels_data_count = - (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL)) - + 2; - - if (labels) { - data_count = 12+labels_data_count+4; - } else { - data_count = 16; - } - - if (labels && (in_max_output < data_count)) { - DEBUG(0, ("FSCTL_GET_SHADOW_COPY_DATA: " - "in_max_output(%u) too small (%u) bytes " - "needed!\n", in_max_output, data_count)); - TALLOC_FREE(shadow_data); - tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); - return tevent_req_post(req, ev); - } - - state->out_output = data_blob_talloc(state, NULL, data_count); - if (tevent_req_nomem(state->out_output.data, req)) { - return tevent_req_post(req, ev); - } - - pdata = (char *)state->out_output.data; - - /* num_volumes 4 bytes */ - SIVAL(pdata, 0, shadow_data->num_volumes); - - if (labels) { - /* num_labels 4 bytes */ - SIVAL(pdata, 4, shadow_data->num_volumes); - } - - /* needed_data_count 4 bytes */ - SIVAL(pdata, 8, labels_data_count+4); - - pdata += 12; - - DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for " - "path[%s].\n", - shadow_data->num_volumes, fsp_str_dbg(fsp))); - if (labels && shadow_data->labels) { - for (i=0; i<shadow_data->num_volumes; i++) { - srvstr_push(pdata, smbreq->flags2, - pdata, shadow_data->labels[i], - 2*sizeof(SHADOW_COPY_LABEL), - STR_UNICODE|STR_TERMINATE); - pdata += 2*sizeof(SHADOW_COPY_LABEL); - DEBUGADD(10, ("Label[%u]: '%s'\n", i, - shadow_data->labels[i])); + status = NT_STATUS_INVALID_DEVICE_REQUEST; } } - TALLOC_FREE(shadow_data); - - tevent_req_done(req); - return tevent_req_post(req, ev); - } - - default: - if (IS_IPC(smbreq->conn)) { - tevent_req_nterror(req, NT_STATUS_FS_DRIVER_REQUIRED); - return tevent_req_post(req, ev); - } - tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST); + tevent_req_nterror(req, status); return tevent_req_post(req, ev); } + } tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return tevent_req_post(req, ev); @@ -598,12 +514,15 @@ static void smbd_smb2_ioctl_pipe_read_done(struct tevent_req *subreq) static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - DATA_BLOB *out_output) + DATA_BLOB *out_output, + bool *disconnect) { NTSTATUS status = NT_STATUS_OK; struct smbd_smb2_ioctl_state *state = tevent_req_data(req, struct smbd_smb2_ioctl_state); + *disconnect = state->disconnect; + if (tevent_req_is_nterror(req, &status)) { if (!NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { tevent_req_received(req); -- Samba Shared Repository