-
- status = cli_smb_req_send(req);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- }
- return req;
-}
-
-static void cli_smb_sent(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct cli_smb_state *state = tevent_req_data(
- req, struct cli_smb_state);
- ssize_t nwritten;
- int err;
-
- nwritten = writev_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (nwritten == -1) {
- NTSTATUS status = map_nt_error_from_unix(err);
- cli_state_notify_pending(state->cli, status);
- return;
- }
-
- if (state->one_way) {
- state->inbuf = NULL;
- tevent_req_done(req);
- return;
- }
-
- if (!cli_smb_req_set_pending(req)) {
- tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-}
-
-static void cli_smb_received(struct tevent_req *subreq)
-{
- struct cli_state *cli = tevent_req_callback_data(
- subreq, struct cli_state);
- TALLOC_CTX *frame = talloc_stackframe();
- NTSTATUS status;
- uint8_t *inbuf;
- ssize_t received;
- int err;
-
- if (subreq != cli->conn.read_smb_req) {
- DEBUG(1, ("Internal error: cli_smb_received called with "
- "unexpected subreq\n"));
- status = NT_STATUS_INTERNAL_ERROR;
- cli_state_notify_pending(cli, status);
- TALLOC_FREE(frame);
- return;
- }
-
- received = read_smb_recv(subreq, frame, &inbuf, &err);
- TALLOC_FREE(subreq);
- cli->conn.read_smb_req = NULL;
- if (received == -1) {
- status = map_nt_error_from_unix(err);
- cli_state_notify_pending(cli, status);
- TALLOC_FREE(frame);
- return;
- }
-
- status = cli->conn.dispatch_incoming(cli, frame, inbuf);
- TALLOC_FREE(frame);
- if (NT_STATUS_IS_OK(status)) {
- /*
- * We should not do any more processing
- * as the dispatch function called
- * tevent_req_done().
- */
- return;
- } else if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
- /*
- * We got an error, so notify all pending requests
- */
- cli_state_notify_pending(cli, status);
- return;
- }
-
- /*
- * We got NT_STATUS_RETRY, so we may ask for a
- * next incoming pdu.
- */
- if (!cli_state_receive_next(cli)) {
- cli_state_notify_pending(cli, NT_STATUS_NO_MEMORY);
- }
-}
-
-static NTSTATUS cli_state_dispatch_smb1(struct cli_state *cli,
- TALLOC_CTX *frame,
- uint8_t *inbuf)
-{
- struct tevent_req *req;
- struct cli_smb_state *state;
- NTSTATUS status;
- int num_pending;
- int i;
- uint16_t mid;
- bool oplock_break;
-
- if ((IVAL(inbuf, 4) != 0x424d53ff) /* 0xFF"SMB" */
- && (SVAL(inbuf, 4) != 0x45ff)) /* 0xFF"E" */ {
- DEBUG(10, ("Got non-SMB PDU\n"));
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
- }
-
- if (cli_state_encryption_on(cli) && (CVAL(inbuf, 0) == 0)) {
- uint16_t enc_ctx_num;
-
- status = get_enc_ctx_num(inbuf, &enc_ctx_num);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("get_enc_ctx_num returned %s\n",
- nt_errstr(status)));
- return status;
- }
-
- if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) {
- DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
- enc_ctx_num,
- cli->trans_enc_state->enc_ctx_num));
- return NT_STATUS_INVALID_HANDLE;
- }
-
- status = common_decrypt_buffer(cli->trans_enc_state,
- (char *)inbuf);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("common_decrypt_buffer returned %s\n",
- nt_errstr(status)));
- return status;
- }
- }
-
- mid = SVAL(inbuf, smb_mid);
- num_pending = talloc_array_length(cli->conn.pending);
-
- for (i=0; i<num_pending; i++) {
- if (mid == cli_smb_req_mid(cli->conn.pending[i])) {
- break;
- }
- }
- if (i == num_pending) {
- /* Dump unexpected reply */
- return NT_STATUS_RETRY;