summaryrefslogtreecommitdiff
path: root/source3/libsmb/async_smb.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2008-08-25 13:33:41 +0200
committerVolker Lendecke <vl@samba.org>2008-08-28 17:53:37 +0200
commit128524930d490fb5ea637d99bffb36157c80869b (patch)
treeac12973877b56e5117ead320c5528a037da48770 /source3/libsmb/async_smb.c
parent2650207d4adbfd68974fc2b342dd2af079a2552c (diff)
downloadsamba-128524930d490fb5ea637d99bffb36157c80869b.tar.gz
samba-128524930d490fb5ea637d99bffb36157c80869b.tar.bz2
samba-128524930d490fb5ea637d99bffb36157c80869b.zip
Add cli_pull_reply
Along the lines of cli_request_send this abstracts away the smb-level buffer handling when parsing replies we got from the server. (This used to be commit 253134d3aaa359fdfb665709dd5686f69af7f8fd)
Diffstat (limited to 'source3/libsmb/async_smb.c')
-rw-r--r--source3/libsmb/async_smb.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c
index e58b753da2..32f0e8abd6 100644
--- a/source3/libsmb/async_smb.c
+++ b/source3/libsmb/async_smb.c
@@ -230,6 +230,60 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx,
return result;
}
+/**
+ * @brief Pull reply data out of a request
+ * @param[in] req The request that we just received a reply for
+ * @param[out] pwct How many words did the server send?
+ * @param[out] pvwv The words themselves
+ * @param[out] pnum_bytes How many bytes did the server send?
+ * @param[out] pbytes The bytes themselves
+ * @retval Was the reply formally correct?
+ */
+
+NTSTATUS cli_pull_reply(struct async_req *req,
+ uint8_t *pwct, uint16_t **pvwv,
+ uint16_t *pnum_bytes, uint8_t **pbytes)
+{
+ struct cli_request *cli_req = cli_request_get(req);
+ uint8_t wct, cmd;
+ uint16_t num_bytes;
+ size_t wct_ofs, bytes_offset;
+ NTSTATUS status;
+
+ status = cli_pull_error(cli_req->inbuf);
+
+ if (NT_STATUS_IS_ERR(status)) {
+ cli_set_error(cli_req->cli, status);
+ return status;
+ }
+
+ cmd = CVAL(cli_req->inbuf, smb_com);
+ wct_ofs = smb_wct;
+
+ wct = CVAL(cli_req->inbuf, wct_ofs);
+
+ bytes_offset = wct_ofs + 1 + wct * sizeof(uint16_t);
+ num_bytes = SVAL(cli_req->inbuf, bytes_offset);
+
+ /*
+ * wct_ofs is a 16-bit value plus 4, wct is a 8-bit value, num_bytes
+ * is a 16-bit value. So bytes_offset being size_t should be far from
+ * wrapping.
+ */
+
+ if ((bytes_offset + 2 > talloc_get_size(cli_req->inbuf))
+ || (bytes_offset > 0xffff)) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ *pwct = wct;
+ *pvwv = (uint16_t *)(cli_req->inbuf + wct_ofs + 1);
+ *pnum_bytes = num_bytes;
+ *pbytes = (uint8_t *)cli_req->inbuf + bytes_offset + 2;
+
+ return NT_STATUS_OK;
+}
+
/*
* Convenience function to get the SMB part out of an async_req
*/