The branch, master has been updated via 140fe782a9f249f58c93e56753e6e8646783d19b (commit) via d1db140a73e6d443fb2f82ea6a02479c98e97e67 (commit) via 76acd7bfad6b1853d73d27f62396aa6ce541f269 (commit) via ee83d1aead1a166af9554709d5e1c522d9c147cb (commit) via 014ee5d0c21cd18d6c408c8e49331f0aa8611211 (commit) from a3e328859b0004b974d38f0feae8ca6894c9b014 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 140fe782a9f249f58c93e56753e6e8646783d19b Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 5 18:38:20 2009 +0200 s3:smbd: add support for SMB2 Ioctl FSCTL_DFS_GET_REFERRALS metze commit d1db140a73e6d443fb2f82ea6a02479c98e97e67 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 5 20:14:17 2009 +0200 s3:smbd: add support for STATUS_BUFFER_OVERFLOW to SMB2 Ioctl metze commit 76acd7bfad6b1853d73d27f62396aa6ce541f269 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 5 20:02:21 2009 +0200 s3:smbd: keep the chain_fsp for SMB2 requests metze commit ee83d1aead1a166af9554709d5e1c522d9c147cb Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 5 19:49:40 2009 +0200 s3:smbd: fix the logic for compounded requests metze commit 014ee5d0c21cd18d6c408c8e49331f0aa8611211 Author: Stefan Metzmacher <me...@samba.org> Date: Fri Jun 5 19:46:27 2009 +0200 s3:smbd: only setup the dyn iovec if a a dyn blob is given Otherwise leave the default in there, which takes care of padding for compounded requests. metze ----------------------------------------------------------------------- Summary of changes: source3/smbd/globals.h | 2 + source3/smbd/smb2_create.c | 2 + source3/smbd/smb2_glue.c | 1 + source3/smbd/smb2_ioctl.c | 89 +++++++++++++++++++++++++++++++++++++++++-- source3/smbd/smb2_server.c | 5 +- 5 files changed, 91 insertions(+), 8 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index db19a3a..581e5b1 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -227,6 +227,8 @@ struct smbd_smb2_request { int current_idx; bool do_signing; + struct files_struct *compat_chain_fsp; + struct { /* the NBT header is not allocated */ uint8_t nbt_hdr[4]; diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 5d379ec..d1472d5 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -275,6 +275,8 @@ static NTSTATUS smbd_smb2_create(struct smbd_smb2_request *req, } } + req->compat_chain_fsp = smbreq->chain_fsp; + *out_oplock_level = 0; if ((in_create_disposition == FILE_SUPERSEDE) && (info == FILE_WAS_OVERWRITTEN)) { diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c index c3c3854..5fa3bd2 100644 --- a/source3/smbd/smb2_glue.c +++ b/source3/smbd/smb2_glue.c @@ -46,6 +46,7 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req) if (IVAL(inhdr, SMB2_HDR_FLAGS) & SMB2_HDR_FLAG_DFS) { smbreq->flags2 |= FLAGS2_DFS_PATHNAMES; } + smbreq->chain_fsp = req->compat_chain_fsp; return smbreq; } diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c index e7a3d35..4a00e9d 100644 --- a/source3/smbd/smb2_ioctl.c +++ b/source3/smbd/smb2_ioctl.c @@ -120,7 +120,9 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq) status = smbd_smb2_ioctl_recv(subreq, req, &out_output_buffer); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { + /* also ok */ + } else if (!NT_STATUS_IS_OK(status)) { error = smbd_smb2_request_error(req, status); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(req->conn, @@ -166,7 +168,8 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq) */ outdyn = out_output_buffer; - error = smbd_smb2_request_done(req, outbody, &outdyn); + error = smbd_smb2_request_done_ex(req, status, outbody, &outdyn, + __location__); if (!NT_STATUS_IS_OK(error)) { smbd_server_connection_terminate(req->conn, nt_errstr(error)); @@ -240,6 +243,80 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx, } switch (in_ctl_code) { + case 0x00060194: /* FSCTL_DFS_GET_REFERRALS */ + { + uint16_t in_max_referral_level; + DATA_BLOB in_file_name_buffer; + char *in_file_name_string; + size_t in_file_name_string_size; + bool ok; + bool overflow = false; + NTSTATUS status; + int dfs_size; + char *dfs_data = NULL; + + if (!IS_IPC(smbreq->conn)) { + tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST); + return tevent_req_post(req, ev); + } + + if (!lp_host_msdfs()) { + tevent_req_nterror(req, NT_STATUS_FS_DRIVER_REQUIRED); + return tevent_req_post(req, ev); + } + + if (in_input.length < (2 + 2)) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + in_max_referral_level = SVAL(in_input.data, 0); + in_file_name_buffer.data = in_input.data + 2; + in_file_name_buffer.length = in_input.length - 2; + + ok = convert_string_talloc(state, CH_UTF16, CH_UNIX, + in_file_name_buffer.data, + in_file_name_buffer.length, + &in_file_name_string, + &in_file_name_string_size, false); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_ILLEGAL_CHARACTER); + return tevent_req_post(req, ev); + } + + dfs_size = setup_dfs_referral(smbreq->conn, + in_file_name_string, + in_max_referral_level, + &dfs_data, &status); + if (dfs_size < 0) { + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + if (dfs_size > in_max_output) { + /* + * TODO: we need a testsuite for this + */ + overflow = true; + dfs_size = in_max_output; + } + + state->out_output = data_blob_talloc(state, + (uint8_t *)dfs_data, + dfs_size); + SAFE_FREE(dfs_data); + if (dfs_size > 0 && + tevent_req_nomem(state->out_output.data, req)) { + return tevent_req_post(req, ev); + } + + if (overflow) { + tevent_req_nterror(STATUS_BUFFER_OVERFLOW); + } else { + tevent_req_done(req); + } + return tevent_req_post(req, ev); + } case 0x0011C017: /* FSCTL_PIPE_TRANSCEIVE */ if (!IS_IPC(smbreq->conn)) { @@ -351,13 +428,15 @@ static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req, struct smbd_smb2_ioctl_state); if (tevent_req_is_nterror(req, &status)) { - tevent_req_received(req); - return status; + if (!NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { + tevent_req_received(req); + return status; + } } *out_output = state->out_output; talloc_steal(mem_ctx, out_output->data); tevent_req_received(req); - return NT_STATUS_OK; + return status; } diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 75138a8..0413832 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -514,7 +514,7 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) req->current_idx += 3; - if (req->current_idx > req->in.vector_count) { + if (req->current_idx < req->out.vector_count) { struct timeval zero = timeval_zero(); subreq = tevent_wakeup_send(req, req->conn->smb2.event_ctx, @@ -663,8 +663,7 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, req->out.vector[i+2].iov_base = (void *)dyn->data; req->out.vector[i+2].iov_len = dyn->length; } else { - req->out.vector[i+2].iov_base = (void *)outdyn; - req->out.vector[i+2].iov_len = 1; + /* the dyn section is already initialized */ } } else { req->out.vector[i+2].iov_base = NULL; -- Samba Shared Repository