The branch, master has been updated
       via  f4d0bb164f0 smb2_server: skip tcon check and 
chdir_current_service() for FSCTL_QUERY_NETWORK_INTERFACE_INFO
       via  629d161b8f5 s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO 
should work on noperm share
       via  1744dd8c5bc smb2_server: don't let SMB2_OP_IOCTL force FILE_CLOSED 
for invalid file ids
       via  fb33f145ff5 s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO 
gives INVALID_PARAMETER with invalid file ids
       via  aab54050343 smb2_ioctl: return BUFFER_TOO_SMALL in 
smbd_smb2_request_ioctl_done()
       via  b3212b359ed s4:torture/smb2: test 
FSCTL_QUERY_NETWORK_INTERFACE_INFO with BUFFER_TOO_SMALL
       via  c850ce96fd3 smb2_server: skip tcon check and 
chdir_current_service() for FSCTL_VALIDATE_NEGOTIATE_INFO
       via  bd3ba3c96e6 smb2_server: decouple IOCTL check from 
signing/encryption states
       via  1cd948d8520 smb2_server: make sure in_ctl_code = IVAL(body, 0x04); 
reads valid bytes
       via  735fc34682c s4:torture/smb2: add 
smb2.ioctl.bug14788.VALIDATE_NEGOTIATE
       via  04a79139a42 libcli/smb: split out smb2cli_raw_tcon* from 
smb2cli_tcon*
      from  0991946ab2e heimdal_build: Remove memset_s from roken, already in 
libreplace

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


- Log -----------------------------------------------------------------
commit f4d0bb164f028da46eab766135bb38175c117deb
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 15 19:29:40 2021 +0200

    smb2_server: skip tcon check and chdir_current_service() for 
FSCTL_QUERY_NETWORK_INTERFACE_INFO
    
    We should not fail this just because the user doesn't have
    permissions on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>
    
    Autobuild-User(master): Ralph Böhme <s...@samba.org>
    Autobuild-Date(master): Wed Dec  1 11:51:50 UTC 2021 on sn-devel-184

commit 629d161b8f579bc24acfaf3fe02612a5237345b4
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Nov 29 19:56:20 2021 +0100

    s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO should work on noperm 
share
    
    Demonstrate that smbd fails FSCTL_QUERY_NETWORK_INTERFACE_INFO
    only because the user doesn't have permissions on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 1744dd8c5bc342a74e397951506468636275fe45
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 15 20:27:12 2021 +0200

    smb2_server: don't let SMB2_OP_IOCTL force FILE_CLOSED for invalid file ids
    
    smbd_smb2_request_process_ioctl() already detailed checks for file_ids,
    which not reached before.
    
    .allow_invalid_fileid = true was only used for SMB2_OP_IOCTL.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit fb33f145ff598b03a08098b7f12f3c53491f6c04
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Nov 29 19:56:20 2021 +0100

    s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO gives INVALID_PARAMETER 
with invalid file ids
    
    An invalid file id for FSCTL_QUERY_NETWORK_INTERFACE_INFO gives
    INVALID_PARAMETER instead of FILE_CLOSED.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit aab540503434817cc6b2de1d9c507f9d0b3ad980
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 15 20:26:58 2021 +0200

    smb2_ioctl: return BUFFER_TOO_SMALL in smbd_smb2_request_ioctl_done()
    
    We should not send more data than the client requested.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit b3212b359edb78d4c60fed377fa18478c8e75d9a
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Nov 29 19:44:12 2021 +0100

    s4:torture/smb2: test FSCTL_QUERY_NETWORK_INTERFACE_INFO with 
BUFFER_TOO_SMALL
    
    It seems that we currently don't have BUFFER_TOO_SMALL handling
    for FSCTL/IOCTL calls.
    
    FSCTL_QUERY_NETWORK_INTERFACE_INFO is just an easy example
    to demonstrate it.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit c850ce96fd32ea91d8a31223bb09dd5b8b98d99e
Author: Stefan Metzmacher <me...@samba.org>
Date:   Mon Aug 16 17:28:05 2021 +0200

    smb2_server: skip tcon check and chdir_current_service() for 
FSCTL_VALIDATE_NEGOTIATE_INFO
    
    We should not fail this just because the user doesn't have permissions
    on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit bd3ba3c96e6ba811afd5898ff5470188557a6e33
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 15 17:25:53 2021 +0200

    smb2_server: decouple IOCTL check from signing/encryption states
    
    There's no reason to handle FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT
    differently if signing/encryption is used.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 1cd948d8520fd41a4e2f0cc6ee787c1e20211e33
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 15 17:22:39 2021 +0200

    smb2_server: make sure in_ctl_code = IVAL(body, 0x04); reads valid bytes
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 735fc34682c541056fd912d07c69f299f961983c
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Sep 15 18:31:06 2021 +0200

    s4:torture/smb2: add smb2.ioctl.bug14788.VALIDATE_NEGOTIATE
    
    Demonstrate that smbd fails FSCTL_VALIDATE_NEGOTIATE_INFO
    only because the user doesn't have permissions on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

commit 04a79139a42cfd1b607317dec041618cbf629584
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Sep 16 10:51:43 2021 +0200

    libcli/smb: split out smb2cli_raw_tcon* from smb2cli_tcon*
    
    This will be used in tests in order to separate the tcon from
    validate_negotiate_info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Ralph Boehme <s...@samba.org>

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

Summary of changes:
 libcli/smb/smb2cli_tcon.c    | 183 ++++++++++++++++----
 libcli/smb/smbXcli_base.h    |  20 +++
 source3/smbd/smb2_ioctl.c    |  19 +++
 source3/smbd/smb2_server.c   |  30 ++--
 source4/torture/smb2/ioctl.c | 396 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 599 insertions(+), 49 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2cli_tcon.c b/libcli/smb/smb2cli_tcon.c
index 03fb604db5f..d5e4fc30fba 100644
--- a/libcli/smb/smb2cli_tcon.c
+++ b/libcli/smb/smb2cli_tcon.c
@@ -23,42 +23,38 @@
 #include "../libcli/smb/smb_common.h"
 #include "../libcli/smb/smbXcli_base.h"
 
-struct smb2cli_tcon_state {
-       struct tevent_context *ev;
-       struct smbXcli_conn *conn;
-       uint32_t timeout_msec;
+struct smb2cli_raw_tcon_state {
        struct smbXcli_session *session;
        struct smbXcli_tcon *tcon;
        uint8_t fixed[8];
        uint8_t dyn_pad[1];
 };
 
-static void smb2cli_tcon_done(struct tevent_req *subreq);
-
-struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
-                                    struct tevent_context *ev,
-                                    struct smbXcli_conn *conn,
-                                    uint32_t timeout_msec,
-                                    struct smbXcli_session *session,
-                                    struct smbXcli_tcon *tcon,
-                                    uint16_t flags,
-                                    const char *unc)
+static void smb2cli_raw_tcon_done(struct tevent_req *subreq);
+
+struct tevent_req *smb2cli_raw_tcon_send(TALLOC_CTX *mem_ctx,
+                                        struct tevent_context *ev,
+                                        struct smbXcli_conn *conn,
+                                        uint32_t additional_flags,
+                                        uint32_t clear_flags,
+                                        uint32_t timeout_msec,
+                                        struct smbXcli_session *session,
+                                        struct smbXcli_tcon *tcon,
+                                        uint16_t tcon_flags,
+                                        const char *unc)
 {
-       struct tevent_req *req, *subreq;
-       struct smb2cli_tcon_state *state;
-       uint8_t *fixed;
-       uint8_t *dyn;
+       struct tevent_req *req = NULL;
+       struct smb2cli_raw_tcon_state *state = NULL;
+       struct tevent_req *subreq = NULL;
+       uint8_t *fixed = NULL;
+       uint8_t *dyn = NULL;
        size_t dyn_len;
-       uint32_t additional_flags = 0;
-       uint32_t clear_flags = 0;
 
-       req = tevent_req_create(mem_ctx, &state, struct smb2cli_tcon_state);
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb2cli_raw_tcon_state);
        if (req == NULL) {
                return NULL;
        }
-       state->ev = ev;
-       state->conn = conn;
-       state->timeout_msec = timeout_msec;
        state->session = session;
        state->tcon = tcon;
 
@@ -77,7 +73,7 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
        fixed = state->fixed;
        SSVAL(fixed, 0, 9);
        if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
-               SSVAL(fixed, 2, flags);
+               SSVAL(fixed, 2, tcon_flags);
        } else {
                SSVAL(fixed, 2, 0); /* Reserved */
        }
@@ -89,10 +85,6 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
                dyn_len = sizeof(state->dyn_pad);
        }
 
-       if (smbXcli_session_is_authenticated(state->session)) {
-               additional_flags |= SMB2_HDR_FLAG_SIGNED;
-       }
-
        subreq = smb2cli_req_send(state, ev, conn, SMB2_OP_TCON,
                                  additional_flags, clear_flags,
                                  timeout_msec,
@@ -104,19 +96,17 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, smb2cli_tcon_done, req);
+       tevent_req_set_callback(subreq, smb2cli_raw_tcon_done, req);
 
        return req;
 }
 
-static void smb2cli_tcon_validate(struct tevent_req *subreq);
-
-static void smb2cli_tcon_done(struct tevent_req *subreq)
+static void smb2cli_raw_tcon_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
-       struct smb2cli_tcon_state *state = tevent_req_data(
-               req, struct smb2cli_tcon_state);
+       struct smb2cli_raw_tcon_state *state = tevent_req_data(
+               req, struct smb2cli_raw_tcon_state);
        NTSTATUS status;
        struct iovec *iov;
        uint8_t *body;
@@ -156,6 +146,129 @@ static void smb2cli_tcon_done(struct tevent_req *subreq)
                                share_capabilities,
                                maximal_access);
 
+       tevent_req_done(req);
+}
+
+NTSTATUS smb2cli_raw_tcon_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS smb2cli_raw_tcon(struct smbXcli_conn *conn,
+                         uint32_t additional_flags,
+                         uint32_t clear_flags,
+                         uint32_t timeout_msec,
+                         struct smbXcli_session *session,
+                         struct smbXcli_tcon *tcon,
+                         uint16_t tcon_flags,
+                         const char *unc)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct tevent_context *ev;
+       struct tevent_req *req;
+       NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+       if (smbXcli_conn_has_async_calls(conn)) {
+               /*
+                * Can't use sync call while an async call is in flight
+                */
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
+       }
+       ev = samba_tevent_context_init(frame);
+       if (ev == NULL) {
+               goto fail;
+       }
+       req = smb2cli_raw_tcon_send(frame, ev, conn,
+                                   additional_flags, clear_flags,
+                                   timeout_msec, session, tcon,
+                                   tcon_flags, unc);
+       if (req == NULL) {
+               goto fail;
+       }
+       if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+               goto fail;
+       }
+       status = smb2cli_raw_tcon_recv(req);
+ fail:
+       TALLOC_FREE(frame);
+       return status;
+}
+
+struct smb2cli_tcon_state {
+       struct tevent_context *ev;
+       struct smbXcli_conn *conn;
+       uint32_t timeout_msec;
+       struct smbXcli_session *session;
+       struct smbXcli_tcon *tcon;
+       uint8_t fixed[8];
+       uint8_t dyn_pad[1];
+};
+
+static void smb2cli_tcon_done(struct tevent_req *subreq);
+
+struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
+                                    struct tevent_context *ev,
+                                    struct smbXcli_conn *conn,
+                                    uint32_t timeout_msec,
+                                    struct smbXcli_session *session,
+                                    struct smbXcli_tcon *tcon,
+                                    uint16_t flags,
+                                    const char *unc)
+{
+       struct tevent_req *req, *subreq;
+       struct smb2cli_tcon_state *state;
+       uint32_t additional_flags = 0;
+       uint32_t clear_flags = 0;
+
+       req = tevent_req_create(mem_ctx, &state, struct smb2cli_tcon_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+       state->conn = conn;
+       state->timeout_msec = timeout_msec;
+       state->session = session;
+       state->tcon = tcon;
+
+       if (smbXcli_session_is_authenticated(state->session)) {
+               additional_flags |= SMB2_HDR_FLAG_SIGNED;
+       }
+
+       subreq = smb2cli_raw_tcon_send(state,
+                                      state->ev,
+                                      state->conn,
+                                      additional_flags,
+                                      clear_flags,
+                                      state->timeout_msec,
+                                      state->session,
+                                      state->tcon,
+                                      flags,
+                                      unc);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, smb2cli_tcon_done, req);
+
+       return req;
+}
+
+static void smb2cli_tcon_validate(struct tevent_req *subreq);
+
+static void smb2cli_tcon_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct smb2cli_tcon_state *state = tevent_req_data(
+               req, struct smb2cli_tcon_state);
+       NTSTATUS status;
+
+       status = smb2cli_raw_tcon_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+
        if (!smbXcli_session_is_authenticated(state->session)) {
                tevent_req_done(req);
                return;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 136e0e0111a..805a62ce342 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -593,6 +593,26 @@ NTSTATUS smb2cli_logoff(struct smbXcli_conn *conn,
                        uint32_t timeout_msec,
                        struct smbXcli_session *session);
 
+/* smb2cli_raw_tcon* should only be used in tests! */
+struct tevent_req *smb2cli_raw_tcon_send(TALLOC_CTX *mem_ctx,
+                                        struct tevent_context *ev,
+                                        struct smbXcli_conn *conn,
+                                        uint32_t additional_flags,
+                                        uint32_t clear_flags,
+                                        uint32_t timeout_msec,
+                                        struct smbXcli_session *session,
+                                        struct smbXcli_tcon *tcon,
+                                        uint16_t tcon_flags,
+                                        const char *unc);
+NTSTATUS smb2cli_raw_tcon_recv(struct tevent_req *req);
+NTSTATUS smb2cli_raw_tcon(struct smbXcli_conn *conn,
+                         uint32_t additional_flags,
+                         uint32_t clear_flags,
+                         uint32_t timeout_msec,
+                         struct smbXcli_session *session,
+                         struct smbXcli_tcon *tcon,
+                         uint16_t tcon_flags,
+                         const char *unc);
 struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
                                     struct tevent_context *ev,
                                     struct smbXcli_conn *conn,
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 136f9baeda3..e4f8c10e3af 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -296,6 +296,7 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req 
*subreq)
        uint32_t in_ctl_code;
        uint64_t in_file_id_persistent;
        uint64_t in_file_id_volatile;
+       uint32_t in_max_output_length;
        uint32_t out_input_offset;
        uint32_t out_output_offset;
        DATA_BLOB out_output_buffer = data_blob_null;
@@ -328,6 +329,24 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req 
*subreq)
        in_ctl_code             = IVAL(inbody, 0x04);
        in_file_id_persistent   = BVAL(inbody, 0x08);
        in_file_id_volatile     = BVAL(inbody, 0x10);
+       in_max_output_length    = IVAL(inbody, 0x2C);
+
+       if (out_output_buffer.length > in_max_output_length) {
+               /*
+                * Return NT_STATUS_BUFFER_TOO_SMALL by
+                * default if the provided buffer doesn't
+                * fit.
+                *
+                * If someone wants truncated data
+                * together with STATUS_BUFFER_OVERFLOW
+                * it needs to be done explicitly in
+                * the backends. We currently do that
+                * in:
+                * - fsctl_dfs_get_refers()
+                * - smbd_smb2_ioctl_pipe_read_done()
+                */
+               status = NT_STATUS_BUFFER_TOO_SMALL;
+       }
 
        if (smbd_smb2_ioctl_is_failure(in_ctl_code, status,
                                       out_output_buffer.length)) {
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 4f302c35419..042f343b0ca 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -67,7 +67,6 @@ static const struct smbd_smb2_dispatch_table {
        bool need_tcon;
        bool as_root;
        uint16_t fileid_ofs;
-       bool allow_invalid_fileid;
        bool modify;
 } smbd_smb2_table[] = {
 #define _OP(o) .opcode = o, .name = #o
@@ -132,7 +131,6 @@ static const struct smbd_smb2_dispatch_table {
                .need_session = true,
                .need_tcon = true,
                .fileid_ofs = 0x08,
-               .allow_invalid_fileid = true,
                .modify = true,
        },{
                _OP(SMB2_OP_CANCEL),
@@ -3174,7 +3172,9 @@ NTSTATUS smbd_smb2_request_dispatch(struct 
smbd_smb2_request *req)
                if (!NT_STATUS_IS_OK(session_status)) {
                        return smbd_smb2_request_error(req, session_status);
                }
-       } else if (opcode == SMB2_OP_IOCTL) {
+       }
+
+       if (opcode == SMB2_OP_IOCTL) {
                /*
                 * Some special IOCTL calls don't require
                 * file, tcon nor session.
@@ -3194,7 +3194,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct 
smbd_smb2_request *req)
                const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
                size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
                uint32_t in_ctl_code;
-               size_t needed = 4;
+               size_t needed = 8;
 
                if (needed > body_size) {
                        return smbd_smb2_request_error(req,
@@ -3209,6 +3209,12 @@ NTSTATUS smbd_smb2_request_dispatch(struct 
smbd_smb2_request *req)
                case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
                        call = &_root_ioctl_call;
                        break;
+               case FSCTL_VALIDATE_NEGOTIATE_INFO:
+                       call = &_root_ioctl_call;
+                       break;
+               case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
+                       call = &_root_ioctl_call;
+                       break;
                }
        }
 
@@ -3318,16 +3324,12 @@ skipped_signing:
                                return smbd_smb2_request_error(req,
                                                req->compound_create_err);
                        }
-                       if (!call->allow_invalid_fileid) {
-                               return smbd_smb2_request_error(req,
-                                               NT_STATUS_FILE_CLOSED);
-                       }
-
-                       if (file_id_persistent != UINT64_MAX) {
-                               return smbd_smb2_request_error(req,
-                                               NT_STATUS_FILE_CLOSED);
-                       }
-                       if (file_id_volatile != UINT64_MAX) {
+                       /*
+                        * smbd_smb2_request_process_ioctl()
+                        * has more checks in order to return more
+                        * detailed error codes...
+                        */
+                       if (opcode != SMB2_OP_IOCTL) {
                                return smbd_smb2_request_error(req,
                                                NT_STATUS_FILE_CLOSED);
                        }
diff --git a/source4/torture/smb2/ioctl.c b/source4/torture/smb2/ioctl.c
index 022ea001688..a4d8885fe13 100644
--- a/source4/torture/smb2/ioctl.c
+++ b/source4/torture/smb2/ioctl.c
@@ -27,6 +27,10 @@
 #include "torture/smb2/proto.h"
 #include "../libcli/smb/smbXcli_base.h"
 #include "librpc/gen_ndr/ndr_ioctl.h"
+#include "lib/cmdline/cmdline.h"
+#include "libcli/resolve/resolve.h"
+#include "lib/param/param.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #define FNAME  "testfsctl.dat"
 #define FNAME2 "testfsctl2.dat"
@@ -6923,12 +6927,398 @@ static bool test_ioctl_bug14769(struct torture_context 
*torture,
        return ret;
 }
 
+/*
+   basic regression test for BUG 14788,
+   with FSCTL_VALIDATE_NEGOTIATE_INFO
+   https://bugzilla.samba.org/show_bug.cgi?id=14788
+*/
+static bool test_ioctl_bug14788_VALIDATE_NEGOTIATE(struct torture_context 
*torture,
+                               struct smb2_tree *tree0)
+{
+       const char *host = torture_setting_string(torture, "host", NULL);
+       const char *share = torture_setting_string(torture, "share", NULL);
+       const char *noperm_share = torture_setting_string(torture, 
"noperm_share", "noperm");
+       struct smb2_transport *transport0 = tree0->session->transport;
+       struct smbcli_options options;
+       struct smb2_transport *transport = NULL;
+       struct smb2_tree *tree = NULL;
+       struct smb2_session *session = NULL;
+       uint16_t noperm_flags = 0;
+       const char *noperm_unc = NULL;
+       struct smb2_tree *noperm_tree = NULL;
+       uint32_t timeout_msec;
+       struct tevent_req *subreq = NULL;
+       struct cli_credentials *credentials = samba_cmdline_get_creds();
+       NTSTATUS status;
+
+       if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) {
+               torture_skip(torture, "Can't test without SMB 3 support");
+       }
+
+       options = transport0->options;
+       options.client_guid = GUID_random();
+       options.min_protocol = PROTOCOL_SMB3_00;
+       options.max_protocol = PROTOCOL_SMB3_02;
+
+       status = smb2_connect(torture,
+                             host,
+                             lpcfg_smb_ports(torture->lp_ctx),
+                             share,
+                             lpcfg_resolve_context(torture->lp_ctx),
+                             credentials,
+                             &tree,
+                             torture->ev,
+                             &options,
+                             lpcfg_socket_options(torture->lp_ctx),
+                             lpcfg_gensec_settings(torture, torture->lp_ctx)
+                             );
+       torture_assert_ntstatus_ok(torture, status, "smb2_connect options 
failed");
+       session = tree->session;
+       transport = session->transport;
+
+       timeout_msec = tree->session->transport->options.request_timeout * 1000;
+
+       subreq = smb2cli_validate_negotiate_info_send(torture,
+                                                     torture->ev,
+                                                     transport->conn,
+                                                     timeout_msec,
+                                                     session->smbXcli,
+                                                     tree->smbXcli);
+       torture_assert(torture,
+                      tevent_req_poll_ntstatus(subreq, torture->ev, &status),
+                      "tevent_req_poll_ntstatus");
+       status = smb2cli_validate_negotiate_info_recv(subreq);
+       torture_assert_ntstatus_ok(torture, status, 
"smb2cli_validate_negotiate_info");
+
+       noperm_unc = talloc_asprintf(torture, "\\\\%s\\%s", host, noperm_share);
+       torture_assert(torture, noperm_unc != NULL, "talloc_asprintf");
+
+       noperm_tree = smb2_tree_init(session, torture, false);
+       torture_assert(torture, noperm_tree != NULL, "smb2_tree_init");
+
+       status = smb2cli_raw_tcon(transport->conn,
+                                 SMB2_HDR_FLAG_SIGNED,
+                                 0, /* clear_flags */
+                                 timeout_msec,
+                                 session->smbXcli,
+                                 noperm_tree->smbXcli,
+                                 noperm_flags,
+                                 noperm_unc);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_NETWORK_NAME)) {
+               torture_skip(torture, talloc_asprintf(torture,
+                            "noperm_unc[%s] %s",
+                            noperm_unc, nt_errstr(status)));
+       }
+       torture_assert_ntstatus_ok(torture, status,
+                                  talloc_asprintf(torture,
+                                  "smb2cli_tcon(%s)",
+                                  noperm_unc));
+
+       subreq = smb2cli_validate_negotiate_info_send(torture,
+                                                     torture->ev,
+                                                     transport->conn,
+                                                     timeout_msec,
+                                                     session->smbXcli,
+                                                     noperm_tree->smbXcli);
+       torture_assert(torture,
+                      tevent_req_poll_ntstatus(subreq, torture->ev, &status),
+                      "tevent_req_poll_ntstatus");


-- 
Samba Shared Repository

Reply via email to