LCOV - code coverage report
Current view: top level - source4/libcli/raw - clitree.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 81 103 78.6 %
Date: 2024-02-28 12:06:22 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    SMB client tree context management functions
       5             : 
       6             :    Copyright (C) Andrew Tridgell 1994-2005
       7             :    Copyright (C) James Myers 2003 <myersjj@samba.org>
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "libcli/raw/libcliraw.h"
      25             : #include "libcli/raw/raw_proto.h"
      26             : #include "libcli/smb_composite/smb_composite.h"
      27             : #include "../libcli/smb/smbXcli_base.h"
      28             : 
      29             : #define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \
      30             :         req = smbcli_request_setup(tree, cmd, wct, buflen); \
      31             :         if (!req) return NULL; \
      32             : } while (0)
      33             : 
      34             : /****************************************************************************
      35             :  Initialize the tree context
      36             : ****************************************************************************/
      37        2943 : _PUBLIC_ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session,
      38             :                                      TALLOC_CTX *parent_ctx, bool primary)
      39             : {
      40         144 :         struct smbcli_tree *tree;
      41             : 
      42        2943 :         tree = talloc_zero(parent_ctx, struct smbcli_tree);
      43        2943 :         if (!tree) {
      44           0 :                 return NULL;
      45             :         }
      46             : 
      47        2943 :         if (primary) {
      48        2826 :                 tree->session = talloc_steal(tree, session);
      49             :         } else {
      50         117 :                 tree->session = talloc_reference(tree, session);
      51             :         }
      52             : 
      53        2943 :         tree->smbXcli = smbXcli_tcon_create(tree);
      54        2943 :         if (tree->smbXcli == NULL) {
      55           0 :                 talloc_free(tree);
      56           0 :                 return NULL;
      57             :         }
      58             : 
      59        2799 :         return tree;
      60             : }
      61             : 
      62             : /****************************************************************************
      63             :  Send a tconX (async send)
      64             : ****************************************************************************/
      65        2935 : struct smbcli_request *smb_raw_tcon_send(struct smbcli_tree *tree,
      66             :                                          union smb_tcon *parms)
      67             : {
      68        2935 :         struct smbcli_request *req = NULL;
      69             : 
      70        2935 :         switch (parms->tcon.level) {
      71           0 :         case RAW_TCON_TCON:
      72           0 :                 SETUP_REQUEST_TREE(SMBtcon, 0, 0);
      73           0 :                 smbcli_req_append_ascii4(req, parms->tcon.in.service, STR_ASCII);
      74           0 :                 smbcli_req_append_ascii4(req, parms->tcon.in.password,STR_ASCII);
      75           0 :                 smbcli_req_append_ascii4(req, parms->tcon.in.dev,     STR_ASCII);
      76           0 :                 break;
      77             : 
      78        2935 :         case RAW_TCON_TCONX:
      79        2935 :                 SETUP_REQUEST_TREE(SMBtconX, 4, 0);
      80        2935 :                 SSVAL(req->out.vwv, VWV(0), 0xFF);
      81        2935 :                 SSVAL(req->out.vwv, VWV(1), 0);
      82        2935 :                 SSVAL(req->out.vwv, VWV(2), parms->tconx.in.flags);
      83        2935 :                 SSVAL(req->out.vwv, VWV(3), parms->tconx.in.password.length);
      84        2935 :                 smbcli_req_append_blob(req, &parms->tconx.in.password);
      85        2935 :                 smbcli_req_append_string(req, parms->tconx.in.path,   STR_TERMINATE | STR_UPPER);
      86        2935 :                 smbcli_req_append_string(req, parms->tconx.in.device, STR_TERMINATE | STR_ASCII);
      87        2935 :                 break;
      88             : 
      89           0 :         case RAW_TCON_SMB2:
      90           0 :                 return NULL;
      91             :         }
      92             : 
      93        2935 :         if (!smbcli_request_send(req)) {
      94           0 :                 smbcli_request_destroy(req);
      95           0 :                 return NULL;
      96             :         }
      97             : 
      98        2791 :         return req;
      99             : }
     100             : 
     101             : /****************************************************************************
     102             :  Send a tconX (async recv)
     103             : ****************************************************************************/
     104        2935 : NTSTATUS smb_raw_tcon_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx,
     105             :                            union smb_tcon *parms)
     106             : {
     107         144 :         uint8_t *p;
     108             : 
     109        5870 :         if (!smbcli_request_receive(req) ||
     110        2935 :             smbcli_request_is_error(req)) {
     111          49 :                 goto failed;
     112             :         }
     113             : 
     114        2886 :         switch (parms->tcon.level) {
     115           0 :         case RAW_TCON_TCON:
     116           0 :                 SMBCLI_CHECK_WCT(req, 2);
     117           0 :                 parms->tcon.out.max_xmit = SVAL(req->in.vwv, VWV(0));
     118           0 :                 parms->tcon.out.tid = SVAL(req->in.vwv, VWV(1));
     119        2748 :                 break;
     120             : 
     121        2886 :         case RAW_TCON_TCONX:
     122        2886 :                 ZERO_STRUCT(parms->tconx.out);
     123        2886 :                 parms->tconx.out.tid = SVAL(req->in.hdr, HDR_TID);
     124        2886 :                 if (req->in.wct >= 3) {
     125        2886 :                         parms->tconx.out.options = SVAL(req->in.vwv, VWV(2));
     126             :                 }
     127        2886 :                 if (req->in.wct >= 7) {
     128        2018 :                         parms->tconx.out.max_access = IVAL(req->in.vwv, VWV(3));
     129        2018 :                         parms->tconx.out.guest_max_access = IVAL(req->in.vwv, VWV(5));
     130             :                 }
     131             : 
     132             :                 /* output is actual service name */
     133        2886 :                 p = req->in.data;
     134        2886 :                 if (!p) break;
     135             : 
     136        2886 :                 p += smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.dev_type,
     137             :                                             p, -1, STR_ASCII | STR_TERMINATE);
     138        2886 :                 smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->tconx.out.fs_type,
     139             :                                          p, -1, STR_TERMINATE);
     140        2886 :                 break;
     141             : 
     142           0 :         case RAW_TCON_SMB2:
     143           0 :                 req->status = NT_STATUS_INTERNAL_ERROR;
     144           0 :                 break;
     145             :         }
     146             : 
     147        2935 : failed:
     148        2935 :         return smbcli_request_destroy(req);
     149             : }
     150             : 
     151             : /****************************************************************************
     152             :  Send a tconX (sync interface)
     153             : ****************************************************************************/
     154         194 : _PUBLIC_ NTSTATUS smb_raw_tcon(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx,
     155             :                       union smb_tcon *parms)
     156             : {
     157         194 :         struct smbcli_request *req = smb_raw_tcon_send(tree, parms);
     158         194 :         return smb_raw_tcon_recv(req, mem_ctx, parms);
     159             : }
     160             : 
     161             : 
     162             : /****************************************************************************
     163             :  Send a tree disconnect.
     164             : ****************************************************************************/
     165         222 : _PUBLIC_ NTSTATUS smb_tree_disconnect(struct smbcli_tree *tree)
     166             : {
     167          16 :         struct smbcli_request *req;
     168             : 
     169         222 :         if (!tree) return NT_STATUS_OK;
     170         210 :         req = smbcli_request_setup(tree, SMBtdis, 0, 0);
     171         210 :         if (req == NULL) {
     172           0 :                 return NT_STATUS_NO_MEMORY;
     173             :         }
     174             : 
     175         210 :         if (smbcli_request_send(req)) {
     176         210 :                 (void) smbcli_request_receive(req);
     177             :         }
     178         210 :         return smbcli_request_destroy(req);
     179             : }
     180             : 
     181             : 
     182             : /*
     183             :   a convenient function to establish a smbcli_tree from scratch
     184             : */
     185        2575 : NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx,
     186             :                                      struct smbcli_tree **ret_tree,
     187             :                                      const char *dest_host, const char **dest_ports,
     188             :                                      const char *service, const char *service_type,
     189             :                                          const char *socket_options,
     190             :                                      struct cli_credentials *credentials,
     191             :                                      struct resolve_context *resolve_ctx,
     192             :                                      struct tevent_context *ev,
     193             :                                      struct smbcli_options *options,
     194             :                                      struct smbcli_session_options *session_options,
     195             :                                          struct gensec_settings *gensec_settings)
     196             : {
     197         141 :         struct smb_composite_connect io;
     198         141 :         NTSTATUS status;
     199        2575 :         TALLOC_CTX *tmp_ctx = talloc_new(parent_ctx);
     200        2575 :         if (!tmp_ctx) {
     201           0 :                 return NT_STATUS_NO_MEMORY;
     202             :         }
     203             : 
     204        2575 :         io.in.dest_host = dest_host;
     205        2575 :         io.in.dest_ports = dest_ports;
     206        2575 :         io.in.socket_options = socket_options;
     207        2575 :         io.in.called_name = strupper_talloc(tmp_ctx, dest_host);
     208        2575 :         io.in.service = service;
     209        2575 :         io.in.service_type = service_type;
     210        2575 :         io.in.existing_conn = NULL;
     211        2575 :         io.in.credentials = credentials;
     212        2575 :         io.in.gensec_settings = gensec_settings;
     213        2575 :         io.in.fallback_to_anonymous = false;
     214             : 
     215             :         /* This workgroup gets sent out by the SPNEGO session setup.
     216             :          * I don't know of any servers that look at it, so we
     217             :          * hardcode it to "". */
     218        2575 :         io.in.workgroup = "";
     219        2575 :         io.in.options = *options;
     220        2575 :         io.in.session_options = *session_options;
     221             : 
     222        2575 :         status = smb_composite_connect(&io, parent_ctx, resolve_ctx, ev);
     223        2575 :         if (NT_STATUS_IS_OK(status)) {
     224        2463 :                 *ret_tree = io.out.tree;
     225             :         }
     226        2575 :         talloc_free(tmp_ctx);
     227        2575 :         return status;
     228             : }

Generated by: LCOV version 1.14