s3:smb2cli: pass an array of expected status/body_size pairs to smb2cli_req_recv()
authorStefan Metzmacher <metze@samba.org>
Tue, 30 Aug 2011 22:40:06 +0000 (00:40 +0200)
committerStefan Metzmacher <metze@samba.org>
Sun, 18 Sep 2011 03:33:10 +0000 (05:33 +0200)
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
source3/libsmb/smb2cli_base.h
source3/libsmb/smb2cli_close.c
source3/libsmb/smb2cli_create.c
source3/libsmb/smb2cli_flush.c
source3/libsmb/smb2cli_negprot.c
source3/libsmb/smb2cli_query_directory.c
source3/libsmb/smb2cli_read.c
source3/libsmb/smb2cli_session.c
source3/libsmb/smb2cli_tcon.c
source3/libsmb/smb2cli_write.c

index d26e1b4a2588583bede6e4b4394422ac77c9555f..def7f57d451a9a89c05e240de2bf3d668d8a037b 100644 (file)
@@ -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);
        }
index 348f842d40f54d578f41bce6c00b98ab63c39335..595665d7182d1ef8db39a61de9f08492bb798886 100644 (file)
@@ -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
index 3c6ad9fb3a106934bb609959098783aa22198b2f..3567449ee97dc5ef1b4e88cd39c09b284a3b0168 100644 (file)
@@ -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;
        }
index 2145ce25f6aa6b7f7e2c33720d1be335fda6bc41..eaabf6843164a56888b754b3ce385e131b2d4c2e 100644 (file)
@@ -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;
        }
index c7671482306a65531ec0f0e0ea2d954b91d6e3f3..6f3de14787b5bc1b2e6d0a6a1bbb03011bdb447e 100644 (file)
@@ -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;
        }
index df35225dd4f99ac0137faadd2f95f530b2b9effa..ea983a9ff9a99f0e34f4da9f2f1590700f06b3bf 100644 (file)
@@ -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);
index 4a0e69b5349073003e1470f31bc931f95f991034..f2101abd377ed61df04cd005c577f29edbbf1548 100644 (file)
@@ -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;
        }
index e45a75f6cadd8a6369a1800709b29beecc329314..7e2b53471b18bbeb708e35aed79cd5bc9f7be535 100644 (file)
@@ -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;
        }
index 4ffdf13dd6049341c50f4f96f8569afa610426b5..2a00593ed0e1d142e4580648072666f4d010e527 100644 (file)
@@ -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;
index 9cf73e3a4bfda650de187fda8b0d7d48d2ac7b0c..dee9140ce61c021961b217d55a3f5c251cbc3148 100644 (file)
@@ -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;
index d512f0092b8923b0055cc33e93061b2d96189a0e..149a0655d2da0e0fb7668fbf065bf10bc6bdbe1b 100644 (file)
@@ -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;
        }