LCOV - code coverage report
Current view: top level - libcli/smb - smb1cli_echo.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 27 66 40.9 %
Date: 2024-04-21 15:09:00 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    smb2 lib
       4             :    Copyright (C) Stefan Metzmacher 2012
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "system/network.h"
      22             : #include "lib/util/tevent_ntstatus.h"
      23             : #include "smb_common.h"
      24             : #include "smbXcli_base.h"
      25             : 
      26             : struct smb1cli_echo_state {
      27             :         uint16_t vwv[1];
      28             :         DATA_BLOB data;
      29             :         uint16_t num_echos;
      30             : };
      31             : 
      32             : static void smb1cli_echo_done(struct tevent_req *subreq);
      33             : 
      34          21 : struct tevent_req *smb1cli_echo_send(TALLOC_CTX *mem_ctx,
      35             :                                      struct tevent_context *ev,
      36             :                                      struct smbXcli_conn *conn,
      37             :                                      uint32_t timeout_msec,
      38             :                                      uint16_t num_echos,
      39             :                                      DATA_BLOB data)
      40             : {
      41           0 :         struct tevent_req *req, *subreq;
      42           0 :         struct smb1cli_echo_state *state;
      43             : 
      44          21 :         req = tevent_req_create(mem_ctx, &state, struct smb1cli_echo_state);
      45          21 :         if (req == NULL) {
      46           0 :                 return NULL;
      47             :         }
      48          21 :         SSVAL(state->vwv, 0, num_echos);
      49          21 :         state->data = data;
      50          21 :         state->num_echos = num_echos;
      51             : 
      52          21 :         subreq = smb1cli_req_send(state, ev, conn, SMBecho,
      53             :                                   0, 0, /* *_flags */
      54             :                                   0, 0, /* *_flags2 */
      55             :                                   timeout_msec,
      56             :                                   0, /* pid */
      57             :                                   NULL, /* tcon */
      58             :                                   NULL, /* session */
      59          21 :                                   ARRAY_SIZE(state->vwv), state->vwv,
      60          21 :                                   data.length, data.data);
      61          21 :         if (subreq == NULL) {
      62           0 :                 goto fail;
      63             :         }
      64          21 :         tevent_req_set_callback(subreq, smb1cli_echo_done, req);
      65          21 :         return req;
      66           0 :  fail:
      67           0 :         TALLOC_FREE(req);
      68           0 :         return NULL;
      69             : }
      70             : 
      71          21 : static void smb1cli_echo_done(struct tevent_req *subreq)
      72             : {
      73          21 :         struct tevent_req *req = tevent_req_callback_data(
      74             :                 subreq, struct tevent_req);
      75          21 :         struct smb1cli_echo_state *state = tevent_req_data(
      76             :                 req, struct smb1cli_echo_state);
      77           0 :         NTSTATUS status;
      78           0 :         uint32_t num_bytes;
      79           0 :         uint8_t *bytes;
      80           0 :         struct iovec *recv_iov;
      81          21 :         struct smb1cli_req_expected_response expected[] = {
      82             :         {
      83             :                 .status = NT_STATUS_OK,
      84             :                 .wct    = 1,
      85             :         },
      86             :         };
      87             : 
      88          21 :         status = smb1cli_req_recv(subreq, state,
      89             :                                   &recv_iov,
      90             :                                   NULL, /* phdr */
      91             :                                   NULL, /* pwct */
      92             :                                   NULL, /* pvwv */
      93             :                                   NULL, /* pvwv_offset */
      94             :                                   &num_bytes,
      95             :                                   &bytes,
      96             :                                   NULL, /* pbytes_offset */
      97             :                                   NULL, /* pinbuf */
      98             :                                   expected, ARRAY_SIZE(expected));
      99          21 :         if (!NT_STATUS_IS_OK(status)) {
     100           0 :                 tevent_req_nterror(req, status);
     101          21 :                 return;
     102             :         }
     103             : 
     104          21 :         if (num_bytes != state->data.length) {
     105           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     106           0 :                 return;
     107             :         }
     108             : 
     109          21 :         if (memcmp(bytes, state->data.data, num_bytes) != 0) {
     110           0 :                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     111           0 :                 return;
     112             :         }
     113             : 
     114             :         /* TODO: do we want to verify the sequence number? */
     115             : 
     116          21 :         state->num_echos -=1;
     117          21 :         if (state->num_echos == 0) {
     118          21 :                 tevent_req_done(req);
     119          21 :                 return;
     120             :         }
     121             : 
     122           0 :         if (!smbXcli_req_set_pending(subreq)) {
     123           0 :                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     124           0 :                 return;
     125             :         }
     126             : }
     127             : 
     128             : /**
     129             :  * Get the result out from an echo request
     130             :  * @param[in] req       The async_req from smb1cli_echo_send
     131             :  * @retval Did the server reply correctly?
     132             :  */
     133             : 
     134          21 : NTSTATUS smb1cli_echo_recv(struct tevent_req *req)
     135             : {
     136          21 :         return tevent_req_simple_recv_ntstatus(req);
     137             : }
     138             : 
     139           0 : NTSTATUS smb1cli_echo(struct smbXcli_conn *conn, uint32_t timeout_msec,
     140             :                       uint16_t num_echos, DATA_BLOB data)
     141             : {
     142           0 :         TALLOC_CTX *frame = talloc_stackframe();
     143           0 :         struct tevent_context *ev;
     144           0 :         struct tevent_req *req;
     145           0 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     146             : 
     147           0 :         if (smbXcli_conn_has_async_calls(conn)) {
     148             :                 /*
     149             :                  * Can't use sync call while an async call is in flight
     150             :                  */
     151           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     152           0 :                 goto fail;
     153             :         }
     154           0 :         ev = samba_tevent_context_init(frame);
     155           0 :         if (ev == NULL) {
     156           0 :                 goto fail;
     157             :         }
     158           0 :         req = smb1cli_echo_send(frame, ev, conn, timeout_msec, num_echos, data);
     159           0 :         if (req == NULL) {
     160           0 :                 goto fail;
     161             :         }
     162           0 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     163           0 :                 goto fail;
     164             :         }
     165           0 :         status = smb1cli_echo_recv(req);
     166           0 :  fail:
     167           0 :         TALLOC_FREE(frame);
     168           0 :         return status;
     169             : }

Generated by: LCOV version 1.14