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 <[email protected]>
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 <[email protected]>
    Autobuild-Date: Fri Aug 12 19:38:27 CEST 2011 on sn-devel-104

commit 28c4d2d0f318d017e356cf8e80ff0da516346fee
Author: Stefan Metzmacher <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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

Reply via email to