[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Fri Aug 12 11:39:04 MDT 2011


The branch, master has been updated
       via  eeb0298 s3:smb2cli: pass more fields to smb2cli_req_create()/smb2cli_req_send()
       via  28c4d2d s3:smb2cli: allow 32bit dyn_len in smb2cli_req_create()/smb2cli_req_send()
       via  b41d44e s3:libsmb: keep a cli_smb_state->one_way
       via  c485df9 s3:libsmb: abstract the incoming dispatch function via a function pointer
       via  58003b5 s3:libsmb: split out cli_state_dispatch_smb1() from cli_smb_received()
       via  9b15963 s3:libsmb: add missing TALLOC_FREE(frame) to cli_smb_received()
      from  42cde04 s3:smb2_server: make sure we prefer responses over requests on the client socket

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


- Log -----------------------------------------------------------------
commit eeb0298ac1ba70d5114b48d7de4549e80d83e709
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 12 17:26:13 2011 +0200

    s3:smb2cli: pass more fields to smb2cli_req_create()/smb2cli_req_send()
    
    The caller should take care of the global cli_state values.
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Fri Aug 12 19:38:27 CEST 2011 on sn-devel-104

commit 28c4d2d0f318d017e356cf8e80ff0da516346fee
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 12 17:23:04 2011 +0200

    s3:smb2cli: allow 32bit dyn_len in smb2cli_req_create()/smb2cli_req_send()
    
    metze

commit b41d44eda3ae7d72b3ddcfbd749b19f900bcd958
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 12 17:40:04 2011 +0200

    s3:libsmb: keep a cli_smb_state->one_way
    
    This moves the SMB1 specific stuff to cli_smb_req_create(),
    instead of having it in the core dispatching code.
    
    metze

commit c485df9530fda65fb1a2142f53c60638d2ca1923
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 12 14:50:09 2011 +0200

    s3:libsmb: abstract the incoming dispatch function via a function pointer
    
    This will allow handling of SMB2 in future.
    
    metze

commit 58003b5a77910ec54fd84f71a26e582af0f83e98
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 12 14:41:23 2011 +0200

    s3:libsmb: split out cli_state_dispatch_smb1() from cli_smb_received()
    
    metze

commit 9b15963695ab196380834af703e9f193092a2263
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 12 14:44:44 2011 +0200

    s3:libsmb: add missing TALLOC_FREE(frame) to cli_smb_received()
    
    metze

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

Summary of changes:
 source3/include/client.h                 |   11 +++
 source3/libsmb/async_smb.c               |  144 ++++++++++++++++++------------
 source3/libsmb/smb2cli_base.c            |   26 ++++--
 source3/libsmb/smb2cli_base.h            |   16 +++-
 source3/libsmb/smb2cli_close.c           |    6 +-
 source3/libsmb/smb2cli_create.c          |    6 +-
 source3/libsmb/smb2cli_flush.c           |    6 +-
 source3/libsmb/smb2cli_negprot.c         |    5 +-
 source3/libsmb/smb2cli_query_directory.c |    6 +-
 source3/libsmb/smb2cli_read.c            |    6 +-
 source3/libsmb/smb2cli_session.c         |   11 ++-
 source3/libsmb/smb2cli_tcon.c            |   12 ++-
 source3/libsmb/smb2cli_write.c           |    6 +-
 13 files changed, 183 insertions(+), 78 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/client.h b/source3/include/client.h
index f44e52f..79ce709 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -128,6 +128,17 @@ struct cli_state {
 		struct tevent_req *read_smb_req;
 		struct tevent_queue *outgoing;
 		struct tevent_req **pending;
+		/*
+		 * The incoming dispatch function should return:
+		 * - NT_STATUS_RETRY, if more incoming PDUs are expected.
+		 * - NT_STATUS_OK, if no more processing is desired, e.g.
+		 *                 the dispatch function called
+		 *                 tevent_req_done().
+		 * - All other return values disconnect the connection.
+		 */
+		NTSTATUS (*dispatch_incoming)(struct cli_state *cli,
+					      TALLOC_CTX *frame,
+					      uint8_t *inbuf);
 	} conn;
 
 	struct {
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index 488e953..5f2a644 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -89,6 +89,8 @@ struct cli_smb_state {
 	int chain_num;
 	int chain_length;
 	struct tevent_req **chained_requests;
+
+	bool one_way;
 };
 
 static uint16_t cli_alloc_mid(struct cli_state *cli)
@@ -228,6 +230,9 @@ bool cli_smb_req_set_pending(struct tevent_req *req)
 }
 
 static void cli_smb_received(struct tevent_req *subreq);
+static NTSTATUS cli_state_dispatch_smb1(struct cli_state *cli,
+					TALLOC_CTX *frame,
+					uint8_t *inbuf);
 
 static bool cli_state_receive_next(struct cli_state *cli)
 {
@@ -246,6 +251,8 @@ static bool cli_state_receive_next(struct cli_state *cli)
 	req = cli->conn.pending[0];
 	state = tevent_req_data(req, struct cli_smb_state);
 
+	cli->conn.dispatch_incoming = cli_state_dispatch_smb1;
+
 	/*
 	 * We're the first ones, add the read_smb request that waits for the
 	 * answer from the server
@@ -406,6 +413,22 @@ struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx,
 			tevent_req_oom(result);
 		}
 	}
+
+	switch (smb_command) {
+	case SMBtranss:
+	case SMBtranss2:
+	case SMBnttranss:
+	case SMBntcancel:
+		state->one_way = true;
+		break;
+	case SMBlockingX:
+		if ((wct == 8) &&
+		    (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
+			state->one_way = true;
+		}
+		break;
+	}
+
 	return result;
 }
 
@@ -556,21 +579,10 @@ static void cli_smb_sent(struct tevent_req *subreq)
 		return;
 	}
 
-	switch (CVAL(state->header, smb_com)) {
-	case SMBtranss:
-	case SMBtranss2:
-	case SMBnttranss:
-	case SMBntcancel:
+	if (state->one_way) {
 		state->inbuf = NULL;
 		tevent_req_done(req);
 		return;
-	case SMBlockingX:
-		if ((CVAL(state->header, smb_wct) == 8) &&
-		    (CVAL(state->vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
-			state->inbuf = NULL;
-			tevent_req_done(req);
-			return;
-		}
 	}
 
 	if (!cli_smb_req_set_pending(req)) {
@@ -584,21 +596,17 @@ static void cli_smb_received(struct tevent_req *subreq)
 	struct cli_state *cli = tevent_req_callback_data(
 		subreq, struct cli_state);
 	TALLOC_CTX *frame = talloc_stackframe();
-	struct tevent_req *req;
-	struct cli_smb_state *state;
 	NTSTATUS status;
 	uint8_t *inbuf;
 	ssize_t received;
-	int num_pending;
-	int i, err;
-	uint16_t mid;
-	bool oplock_break;
+	int err;
 
 	if (subreq != cli->conn.read_smb_req) {
 		DEBUG(1, ("Internal error: cli_smb_received called with "
 			  "unexpected subreq\n"));
 		status = NT_STATUS_INTERNAL_ERROR;
 		cli_state_notify_pending(cli, status);
+		TALLOC_FREE(frame);
 		return;
 	}
 
@@ -612,13 +620,48 @@ static void cli_smb_received(struct tevent_req *subreq)
 		return;
 	}
 
+	status = cli->conn.dispatch_incoming(cli, frame, inbuf);
+	TALLOC_FREE(frame);
+	if (NT_STATUS_IS_OK(status)) {
+		/*
+		 * We should not do any more processing
+		 * as the dispatch function called
+		 * tevent_req_done().
+		 */
+		return;
+	} else if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+		/*
+		 * We got an error, so notify all pending requests
+		 */
+		cli_state_notify_pending(cli, status);
+		return;
+	}
+
+	/*
+	 * We got NT_STATUS_RETRY, so we may ask for a
+	 * next incoming pdu.
+	 */
+	if (!cli_state_receive_next(cli)) {
+		cli_state_notify_pending(cli, NT_STATUS_NO_MEMORY);
+	}
+}
+
+static NTSTATUS cli_state_dispatch_smb1(struct cli_state *cli,
+					TALLOC_CTX *frame,
+					uint8_t *inbuf)
+{
+	struct tevent_req *req;
+	struct cli_smb_state *state;
+	NTSTATUS status;
+	int num_pending;
+	int i;
+	uint16_t mid;
+	bool oplock_break;
+
 	if ((IVAL(inbuf, 4) != 0x424d53ff) /* 0xFF"SMB" */
 	    && (SVAL(inbuf, 4) != 0x45ff)) /* 0xFF"E" */ {
 		DEBUG(10, ("Got non-SMB PDU\n"));
-		status = NT_STATUS_INVALID_NETWORK_RESPONSE;
-		cli_state_notify_pending(cli, status);
-		TALLOC_FREE(frame);
-		return;
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
 	}
 
 	if (cli_encryption_on(cli) && (CVAL(inbuf, 0) == 0)) {
@@ -628,19 +671,14 @@ static void cli_smb_received(struct tevent_req *subreq)
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(10, ("get_enc_ctx_num returned %s\n",
 				   nt_errstr(status)));
-			cli_state_notify_pending(cli, status);
-			TALLOC_FREE(frame);
-			return;
+			return status;
 		}
 
 		if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) {
 			DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
 				   enc_ctx_num,
 				   cli->trans_enc_state->enc_ctx_num));
-			status = NT_STATUS_INVALID_HANDLE;
-			cli_state_notify_pending(cli, status);
-			TALLOC_FREE(frame);
-			return;
+			return NT_STATUS_INVALID_HANDLE;
 		}
 
 		status = common_decrypt_buffer(cli->trans_enc_state,
@@ -648,9 +686,7 @@ static void cli_smb_received(struct tevent_req *subreq)
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(10, ("common_decrypt_buffer returned %s\n",
 				   nt_errstr(status)));
-			cli_state_notify_pending(cli, status);
-			TALLOC_FREE(frame);
-			return;
+			return status;
 		}
 	}
 
@@ -664,7 +700,7 @@ static void cli_smb_received(struct tevent_req *subreq)
 	}
 	if (i == num_pending) {
 		/* Dump unexpected reply */
-		goto done;
+		return NT_STATUS_RETRY;
 	}
 
 	oplock_break = false;
@@ -681,7 +717,7 @@ static void cli_smb_received(struct tevent_req *subreq)
 
 		if (!oplock_break) {
 			/* Dump unexpected reply */
-			goto done;
+			return NT_STATUS_RETRY;
 		}
 	}
 
@@ -691,27 +727,10 @@ static void cli_smb_received(struct tevent_req *subreq)
 	if (!oplock_break /* oplock breaks are not signed */
 	    && !cli_check_sign_mac(cli, (char *)inbuf, state->seqnum+1)) {
 		DEBUG(10, ("cli_check_sign_mac failed\n"));
-		status = NT_STATUS_ACCESS_DENIED;
-		cli_state_notify_pending(cli, status);
-		TALLOC_FREE(frame);
-		return;
+		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	if (state->chained_requests == NULL) {
-		state->inbuf = talloc_move(state, &inbuf);
-		cli_smb_req_unset_pending(req);
-		state->chain_num = 0;
-		state->chain_length = 1;
-
-		if (talloc_array_length(cli->conn.pending) == 0) {
-			tevent_req_done(req);
-			TALLOC_FREE(frame);
-			return;
-		}
-
-		tevent_req_defer_callback(req, state->ev);
-		tevent_req_done(req);
-	} else {
+	if (state->chained_requests != NULL) {
 		struct tevent_req **chain = talloc_move(frame,
 					    &state->chained_requests);
 		int num_chained = talloc_array_length(chain);
@@ -754,13 +773,24 @@ static void cli_smb_received(struct tevent_req *subreq)
 
 			tevent_req_done(req);
 		}
+
+		return NT_STATUS_RETRY;
 	}
- done:
-	TALLOC_FREE(frame);
 
-	if (!cli_state_receive_next(cli)) {
-		cli_state_notify_pending(cli, NT_STATUS_NO_MEMORY);
+	cli_smb_req_unset_pending(req);
+
+	state->inbuf = talloc_move(state, &inbuf);
+	state->chain_num = 0;
+	state->chain_length = 1;
+
+	if (talloc_array_length(cli->conn.pending) == 0) {
+		tevent_req_done(req);
+		return NT_STATUS_OK;
 	}
+
+	tevent_req_defer_callback(req, state->ev);
+	tevent_req_done(req);
+	return NT_STATUS_RETRY;
 }
 
 NTSTATUS cli_smb_recv(struct tevent_req *req,
diff --git a/source3/libsmb/smb2cli_base.c b/source3/libsmb/smb2cli_base.c
index e7ba517..9fc824c 100644
--- a/source3/libsmb/smb2cli_base.c
+++ b/source3/libsmb/smb2cli_base.c
@@ -32,7 +32,7 @@ struct smb2cli_req_state {
 	const uint8_t *fixed;
 	uint16_t fixed_len;
 	const uint8_t *dyn;
-	uint16_t dyn_len;
+	uint32_t dyn_len;
 
 	uint8_t nbt[4];
 	uint8_t hdr[64];
@@ -175,14 +175,19 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
 				      struct tevent_context *ev,
 				      struct cli_state *cli,
 				      uint16_t cmd,
-				      uint32_t flags,
+				      uint32_t additional_flags,
+				      uint32_t clear_flags,
+				      uint32_t pid,
+				      uint32_t tid,
+				      uint64_t uid,
 				      const uint8_t *fixed,
 				      uint16_t fixed_len,
 				      const uint8_t *dyn,
-				      uint16_t dyn_len)
+				      uint32_t dyn_len)
 {
 	struct tevent_req *req;
 	struct smb2cli_req_state *state;
+	uint32_t flags = 0;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smb2cli_req_state);
@@ -198,6 +203,9 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
+	flags |= additional_flags;
+	flags &= ~clear_flags;
+
 	state->fixed = fixed;
 	state->fixed_len = fixed_len;
 	state->dyn = dyn;
@@ -306,16 +314,22 @@ struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
 				    struct tevent_context *ev,
 				    struct cli_state *cli,
 				    uint16_t cmd,
-				    uint32_t flags,
+				    uint32_t additional_flags,
+				    uint32_t clear_flags,
+				    uint32_t pid,
+				    uint32_t tid,
+				    uint64_t uid,
 				    const uint8_t *fixed,
 				    uint16_t fixed_len,
 				    const uint8_t *dyn,
-				    uint16_t dyn_len)
+				    uint32_t dyn_len)
 {
 	struct tevent_req *req;
 	NTSTATUS status;
 
-	req = smb2cli_req_create(mem_ctx, ev, cli, cmd, flags,
+	req = smb2cli_req_create(mem_ctx, ev, cli, cmd,
+				 additional_flags, clear_flags,
+				 pid, tid, uid,
 				 fixed, fixed_len, dyn, dyn_len);
 	if (req == NULL) {
 		return NULL;
diff --git a/source3/libsmb/smb2cli_base.h b/source3/libsmb/smb2cli_base.h
index 9c49a8c..348f842 100644
--- a/source3/libsmb/smb2cli_base.h
+++ b/source3/libsmb/smb2cli_base.h
@@ -24,22 +24,30 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
 				      struct tevent_context *ev,
 				      struct cli_state *cli,
 				      uint16_t cmd,
-				      uint32_t flags,
+				      uint32_t additional_flags,
+				      uint32_t clear_flags,
+				      uint32_t pid,
+				      uint32_t tid,
+				      uint64_t uid,
 				      const uint8_t *fixed,
 				      uint16_t fixed_len,
 				      const uint8_t *dyn,
-				      uint16_t dyn_len);
+				      uint32_t dyn_len);
 NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
 				     int num_reqs);
 struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
 				    struct tevent_context *ev,
 				    struct cli_state *cli,
 				    uint16_t cmd,
-				    uint32_t flags,
+				    uint32_t additional_flags,
+				    uint32_t clear_flags,
+				    uint32_t pid,
+				    uint32_t tid,
+				    uint64_t uid,
 				    const uint8_t *fixed,
 				    uint16_t fixed_len,
 				    const uint8_t *dyn,
-				    uint16_t dyn_len);
+				    uint32_t dyn_len);
 NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 			  struct iovec **piov, int body_size);
 
diff --git a/source3/libsmb/smb2cli_close.c b/source3/libsmb/smb2cli_close.c
index fcbf298..3c6ad9f 100644
--- a/source3/libsmb/smb2cli_close.c
+++ b/source3/libsmb/smb2cli_close.c
@@ -53,7 +53,11 @@ struct tevent_req *smb2cli_close_send(TALLOC_CTX *mem_ctx,
 	SBVAL(fixed, 8, fid_persistent);
 	SBVAL(fixed, 16, fid_volatile);
 
-	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_CLOSE, 0,
+	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_CLOSE,
+				  0, 0, /* flags */
+				  cli->smb2.pid,
+				  cli->smb2.tid,
+				  cli->smb2.uid,
 				  state->fixed, sizeof(state->fixed),
 				  NULL, 0);
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/libsmb/smb2cli_create.c b/source3/libsmb/smb2cli_create.c
index 794b1f1..ecb220d 100644
--- a/source3/libsmb/smb2cli_create.c
+++ b/source3/libsmb/smb2cli_create.c
@@ -127,7 +127,11 @@ struct tevent_req *smb2cli_create_send(
 		data_blob_free(&blob);
 	}
 
-	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_CREATE, 0,
+	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_CREATE,
+				  0, 0, /* flags */
+				  cli->smb2.pid,
+				  cli->smb2.tid,
+				  cli->smb2.uid,
 				  state->fixed, sizeof(state->fixed),
 				  dyn, dyn_len);
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/libsmb/smb2cli_flush.c b/source3/libsmb/smb2cli_flush.c
index b93c785..6fe7178 100644
--- a/source3/libsmb/smb2cli_flush.c
+++ b/source3/libsmb/smb2cli_flush.c
@@ -51,7 +51,11 @@ struct tevent_req *smb2cli_flush_send(TALLOC_CTX *mem_ctx,
 	SBVAL(fixed, 8, fid_persistent);
 	SBVAL(fixed, 16, fid_volatile);
 
-	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_FLUSH, 0,
+	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_FLUSH,
+				  0, 0, /* flags */
+				  cli->smb2.pid,
+				  cli->smb2.tid,
+				  cli->smb2.uid,
 				  state->fixed, sizeof(state->fixed),
 				  NULL, 0);
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/libsmb/smb2cli_negprot.c b/source3/libsmb/smb2cli_negprot.c
index 3056322..75532cd 100644
--- a/source3/libsmb/smb2cli_negprot.c
+++ b/source3/libsmb/smb2cli_negprot.c
@@ -66,7 +66,10 @@ struct tevent_req *smb2cli_negprot_send(TALLOC_CTX *mem_ctx,
 	SSVAL(buf, 0, 0x202);	/* SMB2.002 */
 	SSVAL(buf, 2, 0x210);	/* SMB2.1 */
 
-	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_NEGPROT, 0,
+	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_NEGPROT,
+				  0, 0, /* flags */
+				  cli->smb2.pid,
+				  0, 0, /* tid, uid */
 				  state->fixed, sizeof(state->fixed),
 				  state->dyn, sizeof(state->dyn));
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/libsmb/smb2cli_query_directory.c b/source3/libsmb/smb2cli_query_directory.c
index f9a1bfe..3feaa07 100644
--- a/source3/libsmb/smb2cli_query_directory.c
+++ b/source3/libsmb/smb2cli_query_directory.c
@@ -75,7 +75,11 @@ struct tevent_req *smb2cli_query_directory_send(TALLOC_CTX *mem_ctx,
 	SSVAL(fixed, 26, dyn_len);
 	SSVAL(fixed, 28, outbuf_len);
 
-	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_FIND, 0,
+	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_FIND,
+				  0, 0, /* flags */
+				  cli->smb2.pid,
+				  cli->smb2.tid,
+				  cli->smb2.uid,
 				  state->fixed, sizeof(state->fixed),
 				  dyn, dyn_len);
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/libsmb/smb2cli_read.c b/source3/libsmb/smb2cli_read.c
index c348c99..bcdbd87 100644
--- a/source3/libsmb/smb2cli_read.c
+++ b/source3/libsmb/smb2cli_read.c
@@ -64,7 +64,11 @@ struct tevent_req *smb2cli_read_send(TALLOC_CTX *mem_ctx,
 	SBVAL(fixed, 32, minimum_count);
 	SBVAL(fixed, 40, remaining_bytes);
 
-	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_READ, 0,
+	subreq = smb2cli_req_send(state, ev, cli, SMB2_OP_READ,
+				  0, 0, /* flags */
+				  cli->smb2.pid,
+				  cli->smb2.tid,
+				  cli->smb2.uid,
 				  state->fixed, sizeof(state->fixed),
 				  NULL, 0);
 	if (tevent_req_nomem(subreq, req)) {
diff --git a/source3/libsmb/smb2cli_session.c b/source3/libsmb/smb2cli_session.c
index c7d880e..7cc1842 100644


-- 
Samba Shared Repository


More information about the samba-cvs mailing list