LCOV - code coverage report
Current view: top level - source4/libcli - cliconnect.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 69 106 65.1 %
Date: 2024-04-21 15:09:00 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    client connect/disconnect routines
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003-2005
       7             :    Copyright (C) James Peach 2005
       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/libcli.h"
      25             : #include "libcli/raw/libcliraw.h"
      26             : #include "libcli/raw/raw_proto.h"
      27             : #include "libcli/auth/libcli_auth.h"
      28             : #include "libcli/smb_composite/smb_composite.h"
      29             : #include "libcli/smb/smbXcli_base.h"
      30             : 
      31             : /*
      32             :   wrapper around smbcli_sock_connect()
      33             : */
      34           6 : bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, 
      35             :                            const char **ports, 
      36             :                            struct tevent_context *ev_ctx,
      37             :                            struct resolve_context *resolve_ctx,
      38             :                            struct smbcli_options *options,
      39             :                            const char *socket_options,
      40             :                            struct nbt_name *calling,
      41             :                            struct nbt_name *called)
      42             : {
      43           0 :         NTSTATUS status;
      44             : 
      45           6 :         cli->options = *options;
      46             : 
      47           6 :         status = smbcli_sock_connect(cli,
      48             :                                      NULL, /* host_addr */
      49             :                                      ports,
      50             :                                      server,
      51             :                                      resolve_ctx,
      52             :                                      ev_ctx,
      53             :                                      socket_options,
      54             :                                      calling,
      55             :                                      called,
      56             :                                      &cli->sock);
      57           6 :         if (!NT_STATUS_IS_OK(status)) {
      58           0 :                 return false;
      59             :         }
      60             : 
      61           6 :         return true;
      62             : }
      63             : 
      64             : /* wrapper around smb_raw_negotiate() */
      65           0 : NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol)
      66             : {
      67           0 :         if (unicode) {
      68           0 :                 cli->options.unicode = 1;
      69             :         } else {
      70           0 :                 cli->options.unicode = 0;
      71             :         }
      72             : 
      73           0 :         cli->transport = smbcli_transport_init(cli->sock, cli,
      74             :                                                true, &cli->options);
      75           0 :         cli->sock = NULL;
      76           0 :         if (!cli->transport) {
      77           0 :                 return NT_STATUS_NO_MEMORY;
      78             :         }
      79             : 
      80           0 :         return smb_raw_negotiate(cli->transport, unicode, PROTOCOL_CORE, maxprotocol);
      81             : }
      82             : 
      83             : /* wrapper around smb_raw_sesssetup() */
      84           0 : NTSTATUS smbcli_session_setup(struct smbcli_state *cli, 
      85             :                               struct cli_credentials *credentials,
      86             :                               const char *workgroup,
      87             :                               struct smbcli_session_options options,
      88             :                               struct gensec_settings *gensec_settings)
      89             : {
      90           0 :         struct smb_composite_sesssetup setup;
      91           0 :         NTSTATUS status;
      92             : 
      93           0 :         cli->session = smbcli_session_init(cli->transport, cli, true,
      94             :                                            options);
      95           0 :         if (!cli->session) return NT_STATUS_UNSUCCESSFUL;
      96             : 
      97           0 :         setup.in.sesskey = cli->transport->negotiate.sesskey;
      98           0 :         setup.in.capabilities = cli->transport->negotiate.capabilities;
      99           0 :         setup.in.credentials = credentials;
     100           0 :         setup.in.workgroup = workgroup;
     101           0 :         setup.in.gensec_settings = gensec_settings;
     102             : 
     103           0 :         status = smb_composite_sesssetup(cli->session, &setup);
     104             : 
     105           0 :         cli->session->vuid = setup.out.vuid;
     106             : 
     107           0 :         return status;
     108             : }
     109             : 
     110             : /* wrapper around smb_raw_tcon() */
     111          77 : NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename, 
     112             :                       const char *devtype, const char *password)
     113             : {
     114          11 :         union smb_tcon tcon;
     115          11 :         TALLOC_CTX *mem_ctx;
     116          11 :         NTSTATUS status;
     117             : 
     118          77 :         cli->tree = smbcli_tree_init(cli->session, cli, true);
     119          77 :         if (!cli->tree) return NT_STATUS_UNSUCCESSFUL;
     120             : 
     121          77 :         mem_ctx = talloc_init("tcon");
     122          77 :         if (!mem_ctx) {
     123           0 :                 return NT_STATUS_NO_MEMORY;
     124             :         }
     125             : 
     126             :         /* setup a tree connect */
     127          77 :         tcon.generic.level = RAW_TCON_TCONX;
     128          77 :         tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
     129          77 :         tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
     130          77 :         if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
     131          77 :                 tcon.tconx.in.password = data_blob(NULL, 0);
     132           0 :         } else if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
     133           0 :                 tcon.tconx.in.password = data_blob_talloc(mem_ctx, NULL, 24);
     134           0 :                 if (cli->transport->negotiate.secblob.length < 8) {
     135           0 :                         return NT_STATUS_INVALID_PARAMETER;
     136             :                 }
     137           0 :                 SMBencrypt(password, cli->transport->negotiate.secblob.data, tcon.tconx.in.password.data);
     138             :         } else {
     139           0 :                 tcon.tconx.in.password = data_blob_talloc(mem_ctx, password, strlen(password)+1);
     140             :         }
     141          77 :         tcon.tconx.in.path = sharename;
     142          77 :         tcon.tconx.in.device = devtype;
     143             :         
     144          77 :         status = smb_raw_tcon(cli->tree, mem_ctx, &tcon);
     145          77 :         if (!NT_STATUS_IS_OK(status)) {
     146          42 :                 goto out;
     147             :         }
     148          35 :         cli->tree->tid = tcon.tconx.out.tid;
     149             : 
     150          35 :         if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) {
     151           0 :                 smb1cli_session_protect_session_key(cli->tree->session->smbXcli);
     152             :         }
     153             : 
     154          35 : out:
     155          77 :         talloc_free(mem_ctx);
     156             : 
     157          77 :         return status;
     158             : }
     159             : 
     160             : 
     161             : /*
     162             :   easy way to get to a fully connected smbcli_state in one call
     163             : */
     164        2571 : NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx,
     165             :                                 struct smbcli_state **ret_cli, 
     166             :                                 const char *host,
     167             :                                 const char **ports,
     168             :                                 const char *sharename,
     169             :                                 const char *devtype,
     170             :                                 const char *socket_options,
     171             :                                 struct cli_credentials *credentials,
     172             :                                 struct resolve_context *resolve_ctx,
     173             :                                 struct tevent_context *ev,
     174             :                                 struct smbcli_options *options,
     175             :                                 struct smbcli_session_options *session_options,
     176             :                                 struct gensec_settings *gensec_settings)
     177             : {
     178         141 :         struct smbcli_tree *tree;
     179         141 :         NTSTATUS status;
     180             : 
     181        2571 :         *ret_cli = NULL;
     182             : 
     183        2571 :         status = smbcli_tree_full_connection(parent_ctx,
     184             :                                              &tree, host, ports, 
     185             :                                              sharename, devtype,
     186             :                                                  socket_options,
     187             :                                              credentials, resolve_ctx, ev,
     188             :                                              options,
     189             :                                              session_options,
     190             :                                                  gensec_settings);
     191        2571 :         if (!NT_STATUS_IS_OK(status)) {
     192         112 :                 goto done;
     193             :         }
     194             : 
     195        2459 :         (*ret_cli) = smbcli_state_init(parent_ctx);
     196             : 
     197        2459 :         (*ret_cli)->tree = tree;
     198        2459 :         (*ret_cli)->session = tree->session;
     199        2459 :         (*ret_cli)->transport = tree->session->transport;
     200             : 
     201        2459 :         talloc_steal(*ret_cli, tree);
     202             :         
     203        2571 : done:
     204        2571 :         return status;
     205             : }
     206             : 
     207             : 
     208             : /*
     209             :   disconnect the tree
     210             : */
     211         162 : NTSTATUS smbcli_tdis(struct smbcli_state *cli)
     212             : {
     213         162 :         return smb_tree_disconnect(cli->tree);
     214             : }
     215             : 
     216             : /****************************************************************************
     217             :  Initialise a client state structure.
     218             : ****************************************************************************/
     219        2465 : struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx)
     220             : {
     221        2465 :         return talloc_zero(mem_ctx, struct smbcli_state);
     222             : }
     223             : 
     224             : /* Insert a NULL at the first separator of the given path and return a pointer
     225             :  * to the remainder of the string.
     226             :  */
     227             : static char *
     228        2408 : terminate_path_at_separator(char * path)
     229             : {
     230          82 :         char * p;
     231             : 
     232        2408 :         if (!path) {
     233           0 :                 return NULL;
     234             :         }
     235             : 
     236        2408 :         if ((p = strchr_m(path, '/'))) {
     237        1131 :                 *p = '\0';
     238        1131 :                 return p + 1;
     239             :         }
     240             : 
     241        1277 :         if ((p = strchr_m(path, '\\'))) {
     242          94 :                 *p = '\0';
     243          94 :                 return p + 1;
     244             :         }
     245             :         
     246             :         /* No separator. */
     247        1142 :         return NULL;
     248             : }
     249             : 
     250             : /*
     251             :   parse a //server/share type UNC name
     252             : */
     253        2390 : bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
     254             :                       char **hostname, char **sharename)
     255             : {
     256         119 :         char *p;
     257             : 
     258        2390 :         if (strncmp(unc_name, "\\\\", 2) &&
     259        2296 :             strncmp(unc_name, "//", 2)) {
     260        1108 :                 return false;
     261             :         }
     262             : 
     263        1204 :         *hostname = *sharename = NULL;
     264             : 
     265        1204 :         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
     266        1204 :         p = terminate_path_at_separator(*hostname);
     267             : 
     268        1204 :         if (p != NULL && *p) {
     269        1204 :                 *sharename = talloc_strdup(mem_ctx, p);
     270        1204 :                 terminate_path_at_separator(*sharename);
     271             :         }
     272             : 
     273        1204 :         if (*hostname && *sharename) {
     274        1163 :                 return true;
     275             :         }
     276             : 
     277           0 :         talloc_free(*hostname);
     278           0 :         talloc_free(*sharename);
     279           0 :         *hostname = *sharename = NULL;
     280           0 :         return false;
     281             : }
     282             : 
     283             : 
     284             : 

Generated by: LCOV version 1.14