LCOV - code coverage report
Current view: top level - source4/libcli/raw - rawtrans.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 205 226 90.7 %
Date: 2024-05-31 13:13:24 Functions: 12 13 92.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    raw trans/trans2/nttrans operations
       4             : 
       5             :    Copyright (C) James Myers 2003 <myersjj@samba.org>
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include <tevent.h>
      23             : #include "libcli/raw/libcliraw.h"
      24             : #include "libcli/raw/raw_proto.h"
      25             : #include "../libcli/smb/smbXcli_base.h"
      26             : 
      27             : static void smb_raw_trans_backend_done(struct tevent_req *subreq);
      28             : 
      29       55432 : static struct smbcli_request *smb_raw_trans_backend_send(struct smbcli_tree *tree,
      30             :                                                          struct smb_trans2 *parms,
      31             :                                                          uint8_t command)
      32             : {
      33        1218 :         struct smbcli_request *req;
      34        1218 :         uint8_t additional_flags;
      35        1218 :         uint8_t clear_flags;
      36        1218 :         uint16_t additional_flags2;
      37        1218 :         uint16_t clear_flags2;
      38        1218 :         uint32_t pid;
      39       55432 :         struct smbXcli_tcon *tcon = NULL;
      40       55432 :         struct smbXcli_session *session = NULL;
      41       55432 :         const char *pipe_name = NULL;
      42        1218 :         uint8_t s;
      43        1218 :         uint32_t timeout_msec;
      44        1218 :         uint32_t tmp;
      45             : 
      46       55432 :         tmp = parms->in.params.length + parms->in.data.length;
      47             : 
      48       55432 :         req = smbcli_request_setup(tree, command, parms->in.setup_count, tmp);
      49       55432 :         if (req == NULL) {
      50           0 :                 return NULL;
      51             :         }
      52             : 
      53       55432 :         additional_flags = CVAL(req->out.hdr, HDR_FLG);
      54       55432 :         additional_flags2 = SVAL(req->out.hdr, HDR_FLG2);
      55       55432 :         pid  = SVAL(req->out.hdr, HDR_PID);
      56       55432 :         pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16;
      57             : 
      58       55432 :         if (req->session) {
      59       55432 :                 session = req->session->smbXcli;
      60             :         }
      61             : 
      62       55432 :         if (req->tree) {
      63       55432 :                 tcon = req->tree->smbXcli;
      64             :         }
      65             : 
      66       55432 :         clear_flags = ~additional_flags;
      67       55432 :         clear_flags2 = ~additional_flags2;
      68             : 
      69       55432 :         timeout_msec = req->transport->options.request_timeout * 1000;
      70             : 
      71      110774 :         for (s=0; s < parms->in.setup_count; s++) {
      72       55342 :                 SSVAL(req->out.vwv, VWV(s), parms->in.setup[s]);
      73             :         }
      74             : 
      75       55432 :         if (parms->in.params.length > 0) {
      76       56650 :                 memcpy(req->out.data,
      77       55432 :                        parms->in.params.data,
      78             :                        parms->in.params.length);
      79             :         }
      80       55432 :         if (parms->in.data.length > 0) {
      81       11868 :                 memcpy(req->out.data + parms->in.params.length,
      82       10650 :                        parms->in.data.data,
      83             :                        parms->in.data.length);
      84             :         }
      85             : 
      86       55432 :         if (command == SMBtrans && parms->in.trans_name) {
      87          90 :                 pipe_name = parms->in.trans_name;
      88             :         }
      89             : 
      90      110864 :         req->subreqs[0] = smb1cli_trans_send(req,
      91       54214 :                                              req->transport->ev,
      92       55432 :                                              req->transport->conn,
      93             :                                              command,
      94             :                                              additional_flags,
      95             :                                              clear_flags,
      96             :                                              additional_flags2,
      97             :                                              clear_flags2,
      98             :                                              timeout_msec,
      99             :                                              pid,
     100             :                                              tcon,
     101             :                                              session,
     102             :                                              pipe_name,
     103             :                                              0xFFFF, /* fid */
     104             :                                              0, /* function */
     105       55432 :                                              parms->in.flags,
     106       55432 :                                              (uint16_t *)req->out.vwv,
     107       55432 :                                              parms->in.setup_count,
     108       55432 :                                              parms->in.max_setup,
     109             :                                              req->out.data,
     110       54214 :                                              parms->in.params.length,
     111       55432 :                                              parms->in.max_param,
     112       55432 :                                              req->out.data+
     113       55432 :                                              parms->in.params.length,
     114       55432 :                                              parms->in.data.length,
     115       55432 :                                              parms->in.max_data);
     116       55432 :         if (req->subreqs[0] == NULL) {
     117           0 :                 talloc_free(req);
     118           0 :                 return NULL;
     119             :         }
     120       55432 :         tevent_req_set_callback(req->subreqs[0],
     121             :                                 smb_raw_trans_backend_done,
     122             :                                 req);
     123             : 
     124       55432 :         return req;
     125             : }
     126             : 
     127       55432 : static void smb_raw_trans_backend_done(struct tevent_req *subreq)
     128             : {
     129        1218 :         struct smbcli_request *req =
     130       55432 :                 tevent_req_callback_data(subreq,
     131             :                 struct smbcli_request);
     132       55432 :         struct smbcli_transport *transport = req->transport;
     133       55432 :         uint16_t *setup = NULL;
     134       55432 :         uint8_t num_setup = 0;
     135        1218 :         uint8_t s;
     136       55432 :         uint8_t *param = NULL;
     137       55432 :         uint32_t num_param = 0;
     138       55432 :         uint8_t *data = NULL;
     139       55432 :         uint32_t num_data = 0;
     140             : 
     141       55432 :         req->status = smb1cli_trans_recv(req->subreqs[0], req,
     142             :                                          &req->flags2,
     143             :                                          &setup,
     144             :                                          0, /* min_setup */
     145             :                                          &num_setup,
     146             :                                          &param,
     147             :                                          0, /* min_param */
     148             :                                          &num_param,
     149             :                                          &data,
     150             :                                          0, /* min_data */
     151             :                                          &num_data);
     152       55432 :         TALLOC_FREE(req->subreqs[0]);
     153       55432 :         if (NT_STATUS_IS_ERR(req->status)) {
     154       30586 :                 req->state = SMBCLI_REQUEST_ERROR;
     155       30586 :                 transport->error.e.nt_status = req->status;
     156       30586 :                 transport->error.etype = ETYPE_SMB;
     157       30586 :                 if (req->async.fn) {
     158        5950 :                         req->async.fn(req);
     159             :                 }
     160       30586 :                 return;
     161             :         }
     162             : 
     163       24846 :         req->trans2.out.setup_count = num_setup;
     164       24846 :         req->trans2.out.setup = talloc_array(req, uint16_t, num_setup);
     165       24846 :         if (req->trans2.out.setup == NULL) {
     166           0 :                 req->state = SMBCLI_REQUEST_ERROR;
     167           0 :                 req->status = NT_STATUS_NO_MEMORY;
     168           0 :                 transport->error.e.nt_status = req->status;
     169           0 :                 transport->error.etype = ETYPE_SMB;
     170           0 :                 if (req->async.fn) {
     171           0 :                         req->async.fn(req);
     172             :                 }
     173           0 :                 return;
     174             :         }
     175       24846 :         for (s = 0; s < num_setup; s++) {
     176           0 :                 req->trans2.out.setup[s] = SVAL(setup, VWV(s));
     177             :         }
     178             : 
     179       24846 :         req->trans2.out.params.data = param;
     180       24846 :         req->trans2.out.params.length = num_param;
     181             : 
     182       24846 :         req->trans2.out.data.data = data;
     183       24846 :         req->trans2.out.data.length = num_data;
     184             : 
     185       24846 :         transport->error.e.nt_status = req->status;
     186       24846 :         if (NT_STATUS_IS_OK(req->status)) {
     187       24611 :                 transport->error.etype = ETYPE_NONE;
     188             :         } else {
     189         235 :                 transport->error.etype = ETYPE_SMB;
     190             :         }
     191             : 
     192       24846 :         req->state = SMBCLI_REQUEST_DONE;
     193       24846 :         if (req->async.fn) {
     194         393 :                 req->async.fn(req);
     195             :         }
     196             : }
     197             : 
     198       49457 : static NTSTATUS smb_raw_trans_backend_recv(struct smbcli_request *req,
     199             :                                            TALLOC_CTX *mem_ctx,
     200             :                                            struct smb_trans2 *parms)
     201             : {
     202       68890 :         if (!smbcli_request_receive(req) ||
     203       19433 :             smbcli_request_is_error(req)) {
     204       30024 :                 goto failed;
     205             :         }
     206             : 
     207       19433 :         parms->out = req->trans2.out;
     208       19433 :         talloc_steal(mem_ctx, parms->out.setup);
     209       19433 :         talloc_steal(mem_ctx, parms->out.params.data);
     210       19433 :         talloc_steal(mem_ctx, parms->out.data.data);
     211             : 
     212       49457 : failed:
     213       49457 :         return smbcli_request_destroy(req);
     214             : }
     215             : 
     216          90 : _PUBLIC_ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree,
     217             :                                        struct smb_trans2 *parms)
     218             : {
     219          90 :         return smb_raw_trans_backend_send(tree, parms, SMBtrans);
     220             : }
     221             : 
     222          90 : _PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req,
     223             :                              TALLOC_CTX *mem_ctx,
     224             :                              struct smb_trans2 *parms)
     225             : {
     226          90 :         return smb_raw_trans_backend_recv(req, mem_ctx, parms);
     227             : }
     228             : 
     229          90 : _PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree,
     230             :                        TALLOC_CTX *mem_ctx,
     231             :                        struct smb_trans2 *parms)
     232             : {
     233           0 :         struct smbcli_request *req;
     234          90 :         req = smb_raw_trans_send(tree, parms);
     235          90 :         if (!req) return NT_STATUS_UNSUCCESSFUL;
     236          90 :         return smb_raw_trans_recv(req, mem_ctx, parms);
     237             : }
     238             : 
     239       55342 : struct smbcli_request *smb_raw_trans2_send(struct smbcli_tree *tree,
     240             :                                        struct smb_trans2 *parms)
     241             : {
     242       55342 :         return smb_raw_trans_backend_send(tree, parms, SMBtrans2);
     243             : }
     244             : 
     245       49367 : NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req,
     246             :                              TALLOC_CTX *mem_ctx,
     247             :                              struct smb_trans2 *parms)
     248             : {
     249       49367 :         return smb_raw_trans_backend_recv(req, mem_ctx, parms);
     250             : }
     251             : 
     252       35298 : NTSTATUS smb_raw_trans2(struct smbcli_tree *tree,
     253             :                         TALLOC_CTX *mem_ctx,
     254             :                         struct smb_trans2 *parms)
     255             : {
     256         175 :         struct smbcli_request *req;
     257       35298 :         req = smb_raw_trans2_send(tree, parms);
     258       35298 :         if (!req) return NT_STATUS_UNSUCCESSFUL;
     259       35298 :         return smb_raw_trans2_recv(req, mem_ctx, parms);
     260             : }
     261             : 
     262             : static void smb_raw_nttrans_done(struct tevent_req *subreq);
     263             : 
     264       17216 : struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree,
     265             :                                             struct smb_nttrans *parms)
     266             : {
     267          65 :         struct smbcli_request *req;
     268          65 :         uint8_t additional_flags;
     269          65 :         uint8_t clear_flags;
     270          65 :         uint16_t additional_flags2;
     271          65 :         uint16_t clear_flags2;
     272          65 :         uint32_t pid;
     273       17216 :         struct smbXcli_tcon *tcon = NULL;
     274       17216 :         struct smbXcli_session *session = NULL;
     275          65 :         uint32_t timeout_msec;
     276          65 :         uint32_t tmp;
     277             : 
     278       17216 :         tmp = parms->in.params.length + parms->in.data.length;
     279             : 
     280       17216 :         req = smbcli_request_setup(tree, SMBnttrans, parms->in.setup_count, tmp);
     281       17216 :         if (req == NULL) {
     282           0 :                 return NULL;
     283             :         }
     284             : 
     285       17216 :         additional_flags = CVAL(req->out.hdr, HDR_FLG);
     286       17216 :         additional_flags2 = SVAL(req->out.hdr, HDR_FLG2);
     287       17216 :         pid  = SVAL(req->out.hdr, HDR_PID);
     288       17216 :         pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16;
     289             : 
     290       17216 :         if (req->session) {
     291       17216 :                 session = req->session->smbXcli;
     292             :         }
     293             : 
     294       17216 :         if (req->tree) {
     295       17216 :                 tcon = req->tree->smbXcli;
     296             :         }
     297             : 
     298       17216 :         clear_flags = ~additional_flags;
     299       17216 :         clear_flags2 = ~additional_flags2;
     300             : 
     301       17216 :         timeout_msec = req->transport->options.request_timeout * 1000;
     302             : 
     303       17216 :         if (parms->in.setup_count > 0) {
     304        1732 :                 memcpy(
     305        1667 :                     req->out.vwv, parms->in.setup, parms->in.setup_count * 2);
     306             :         }
     307             : 
     308       17216 :         if (parms->in.params.length > 0) {
     309       15614 :                 memcpy(req->out.data,
     310       15549 :                        parms->in.params.data,
     311             :                        parms->in.params.length);
     312             :         }
     313       17216 :         if (parms->in.data.length > 0) {
     314        7339 :                 memcpy(req->out.data + parms->in.params.length,
     315        7274 :                        parms->in.data.data,
     316             :                        parms->in.data.length);
     317             :         }
     318             : 
     319       34432 :         req->subreqs[0] = smb1cli_trans_send(req,
     320       17151 :                                              req->transport->ev,
     321       17216 :                                              req->transport->conn,
     322             :                                              SMBnttrans,
     323             :                                              additional_flags,
     324             :                                              clear_flags,
     325             :                                              additional_flags2,
     326             :                                              clear_flags2,
     327             :                                              timeout_msec,
     328             :                                              pid,
     329             :                                              tcon,
     330             :                                              session,
     331             :                                              NULL, /* pipe_name */
     332             :                                              0xFFFF, /* fid */
     333       17216 :                                              parms->in.function,
     334             :                                              0, /* flags */
     335       17216 :                                              (uint16_t *)req->out.vwv,
     336       17216 :                                              parms->in.setup_count,
     337       17216 :                                              parms->in.max_setup,
     338             :                                              req->out.data,
     339       17151 :                                              parms->in.params.length,
     340             :                                              parms->in.max_param,
     341       17216 :                                              req->out.data+
     342       17216 :                                              parms->in.params.length,
     343       17216 :                                              parms->in.data.length,
     344             :                                              parms->in.max_data);
     345       17216 :         if (req->subreqs[0] == NULL) {
     346           0 :                 talloc_free(req);
     347           0 :                 return NULL;
     348             :         }
     349       17216 :         tevent_req_set_callback(req->subreqs[0],
     350             :                                 smb_raw_nttrans_done,
     351             :                                 req);
     352             : 
     353       17216 :         return req;
     354             : }
     355             : 
     356       17216 : static void smb_raw_nttrans_done(struct tevent_req *subreq)
     357             : {
     358          65 :         struct smbcli_request *req =
     359       17216 :                 tevent_req_callback_data(subreq,
     360             :                 struct smbcli_request);
     361       17216 :         struct smbcli_transport *transport = req->transport;
     362       17216 :         uint16_t *setup = NULL;
     363       17216 :         uint8_t num_setup = 0;
     364       17216 :         uint8_t *param = NULL;
     365       17216 :         uint32_t num_param = 0;
     366       17216 :         uint8_t *data = NULL;
     367       17216 :         uint32_t num_data = 0;
     368             : 
     369       17216 :         req->status = smb1cli_trans_recv(req->subreqs[0], req,
     370             :                                          &req->flags2,
     371             :                                          &setup,
     372             :                                          0, /* min_setup */
     373             :                                          &num_setup,
     374             :                                          &param,
     375             :                                          0, /* min_param */
     376             :                                          &num_param,
     377             :                                          &data,
     378             :                                          0, /* min_data */
     379             :                                          &num_data);
     380       17216 :         TALLOC_FREE(req->subreqs[0]);
     381       17216 :         if (NT_STATUS_IS_ERR(req->status)) {
     382        1622 :                 req->state = SMBCLI_REQUEST_ERROR;
     383        1622 :                 transport->error.e.nt_status = req->status;
     384        1622 :                 transport->error.etype = ETYPE_SMB;
     385        1622 :                 if (req->async.fn) {
     386          11 :                         req->async.fn(req);
     387             :                 }
     388        1622 :                 return;
     389             :         }
     390             : 
     391       15594 :         req->nttrans.out.setup_count = num_setup;
     392       15594 :         req->nttrans.out.setup = (uint8_t *)setup;
     393             : 
     394       15594 :         req->nttrans.out.params.data = param;
     395       15594 :         req->nttrans.out.params.length = num_param;
     396             : 
     397       15594 :         req->nttrans.out.data.data = data;
     398       15594 :         req->nttrans.out.data.length = num_data;
     399             : 
     400       15594 :         transport->error.e.nt_status = req->status;
     401       15594 :         if (NT_STATUS_IS_OK(req->status)) {
     402       15589 :                 transport->error.etype = ETYPE_NONE;
     403             :         } else {
     404           5 :                 transport->error.etype = ETYPE_SMB;
     405             :         }
     406             : 
     407       15594 :         req->state = SMBCLI_REQUEST_DONE;
     408       15594 :         if (req->async.fn) {
     409        1503 :                 req->async.fn(req);
     410             :         }
     411             : }
     412             : 
     413        9988 : NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req,
     414             :                               TALLOC_CTX *mem_ctx,
     415             :                               struct smb_nttrans *parms)
     416             : {
     417       18522 :         if (!smbcli_request_receive(req) ||
     418        8534 :             smbcli_request_is_error(req)) {
     419        1454 :                 goto failed;
     420             :         }
     421             : 
     422        8534 :         parms->out = req->nttrans.out;
     423        8534 :         talloc_steal(mem_ctx, parms->out.setup);
     424        8534 :         talloc_steal(mem_ctx, parms->out.params.data);
     425        8534 :         talloc_steal(mem_ctx, parms->out.data.data);
     426             : 
     427        9988 : failed:
     428        9988 :         return smbcli_request_destroy(req);
     429             : }
     430             : 
     431             : /****************************************************************************
     432             :   receive a SMB nttrans response allocating the necessary memory
     433             :   ****************************************************************************/
     434           0 : NTSTATUS smb_raw_nttrans(struct smbcli_tree *tree,
     435             :                          TALLOC_CTX *mem_ctx,
     436             :                          struct smb_nttrans *parms)
     437             : {
     438           0 :         struct smbcli_request *req;
     439             : 
     440           0 :         req = smb_raw_nttrans_send(tree, parms);
     441           0 :         if (!req) {
     442           0 :                 return NT_STATUS_UNSUCCESSFUL;
     443             :         }
     444             : 
     445           0 :         return smb_raw_nttrans_recv(req, mem_ctx, parms);
     446             : }

Generated by: LCOV version 1.14