- if (!tevent_req_is_in_progress(req)) {
- return tevent_req_post(req, ev);
- }
- 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_common(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_common(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;
- const uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
-
- if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
- && (SVAL(inhdr, 0) != 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(inhdr, HDR_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;
- }
-
- oplock_break = false;
-
- if (mid == 0xffff) {
- /*
- * Paranoia checks that this is really an oplock break request.
- */
- oplock_break = (smb_len_nbt(inbuf) == 51); /* hdr + 8 words */
- oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
- oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
- oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
- oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
-
- if (!oplock_break) {
- /* Dump unexpected reply */
- return NT_STATUS_RETRY;
- }
- }
-
- req = cli->conn.pending[i];
- state = tevent_req_data(req, struct cli_smb_state);
-
- if (!oplock_break /* oplock breaks are not signed */
- && !cli_check_sign_mac(cli, (char *)inbuf, state->seqnum+1)) {
- DEBUG(10, ("cli_check_sign_mac failed\n"));
- return NT_STATUS_ACCESS_DENIED;