libcli/smb: Fix smb2cli_write_recv() and smb2cli_write() to return the bytes written.
authorJeremy Allison <jra@samba.org>
Wed, 7 Aug 2013 21:41:24 +0000 (14:41 -0700)
committerStefan Metzmacher <metze@samba.org>
Thu, 15 Aug 2013 07:07:05 +0000 (09:07 +0200)
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
libcli/smb/smb2cli_write.c
libcli/smb/smbXcli_base.h
source3/libsmb/cli_np_tstream.c
source3/torture/test_smb2.c

index 8e65460fcb5a0b1f54d9a3f8e6eb8bbc3b9001ff..89137bd5baf4eab2caf935b86205c76ff75ca906 100644 (file)
@@ -26,6 +26,7 @@
 struct smb2cli_write_state {
        uint8_t fixed[48];
        uint8_t dyn_pad[1];
+       uint32_t written;
 };
 
 static void smb2cli_write_done(struct tevent_req *subreq);
@@ -94,7 +95,11 @@ static void smb2cli_write_done(struct tevent_req *subreq)
        struct tevent_req *req =
                tevent_req_callback_data(subreq,
                struct tevent_req);
+       struct smb2cli_write_state *state =
+               tevent_req_data(req,
+               struct smb2cli_write_state);
        NTSTATUS status;
+       struct iovec *iov;
        static const struct smb2cli_req_expected_response expected[] = {
        {
                .status = NT_STATUS_OK,
@@ -102,18 +107,32 @@ static void smb2cli_write_done(struct tevent_req *subreq)
        }
        };
 
-       status = smb2cli_req_recv(subreq, NULL, NULL,
+       status = smb2cli_req_recv(subreq, state, &iov,
                                  expected, ARRAY_SIZE(expected));
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
        }
+       state->written = IVAL(iov[1].iov_base, 4);
        tevent_req_done(req);
 }
 
-NTSTATUS smb2cli_write_recv(struct tevent_req *req)
+NTSTATUS smb2cli_write_recv(struct tevent_req *req, uint32_t *written)
 {
-       return tevent_req_simple_recv_ntstatus(req);
+       struct smb2cli_write_state *state =
+               tevent_req_data(req,
+               struct smb2cli_write_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+       if (written) {
+               *written = state->written;
+       }
+       tevent_req_received(req);
+       return NT_STATUS_OK;
 }
 
 NTSTATUS smb2cli_write(struct smbXcli_conn *conn,
@@ -126,7 +145,8 @@ NTSTATUS smb2cli_write(struct smbXcli_conn *conn,
                       uint64_t fid_volatile,
                       uint32_t remaining_bytes,
                       uint32_t flags,
-                      const uint8_t *data)
+                      const uint8_t *data,
+                      uint32_t *written)
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct tevent_context *ev;
@@ -155,7 +175,7 @@ NTSTATUS smb2cli_write(struct smbXcli_conn *conn,
        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
                goto fail;
        }
-       status = smb2cli_write_recv(req);
+       status = smb2cli_write_recv(req, written);
  fail:
        TALLOC_FREE(frame);
        return status;
index f7b60d30bbf71a1ace279d1b438bf4198a7d4a53..997869ba0799581560c8647bcdb2e83b173ec0de 100644 (file)
@@ -429,7 +429,8 @@ struct tevent_req *smb2cli_write_send(TALLOC_CTX *mem_ctx,
                                      uint32_t remaining_bytes,
                                      uint32_t flags,
                                      const uint8_t *data);
-NTSTATUS smb2cli_write_recv(struct tevent_req *req);
+NTSTATUS smb2cli_write_recv(struct tevent_req *req,
+                       uint32_t *written);
 NTSTATUS smb2cli_write(struct smbXcli_conn *conn,
                       uint32_t timeout_msec,
                       struct smbXcli_session *session,
@@ -440,7 +441,8 @@ NTSTATUS smb2cli_write(struct smbXcli_conn *conn,
                       uint64_t fid_volatile,
                       uint32_t remaining_bytes,
                       uint32_t flags,
-                      const uint8_t *data);
+                      const uint8_t *data,
+                      uint32_t *written);
 
 struct tevent_req *smb2cli_flush_send(TALLOC_CTX *mem_ctx,
                                      struct tevent_context *ev,
index c7ec664c5106cbb540f8001dd7b15f891ede5824..07835a5bc2ee1f48170805be8a4a22bb707efba1 100644 (file)
@@ -527,8 +527,11 @@ static void tstream_cli_np_writev_write_done(struct tevent_req *subreq)
        if (cli_nps->is_smb1) {
                status = cli_write_andx_recv(subreq, &written);
        } else {
-               status = smb2cli_write_recv(subreq);
-               written = cli_nps->write.ofs; // TODO: get the value from the server
+               uint32_t smb2_written;
+               status = smb2cli_write_recv(subreq, &smb2_written);
+               if (NT_STATUS_IS_OK(status)) {
+                       written = smb2_written;
+               }
        }
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
index ec695da8f6d49fe20e4feef01aec54b895c487ab..7ca9f49d1a413fe06b00b9f0f9679deaaa51cc0b 100644 (file)
@@ -91,7 +91,7 @@ bool run_smb2_basic(int dummy)
 
        status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
                               cli->smb2.tcon, strlen(hello), 0, fid_persistent,
-                              fid_volatile, 0, 0, (const uint8_t *)hello);
+                              fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                printf("smb2cli_write returned %s\n", nt_errstr(status));
                return false;
@@ -349,7 +349,7 @@ bool run_smb2_session_reconnect(int dummy)
 
        status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
                               cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
-                              fid_volatile, 0, 0, (const uint8_t *)hello);
+                              fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                printf("smb2cli_write returned %s\n", nt_errstr(status));
                return false;
@@ -545,7 +545,7 @@ bool run_smb2_session_reconnect(int dummy)
 
        status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
                               cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
-                              fid_volatile, 0, 0, (const uint8_t *)hello);
+                              fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
            !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
        {
@@ -605,7 +605,7 @@ bool run_smb2_session_reconnect(int dummy)
 
        status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
                               cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
-                              fid_volatile, 0, 0, (const uint8_t *)hello);
+                              fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
            !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
        {
@@ -670,7 +670,7 @@ bool run_smb2_session_reconnect(int dummy)
 
        status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
                               cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
-                              fid_volatile, 0, 0, (const uint8_t *)hello);
+                              fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                printf("smb2cli_write returned %s\n", nt_errstr(status));
                return false;
@@ -765,7 +765,7 @@ bool run_smb2_tcon_dependence(int dummy)
 
        status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
                               cli->smb2.tcon, strlen(hello), 0, fid_persistent,
-                              fid_volatile, 0, 0, (const uint8_t *)hello);
+                              fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                printf("smb2cli_write returned %s\n", nt_errstr(status));
                return false;
@@ -1172,7 +1172,7 @@ bool run_smb2_multi_channel(int dummy)
 
        status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
                               cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
-                              fid_volatile, 0, 0, (const uint8_t *)hello);
+                              fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                printf("smb2cli_write returned %s\n", nt_errstr(status));
                return false;