LCOV - code coverage report
Current view: top level - source4/smb_server - tcon.c (source / functions) Hit Total Coverage
Test: coverage report for master 469b22b8 Lines: 65 82 79.3 %
Date: 2024-06-10 12:05:21 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Manage smbsrv_tcon structures
       4             :    Copyright (C) Andrew Tridgell 1998
       5             :    Copyright (C) Alexander Bokovoy 2002
       6             :    Copyright (C) Stefan Metzmacher 2005-2006
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "smb_server/smb_server.h"
      24             : #include "samba/service_stream.h"
      25             : #include "lib/tsocket/tsocket.h"
      26             : #include "ntvfs/ntvfs.h"
      27             : #include "lib/util/idtree_random.h"
      28             : 
      29             : /****************************************************************************
      30             : init the tcon structures
      31             : ****************************************************************************/
      32        3649 : static NTSTATUS smbsrv_init_tcons(struct smbsrv_tcons_context *tcons_ctx, TALLOC_CTX *mem_ctx, uint32_t limit)
      33             : {
      34             :         /* 
      35             :          * the idr_* functions take 'int' as limit,
      36             :          * and only work with a max limit 0x00FFFFFF
      37             :          */
      38        3649 :         limit &= 0x00FFFFFF;
      39             : 
      40        3649 :         tcons_ctx->idtree_tid        = idr_init(mem_ctx);
      41        3649 :         NT_STATUS_HAVE_NO_MEMORY(tcons_ctx->idtree_tid);
      42        3649 :         tcons_ctx->idtree_limit      = limit;
      43        3649 :         tcons_ctx->list              = NULL;
      44             : 
      45        3649 :         return NT_STATUS_OK;
      46             : }
      47             : 
      48        2101 : NTSTATUS smbsrv_smb_init_tcons(struct smbsrv_connection *smb_conn)
      49             : {
      50        2101 :         return smbsrv_init_tcons(&smb_conn->smb_tcons, smb_conn, UINT16_MAX);
      51             : }
      52             : 
      53        1548 : NTSTATUS smbsrv_smb2_init_tcons(struct smbsrv_session *smb_sess)
      54             : {
      55        1548 :         return smbsrv_init_tcons(&smb_sess->smb2_tcons, smb_sess, UINT32_MAX);
      56             : }
      57             : 
      58             : /****************************************************************************
      59             : find a tcon given a tid for SMB
      60             : ****************************************************************************/
      61      831525 : static struct smbsrv_tcon *smbsrv_tcon_find(struct smbsrv_tcons_context *tcons_ctx,
      62             :                                             uint32_t tid, struct timeval request_time)
      63             : {
      64           0 :         void *p;
      65           0 :         struct smbsrv_tcon *tcon;
      66             : 
      67      831525 :         if (tid == 0) return NULL;
      68             : 
      69      825203 :         if (tid > tcons_ctx->idtree_limit) return NULL;
      70             : 
      71      825203 :         p = idr_find(tcons_ctx->idtree_tid, tid);
      72      825203 :         if (!p) return NULL;
      73             : 
      74      825104 :         tcon = talloc_get_type(p, struct smbsrv_tcon);
      75      825104 :         if (!tcon) return NULL;
      76             : 
      77      825104 :         tcon->statistics.last_request_time = request_time;
      78             : 
      79      825104 :         return tcon;
      80             : }
      81             : 
      82      423332 : struct smbsrv_tcon *smbsrv_smb_tcon_find(struct smbsrv_connection *smb_conn,
      83             :                                          uint32_t tid, struct timeval request_time)
      84             : {
      85      423332 :         return smbsrv_tcon_find(&smb_conn->smb_tcons, tid, request_time);
      86             : }
      87             : 
      88      410230 : struct smbsrv_tcon *smbsrv_smb2_tcon_find(struct smbsrv_session *smb_sess,
      89             :                                           uint32_t tid, struct timeval request_time)
      90             : {
      91      410230 :         if (!smb_sess) return NULL;
      92      408193 :         return smbsrv_tcon_find(&smb_sess->smb2_tcons, tid, request_time);
      93             : }
      94             : 
      95             : /*
      96             :   destroy a connection structure
      97             : */
      98        2491 : static int smbsrv_tcon_destructor(struct smbsrv_tcon *tcon)
      99             : {
     100           0 :         struct smbsrv_tcons_context *tcons_ctx;
     101           0 :         struct tsocket_address *client_addr;
     102             : 
     103        2491 :         client_addr = tcon->smb_conn->connection->remote_address;
     104             : 
     105        2491 :         DEBUG(3,("%s closed connection to service %s\n",
     106             :                  tsocket_address_string(client_addr, tcon),
     107             :                  tcon->share_name));
     108             : 
     109             :         /* tell the ntvfs backend that we are disconnecting */
     110        2491 :         if (tcon->ntvfs) {
     111        2491 :                 ntvfs_disconnect(tcon->ntvfs);
     112        2491 :                 tcon->ntvfs = NULL;
     113             :         }
     114             : 
     115        2491 :         if (tcon->smb2.session) {
     116        1538 :                 tcons_ctx = &tcon->smb2.session->smb2_tcons;
     117             :         } else {
     118         953 :                 tcons_ctx = &tcon->smb_conn->smb_tcons;
     119             :         }
     120             : 
     121        2491 :         idr_remove(tcons_ctx->idtree_tid, tcon->tid);
     122        2491 :         DLIST_REMOVE(tcons_ctx->list, tcon);
     123        2491 :         return 0;
     124             : }
     125             : 
     126             : /*
     127             :   find first available connection slot
     128             : */
     129        2491 : static struct smbsrv_tcon *smbsrv_tcon_new(struct smbsrv_connection *smb_conn,
     130             :                                            struct smbsrv_session *smb_sess,
     131             :                                            const char *share_name)
     132             : {
     133           0 :         TALLOC_CTX *mem_ctx;
     134           0 :         struct smbsrv_tcons_context *tcons_ctx;
     135           0 :         uint32_t handle_uint_max;
     136           0 :         struct smbsrv_tcon *tcon;
     137           0 :         NTSTATUS status;
     138           0 :         int i;
     139             : 
     140        2491 :         if (smb_sess) {
     141        1538 :                 mem_ctx = smb_sess;
     142        1538 :                 tcons_ctx = &smb_sess->smb2_tcons;
     143        1538 :                 handle_uint_max = UINT32_MAX;
     144             :         } else {
     145         953 :                 mem_ctx = smb_conn;
     146         953 :                 tcons_ctx = &smb_conn->smb_tcons;
     147         953 :                 handle_uint_max = UINT16_MAX;
     148             :         }
     149             : 
     150        2491 :         tcon = talloc_zero(mem_ctx, struct smbsrv_tcon);
     151        2491 :         if (!tcon) return NULL;
     152        2491 :         tcon->smb_conn               = smb_conn;
     153        2491 :         tcon->smb2.session   = smb_sess;
     154        2491 :         tcon->share_name     = talloc_strdup(tcon, share_name);
     155        2491 :         if (!tcon->share_name) goto failed;
     156             : 
     157             :         /*
     158             :          * the use -1 here, because we don't want to give away the wildcard
     159             :          * fnum used in SMBflush
     160             :          */
     161        2491 :         status = smbsrv_init_handles(tcon, handle_uint_max - 1);
     162        2491 :         if (!NT_STATUS_IS_OK(status)) {
     163           0 :                 DEBUG(1,("ERROR! failed to init handles: %s\n", nt_errstr(status)));
     164           0 :                 goto failed;
     165             :         }
     166             : 
     167        2491 :         i = idr_get_new_random(
     168        2491 :                 tcons_ctx->idtree_tid, tcon, 1, tcons_ctx->idtree_limit);
     169        2491 :         if (i == -1) {
     170           0 :                 DEBUG(1,("ERROR! Out of connection structures\n"));
     171           0 :                 goto failed;
     172             :         }
     173        2491 :         tcon->tid = i;
     174             : 
     175        2491 :         DLIST_ADD(tcons_ctx->list, tcon);
     176        2491 :         talloc_set_destructor(tcon, smbsrv_tcon_destructor);
     177             : 
     178             :         /* now fill in some statistics */
     179        2491 :         tcon->statistics.connect_time = timeval_current();
     180             : 
     181        2491 :         return tcon;
     182             : 
     183           0 : failed:
     184           0 :         talloc_free(tcon);
     185           0 :         return NULL;
     186             : }
     187             : 
     188         953 : struct smbsrv_tcon *smbsrv_smb_tcon_new(struct smbsrv_connection *smb_conn, const char *share_name)
     189             : {
     190         953 :         return smbsrv_tcon_new(smb_conn, NULL, share_name);
     191             : }
     192             : 
     193        1538 : struct smbsrv_tcon *smbsrv_smb2_tcon_new(struct smbsrv_session *smb_sess, const char *share_name)
     194             : {
     195        1538 :         return smbsrv_tcon_new(smb_sess->smb_conn, smb_sess, share_name);
     196             : }

Generated by: LCOV version 1.14