LCOV - code coverage report
Current view: top level - source4/libcli/raw - rawtrans.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 175 205 85.4 %
Date: 2024-06-13 04:01:37 Functions: 9 13 69.2 %

          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       36420 : static struct smbcli_request *smb_raw_trans_backend_send(struct smbcli_tree *tree,
      30             :                                                          struct smb_trans2 *parms,
      31             :                                                          uint8_t command)
      32             : {
      33             :         struct smbcli_request *req;
      34             :         uint8_t additional_flags;
      35             :         uint8_t clear_flags;
      36             :         uint16_t additional_flags2;
      37             :         uint16_t clear_flags2;
      38             :         uint32_t pid;
      39       36420 :         struct smbXcli_tcon *tcon = NULL;
      40       36420 :         struct smbXcli_session *session = NULL;
      41       36420 :         const char *pipe_name = NULL;
      42             :         uint8_t s;
      43             :         uint32_t timeout_msec;
      44             :         uint32_t tmp;
      45             : 
      46       36420 :         tmp = parms->in.params.length + parms->in.data.length;
      47             : 
      48       36420 :         req = smbcli_request_setup(tree, command, parms->in.setup_count, tmp);
      49       36420 :         if (req == NULL) {
      50           0 :                 return NULL;
      51             :         }
      52             : 
      53       36420 :         additional_flags = CVAL(req->out.hdr, HDR_FLG);
      54       36420 :         additional_flags2 = SVAL(req->out.hdr, HDR_FLG2);
      55       36420 :         pid  = SVAL(req->out.hdr, HDR_PID);
      56       36420 :         pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16;
      57             : 
      58       36420 :         if (req->session) {
      59       36420 :                 session = req->session->smbXcli;
      60             :         }
      61             : 
      62       36420 :         if (req->tree) {
      63       36420 :                 tcon = req->tree->smbXcli;
      64             :         }
      65             : 
      66       36420 :         clear_flags = ~additional_flags;
      67       36420 :         clear_flags2 = ~additional_flags2;
      68             : 
      69       36420 :         timeout_msec = req->transport->options.request_timeout * 1000;
      70             : 
      71       72840 :         for (s=0; s < parms->in.setup_count; s++) {
      72       36420 :                 SSVAL(req->out.vwv, VWV(s), parms->in.setup[s]);
      73             :         }
      74             : 
      75       36420 :         if (parms->in.params.length > 0) {
      76       72805 :                 memcpy(req->out.data,
      77       36420 :                        parms->in.params.data,
      78             :                        parms->in.params.length);
      79             :         }
      80       36420 :         if (parms->in.data.length > 0) {
      81       11878 :                 memcpy(req->out.data + parms->in.params.length,
      82        5939 :                        parms->in.data.data,
      83             :                        parms->in.data.length);
      84             :         }
      85             : 
      86       36420 :         if (command == SMBtrans && parms->in.trans_name) {
      87           0 :                 pipe_name = parms->in.trans_name;
      88             :         }
      89             : 
      90      363920 :         req->subreqs[0] = smb1cli_trans_send(req,
      91       36420 :                                              req->transport->ev,
      92       36420 :                                              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       36420 :                                              parms->in.flags,
     106       36420 :                                              (uint16_t *)req->out.vwv,
     107       36420 :                                              parms->in.setup_count,
     108       36420 :                                              parms->in.max_setup,
     109             :                                              req->out.data,
     110       36420 :                                              parms->in.params.length,
     111       36420 :                                              parms->in.max_param,
     112       36420 :                                              req->out.data+
     113       36420 :                                              parms->in.params.length,
     114       36420 :                                              parms->in.data.length,
     115       36420 :                                              parms->in.max_data);
     116       36420 :         if (req->subreqs[0] == NULL) {
     117           0 :                 talloc_free(req);
     118           0 :                 return NULL;
     119             :         }
     120       36420 :         tevent_req_set_callback(req->subreqs[0],
     121             :                                 smb_raw_trans_backend_done,
     122             :                                 req);
     123             : 
     124       36420 :         return req;
     125             : }
     126             : 
     127       36420 : static void smb_raw_trans_backend_done(struct tevent_req *subreq)
     128             : {
     129       36385 :         struct smbcli_request *req =
     130       36420 :                 tevent_req_callback_data(subreq,
     131             :                 struct smbcli_request);
     132       36420 :         struct smbcli_transport *transport = req->transport;
     133       36420 :         uint16_t *setup = NULL;
     134       36420 :         uint8_t num_setup = 0;
     135             :         uint8_t s;
     136       36420 :         uint8_t *param = NULL;
     137       36420 :         uint32_t num_param = 0;
     138       36420 :         uint8_t *data = NULL;
     139       36420 :         uint32_t num_data = 0;
     140             : 
     141       36420 :         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       36420 :         TALLOC_FREE(req->subreqs[0]);
     153       36420 :         if (NT_STATUS_IS_ERR(req->status)) {
     154       29048 :                 req->state = SMBCLI_REQUEST_ERROR;
     155       29048 :                 transport->error.e.nt_status = req->status;
     156       29048 :                 transport->error.etype = ETYPE_SMB;
     157       29048 :                 if (req->async.fn) {
     158        5950 :                         req->async.fn(req);
     159             :                 }
     160       58095 :                 return;
     161             :         }
     162             : 
     163        7372 :         req->trans2.out.setup_count = num_setup;
     164        7372 :         req->trans2.out.setup = talloc_array(req, uint16_t, num_setup);
     165        7372 :         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        7372 :         for (s = 0; s < num_setup; s++) {
     176           0 :                 req->trans2.out.setup[s] = SVAL(setup, VWV(s));
     177             :         }
     178             : 
     179        7372 :         req->trans2.out.params.data = param;
     180        7372 :         req->trans2.out.params.length = num_param;
     181             : 
     182        7372 :         req->trans2.out.data.data = data;
     183        7372 :         req->trans2.out.data.length = num_data;
     184             : 
     185        7372 :         transport->error.e.nt_status = req->status;
     186        7372 :         if (NT_STATUS_IS_OK(req->status)) {
     187        7372 :                 transport->error.etype = ETYPE_NONE;
     188             :         } else {
     189           0 :                 transport->error.etype = ETYPE_SMB;
     190             :         }
     191             : 
     192        7372 :         req->state = SMBCLI_REQUEST_DONE;
     193        7372 :         if (req->async.fn) {
     194         353 :                 req->async.fn(req);
     195             :         }
     196             : }
     197             : 
     198       34921 : static NTSTATUS smb_raw_trans_backend_recv(struct smbcli_request *req,
     199             :                                            TALLOC_CTX *mem_ctx,
     200             :                                            struct smb_trans2 *parms)
     201             : {
     202       41095 :         if (!smbcli_request_receive(req) ||
     203        6174 :             smbcli_request_is_error(req)) {
     204           1 :                 goto failed;
     205             :         }
     206             : 
     207        6174 :         parms->out = req->trans2.out;
     208        6174 :         talloc_steal(mem_ctx, parms->out.setup);
     209        6174 :         talloc_steal(mem_ctx, parms->out.params.data);
     210        6174 :         talloc_steal(mem_ctx, parms->out.data.data);
     211             : 
     212       63667 : failed:
     213       34921 :         return smbcli_request_destroy(req);
     214             : }
     215             : 
     216           0 : _PUBLIC_ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree,
     217             :                                        struct smb_trans2 *parms)
     218             : {
     219           0 :         return smb_raw_trans_backend_send(tree, parms, SMBtrans);
     220             : }
     221             : 
     222           0 : _PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req,
     223             :                              TALLOC_CTX *mem_ctx,
     224             :                              struct smb_trans2 *parms)
     225             : {
     226           0 :         return smb_raw_trans_backend_recv(req, mem_ctx, parms);
     227             : }
     228             : 
     229           0 : _PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree,
     230             :                        TALLOC_CTX *mem_ctx,
     231             :                        struct smb_trans2 *parms)
     232             : {
     233             :         struct smbcli_request *req;
     234           0 :         req = smb_raw_trans_send(tree, parms);
     235           0 :         if (!req) return NT_STATUS_UNSUCCESSFUL;
     236           0 :         return smb_raw_trans_recv(req, mem_ctx, parms);
     237             : }
     238             : 
     239       36420 : struct smbcli_request *smb_raw_trans2_send(struct smbcli_tree *tree,
     240             :                                        struct smb_trans2 *parms)
     241             : {
     242       36420 :         return smb_raw_trans_backend_send(tree, parms, SMBtrans2);
     243             : }
     244             : 
     245       34921 : NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req,
     246             :                              TALLOC_CTX *mem_ctx,
     247             :                              struct smb_trans2 *parms)
     248             : {
     249       34921 :         return smb_raw_trans_backend_recv(req, mem_ctx, parms);
     250             : }
     251             : 
     252       26997 : NTSTATUS smb_raw_trans2(struct smbcli_tree *tree,
     253             :                         TALLOC_CTX *mem_ctx,
     254             :                         struct smb_trans2 *parms)
     255             : {
     256             :         struct smbcli_request *req;
     257       26997 :         req = smb_raw_trans2_send(tree, parms);
     258       26997 :         if (!req) return NT_STATUS_UNSUCCESSFUL;
     259       26997 :         return smb_raw_trans2_recv(req, mem_ctx, parms);
     260             : }
     261             : 
     262             : static void smb_raw_nttrans_done(struct tevent_req *subreq);
     263             : 
     264        1771 : struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree,
     265             :                                             struct smb_nttrans *parms)
     266             : {
     267             :         struct smbcli_request *req;
     268             :         uint8_t additional_flags;
     269             :         uint8_t clear_flags;
     270             :         uint16_t additional_flags2;
     271             :         uint16_t clear_flags2;
     272             :         uint32_t pid;
     273        1771 :         struct smbXcli_tcon *tcon = NULL;
     274        1771 :         struct smbXcli_session *session = NULL;
     275             :         uint32_t timeout_msec;
     276             :         uint32_t tmp;
     277             : 
     278        1771 :         tmp = parms->in.params.length + parms->in.data.length;
     279             : 
     280        1771 :         req = smbcli_request_setup(tree, SMBnttrans, parms->in.setup_count, tmp);
     281        1771 :         if (req == NULL) {
     282           0 :                 return NULL;
     283             :         }
     284             : 
     285        1771 :         additional_flags = CVAL(req->out.hdr, HDR_FLG);
     286        1771 :         additional_flags2 = SVAL(req->out.hdr, HDR_FLG2);
     287        1771 :         pid  = SVAL(req->out.hdr, HDR_PID);
     288        1771 :         pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16;
     289             : 
     290        1771 :         if (req->session) {
     291        1771 :                 session = req->session->smbXcli;
     292             :         }
     293             : 
     294        1771 :         if (req->tree) {
     295        1771 :                 tcon = req->tree->smbXcli;
     296             :         }
     297             : 
     298        1771 :         clear_flags = ~additional_flags;
     299        1771 :         clear_flags2 = ~additional_flags2;
     300             : 
     301        1771 :         timeout_msec = req->transport->options.request_timeout * 1000;
     302             : 
     303        1771 :         if (parms->in.setup_count > 0) {
     304        1161 :                 memcpy(
     305        1161 :                     req->out.vwv, parms->in.setup, parms->in.setup_count * 2);
     306             :         }
     307             : 
     308        1771 :         if (parms->in.params.length > 0) {
     309        2380 :                 memcpy(req->out.data,
     310        1190 :                        parms->in.params.data,
     311             :                        parms->in.params.length);
     312             :         }
     313        1771 :         if (parms->in.data.length > 0) {
     314        1102 :                 memcpy(req->out.data + parms->in.params.length,
     315         551 :                        parms->in.data.data,
     316             :                        parms->in.data.length);
     317             :         }
     318             : 
     319       15932 :         req->subreqs[0] = smb1cli_trans_send(req,
     320        1771 :                                              req->transport->ev,
     321        1771 :                                              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        1771 :                                              parms->in.function,
     334             :                                              0, /* flags */
     335        1771 :                                              (uint16_t *)req->out.vwv,
     336        1771 :                                              parms->in.setup_count,
     337        1771 :                                              parms->in.max_setup,
     338             :                                              req->out.data,
     339        1771 :                                              parms->in.params.length,
     340             :                                              parms->in.max_param,
     341        1771 :                                              req->out.data+
     342        1771 :                                              parms->in.params.length,
     343        1771 :                                              parms->in.data.length,
     344             :                                              parms->in.max_data);
     345        1771 :         if (req->subreqs[0] == NULL) {
     346           0 :                 talloc_free(req);
     347           0 :                 return NULL;
     348             :         }
     349        1771 :         tevent_req_set_callback(req->subreqs[0],
     350             :                                 smb_raw_nttrans_done,
     351             :                                 req);
     352             : 
     353        1771 :         return req;
     354             : }
     355             : 
     356        1771 : static void smb_raw_nttrans_done(struct tevent_req *subreq)
     357             : {
     358        1770 :         struct smbcli_request *req =
     359        1771 :                 tevent_req_callback_data(subreq,
     360             :                 struct smbcli_request);
     361        1771 :         struct smbcli_transport *transport = req->transport;
     362        1771 :         uint16_t *setup = NULL;
     363        1771 :         uint8_t num_setup = 0;
     364        1771 :         uint8_t *param = NULL;
     365        1771 :         uint32_t num_param = 0;
     366        1771 :         uint8_t *data = NULL;
     367        1771 :         uint32_t num_data = 0;
     368             : 
     369        1771 :         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        1771 :         TALLOC_FREE(req->subreqs[0]);
     381        1771 :         if (NT_STATUS_IS_ERR(req->status)) {
     382         540 :                 req->state = SMBCLI_REQUEST_ERROR;
     383         540 :                 transport->error.e.nt_status = req->status;
     384         540 :                 transport->error.etype = ETYPE_SMB;
     385         540 :                 if (req->async.fn) {
     386          15 :                         req->async.fn(req);
     387             :                 }
     388         540 :                 return;
     389             :         }
     390             : 
     391        1231 :         req->nttrans.out.setup_count = num_setup;
     392        1231 :         req->nttrans.out.setup = (uint8_t *)setup;
     393             : 
     394        1231 :         req->nttrans.out.params.data = param;
     395        1231 :         req->nttrans.out.params.length = num_param;
     396             : 
     397        1231 :         req->nttrans.out.data.data = data;
     398        1231 :         req->nttrans.out.data.length = num_data;
     399             : 
     400        1231 :         transport->error.e.nt_status = req->status;
     401        1231 :         if (NT_STATUS_IS_OK(req->status)) {
     402        1231 :                 transport->error.etype = ETYPE_NONE;
     403             :         } else {
     404           0 :                 transport->error.etype = ETYPE_SMB;
     405             :         }
     406             : 
     407        1231 :         req->state = SMBCLI_REQUEST_DONE;
     408        1231 :         if (req->async.fn) {
     409         303 :                 req->async.fn(req);
     410             :         }
     411             : }
     412             : 
     413        1213 : NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req,
     414             :                               TALLOC_CTX *mem_ctx,
     415             :                               struct smb_nttrans *parms)
     416             : {
     417        1913 :         if (!smbcli_request_receive(req) ||
     418         700 :             smbcli_request_is_error(req)) {
     419           1 :                 goto failed;
     420             :         }
     421             : 
     422         700 :         parms->out = req->nttrans.out;
     423         700 :         talloc_steal(mem_ctx, parms->out.setup);
     424         700 :         talloc_steal(mem_ctx, parms->out.params.data);
     425         700 :         talloc_steal(mem_ctx, parms->out.data.data);
     426             : 
     427        1725 : failed:
     428        1213 :         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             :         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.13