smbXcli: Pass negotiate contexts through smbXcli_negprot_send/recv
authorVolker Lendecke <vl@samba.org>
Thu, 25 Aug 2022 07:54:52 +0000 (09:54 +0200)
committerJeremy Allison <jra@samba.org>
Fri, 26 Aug 2022 19:54:03 +0000 (19:54 +0000)
We already don't allow setting max_credits in the sync wrapper, so
omit the contexts there as well.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri Aug 26 19:54:03 UTC 2022 on sn-devel-184

libcli/smb/smbXcli_base.c
libcli/smb/smbXcli_base.h
source3/libsmb/cliconnect.c
source3/torture/torture.c
source4/libcli/raw/rawnegotiate.c
source4/libcli/smb2/connect.c
source4/libcli/smb_composite/connect_nego.c

index c5d13bd58376e2d574a09c76eae09497f62338a3..353b4816e3dfea4b134345cd1e72cc8dfdc93818 100644 (file)
@@ -4220,6 +4220,8 @@ static const struct {
 struct smbXcli_negprot_state {
        struct smbXcli_conn *conn;
        struct tevent_context *ev;
+       struct smb2_negotiate_contexts *in_ctx;
+       struct smb2_negotiate_contexts *out_ctx;
        uint32_t timeout_msec;
 
        struct {
@@ -4242,7 +4244,8 @@ struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
                                        uint32_t timeout_msec,
                                        enum protocol_types min_protocol,
                                        enum protocol_types max_protocol,
-                                       uint16_t max_credits)
+                                       uint16_t max_credits,
+                                       struct smb2_negotiate_contexts *in_ctx)
 {
        struct tevent_req *req, *subreq;
        struct smbXcli_negprot_state *state;
@@ -4254,6 +4257,7 @@ struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
        }
        state->conn = conn;
        state->ev = ev;
+       state->in_ctx = in_ctx;
        state->timeout_msec = timeout_msec;
 
        if (min_protocol == PROTOCOL_NONE) {
@@ -4934,6 +4938,25 @@ static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_sta
                        return NULL;
                }
 
+               if (state->in_ctx != NULL) {
+                       struct smb2_negotiate_contexts *ctxs = state->in_ctx;
+
+                       for (i=0; i<ctxs->num_contexts; i++) {
+                               struct smb2_negotiate_context *ctx =
+                                       &ctxs->contexts[i];
+
+                               status = smb2_negotiate_context_add(
+                                       state,
+                                       &c,
+                                       ctx->type,
+                                       ctx->data.data,
+                                       ctx->data.length);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       return NULL;
+                               }
+                       }
+               }
+
                status = smb2_negotiate_context_push(state, &b, c);
                if (!NT_STATUS_IS_OK(status)) {
                        return NULL;
@@ -4988,7 +5011,6 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
        uint8_t *body;
        size_t i;
        uint16_t dialect_revision;
-       struct smb2_negotiate_contexts c = { .num_contexts = 0, };
        uint32_t negotiate_context_offset = 0;
        uint16_t negotiate_context_count = 0;
        DATA_BLOB negotiate_context_blob = data_blob_null;
@@ -5184,10 +5206,15 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
        negotiate_context_blob.data += ctx_ofs;
        negotiate_context_blob.length -= ctx_ofs;
 
-       status = smb2_negotiate_context_parse(state,
+       state->out_ctx = talloc_zero(state, struct smb2_negotiate_contexts);
+       if (tevent_req_nomem(state->out_ctx, req)) {
+               return;
+       }
+
+       status = smb2_negotiate_context_parse(state->out_ctx,
                                              negotiate_context_blob,
                                              negotiate_context_count,
-                                             &c);
+                                             state->out_ctx);
        if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
        }
@@ -5195,8 +5222,8 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
                return;
        }
 
-       preauth = smb2_negotiate_context_find(&c,
-                                       SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
+       preauth = smb2_negotiate_context_find(
+               state->out_ctx, SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
        if (preauth == NULL) {
                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
                return;
@@ -5226,7 +5253,8 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
                return;
        }
 
-       sign_algo = smb2_negotiate_context_find(&c, SMB2_SIGNING_CAPABILITIES);
+       sign_algo = smb2_negotiate_context_find(
+               state->out_ctx, SMB2_SIGNING_CAPABILITIES);
        if (sign_algo != NULL) {
                const struct smb3_signing_capabilities *client_sign_algos =
                        &state->conn->smb2.client.smb3_capabilities.signing;
@@ -5285,7 +5313,8 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
                conn->smb2.server.sign_algo = sign_algo_selected;
        }
 
-       cipher = smb2_negotiate_context_find(&c, SMB2_ENCRYPTION_CAPABILITIES);
+       cipher = smb2_negotiate_context_find(
+               state->out_ctx, SMB2_ENCRYPTION_CAPABILITIES);
        if (cipher != NULL) {
                const struct smb3_encryption_capabilities *client_ciphers =
                        &state->conn->smb2.client.smb3_capabilities.encryption;
@@ -5505,9 +5534,26 @@ static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
        return NT_STATUS_INVALID_NETWORK_RESPONSE;
 }
 
-NTSTATUS smbXcli_negprot_recv(struct tevent_req *req)
+NTSTATUS smbXcli_negprot_recv(
+       struct tevent_req *req,
+       TALLOC_CTX *mem_ctx,
+       struct smb2_negotiate_contexts **out_ctx)
 {
-       return tevent_req_simple_recv_ntstatus(req);
+       struct smbXcli_negprot_state *state = tevent_req_data(
+               req, struct smbXcli_negprot_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+
+       if (out_ctx != NULL) {
+               *out_ctx = talloc_move(mem_ctx, &state->out_ctx);
+       }
+
+       tevent_req_received(req);
+       return NT_STATUS_OK;
 }
 
 NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
@@ -5532,9 +5578,15 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
        if (ev == NULL) {
                goto fail;
        }
-       req = smbXcli_negprot_send(frame, ev, conn, timeout_msec,
-                                  min_protocol, max_protocol,
-                                  WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
+       req = smbXcli_negprot_send(
+               frame,
+               ev,
+               conn,
+               timeout_msec,
+               min_protocol,
+               max_protocol,
+               WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
+               NULL);
        if (req == NULL) {
                goto fail;
        }
@@ -5542,7 +5594,7 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
        if (!ok) {
                goto fail;
        }
-       status = smbXcli_negprot_recv(req);
+       status = smbXcli_negprot_recv(req, NULL, NULL);
  fail:
        TALLOC_FREE(frame);
        return status;
index 805a62ce34226a12f62e80f902973266755d1770..8e4fb81818fcf7472fa50507aad03d3ad21aaf9f 100644 (file)
@@ -457,14 +457,19 @@ NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
                                  struct iovec *sent_iov);
 
+struct smb2_negotiate_contexts;
 struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *ev,
                                        struct smbXcli_conn *conn,
                                        uint32_t timeout_msec,
                                        enum protocol_types min_protocol,
                                        enum protocol_types max_protocol,
-                                       uint16_t max_credits);
-NTSTATUS smbXcli_negprot_recv(struct tevent_req *req);
+                                       uint16_t max_credits,
+                                       struct smb2_negotiate_contexts *in_ctx);
+NTSTATUS smbXcli_negprot_recv(
+       struct tevent_req *req,
+       TALLOC_CTX *mem_ctx,
+       struct smb2_negotiate_contexts **out_ctx);
 NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
                         uint32_t timeout_msec,
                         enum protocol_types min_protocol,
index 02d80e46bef477167b7d8801416d8e72034720a4..34cbbd723a8d05311471e3172db01dbed1aef01e 100644 (file)
@@ -2850,11 +2850,15 @@ static void cli_start_connection_connected(struct tevent_req *subreq)
                return;
        }
 
-       subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
-                                     state->cli->timeout,
-                                     state->min_protocol,
-                                     state->max_protocol,
-                                     WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK);
+       subreq = smbXcli_negprot_send(
+               state,
+               state->ev,
+               state->cli->conn,
+               state->cli->timeout,
+               state->min_protocol,
+               state->max_protocol,
+               WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
+               NULL);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -2869,7 +2873,7 @@ static void cli_start_connection_done(struct tevent_req *subreq)
                req, struct cli_start_connection_state);
        NTSTATUS status;
 
-       status = smbXcli_negprot_recv(subreq);
+       status = smbXcli_negprot_recv(subreq, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
index af28b171cf1368c3624d8b4f882c6a739a177765..1ba19e8a8b009c6e8ebb4a912cfa71cbe255a303 100644 (file)
@@ -3953,8 +3953,15 @@ static bool run_negprot_nowait(int dummy)
        for (i=0;i<50000;i++) {
                struct tevent_req *req;
 
-               req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
-                                          PROTOCOL_CORE, PROTOCOL_NT1, 0);
+               req = smbXcli_negprot_send(
+                       ev,
+                       ev,
+                       cli->conn,
+                       cli->timeout,
+                       PROTOCOL_CORE,
+                       PROTOCOL_NT1,
+                       0,
+                       NULL);
                if (req == NULL) {
                        TALLOC_FREE(ev);
                        return false;
index 51c6f0f9ecbed294c9ee4afc106378dd49628944..6d1b7361932997d47138cac3ace7a1388c8aa296 100644 (file)
@@ -106,7 +106,8 @@ struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx,
                                      timeout_msec,
                                      minprotocol,
                                      maxprotocol,
-                                     transport->options.max_credits);
+                                     transport->options.max_credits,
+                                     NULL);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
@@ -125,7 +126,7 @@ static void smb_raw_negotiate_done(struct tevent_req *subreq)
                struct smb_raw_negotiate_state);
        NTSTATUS status;
 
-       status = smbXcli_negprot_recv(subreq);
+       status = smbXcli_negprot_recv(subreq, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
index 9540704491ea30a272540692fc0dab4b8273f4d7..1f68d90538b254a8e8ddef0c86ebe75ec5e3a060 100644 (file)
@@ -187,7 +187,8 @@ static void smb2_connect_socket_done(struct composite_context *creq)
                                      state->transport->conn, timeout_msec,
                                      min_protocol,
                                      state->transport->options.max_protocol,
-                                     state->transport->options.max_credits);
+                                     state->transport->options.max_credits,
+                                     NULL);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -203,7 +204,7 @@ static void smb2_connect_negprot_done(struct tevent_req *subreq)
                struct tevent_req);
        NTSTATUS status;
 
-       status = smbXcli_negprot_recv(subreq);
+       status = smbXcli_negprot_recv(subreq, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
index 3bd5dbc59e8e9e153f4e05385f187b9b6c0dca40..7224dfa87946f8d3deffeb10f140a58b0894534e 100644 (file)
@@ -167,7 +167,8 @@ static void smb_connect_nego_connect_done(struct composite_context *creq)
                                      timeout_msec,
                                      state->options.min_protocol,
                                      state->options.max_protocol,
-                                     state->options.max_credits);
+                                     state->options.max_credits,
+                                     NULL);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -181,7 +182,7 @@ static void smb_connect_nego_nego_done(struct tevent_req *subreq)
                struct tevent_req);
        NTSTATUS status;
 
-       status = smbXcli_negprot_recv(subreq);
+       status = smbXcli_negprot_recv(subreq, NULL, NULL);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;