From 271f78a9bb814ed10bcc8883a60d6609e1eef500 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 31 Aug 2011 00:40:06 +0200 Subject: s3:smb2cli: pass an array of expected status/body_size pairs to smb2cli_req_recv() This gives the caller more control and correctly reports unexpected errors to the caller, instead of return NT_STATUS_INVALID_NETWOR_RESPONSE metze --- source3/libsmb/smb2cli_base.c | 51 +++++++++++++++++++++++++++++--- source3/libsmb/smb2cli_base.h | 10 ++++++- source3/libsmb/smb2cli_close.c | 9 +++++- source3/libsmb/smb2cli_create.c | 9 +++++- source3/libsmb/smb2cli_flush.c | 9 +++++- source3/libsmb/smb2cli_negprot.c | 9 +++++- source3/libsmb/smb2cli_query_directory.c | 9 +++++- source3/libsmb/smb2cli_read.c | 13 +++++++- source3/libsmb/smb2cli_session.c | 24 +++++++++++++-- source3/libsmb/smb2cli_tcon.c | 18 +++++++++-- source3/libsmb/smb2cli_write.c | 9 +++++- 11 files changed, 153 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb2cli_base.c b/source3/libsmb/smb2cli_base.c index d26e1b4a25..def7f57d45 100644 --- a/source3/libsmb/smb2cli_base.c +++ b/source3/libsmb/smb2cli_base.c @@ -665,24 +665,67 @@ static void smb2cli_inbuf_received(struct tevent_req *subreq) } NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct iovec **piov, int body_size) + struct iovec **piov, + const struct smb2cli_req_expected_response *expected, + size_t num_expected) { struct smb2cli_req_state *state = tevent_req_data(req, struct smb2cli_req_state); NTSTATUS status; + size_t body_size; + bool found_status = false; + bool found_size = false; + size_t i; + + if (num_expected == 0) { + found_status = true; + found_size = true; + } if (tevent_req_is_nterror(req, &status)) { + for (i=0; i < num_expected; i++) { + if (NT_STATUS_EQUAL(status, expected[i].status)) { + found_status = true; + break; + } + } + + if (found_status) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + return status; } status = NT_STATUS(IVAL(state->recv_iov[0].iov_base, SMB2_HDR_STATUS)); + body_size = SVAL(state->recv_iov[1].iov_base, 0); - if (body_size != 0) { - if (body_size != SVAL(state->recv_iov[1].iov_base, 0)) { - return NT_STATUS_INVALID_NETWORK_RESPONSE; + for (i=0; i < num_expected; i++) { + if (!NT_STATUS_EQUAL(status, expected[i].status)) { + continue; + } + + found_status = true; + if (expected[i].body_size == 0) { + found_size = true; + break; + } + + if (expected[i].body_size == body_size) { + found_size = true; + break; } } + + if (!found_status) { + return status; + } + + if (!found_size) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + if (piov != NULL) { *piov = talloc_move(mem_ctx, &state->recv_iov); } diff --git a/source3/libsmb/smb2cli_base.h b/source3/libsmb/smb2cli_base.h index 348f842d40..595665d718 100644 --- a/source3/libsmb/smb2cli_base.h +++ b/source3/libsmb/smb2cli_base.h @@ -35,6 +35,12 @@ struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, uint32_t dyn_len); NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs, int num_reqs); + +struct smb2cli_req_expected_response { + NTSTATUS status; + uint16_t body_size; +}; + struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, @@ -49,6 +55,8 @@ struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx, const uint8_t *dyn, uint32_t dyn_len); NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct iovec **piov, int body_size); + struct iovec **piov, + const struct smb2cli_req_expected_response *expected, + size_t num_expected); #endif diff --git a/source3/libsmb/smb2cli_close.c b/source3/libsmb/smb2cli_close.c index 3c6ad9fb3a..3567449ee9 100644 --- a/source3/libsmb/smb2cli_close.c +++ b/source3/libsmb/smb2cli_close.c @@ -74,8 +74,15 @@ static void smb2cli_close_done(struct tevent_req *subreq) struct tevent_req); NTSTATUS status; struct iovec *iov; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x3C + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 60); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); if (tevent_req_nterror(req, status)) { return; } diff --git a/source3/libsmb/smb2cli_create.c b/source3/libsmb/smb2cli_create.c index 2145ce25f6..eaabf68431 100644 --- a/source3/libsmb/smb2cli_create.c +++ b/source3/libsmb/smb2cli_create.c @@ -162,8 +162,15 @@ static void smb2cli_create_done(struct tevent_req *subreq) struct iovec *iov; uint8_t *body; uint32_t offset, length; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x59 + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 89); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); if (tevent_req_nterror(req, status)) { return; } diff --git a/source3/libsmb/smb2cli_flush.c b/source3/libsmb/smb2cli_flush.c index c767148230..6f3de14787 100644 --- a/source3/libsmb/smb2cli_flush.c +++ b/source3/libsmb/smb2cli_flush.c @@ -72,8 +72,15 @@ static void smb2cli_flush_done(struct tevent_req *subreq) struct tevent_req); NTSTATUS status; struct iovec *iov; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x04 + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 4); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); if (tevent_req_nterror(req, status)) { return; } diff --git a/source3/libsmb/smb2cli_negprot.c b/source3/libsmb/smb2cli_negprot.c index df35225dd4..ea983a9ff9 100644 --- a/source3/libsmb/smb2cli_negprot.c +++ b/source3/libsmb/smb2cli_negprot.c @@ -93,8 +93,15 @@ static void smb2cli_negprot_done(struct tevent_req *subreq) NTSTATUS status; struct iovec *iov; uint8_t *body; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x41 + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 65); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(subreq); tevent_req_nterror(req, status); diff --git a/source3/libsmb/smb2cli_query_directory.c b/source3/libsmb/smb2cli_query_directory.c index 4a0e69b534..f2101abd37 100644 --- a/source3/libsmb/smb2cli_query_directory.c +++ b/source3/libsmb/smb2cli_query_directory.c @@ -111,8 +111,15 @@ static void smb2cli_query_directory_done(struct tevent_req *subreq) NTSTATUS status; struct iovec *iov; uint16_t data_offset; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x09 + } + }; - status = smb2cli_req_recv(subreq, state, &iov, 9); + status = smb2cli_req_recv(subreq, state, &iov, + expected, ARRAY_SIZE(expected)); if (tevent_req_nterror(req, status)) { return; } diff --git a/source3/libsmb/smb2cli_read.c b/source3/libsmb/smb2cli_read.c index e45a75f6ca..7e2b53471b 100644 --- a/source3/libsmb/smb2cli_read.c +++ b/source3/libsmb/smb2cli_read.c @@ -89,8 +89,19 @@ static void smb2cli_read_done(struct tevent_req *subreq) NTSTATUS status; struct iovec *iov; uint8_t data_offset; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = STATUS_BUFFER_OVERFLOW, + .body_size = 0x11 + }, + { + .status = NT_STATUS_OK, + .body_size = 0x11 + } + }; - status = smb2cli_req_recv(subreq, state, &iov, 17); + status = smb2cli_req_recv(subreq, state, &iov, + expected, ARRAY_SIZE(expected)); if (tevent_req_nterror(req, status)) { return; } diff --git a/source3/libsmb/smb2cli_session.c b/source3/libsmb/smb2cli_session.c index 4ffdf13dd6..2a00593ed0 100644 --- a/source3/libsmb/smb2cli_session.c +++ b/source3/libsmb/smb2cli_session.c @@ -98,8 +98,19 @@ static void smb2cli_sesssetup_blob_done(struct tevent_req *subreq) NTSTATUS status; struct iovec *iov; uint16_t offset, length; - - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 9); + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_MORE_PROCESSING_REQUIRED, + .body_size = 0x09 + }, + { + .status = NT_STATUS_OK, + .body_size = 0x09 + } + }; + + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { TALLOC_FREE(subreq); @@ -363,8 +374,15 @@ static void smb2cli_logoff_done(struct tevent_req *subreq) struct tevent_req); NTSTATUS status; struct iovec *iov; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x04 + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 4); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; diff --git a/source3/libsmb/smb2cli_tcon.c b/source3/libsmb/smb2cli_tcon.c index 9cf73e3a4b..dee9140ce6 100644 --- a/source3/libsmb/smb2cli_tcon.c +++ b/source3/libsmb/smb2cli_tcon.c @@ -105,8 +105,15 @@ static void smb2cli_tcon_done(struct tevent_req *subreq) NTSTATUS status; struct iovec *iov; uint8_t *body; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x10 + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 16); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(subreq); tevent_req_nterror(req, status); @@ -202,8 +209,15 @@ static void smb2cli_tdis_done(struct tevent_req *subreq) struct tevent_req); NTSTATUS status; struct iovec *iov; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x04 + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 4); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { return; diff --git a/source3/libsmb/smb2cli_write.c b/source3/libsmb/smb2cli_write.c index d512f0092b..149a0655d2 100644 --- a/source3/libsmb/smb2cli_write.c +++ b/source3/libsmb/smb2cli_write.c @@ -95,8 +95,15 @@ static void smb2cli_write_done(struct tevent_req *subreq) struct tevent_req); NTSTATUS status; struct iovec *iov; + static const struct smb2cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .body_size = 0x11 + } + }; - status = smb2cli_req_recv(subreq, talloc_tos(), &iov, 17); + status = smb2cli_req_recv(subreq, talloc_tos(), &iov, + expected, ARRAY_SIZE(expected)); if (tevent_req_nterror(req, status)) { return; } -- cgit