summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2011-08-31 00:40:06 +0200
committerStefan Metzmacher <metze@samba.org>2011-09-18 05:33:10 +0200
commit271f78a9bb814ed10bcc8883a60d6609e1eef500 (patch)
tree5a33c7c4a1971696c43e30f1986a2ecf7e43d5ac /source3
parentb6b767a2c47b26c1758520212b4f09ddb934c9f3 (diff)
downloadsamba-271f78a9bb814ed10bcc8883a60d6609e1eef500.tar.gz
samba-271f78a9bb814ed10bcc8883a60d6609e1eef500.tar.bz2
samba-271f78a9bb814ed10bcc8883a60d6609e1eef500.zip
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
Diffstat (limited to 'source3')
-rw-r--r--source3/libsmb/smb2cli_base.c51
-rw-r--r--source3/libsmb/smb2cli_base.h10
-rw-r--r--source3/libsmb/smb2cli_close.c9
-rw-r--r--source3/libsmb/smb2cli_create.c9
-rw-r--r--source3/libsmb/smb2cli_flush.c9
-rw-r--r--source3/libsmb/smb2cli_negprot.c9
-rw-r--r--source3/libsmb/smb2cli_query_directory.c9
-rw-r--r--source3/libsmb/smb2cli_read.c13
-rw-r--r--source3/libsmb/smb2cli_session.c24
-rw-r--r--source3/libsmb/smb2cli_tcon.c18
-rw-r--r--source3/libsmb/smb2cli_write.c9
11 files changed, 153 insertions, 17 deletions
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;
}