The branch, master has been updated
       via  1260fcb61c8 s3:rpc_server: Handle an np_read_send with len==0 
correctly
       via  cbadfaaf3d9 s3:smbd: Allow cancel of SMB2 read on ipc handles
       via  bb26e104d64 s3:smbd: let aio_add_req_to_fsp() return the pointer to 
the link
       via  2a90b06679a s3:smbd: Use nt_status_np_pipe() in 
smbd_smb2_ioctl_pipe_{read,write}_done()
       via  ae2a9cb75dd s4:torture: Implement ipc test with len=0
       via  adbacb85744 s4:torture: Add notify test with multichannel for 'smb2 
max async credits'
       via  b0f287c4dff s4:torture: Add notify test with two connection for 
'smb2 max async credits'
       via  64168ebe887 s4:torture: Add notify test for 'smb2 max async credits'
       via  a3e74a1e58d s3:torture: Add IPC test with multichannel for 'smb2 
max async credits'
       via  c15b3f9ee7c s4:torture: Add IPC test with 2 connections for 'smb2 
max async credits'
       via  3884a7c085f s4:torture: Add IPC test for 'smb2 max async credits'
       via  6cb46e5cb60 s4:libcli/smb2: add smb2_tree_channel() helper
       via  e2969ed00fd libcli:smb: Implement smb2cli_notify_set_notify_async()
       via  2856e749984 libcli:smb: Implement smb2cli_read_cancel()
       via  52079c8d911 libcli:smb: Implement smb2cli_read_set_notify_async()
      from  1768e77f3a0 s4:librpc: make use of CHECK_DEBUGLVLC(DBGC_RPC_PARSE, 
...) in dcerpc_bh_do_ndr_print()

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


- Log -----------------------------------------------------------------
commit 1260fcb61c83e4e66d6e32be8d587821c983f090
Author: Stefan Metzmacher <[email protected]>
Date:   Tue Aug 27 14:41:43 2024 +0200

    s3:rpc_server: Handle an np_read_send with len==0 correctly
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>
    
    Autobuild-User(master): Andreas Schneider <[email protected]>
    Autobuild-Date(master): Wed Jan 29 12:17:47 UTC 2025 on atb-devel-224

commit cbadfaaf3d90db871a13e6423a68a643b0ff99e9
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 23 14:40:10 2024 +0200

    s3:smbd: Allow cancel of SMB2 read on ipc handles
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Signed-off-by: Andreas Schneider <[email protected]>

commit bb26e104d6466bdc153508d670370c5d54fc032e
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 23 14:35:07 2024 +0200

    s3:smbd: let aio_add_req_to_fsp() return the pointer to the link
    
    This allows the caller to free the link before the request.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Signed-off-by: Andreas Schneider <[email protected]>

commit 2a90b06679ae6415c4d60dc14a17385da85668c6
Author: Stefan Metzmacher <[email protected]>
Date:   Wed Jul 17 18:04:56 2024 +0200

    s3:smbd: Use nt_status_np_pipe() in smbd_smb2_ioctl_pipe_{read,write}_done()
    
    We should return NT_STATUS_PIPE_DISCONNECTED or
    NT_STATUS_PIPE_BROKEN in the same way SMB2 read/write do it.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit ae2a9cb75ddc9e7cedf1744a434edc583dd2a0a6
Author: Andreas Schneider <[email protected]>
Date:   Mon Aug 26 14:34:32 2024 +0200

    s4:torture: Implement ipc test with len=0
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit adbacb85744d06477254a478853b6864c32c3819
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 9 09:12:04 2024 +0200

    s4:torture: Add notify test with multichannel for 'smb2 max async credits'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit b0f287c4dffb9dea301d52342a433b5b94ac4009
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 9 08:37:44 2024 +0200

    s4:torture: Add notify test with two connection for 'smb2 max async credits'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Signed-off-by: Andreas Schneider <[email protected]>

commit 64168ebe8871e0d15d644966acb54af41f8f74af
Author: Andreas Schneider <[email protected]>
Date:   Thu Aug 1 12:45:14 2024 +0200

    s4:torture: Add notify test for 'smb2 max async credits'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Signed-off-by: Andreas Schneider <[email protected]>

commit a3e74a1e58dff3327b2b6f63ecf044d1cf8f47bb
Author: Andreas Schneider <[email protected]>
Date:   Mon Aug 26 10:53:06 2024 +0200

    s3:torture: Add IPC test with multichannel for 'smb2 max async credits'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit c15b3f9ee7ccd375cf721c63f6947d60235a6e78
Author: Andreas Schneider <[email protected]>
Date:   Mon Aug 26 10:29:23 2024 +0200

    s4:torture: Add IPC test with 2 connections for 'smb2 max async credits'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 3884a7c085f7fe0f32a5801e0abc7d63a95a6433
Author: Andreas Schneider <[email protected]>
Date:   Sat Jul 27 17:14:42 2024 +0200

    s4:torture: Add IPC test for 'smb2 max async credits'
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Signed-off-by: Andreas Schneider <[email protected]>

commit 6cb46e5cb60ce753cac55a8ba19f5cffb697d545
Author: Stefan Metzmacher <[email protected]>
Date:   Fri Aug 9 09:07:40 2024 +0200

    s4:libcli/smb2: add smb2_tree_channel() helper
    
    This can be used after smb2_session_channel() in order
    to have a smb2_tree structure representing the same
    logic tree connect but uses a different channel/connection.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit e2969ed00fd85d5b2bf62d2a17643b5f8481b278
Author: Andreas Schneider <[email protected]>
Date:   Fri Aug 23 11:46:33 2024 +0200

    libcli:smb: Implement smb2cli_notify_set_notify_async()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Pair-Programmed-With: Stefan Metzmacher <[email protected]>
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Signed-off-by: Andreas Schneider <[email protected]>

commit 2856e74998492d17eaf2dc4efc8259f95065262f
Author: Andreas Schneider <[email protected]>
Date:   Wed Aug 28 15:06:11 2024 +0200

    libcli:smb: Implement smb2cli_read_cancel()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Stefan Metzmacher <[email protected]>

commit 52079c8d911a3d5608333a59593249020a0d5b48
Author: Stefan Metzmacher <[email protected]>
Date:   Mon Aug 5 09:16:58 2024 +0200

    libcli:smb: Implement smb2cli_read_set_notify_async()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

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

Summary of changes:
 libcli/smb/smb2cli_notify.c          |   30 +-
 libcli/smb/smb2cli_read.c            |   44 ++
 libcli/smb/smbXcli_base.h            |    2 +
 selftest/knownfail.d/smb2_credits    |    7 +
 source3/rpc_server/srv_pipe_hnd.c    |   45 ++
 source3/smbd/proto.h                 |    3 +-
 source3/smbd/smb2_aio.c              |   10 +-
 source3/smbd/smb2_ioctl_named_pipe.c |    2 +
 source3/smbd/smb2_read.c             |   26 +-
 source4/libcli/smb2/tcon.c           |   25 +
 source4/torture/smb2/credits.c       | 1294 +++++++++++++++++++++++++++++++++-
 11 files changed, 1475 insertions(+), 13 deletions(-)
 create mode 100644 selftest/knownfail.d/smb2_credits


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2cli_notify.c b/libcli/smb/smb2cli_notify.c
index 9026a6b1c30..6cf9ae7ce72 100644
--- a/libcli/smb/smb2cli_notify.c
+++ b/libcli/smb/smb2cli_notify.c
@@ -33,6 +33,8 @@ struct smb2cli_notify_state {
 
        struct tevent_req *subreq;
        struct tevent_req *timeout_subreq;
+       bool notify_async;
+       bool report_pending;
 };
 
 static void smb2cli_notify_done(struct tevent_req *subreq);
@@ -133,6 +135,16 @@ static void smb2cli_notify_timedout(struct tevent_req 
*subreq)
        }
 }
 
+void smb2cli_notify_set_notify_async(struct tevent_req *req)
+{
+       struct smb2cli_notify_state *state =
+               tevent_req_data(req,
+               struct smb2cli_notify_state);
+
+       smb2cli_req_set_notify_async(state->subreq);
+       state->notify_async = true;
+}
+
 static void smb2cli_notify_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
@@ -149,10 +161,20 @@ static void smb2cli_notify_done(struct tevent_req *subreq)
        }
        };
 
+       SMB_ASSERT(state->subreq == subreq);
+
        status = smb2cli_req_recv(subreq, state, &iov,
                                  expected, ARRAY_SIZE(expected));
+       if (NT_STATUS_EQUAL(status, NT_STATUS_PENDING) && state->notify_async) {
+               state->notify_async = false;
+               state->report_pending = true;
+               tevent_req_notify_callback(req);
+               return;
+       }
+       state->notify_async = false;
+       state->report_pending = false;
+       state->subreq = NULL;
        TALLOC_FREE(subreq);
-
        if (NT_STATUS_EQUAL(status, NT_STATUS_CANCELLED)) {
                status = NT_STATUS_IO_TIMEOUT;
        }
@@ -181,6 +203,12 @@ NTSTATUS smb2cli_notify_recv(struct tevent_req *req, 
TALLOC_CTX *mem_ctx,
                req, struct smb2cli_notify_state);
        NTSTATUS status;
 
+       if (state->report_pending) {
+               *data_length = 0;
+               *data = NULL;
+               return NT_STATUS_PENDING;
+       }
+
        if (tevent_req_is_nterror(req, &status)) {
                return status;
        }
diff --git a/libcli/smb/smb2cli_read.c b/libcli/smb/smb2cli_read.c
index c7f48741b87..6efaa8da5ee 100644
--- a/libcli/smb/smb2cli_read.c
+++ b/libcli/smb/smb2cli_read.c
@@ -30,8 +30,12 @@ struct smb2cli_read_state {
        uint8_t *data;
        uint32_t data_length;
        bool out_valid;
+       struct tevent_req *subreq;
+       bool notify_async;
+       bool report_pending;
 };
 
+static bool smb2cli_read_cancel(struct tevent_req *req);
 static void smb2cli_read_done(struct tevent_req *subreq);
 
 struct tevent_req *smb2cli_read_send(TALLOC_CTX *mem_ctx,
@@ -79,9 +83,32 @@ struct tevent_req *smb2cli_read_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
        tevent_req_set_callback(subreq, smb2cli_read_done, req);
+       state->subreq = subreq;
+       tevent_req_set_cancel_fn(req, smb2cli_read_cancel);
+
        return req;
 }
 
+static bool smb2cli_read_cancel(struct tevent_req *req)
+{
+       struct smb2cli_read_state *state = tevent_req_data(
+               req, struct smb2cli_read_state);
+       bool ok;
+
+       ok = tevent_req_cancel(state->subreq);
+       return ok;
+}
+
+void smb2cli_read_set_notify_async(struct tevent_req *req)
+{
+       struct smb2cli_read_state *state =
+               tevent_req_data(req,
+               struct smb2cli_read_state);
+
+       smb2cli_req_set_notify_async(state->subreq);
+       state->notify_async = true;
+}
+
 static void smb2cli_read_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
@@ -108,8 +135,19 @@ static void smb2cli_read_done(struct tevent_req *subreq)
        }
        };
 
+       SMB_ASSERT(state->subreq == subreq);
+
        status = smb2cli_req_recv(subreq, state, &iov,
                                  expected, ARRAY_SIZE(expected));
+       if (NT_STATUS_EQUAL(status, NT_STATUS_PENDING) && state->notify_async) {
+               state->notify_async = false;
+               state->report_pending = true;
+               tevent_req_notify_callback(req);
+               return;
+       }
+       state->notify_async = false;
+       state->report_pending = false;
+       state->subreq = NULL;
        TALLOC_FREE(subreq);
        if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
                /* no error */
@@ -157,6 +195,12 @@ NTSTATUS smb2cli_read_recv(struct tevent_req *req, 
TALLOC_CTX *mem_ctx,
                struct smb2cli_read_state);
        NTSTATUS status = NT_STATUS_OK;
 
+       if (state->report_pending) {
+               *data_length = 0;
+               *data = NULL;
+               return NT_STATUS_PENDING;
+       }
+
        if (tevent_req_is_nterror(req, &status) && !state->out_valid) {
                *data_length = 0;
                *data = NULL;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 69fa131a31d..2e60201c9a0 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -737,6 +737,7 @@ struct tevent_req *smb2cli_read_send(TALLOC_CTX *mem_ctx,
                                     uint64_t fid_volatile,
                                     uint64_t minimum_count,
                                     uint64_t remaining_bytes);
+void smb2cli_read_set_notify_async(struct tevent_req *req);
 NTSTATUS smb2cli_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                           uint8_t **data, uint32_t *data_length);
 NTSTATUS smb2cli_read(struct smbXcli_conn *conn,
@@ -896,6 +897,7 @@ struct tevent_req *smb2cli_notify_send(TALLOC_CTX *mem_ctx,
                                       uint64_t fid_volatile,
                                       uint32_t completion_filter,
                                       bool recursive);
+void smb2cli_notify_set_notify_async(struct tevent_req *req);
 NTSTATUS smb2cli_notify_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                             uint8_t **data, uint32_t *data_length);
 NTSTATUS smb2cli_notify(struct smbXcli_conn *conn,
diff --git a/selftest/knownfail.d/smb2_credits 
b/selftest/knownfail.d/smb2_credits
new file mode 100644
index 00000000000..79c90387d96
--- /dev/null
+++ b/selftest/knownfail.d/smb2_credits
@@ -0,0 +1,7 @@
+samba3.smb2.credits.*1conn_ipc_max_async_credits
+samba3.smb2.credits.*2conn_ipc_max_async_credits
+samba3.smb2.credits.*multichannel_ipc_max_async_credits
+samba3.smb2.credits.*1conn_notify_max_async_credits
+samba3.smb2.credits.*2conn_notify_max_async_credits
+samba3.smb2.credits.*multichannel_max_async_credits
+samba3.smb2.credits.*ipc_max_data_zero
diff --git a/source3/rpc_server/srv_pipe_hnd.c 
b/source3/rpc_server/srv_pipe_hnd.c
index c73a4c7685c..b9e2676e9b2 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -278,14 +278,45 @@ static int np_ipc_readv_next_vector(struct 
tstream_context *stream,
        return 0;
 }
 
+struct np_read_zero_state;
+
 struct np_read_state {
        struct npa_state *p;
        struct np_ipc_readv_next_vector_state next_vector;
 
        ssize_t nread;
        bool is_data_outstanding;
+
+       struct np_read_zero_state *zs;
+};
+
+struct np_read_zero_state {
+       struct np_read_state *state;
+       struct tevent_req *req;
 };
 
+static int np_read_zero_state_destructor(struct np_read_zero_state *zs)
+{
+       if (zs->state != NULL) {
+               zs->state->zs = NULL;
+               zs->state = NULL;
+       }
+       tevent_req_nterror(zs->req, NT_STATUS_PIPE_BROKEN);
+       return 0;
+}
+
+static void np_read_send_cleanup(struct tevent_req *req,
+                                enum tevent_req_state req_state)
+{
+       struct np_read_state *state = tevent_req_data(
+               req, struct np_read_state);
+
+       if (state->zs != NULL) {
+               talloc_set_destructor(state->zs, NULL);
+               TALLOC_FREE(state->zs);
+       }
+}
+
 static void np_read_done(struct tevent_req *subreq);
 
 struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
@@ -302,6 +333,8 @@ struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct 
tevent_context *ev,
                return NULL;
        }
 
+       tevent_req_set_cleanup_fn(req, np_read_send_cleanup);
+
        if (handle->type != FAKE_FILE_TYPE_NAMED_PIPE_PROXY) {
                tevent_req_nterror(req, NT_STATUS_INVALID_HANDLE);
                return tevent_req_post(req, ev);
@@ -309,6 +342,18 @@ struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, 
struct tevent_context *ev,
 
        p = talloc_get_type_abort(handle->private_data, struct npa_state);
 
+       if (len == 0) {
+               state->zs = talloc_zero(p, struct np_read_zero_state);
+               if (tevent_req_nomem(state->zs, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               talloc_set_destructor(state->zs,
+                                     np_read_zero_state_destructor);
+               state->zs->state = state;
+               state->zs->req = req;
+               return req;
+       }
+
        np_ipc_readv_next_vector_init(&state->next_vector, data, len);
 
        subreq = tstream_readv_pdu_queue_send(
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 6ed89b2b8e1..33bfd5b7ae4 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -72,7 +72,8 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
                                DATA_BLOB in_data,
                                bool write_through);
 bool cancel_smb2_aio(struct smb_request *smbreq);
-bool aio_add_req_to_fsp(files_struct *fsp, struct tevent_req *req);
+struct aio_req_fsp_link;
+struct aio_req_fsp_link *aio_add_req_to_fsp(files_struct *fsp, struct 
tevent_req *req);
 struct aio_extra *create_aio_extra(TALLOC_CTX *mem_ctx,
                                   files_struct *fsp,
                                   size_t buflen);
diff --git a/source3/smbd/smb2_aio.c b/source3/smbd/smb2_aio.c
index 7430a830f1b..fc97bdc075a 100644
--- a/source3/smbd/smb2_aio.c
+++ b/source3/smbd/smb2_aio.c
@@ -113,14 +113,14 @@ static int aio_del_req_from_fsp(struct aio_req_fsp_link 
*lnk)
        return 0;
 }
 
-bool aio_add_req_to_fsp(files_struct *fsp, struct tevent_req *req)
+struct aio_req_fsp_link *aio_add_req_to_fsp(files_struct *fsp, struct 
tevent_req *req)
 {
        size_t array_len;
        struct aio_req_fsp_link *lnk;
 
        lnk = talloc(req, struct aio_req_fsp_link);
        if (lnk == NULL) {
-               return false;
+               return NULL;
        }
 
        array_len = talloc_array_length(fsp->aio_requests);
@@ -130,7 +130,7 @@ bool aio_add_req_to_fsp(files_struct *fsp, struct 
tevent_req *req)
                if (fsp->num_aio_requests + 10 < 10) {
                        /* Integer wrap. */
                        TALLOC_FREE(lnk);
-                       return false;
+                       return NULL;
                }
 
                /*
@@ -142,7 +142,7 @@ bool aio_add_req_to_fsp(files_struct *fsp, struct 
tevent_req *req)
                        fsp->num_aio_requests+10);
                if (tmp == NULL) {
                        TALLOC_FREE(lnk);
-                       return false;
+                       return NULL;
                }
                fsp->aio_requests = tmp;
        }
@@ -156,7 +156,7 @@ bool aio_add_req_to_fsp(files_struct *fsp, struct 
tevent_req *req)
 #endif
        talloc_set_destructor(lnk, aio_del_req_from_fsp);
 
-       return true;
+       return lnk;
 }
 
 struct pwrite_fsync_state {
diff --git a/source3/smbd/smb2_ioctl_named_pipe.c 
b/source3/smbd/smb2_ioctl_named_pipe.c
index f9e3dec049c..4c1967cca67 100644
--- a/source3/smbd/smb2_ioctl_named_pipe.c
+++ b/source3/smbd/smb2_ioctl_named_pipe.c
@@ -123,6 +123,7 @@ static void smbd_smb2_ioctl_pipe_write_done(struct 
tevent_req *subreq)
 
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
+               status = nt_status_np_pipe(status);
                tevent_req_nterror(req, status);
                return;
        }
@@ -173,6 +174,7 @@ static void smbd_smb2_ioctl_pipe_read_done(struct 
tevent_req *subreq)
 
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
+               status = nt_status_np_pipe(status);
                tevent_req_nterror(req, status);
                return;
        }
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 6c595a7c340..fc207850c91 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -185,6 +185,7 @@ static void smbd_smb2_request_read_done(struct tevent_req 
*subreq)
 struct smbd_smb2_read_state {
        struct smbd_smb2_request *smb2req;
        struct smb_request *smbreq;
+       struct tevent_req *ipc_subreq;
        files_struct *fsp;
        uint8_t in_flags;
        uint32_t in_length;
@@ -428,6 +429,22 @@ NTSTATUS smb2_read_complete(struct tevent_req *req, 
ssize_t nread, int err)
        return NT_STATUS_OK;
 }
 
+static bool smbd_smb2_read_ipc_cancel(struct tevent_req *req)
+{
+       struct smbd_smb2_read_state *state =
+               tevent_req_data(req,
+               struct smbd_smb2_read_state);
+
+       TALLOC_FREE(state->ipc_subreq);
+       tevent_req_defer_callback(req, 
state->smb2req->xconn->client->raw_ev_ctx);
+       if (state->fsp->fsp_flags.closing) {
+               tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN);
+       } else {
+               tevent_req_nterror(req, NT_STATUS_CANCELLED);
+       }
+       return true;
+}
+
 static bool smbd_smb2_read_cancel(struct tevent_req *req)
 {
        struct smbd_smb2_read_state *state =
@@ -487,7 +504,7 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX 
*mem_ctx,
 
        if (IS_IPC(smbreq->conn)) {
                struct tevent_req *subreq = NULL;
-               bool ok;
+               struct aio_req_fsp_link *aio_lnk = NULL;
 
                state->out_data = data_blob_talloc(state, NULL, in_length);
                if (in_length > 0 && tevent_req_nomem(state->out_data.data, 
req)) {
@@ -515,12 +532,15 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX 
*mem_ctx,
                 * activity so we don't crash on shutdown close.
                 */
 
-               ok = aio_add_req_to_fsp(fsp, req);
-               if (!ok) {
+               aio_lnk = aio_add_req_to_fsp(fsp, req);
+               if (aio_lnk == NULL) {
                        tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
                        return tevent_req_post(req, ev);
                }
+               talloc_move(subreq, &aio_lnk);
 
+               state->ipc_subreq = subreq;
+               tevent_req_set_cancel_fn(req, smbd_smb2_read_ipc_cancel);
                return req;
        }
 
diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c
index 702e308aa63..e66f00790fd 100644
--- a/source4/libcli/smb2/tcon.c
+++ b/source4/libcli/smb2/tcon.c
@@ -50,3 +50,28 @@ struct smb2_tree *smb2_tree_init(struct smb2_session 
*session,
 
        return tree;
 }
+
+struct smb2_tree *smb2_tree_channel(struct smb2_tree *base_tree,
+                                   TALLOC_CTX *parent_ctx, bool primary,
+                                   struct smb2_session *session)
+{
+       struct smb2_tree *tree;
+
+       tree = talloc_zero(parent_ctx, struct smb2_tree);
+       if (!session) {
+               return NULL;
+       }
+       if (primary) {
+               tree->session = talloc_steal(tree, session);
+       } else {
+               tree->session = talloc_reference(tree, session);
+       }
+
+       tree->smbXcli = smbXcli_tcon_copy(tree, base_tree->smbXcli);
+       if (tree->smbXcli == NULL) {
+               talloc_free(tree);
+               return NULL;
+       }
+
+       return tree;
+}
diff --git a/source4/torture/smb2/credits.c b/source4/torture/smb2/credits.c
index b06bae72050..ad0918d1c63 100644
--- a/source4/torture/smb2/credits.c
+++ b/source4/torture/smb2/credits.c
@@ -20,12 +20,17 @@
 */
 
 #include "includes.h"
+#include "torture/torture.h"
+
+#include "lib/cmdline/cmdline.h"
+#include "lib/param/param.h"
+#include "libcli/resolve/resolve.h"
+#include "libcli/smb/smbXcli_base.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
-#include "torture/torture.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
 #include "torture/smb2/proto.h"
-#include "../libcli/smb/smbXcli_base.h"
-#include "lib/param/param.h"
+#include "util/tevent_ntstatus.h"
 
 /**
  * Request 64k credits in negprot/sessionsetup and require at least 8k
@@ -254,6 +259,1266 @@ done:
        return ret;
 }
 
+#define SMBXCLI_NP_DESIRED_ACCESS                                          \
+       (SEC_STD_READ_CONTROL | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA | \
+        SEC_FILE_APPEND_DATA | SEC_FILE_READ_EA | SEC_FILE_WRITE_EA |     \
+        SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | 0)
+
+struct test_ipc_async_credits_loop;
+
+struct test_ipc_async_credits_state {
+       struct torture_context *tctx;
+       struct smbXcli_conn *conn;
+       struct smbXcli_session *session;
+       struct smbXcli_tcon *tcon;
+       uint32_t timeout_msec;
+       uint16_t pid;
+       const char *pipe_name;
+
+       size_t num_loops;
+       struct test_ipc_async_credits_loop *loops;
+       size_t num_status_received;
+
+       size_t num_status_pending;
+       size_t num_status_insufficient;
+
+       bool stop;
+};
+
+struct test_ipc_async_credits_loop {
+       size_t idx;
+       struct test_ipc_async_credits_state *state;
+       struct tevent_req *req;
+       size_t num_started;
+
+       uint32_t max_data;
+       uint64_t fid_persistent;
+       uint64_t fid_volatile;


-- 
Samba Shared Repository

Reply via email to