From 4ddd277c0b77c502ed6b11e07c92c91f24ac9c15 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 25 Aug 2022 09:54:52 +0200 Subject: [PATCH] smbXcli: Pass negotiate contexts through smbXcli_negprot_send/recv We already don't allow setting max_credits in the sync wrapper, so omit the contexts there as well. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Aug 26 19:54:03 UTC 2022 on sn-devel-184 --- libcli/smb/smbXcli_base.c | 80 ++++++++++++++++++++++++----- libcli/smb/smbXcli_base.h | 9 +++- source3/libsmb/cliconnect.c | 16 +++--- source3/torture/torture.c | 11 +++- source4/libcli/raw/rawnegotiate.c | 5 +- source4/libcli/smb2/connect.c | 5 +- source4/libcli/smb_composite/connect_nego.c | 5 +- 7 files changed, 101 insertions(+), 30 deletions(-) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index c5d13bd5837..353b4816e3d 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -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; inum_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; diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 805a62ce342..8e4fb81818f 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -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, diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 02d80e46bef..34cbbd723a8 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -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; diff --git a/source3/torture/torture.c b/source3/torture/torture.c index af28b171cf1..1ba19e8a8b0 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -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; diff --git a/source4/libcli/raw/rawnegotiate.c b/source4/libcli/raw/rawnegotiate.c index 51c6f0f9ecb..6d1b7361932 100644 --- a/source4/libcli/raw/rawnegotiate.c +++ b/source4/libcli/raw/rawnegotiate.c @@ -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; diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 9540704491e..1f68d90538b 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -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; diff --git a/source4/libcli/smb_composite/connect_nego.c b/source4/libcli/smb_composite/connect_nego.c index 3bd5dbc59e8..7224dfa8794 100644 --- a/source4/libcli/smb_composite/connect_nego.c +++ b/source4/libcli/smb_composite/connect_nego.c @@ -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; -- 2.11.4.GIT