The branch, v4-15-test has been updated
       via  68bd2229bd4 WHATSNEW: mention the offline domain join feature
       via  8380f21aadd libcli/smb: allow unexpected padding in SMB2 READ 
responses
       via  170b8195507 libcli/smb: make smb2cli_ioctl_parse_buffer() available 
as smb2cli_parse_dyn_buffer()
       via  b644b297bf8 s3:smbd: implement 
FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
       via  0be68189ffc s3:smbd: introduce a body_size variable in 
smbd_smb2_request_read_done
       via  570b3ced84a s4:torture/smb2: add smb2.read.bug14607 test
      from  81eeb1c6708 VERSION: Bump version up to 4.15.0rc2...

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-15-test


- Log -----------------------------------------------------------------
commit 68bd2229bd4528505ab9695bbcbde59fc0fe2a33
Author: Günther Deschner <g...@samba.org>
Date:   Tue Jul 20 14:21:34 2021 +0200

    WHATSNEW: mention the offline domain join feature
    
    Guenther
    
    Signed-off-by: Guenther Deschner <g...@samba.org>
    Reviewed-by: Karolin Seeger <ksee...@samba.org>
    
    Autobuild-User(v4-15-test): Karolin Seeger <ksee...@samba.org>
    Autobuild-Date(v4-15-test): Wed Jul 21 10:27:55 UTC 2021 on sn-devel-184

commit 8380f21aadde1b5433b0770e8a2d9ed53b61101a
Author: Stefan Metzmacher <me...@samba.org>
Date:   Tue Jun 29 15:42:56 2021 +0200

    libcli/smb: allow unexpected padding in SMB2 READ responses
    
    Make use of smb2cli_parse_dyn_buffer() in smb2cli_read_done()
    as it was exactly introduced for a similar problem see:
    
        commit 4c6c71e1378401d66bf2ed230544a75f7b04376f
        Author:     Stefan Metzmacher <me...@samba.org>
        AuthorDate: Thu Jan 14 17:32:15 2021 +0100
        Commit:     Volker Lendecke <v...@samba.org>
        CommitDate: Fri Jan 15 08:36:34 2021 +0000
    
            libcli/smb: allow unexpected padding in SMB2 IOCTL responses
    
            A NetApp Ontap 7.3.7 SMB server add 8 padding bytes to an
            offset that's already 8 byte aligned.
    
            RN: Work around special SMB2 IOCTL response behavior of NetApp 
Ontap 7.3.7
            BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
            Pair-Programmed-With: Volker Lendecke <v...@samba.org>
    
            Signed-off-by: Stefan Metzmacher <me...@samba.org>
            Signed-off-by: Volker Lendecke <v...@samba.org>
    
            Autobuild-User(master): Volker Lendecke <v...@samba.org>
            Autobuild-Date(master): Fri Jan 15 08:36:34 UTC 2021 on sn-devel-184
    
    RN: Work around special SMB2 READ response behavior of NetApp Ontap 7.3.7
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Thu Jul 15 23:53:55 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 155348cda65b441a6c4db1ed84dbf1682d02973c)

commit 170b81955078c5cb9620516cfd31fe02db6f11f6
Author: Stefan Metzmacher <me...@samba.org>
Date:   Tue Jun 29 15:24:13 2021 +0200

    libcli/smb: make smb2cli_ioctl_parse_buffer() available as 
smb2cli_parse_dyn_buffer()
    
    It will be used in smb2cli_read.c soon...
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    (cherry picked from commit 1faf15b3d0f41fa8a94b76d1616a4460ce0c6fa4)

commit b644b297bf83e49d81c97593f5e33b4dc57686dc
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Jul 5 17:49:00 2021 +0200

    s3:smbd: implement FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
    
    This turns the 'smb2.read.bug14607' test from 'skip' into 'xfailure',
    as the 2nd smb2cli_read() function will now return
    NT_STATUS_INVALID_NETWORK_RESPONSE.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    (cherry picked from commit ef57fba5dbf359b204ba952451e1e33ed68f1c91)

commit 0be68189ffcc746c67dd1ae0610f4b33973c8eee
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Jul 5 17:49:00 2021 +0200

    s3:smbd: introduce a body_size variable in smbd_smb2_request_read_done
    
    This will simplify the following changes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    (cherry picked from commit 5ecac656fde4e81aa6e51e7b3134ea3fb75f564a)

commit 570b3ced84ae14a5e3a0f4b89bc8f2944683d6e1
Author: Stefan Metzmacher <me...@samba.org>
Date:   Tue Jul 6 16:24:59 2021 +0200

    s4:torture/smb2: add smb2.read.bug14607 test
    
    This test will use a FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
    in order to change the server behavior of READ responses regarding
    the data offset.
    
    It will demonstrate the problem in smb2cli_read*() triggered
    by NetApp Ontap servers.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    (cherry picked from commit b3c9823d907b91632679e6f0ffce1b7192e4b9b6)

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

Summary of changes:
 WHATSNEW.txt                |  12 ++++
 libcli/smb/smb2cli_ioctl.c  | 123 ++++++---------------------------------
 libcli/smb/smb2cli_read.c   |  22 +++++--
 libcli/smb/smbXcli_base.c   |  91 +++++++++++++++++++++++++++++
 libcli/smb/smbXcli_base.h   |   9 +++
 libcli/smb/smb_constants.h  |   2 +
 source3/smbd/globals.h      |   4 ++
 source3/smbd/smb2_ioctl.c   |  10 ++++
 source3/smbd/smb2_read.c    |  14 ++++-
 source4/torture/smb2/read.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 310 insertions(+), 113 deletions(-)


Changeset truncated at 500 lines:

diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index a5190766e5e..ab770634725 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -154,6 +154,18 @@ to redirect ticket requests to the right DC. This is e.g. 
needed for one way
 trusts. The options `winbind use krb5 enterprise principals` and
 `winbind scan trusted domains` will be deprecated in one of the next releases.
 
+Support for Offline Domain Join (ODJ)
+-------------------------------------
+
+The net utility is now able to support the offline domain join feature
+as known from the Windows djoin.exe command for many years. Samba's
+implementation is accessible via the "net offlinejoin" subcommand. It
+can provision computers and request offline joining for both Windows
+and Unix machines. It is also possible to provision computers from
+Windows (using djoin.exe) and use the generated data in Samba's net
+utility. The existing options for the provisioning and joining steps
+are documented in the net(8) manpage.
+
 
 REMOVED FEATURES
 ================
diff --git a/libcli/smb/smb2cli_ioctl.c b/libcli/smb/smb2cli_ioctl.c
index f9abcc57bab..d638b281678 100644
--- a/libcli/smb/smb2cli_ioctl.c
+++ b/libcli/smb/smb2cli_ioctl.c
@@ -160,97 +160,6 @@ struct tevent_req *smb2cli_ioctl_send(TALLOC_CTX *mem_ctx,
        return req;
 }
 
-static NTSTATUS smb2cli_ioctl_parse_buffer(uint32_t dyn_offset,
-                                          const DATA_BLOB dyn_buffer,
-                                          uint32_t min_offset,
-                                          uint32_t buffer_offset,
-                                          uint32_t buffer_length,
-                                          uint32_t max_length,
-                                          uint32_t *next_offset,
-                                          DATA_BLOB *buffer)
-{
-       uint32_t offset;
-       bool oob;
-
-       *buffer = data_blob_null;
-       *next_offset = dyn_offset;
-
-       if (buffer_offset == 0) {
-               /*
-                * If the offset is 0, we better ignore
-                * the buffer_length field.
-                */
-               return NT_STATUS_OK;
-       }
-
-       if (buffer_length == 0) {
-               /*
-                * If the length is 0, we better ignore
-                * the buffer_offset field.
-                */
-               return NT_STATUS_OK;
-       }
-
-       if ((buffer_offset % 8) != 0) {
-               /*
-                * The offset needs to be 8 byte aligned.
-                */
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       /*
-        * We used to enforce buffer_offset to be
-        * an exact match of the expected minimum,
-        * but the NetApp Ontap 7.3.7 SMB server
-        * gets the padding wrong and aligns the
-        * input_buffer_offset by a value of 8.
-        *
-        * So we just enforce that the offset is
-        * not lower than the expected value.
-        */
-       SMB_ASSERT(min_offset >= dyn_offset);
-       if (buffer_offset < min_offset) {
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       /*
-        * Make [input|output]_buffer_offset relative to "dyn_buffer"
-        */
-       offset = buffer_offset - dyn_offset;
-       oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
-       if (oob) {
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       /*
-        * Give the caller a hint what we consumed,
-        * the caller may need to add possible padding.
-        */
-       *next_offset = buffer_offset + buffer_length;
-
-       if (max_length == 0) {
-               /*
-                * If max_input_length is 0 we ignore the
-                * input_buffer_length, because Windows 2008 echos the
-                * DCERPC request from the requested input_buffer to
-                * the response input_buffer.
-                *
-                * We just use the same logic also for max_output_length...
-                */
-               buffer_length = 0;
-       }
-
-       if (buffer_length > max_length) {
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
-       }
-
-       *buffer = (DATA_BLOB) {
-               .data = dyn_buffer.data + offset,
-               .length = buffer_length,
-       };
-       return NT_STATUS_OK;
-}
-
 static void smb2cli_ioctl_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
@@ -352,14 +261,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
 
        input_min_offset = dyn_ofs;
        input_next_offset = dyn_ofs;
-       error = smb2cli_ioctl_parse_buffer(dyn_ofs,
-                                          dyn_buffer,
-                                          input_min_offset,
-                                          input_buffer_offset,
-                                          input_buffer_length,
-                                          state->max_input_length,
-                                          &input_next_offset,
-                                          &state->out_input_buffer);
+       error = smb2cli_parse_dyn_buffer(dyn_ofs,
+                                        dyn_buffer,
+                                        input_min_offset,
+                                        input_buffer_offset,
+                                        input_buffer_length,
+                                        state->max_input_length,
+                                        &input_next_offset,
+                                        &state->out_input_buffer);
        if (tevent_req_nterror(req, error)) {
                return;
        }
@@ -370,14 +279,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
         */
        output_min_offset = NDR_ROUND(input_next_offset, 8);
        output_next_offset = 0; /* this variable is completely ignored */
-       error = smb2cli_ioctl_parse_buffer(dyn_ofs,
-                                          dyn_buffer,
-                                          output_min_offset,
-                                          output_buffer_offset,
-                                          output_buffer_length,
-                                          state->max_output_length,
-                                          &output_next_offset,
-                                          &state->out_output_buffer);
+       error = smb2cli_parse_dyn_buffer(dyn_ofs,
+                                        dyn_buffer,
+                                        output_min_offset,
+                                        output_buffer_offset,
+                                        output_buffer_length,
+                                        state->max_output_length,
+                                        &output_next_offset,
+                                        &state->out_output_buffer);
        if (tevent_req_nterror(req, error)) {
                return;
        }
diff --git a/libcli/smb/smb2cli_read.c b/libcli/smb/smb2cli_read.c
index 8110b65d432..c7f48741b87 100644
--- a/libcli/smb/smb2cli_read.c
+++ b/libcli/smb/smb2cli_read.c
@@ -90,8 +90,13 @@ static void smb2cli_read_done(struct tevent_req *subreq)
                tevent_req_data(req,
                struct smb2cli_read_state);
        NTSTATUS status;
+       NTSTATUS error;
        struct iovec *iov;
+       const uint8_t dyn_ofs = SMB2_HDR_BODY + 0x10;
+       DATA_BLOB dyn_buffer = data_blob_null;
        uint8_t data_offset;
+       DATA_BLOB data_buffer = data_blob_null;
+       uint32_t next_offset = 0; /* this variable is completely ignored */
        static const struct smb2cli_req_expected_response expected[] = {
        {
                .status = STATUS_BUFFER_OVERFLOW,
@@ -117,14 +122,23 @@ static void smb2cli_read_done(struct tevent_req *subreq)
        data_offset = CVAL(iov[1].iov_base, 2);
        state->data_length = IVAL(iov[1].iov_base, 4);
 
-       if ((data_offset != SMB2_HDR_BODY + 16) ||
-           (state->data_length > iov[2].iov_len)) {
-               tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+       dyn_buffer = data_blob_const((uint8_t *)iov[2].iov_base,
+                                    iov[2].iov_len);
+
+       error = smb2cli_parse_dyn_buffer(dyn_ofs,
+                                        dyn_buffer,
+                                        dyn_ofs, /* min_offset */
+                                        data_offset,
+                                        state->data_length,
+                                        dyn_buffer.length, /* max_length */
+                                        &next_offset,
+                                        &data_buffer);
+       if (tevent_req_nterror(req, error)) {
                return;
        }
 
        state->recv_iov = iov;
-       state->data = (uint8_t *)iov[2].iov_base;
+       state->data = data_buffer.data;
 
        state->out_valid = true;
 
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 341a371d8b8..3fb51e33ffe 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -6823,3 +6823,94 @@ uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
 {
        return conn->smb2.mid;
 }
+
+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
+                                 const DATA_BLOB dyn_buffer,
+                                 uint32_t min_offset,
+                                 uint32_t buffer_offset,
+                                 uint32_t buffer_length,
+                                 uint32_t max_length,
+                                 uint32_t *next_offset,
+                                 DATA_BLOB *buffer)
+{
+       uint32_t offset;
+       bool oob;
+
+       *buffer = data_blob_null;
+       *next_offset = dyn_offset;
+
+       if (buffer_offset == 0) {
+               /*
+                * If the offset is 0, we better ignore
+                * the buffer_length field.
+                */
+               return NT_STATUS_OK;
+       }
+
+       if (buffer_length == 0) {
+               /*
+                * If the length is 0, we better ignore
+                * the buffer_offset field.
+                */
+               return NT_STATUS_OK;
+       }
+
+       if ((buffer_offset % 8) != 0) {
+               /*
+                * The offset needs to be 8 byte aligned.
+                */
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       /*
+        * We used to enforce buffer_offset to be
+        * an exact match of the expected minimum,
+        * but the NetApp Ontap 7.3.7 SMB server
+        * gets the padding wrong and aligns the
+        * input_buffer_offset by a value of 8.
+        *
+        * So we just enforce that the offset is
+        * not lower than the expected value.
+        */
+       SMB_ASSERT(min_offset >= dyn_offset);
+       if (buffer_offset < min_offset) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       /*
+        * Make [input|output]_buffer_offset relative to "dyn_buffer"
+        */
+       offset = buffer_offset - dyn_offset;
+       oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
+       if (oob) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       /*
+        * Give the caller a hint what we consumed,
+        * the caller may need to add possible padding.
+        */
+       *next_offset = buffer_offset + buffer_length;
+
+       if (max_length == 0) {
+               /*
+                * If max_input_length is 0 we ignore the
+                * input_buffer_length, because Windows 2008 echos the
+                * DCERPC request from the requested input_buffer to
+                * the response input_buffer.
+                *
+                * We just use the same logic also for max_output_length...
+                */
+               buffer_length = 0;
+       }
+
+       if (buffer_length > max_length) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       *buffer = (DATA_BLOB) {
+               .data = dyn_buffer.data + offset,
+               .length = buffer_length,
+       };
+       return NT_STATUS_OK;
+}
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 6914e11156b..136e0e0111a 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -395,6 +395,15 @@ void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn 
*conn,
 void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid);
 uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn);
 
+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
+                                 const DATA_BLOB dyn_buffer,
+                                 uint32_t min_offset,
+                                 uint32_t buffer_offset,
+                                 uint32_t buffer_length,
+                                 uint32_t max_length,
+                                 uint32_t *next_offset,
+                                 DATA_BLOB *buffer);
+
 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
                                      struct tevent_context *ev,
                                      struct smbXcli_conn *conn,
diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index e58e5f35f25..a12086e602b 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -597,6 +597,8 @@ enum csc_policy {
        (FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0000 | FSCTL_METHOD_NEITHER)
 #define FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8 \
        (FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0010 | FSCTL_METHOD_NEITHER)
+#define FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8 \
+       (FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0020 | FSCTL_METHOD_NEITHER)
 
 /*
  * A few values from [MS-FSCC] 2.1.2.1 Reparse Tags
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index e1a520c1977..3215a5a8c2e 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -538,6 +538,10 @@ struct smbXsrv_connection {
                struct smbXsrv_preauth preauth;
 
                struct smbd_smb2_request *requests;
+
+               struct {
+                       uint8_t read_body_padding;
+               } smbtorture;
        } smb2;
 };
 
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 8b65a691638..d29ff5d0303 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -197,6 +197,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct 
smbd_smb2_request *req)
        case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
        case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
        case FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8:
+       case FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8:
                /*
                 * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or
                 * FSCTL_PIPE_WAIT does not take a file handle.
@@ -424,6 +425,15 @@ static struct tevent_req *smb2_ioctl_smbtorture(uint32_t 
ctl_code,
                tevent_req_done(req);
                return tevent_req_post(req, ev);
 
+       case FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8:
+               if (state->in_input.length != 0) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+
+               state->smb2req->xconn->smb2.smbtorture.read_body_padding = 8;
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
        default:
                goto not_supported;
        }
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index cd590a52c95..a846215b0ec 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -116,6 +116,8 @@ static void smbd_smb2_request_read_done(struct tevent_req 
*subreq)
 {
        struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
                                        struct smbd_smb2_request);
+       uint16_t body_size;
+       uint8_t body_padding = req->xconn->smb2.smbtorture.read_body_padding;
        DATA_BLOB outbody;
        DATA_BLOB outdyn;
        uint8_t out_data_offset;
@@ -139,9 +141,14 @@ static void smbd_smb2_request_read_done(struct tevent_req 
*subreq)
                return;
        }
 
-       out_data_offset = SMB2_HDR_BODY + 0x10;
+       /*
+        * Only FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
+        * sets body_padding to a value different from 0.
+        */
+       body_size = 0x10 + body_padding;
+       out_data_offset = SMB2_HDR_BODY + body_size;
 
-       outbody = smbd_smb2_generate_outbody(req, 0x10);
+       outbody = smbd_smb2_generate_outbody(req, body_size);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
@@ -161,6 +168,9 @@ static void smbd_smb2_request_read_done(struct tevent_req 
*subreq)
        SIVAL(outbody.data, 0x08,
              out_data_remaining);              /* data remaining */
        SIVAL(outbody.data, 0x0C, 0);           /* reserved */
+       if (body_padding != 0) {
+               memset(outbody.data + 0x10, 0, body_padding);
+       }
 
        outdyn = out_data_buffer;
 
diff --git a/source4/torture/smb2/read.c b/source4/torture/smb2/read.c
index 2899a491663..2bc0dc98bba 100644
--- a/source4/torture/smb2/read.c
+++ b/source4/torture/smb2/read.c
@@ -26,6 +26,8 @@
 
 #include "torture/torture.h"
 #include "torture/smb2/proto.h"
+#include "../libcli/smb/smbXcli_base.h"
+#include "librpc/gen_ndr/ndr_ioctl.h"
 
 
 #define CHECK_STATUS(_status, _expected) \
@@ -303,6 +305,138 @@ done:
        return ret;
 }
 
+/*
+   basic regression test for BUG 14607
+   https://bugzilla.samba.org/show_bug.cgi?id=14607
+*/
+static bool test_read_bug14607(struct torture_context *torture,
+                               struct smb2_tree *tree)
+{
+       bool ret = true;
+       NTSTATUS status;
+       struct smb2_handle h;
+       uint8_t buf[64 * 1024];
+       struct smb2_read rd;
+       uint32_t timeout_msec;
+       DATA_BLOB out_input_buffer = data_blob_null;
+       DATA_BLOB out_output_buffer = data_blob_null;
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
+       uint8_t *data = NULL;
+       uint32_t data_length = 0;
+
+       memset(buf, 0x1f, ARRAY_SIZE(buf));
+
+       /* create a file */
+       smb2_util_unlink(tree, FNAME);
+
+       status = torture_smb2_testfile(tree, FNAME, &h);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       ZERO_STRUCT(rd);
+       rd.in.file.handle = h;
+       rd.in.length = ARRAY_SIZE(buf);
+       rd.in.offset = 0;
+       status = smb2_read(tree, tree, &rd);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_VALUE(rd.out.data.length, ARRAY_SIZE(buf));
+       torture_assert_mem_equal_goto(torture, rd.out.data.data,
+                                     buf, ARRAY_SIZE(buf),
+                                     ret, done,
+                                     "Invalid content smb2_read");
+
+       timeout_msec = tree->session->transport->options.request_timeout * 1000;
+
+       status = smb2cli_read(tree->session->transport->conn,
+                             timeout_msec,
+                             tree->session->smbXcli,
+                             tree->smbXcli,
+                             rd.in.length,
+                             rd.in.offset,
+                             h.data[0],


-- 
Samba Shared Repository

Reply via email to