[SCM] Samba Shared Repository - branch master updated - 15c942657d4767663d2164a3089253f8dde8b413

Volker Lendecke vlendec at samba.org
Mon Dec 8 21:10:22 GMT 2008


The branch, master has been updated
       via  15c942657d4767663d2164a3089253f8dde8b413 (commit)
       via  2bd8a6e21ed9e52373bc04b12e2d4b80881edb8b (commit)
       via  7fbb64d726f23da49cd2f07e1a678ed575b70bfa (commit)
       via  f9aa69ae352f7f441b04976575b96ecc8b844dbd (commit)
       via  ed25c6c287ca4f5d019d5f0012b1ff40d5e8e328 (commit)
       via  f0bb53dd0fc0d8b2191eda7fc857f146093e0f83 (commit)
      from  53c41661bd9692c7bdba04b7de6adc3887ab529f (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 15c942657d4767663d2164a3089253f8dde8b413
Author: Volker Lendecke <vl at sernet.de>
Date:   Mon Dec 1 08:25:25 2008 +0100

    Add wb_trans_send/revc

commit 2bd8a6e21ed9e52373bc04b12e2d4b80881edb8b
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Nov 28 19:54:46 2008 +0100

    Add infrastructure to transfer winbindd_request/response asynchronously

commit 7fbb64d726f23da49cd2f07e1a678ed575b70bfa
Author: Volker Lendecke <vl at sernet.de>
Date:   Mon Dec 1 08:23:35 2008 +0100

    Simplify async programming a bit with helper routines
    
    Introduce async_req_is_error() and async_req_simple_recv()

commit f9aa69ae352f7f441b04976575b96ecc8b844dbd
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Nov 28 19:52:52 2008 +0100

    Streamline the async_sock API a bit

commit ed25c6c287ca4f5d019d5f0012b1ff40d5e8e328
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Nov 16 18:02:17 2008 +0100

    Add a "bytes_padding" parameter to smb_splice_chain
    
    For example open&x and write&x needs the bytes to be aligned relative to the
    SMB header. In particular for write&x we should not have to move stuff around.

commit f0bb53dd0fc0d8b2191eda7fc857f146093e0f83
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Nov 12 18:43:34 2008 +0100

    Factor out smb_splice_chain(), to be used by chain_reply() in smbd

-----------------------------------------------------------------------

Summary of changes:
 source3/Makefile.in                  |    1 +
 source3/include/async_req.h          |    4 +
 source3/include/async_smb.h          |    4 +
 source3/include/async_sock.h         |   22 +-
 source3/lib/async_req.c              |   23 ++
 source3/lib/async_sock.c             |   61 ++--
 source3/libsmb/async_smb.c           |  160 ++++++---
 source3/libsmb/clientgen.c           |    7 +-
 source3/libsmb/clifile.c             |   11 +-
 source3/libsmb/clireadwrite.c        |   11 +-
 source3/libsmb/clitrans.c            |    6 +-
 source3/winbindd/winbindd_proto.h    |   30 ++
 source3/winbindd/winbindd_reqtrans.c |  685 ++++++++++++++++++++++++++++++++++
 13 files changed, 916 insertions(+), 109 deletions(-)
 create mode 100644 source3/winbindd/winbindd_reqtrans.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 83e94a4..bf79a7d 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1036,6 +1036,7 @@ IDMAP_ADEX_OBJ = \
 
 WINBINDD_OBJ1 = \
 		winbindd/winbindd.o       \
+		winbindd/winbindd_reqtrans.o \
 		winbindd/winbindd_user.o  \
 		winbindd/winbindd_group.o \
 		winbindd/winbindd_util.o  \
diff --git a/source3/include/async_req.h b/source3/include/async_req.h
index 2d01b53..14a3069 100644
--- a/source3/include/async_req.h
+++ b/source3/include/async_req.h
@@ -134,4 +134,8 @@ bool async_post_status(struct async_req *req, NTSTATUS status);
 
 bool async_req_nomem(const void *p, struct async_req *req);
 
+bool async_req_is_error(struct async_req *req, NTSTATUS *status);
+
+NTSTATUS async_req_simple_recv(struct async_req *req);
+
 #endif
diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h
index 4e20618..25fd353 100644
--- a/source3/include/async_smb.h
+++ b/source3/include/async_smb.h
@@ -125,6 +125,10 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev,
 		    size_t size_hint);
 void cli_chain_uncork(struct cli_state *cli);
 bool cli_in_chain(struct cli_state *cli);
+bool smb_splice_chain(char **poutbuf, uint8_t smb_command,
+		      uint8_t wct, const uint16_t *vwv,
+		      size_t bytes_alignment,
+		      uint16_t num_bytes, const uint8_t *bytes);
 
 NTSTATUS cli_pull_reply(struct async_req *req,
 			uint8_t *pwct, uint16_t **pvwv,
diff --git a/source3/include/async_sock.h b/source3/include/async_sock.h
index 3c90453..f0cd5fd 100644
--- a/source3/include/async_sock.h
+++ b/source3/include/async_sock.h
@@ -22,24 +22,28 @@
 
 #include "includes.h"
 
-ssize_t async_syscall_result_ssize_t(struct async_req **req, int *perrno);
-size_t  async_syscall_result_size_t (struct async_req **req, int *perrno);
-ssize_t async_syscall_result_int    (struct async_req **req, int *perrno);
+ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno);
+size_t async_syscall_result_size_t(struct async_req *req, int *perrno);
+ssize_t async_syscall_result_int(struct async_req *req, int *perrno);
 
 struct async_req *async_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
 			     int fd, const void *buffer, size_t length,
 			     int flags);
-struct async_req *async_sendall(TALLOC_CTX *mem_ctx, struct event_context *ev,
-				int fd, const void *buffer, size_t length,
-				int flags);
 struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct event_context *ev,
 			     int fd, void *buffer, size_t length,
 			     int flags);
-struct async_req *async_recvall(TALLOC_CTX *mem_ctx, struct event_context *ev,
-				int fd, void *buffer, size_t length,
-				int flags);
 struct async_req *async_connect(TALLOC_CTX *mem_ctx, struct event_context *ev,
 				int fd, const struct sockaddr *address,
 				socklen_t address_len);
 
+struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+			       int fd, const void *buffer, size_t length,
+			       int flags);
+NTSTATUS sendall_recv(struct async_req *req);
+
+struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+			       int fd, void *buffer, size_t length,
+			       int flags);
+NTSTATUS recvall_recv(struct async_req *req);
+
 #endif
diff --git a/source3/lib/async_req.c b/source3/lib/async_req.c
index 501a6b5..159666f 100644
--- a/source3/lib/async_req.c
+++ b/source3/lib/async_req.c
@@ -172,3 +172,26 @@ bool async_req_nomem(const void *p, struct async_req *req)
 	async_req_error(req, NT_STATUS_NO_MEMORY);
 	return true;
 }
+
+bool async_req_is_error(struct async_req *req, NTSTATUS *status)
+{
+	if (req->state < ASYNC_REQ_DONE) {
+		*status = NT_STATUS_INTERNAL_ERROR;
+		return true;
+	}
+	if (req->state == ASYNC_REQ_ERROR) {
+		*status = req->status;
+		return true;
+	}
+	return false;
+}
+
+NTSTATUS async_req_simple_recv(struct async_req *req)
+{
+	NTSTATUS status;
+
+	if (async_req_is_error(req, &status)) {
+		return status;
+	}
+	return NT_STATUS_OK;
+}
diff --git a/source3/lib/async_sock.c b/source3/lib/async_sock.c
index ffba6de..225cc7b 100644
--- a/source3/lib/async_sock.c
+++ b/source3/lib/async_sock.c
@@ -177,18 +177,13 @@ static struct async_req *async_fde_syscall_new(
  * @retval The return value from the asynchronously called syscall
  */
 
-ssize_t async_syscall_result_ssize_t(struct async_req **req, int *perrno)
+ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno)
 {
 	struct async_syscall_state *state = talloc_get_type_abort(
-		(*req)->private_data, struct async_syscall_state);
-
-	int sys_errno = state->sys_errno;
-	ssize_t result = state->result.result_ssize_t;
-
-	TALLOC_FREE(*req);
+		req->private_data, struct async_syscall_state);
 
-	*perrno = sys_errno;
-	return result;
+	*perrno = state->sys_errno;
+	return state->result.result_ssize_t;
 }
 
 /**
@@ -198,18 +193,13 @@ ssize_t async_syscall_result_ssize_t(struct async_req **req, int *perrno)
  * @retval The return value from the asynchronously called syscall
  */
 
-size_t async_syscall_result_size_t(struct async_req **req, int *perrno)
+size_t async_syscall_result_size_t(struct async_req *req, int *perrno)
 {
 	struct async_syscall_state *state = talloc_get_type_abort(
-		(*req)->private_data, struct async_syscall_state);
-
-	int sys_errno = state->sys_errno;
-	size_t result = state->result.result_ssize_t;
-
-	TALLOC_FREE(*req);
+		req->private_data, struct async_syscall_state);
 
-	*perrno = sys_errno;
-	return result;
+	*perrno = state->sys_errno;
+	return state->result.result_size_t;
 }
 
 /**
@@ -219,18 +209,13 @@ size_t async_syscall_result_size_t(struct async_req **req, int *perrno)
  * @retval The return value from the asynchronously called syscall
  */
 
-ssize_t async_syscall_result_int(struct async_req **req, int *perrno)
+ssize_t async_syscall_result_int(struct async_req *req, int *perrno)
 {
 	struct async_syscall_state *state = talloc_get_type_abort(
-		(*req)->private_data, struct async_syscall_state);
-
-	int sys_errno = state->sys_errno;
-	int result = state->result.result_ssize_t;
-
-	TALLOC_FREE(*req);
+		req->private_data, struct async_syscall_state);
 
-	*perrno = sys_errno;
-	return result;
+	*perrno = state->sys_errno;
+	return state->result.result_int;
 }
 
 /**
@@ -353,9 +338,9 @@ static void async_sendall_callback(struct event_context *ev,
  * "length" bytes
  */
 
-struct async_req *async_sendall(TALLOC_CTX *mem_ctx, struct event_context *ev,
-				int fd, const void *buffer, size_t length,
-				int flags)
+struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+			       int fd, const void *buffer, size_t length,
+			       int flags)
 {
 	struct async_req *result;
 	struct async_syscall_state *state;
@@ -377,6 +362,11 @@ struct async_req *async_sendall(TALLOC_CTX *mem_ctx, struct event_context *ev,
 	return result;
 }
 
+NTSTATUS sendall_recv(struct async_req *req)
+{
+	return async_req_simple_recv(req);
+}
+
 /**
  * fde event handler for the "recv" syscall
  * @param[in] ev	The event context that sent us here
@@ -498,9 +488,9 @@ static void async_recvall_callback(struct event_context *ev,
  * async_recvall will call recv(2) until "length" bytes are received
  */
 
-struct async_req *async_recvall(TALLOC_CTX *mem_ctx, struct event_context *ev,
-				int fd, void *buffer, size_t length,
-				int flags)
+struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+			       int fd, void *buffer, size_t length,
+			       int flags)
 {
 	struct async_req *result;
 	struct async_syscall_state *state;
@@ -522,6 +512,11 @@ struct async_req *async_recvall(TALLOC_CTX *mem_ctx, struct event_context *ev,
 	return result;
 }
 
+NTSTATUS recvall_recv(struct async_req *req)
+{
+	return async_req_simple_recv(req);
+}
+
 /**
  * fde event handler for connect(2)
  * @param[in] ev	The event context that sent us here
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index d371e05..fd2fe93 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -218,6 +218,118 @@ static bool find_andx_cmd_ofs(char *buf, size_t *pofs)
 }
 
 /**
+ * @brief Do the smb chaining at a buffer level
+ * @param[in] poutbuf		Pointer to the talloc'ed buffer to be modified
+ * @param[in] smb_command	The command that we want to issue
+ * @param[in] wct		How many words?
+ * @param[in] vwv		The words, already in network order
+ * @param[in] bytes_alignment	How shall we align "bytes"?
+ * @param[in] num_bytes		How many bytes?
+ * @param[in] bytes		The data the request ships
+ *
+ * smb_splice_chain() adds the vwv and bytes to the request already present in
+ * *poutbuf.
+ */
+
+bool smb_splice_chain(char **poutbuf, uint8_t smb_command,
+		      uint8_t wct, const uint16_t *vwv,
+		      size_t bytes_alignment,
+		      uint16_t num_bytes, const uint8_t *bytes)
+{
+	char *outbuf;
+	size_t old_size, new_size;
+	size_t ofs;
+	size_t chain_padding = 0;
+	size_t bytes_padding = 0;
+	bool first_request;
+
+	old_size = talloc_get_size(*poutbuf);
+
+	/*
+	 * old_size == smb_wct means we're pushing the first request in for
+	 * libsmb/
+	 */
+
+	first_request = (old_size == smb_wct);
+
+	if (!first_request && ((old_size % 4) != 0)) {
+		/*
+		 * Align the wct field of subsequent requests to a 4-byte
+		 * boundary
+		 */
+		chain_padding = 4 - (old_size % 4);
+	}
+
+	/*
+	 * After the old request comes the new wct field (1 byte), the vwv's
+	 * and the num_bytes field. After at we might need to align the bytes
+	 * given to us to "bytes_alignment", increasing the num_bytes value.
+	 */
+
+	new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
+
+	if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
+		bytes_padding = bytes_alignment + (new_size % bytes_alignment);
+	}
+
+	new_size += bytes_padding + num_bytes;
+
+	if (new_size > 0xffff) {
+		DEBUG(1, ("splice_chain: %u bytes won't fit\n",
+			  (unsigned)new_size));
+		return false;
+	}
+
+	outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, char, new_size);
+	if (outbuf == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		return false;
+	}
+	*poutbuf = outbuf;
+
+	if (first_request) {
+		SCVAL(outbuf, smb_com, smb_command);
+	} else {
+		size_t andx_cmd_ofs;
+
+		if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
+			DEBUG(1, ("invalid command chain\n"));
+			*poutbuf = TALLOC_REALLOC_ARRAY(
+				NULL, *poutbuf, char, old_size);
+			return false;
+		}
+
+		if (chain_padding != 0) {
+			memset(outbuf + old_size, 0, chain_padding);
+			old_size += chain_padding;
+		}
+
+		SCVAL(outbuf, andx_cmd_ofs, smb_command);
+		SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
+	}
+
+	ofs = old_size;
+
+	SCVAL(outbuf, ofs, wct);
+	ofs += 1;
+
+	memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
+	ofs += sizeof(uint16_t) * wct;
+
+	SSVAL(outbuf, ofs, num_bytes + bytes_padding);
+	ofs += sizeof(uint16_t);
+
+	if (bytes_padding != 0) {
+		memset(outbuf + ofs, 0, bytes_padding);
+		ofs += bytes_padding;
+	}
+
+	memcpy(outbuf + ofs, bytes, num_bytes);
+
+	return true;
+}
+
+/**
  * @brief Destroy an async_req that is the visible part of a cli_request
  * @param[in] req	The request to kill
  * @retval Return 0 to make talloc happy
@@ -286,10 +398,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx,
 					   const uint8_t *bytes)
 {
 	struct async_req **tmp_reqs;
-	char *tmp_buf;
 	struct cli_request *req;
-	size_t old_size, new_size;
-	size_t ofs;
 
 	req = cli->chain_accumulator;
 
@@ -313,52 +422,11 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx,
 	talloc_set_destructor(req->async[req->num_async-1],
 			      cli_async_req_destructor);
 
-	old_size = talloc_get_size(req->outbuf);
-
-	/*
-	 * We need space for the wct field, the words, the byte count field
-	 * and the bytes themselves.
-	 */
-	new_size = old_size + 1 + wct * sizeof(uint16_t) + 2 + num_bytes;
-
-	if (new_size > 0xffff) {
-		DEBUG(1, ("cli_request_chain: %u bytes won't fit\n",
-			  (unsigned)new_size));
+	if (!smb_splice_chain(&req->outbuf, smb_command, wct, vwv,
+			      0, num_bytes, bytes)) {
 		goto fail;
 	}
 
-	tmp_buf = TALLOC_REALLOC_ARRAY(NULL, req->outbuf, char, new_size);
-	if (tmp_buf == NULL) {
-		DEBUG(0, ("talloc failed\n"));
-		goto fail;
-	}
-	req->outbuf = tmp_buf;
-
-	if (old_size == smb_wct) {
-		SCVAL(req->outbuf, smb_com, smb_command);
-	} else {
-		size_t andx_cmd_ofs;
-		if (!find_andx_cmd_ofs(req->outbuf, &andx_cmd_ofs)) {
-			DEBUG(1, ("invalid command chain\n"));
-			goto fail;
-		}
-		SCVAL(req->outbuf, andx_cmd_ofs, smb_command);
-		SSVAL(req->outbuf, andx_cmd_ofs + 2, old_size - 4);
-	}
-
-	ofs = old_size;
-
-	SCVAL(req->outbuf, ofs, wct);
-	ofs += 1;
-
-	memcpy(req->outbuf + ofs, vwv, sizeof(uint16_t) * wct);
-	ofs += sizeof(uint16_t) * wct;
-
-	SSVAL(req->outbuf, ofs, num_bytes);
-	ofs += sizeof(uint16_t);
-
-	memcpy(req->outbuf + ofs, bytes, num_bytes);
-
 	return req->async[req->num_async-1];
 
  fail:
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 8a5aedf..d944278 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -732,12 +732,7 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
 
 NTSTATUS cli_echo_recv(struct async_req *req)
 {
-	SMB_ASSERT(req->state >= ASYNC_REQ_DONE);
-	if (req->state == ASYNC_REQ_ERROR) {
-		return req->status;
-	}
-
-	return NT_STATUS_OK;
+	return async_req_simple_recv(req);
 }
 
 /**
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index a9e8108..733abb6 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -908,9 +908,8 @@ NTSTATUS cli_open_recv(struct async_req *req, int *fnum)
 	uint8_t *bytes;
 	NTSTATUS status;
 
-	SMB_ASSERT(req->state >= ASYNC_REQ_DONE);
-	if (req->state == ASYNC_REQ_ERROR) {
-		return req->status;
+	if (async_req_is_error(req, &status)) {
+		return status;
 	}
 
 	status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
@@ -985,10 +984,10 @@ NTSTATUS cli_close_recv(struct async_req *req)
 	uint16_t *vwv;
 	uint16_t num_bytes;
 	uint8_t *bytes;
+	NTSTATUS status;
 
-	SMB_ASSERT(req->state >= ASYNC_REQ_DONE);
-	if (req->state == ASYNC_REQ_ERROR) {
-		return req->status;
+	if (async_req_is_error(req, &status)) {
+		return status;
 	}
 
 	return cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c
index cc98268..ecf4939 100644
--- a/source3/libsmb/clireadwrite.c
+++ b/source3/libsmb/clireadwrite.c
@@ -112,9 +112,8 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received,
 	NTSTATUS status;
 	size_t size;
 
-	SMB_ASSERT(req->state >= ASYNC_REQ_DONE);
-	if (req->state == ASYNC_REQ_ERROR) {
-		return req->status;
+	if (async_req_is_error(req, &status)) {
+		return status;
 	}
 
 	status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
@@ -405,10 +404,10 @@ NTSTATUS cli_pull_recv(struct async_req *req, SMB_OFF_T *received)
 {
 	struct cli_pull_state *state = talloc_get_type_abort(
 		req->private_data, struct cli_pull_state);
+	NTSTATUS status;
 
-	SMB_ASSERT(req->state >= ASYNC_REQ_DONE);
-	if (req->state == ASYNC_REQ_ERROR) {
-		return req->status;
+	if (async_req_is_error(req, &status)) {
+		return status;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list