[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-2068-g140fe78

Stefan Metzmacher metze at samba.org
Fri Jun 5 18:20:20 GMT 2009


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 <metze at 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 <metze at 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 <metze at 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 <metze at 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 <metze at 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


More information about the samba-cvs mailing list