LCOV - code coverage report
Current view: top level - source4/smb_server - tcon.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 64 71 90.1 %
Date: 2021-09-23 10:06:22 Functions: 10 11 90.9 %

          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             : 
      28             : /****************************************************************************
      29             : init the tcon structures
      30             : ****************************************************************************/
      31        4615 : static NTSTATUS smbsrv_init_tcons(struct smbsrv_tcons_context *tcons_ctx, TALLOC_CTX *mem_ctx, uint32_t limit)
      32             : {
      33             :         /* 
      34             :          * the idr_* functions take 'int' as limit,
      35             :          * and only work with a max limit 0x00FFFFFF
      36             :          */
      37        4615 :         limit &= 0x00FFFFFF;
      38             : 
      39        4615 :         tcons_ctx->idtree_tid        = idr_init(mem_ctx);
      40        4615 :         NT_STATUS_HAVE_NO_MEMORY(tcons_ctx->idtree_tid);
      41        4615 :         tcons_ctx->idtree_limit      = limit;
      42        4615 :         tcons_ctx->list              = NULL;
      43             : 
      44        4615 :         return NT_STATUS_OK;
      45             : }
      46             : 
      47        2326 : NTSTATUS smbsrv_smb_init_tcons(struct smbsrv_connection *smb_conn)
      48             : {
      49        2326 :         return smbsrv_init_tcons(&smb_conn->smb_tcons, smb_conn, UINT16_MAX);
      50             : }
      51             : 
      52        2289 : NTSTATUS smbsrv_smb2_init_tcons(struct smbsrv_session *smb_sess)
      53             : {
      54        2289 :         return smbsrv_init_tcons(&smb_sess->smb2_tcons, smb_sess, UINT32_MAX);
      55             : }
      56             : 
      57             : /****************************************************************************
      58             : find a tcon given a tid for SMB
      59             : ****************************************************************************/
      60      814687 : static struct smbsrv_tcon *smbsrv_tcon_find(struct smbsrv_tcons_context *tcons_ctx,
      61             :                                             uint32_t tid, struct timeval request_time)
      62             : {
      63             :         void *p;
      64             :         struct smbsrv_tcon *tcon;
      65             : 
      66      814687 :         if (tid == 0) return NULL;
      67             : 
      68      807914 :         if (tid > tcons_ctx->idtree_limit) return NULL;
      69             : 
      70      807914 :         p = idr_find(tcons_ctx->idtree_tid, tid);
      71      807914 :         if (!p) return NULL;
      72             : 
      73      807809 :         tcon = talloc_get_type(p, struct smbsrv_tcon);
      74      807809 :         if (!tcon) return NULL;
      75             : 
      76      807809 :         tcon->statistics.last_request_time = request_time;
      77             : 
      78      807809 :         return tcon;
      79             : }
      80             : 
      81      418964 : struct smbsrv_tcon *smbsrv_smb_tcon_find(struct smbsrv_connection *smb_conn,
      82             :                                          uint32_t tid, struct timeval request_time)
      83             : {
      84      418964 :         return smbsrv_tcon_find(&smb_conn->smb_tcons, tid, request_time);
      85             : }
      86             : 
      87      399081 : struct smbsrv_tcon *smbsrv_smb2_tcon_find(struct smbsrv_session *smb_sess,
      88             :                                           uint32_t tid, struct timeval request_time)
      89             : {
      90      399081 :         if (!smb_sess) return NULL;
      91      395723 :         return smbsrv_tcon_find(&smb_sess->smb2_tcons, tid, request_time);
      92             : }
      93             : 
      94             : /*
      95             :   destroy a connection structure
      96             : */
      97        2690 : static int smbsrv_tcon_destructor(struct smbsrv_tcon *tcon)
      98             : {
      99             :         struct smbsrv_tcons_context *tcons_ctx;
     100             :         struct tsocket_address *client_addr;
     101             : 
     102        2690 :         client_addr = tcon->smb_conn->connection->remote_address;
     103             : 
     104        2690 :         DEBUG(3,("%s closed connection to service %s\n",
     105             :                  tsocket_address_string(client_addr, tcon),
     106             :                  tcon->share_name));
     107             : 
     108             :         /* tell the ntvfs backend that we are disconnecting */
     109        2690 :         if (tcon->ntvfs) {
     110        2690 :                 ntvfs_disconnect(tcon->ntvfs);
     111        2690 :                 tcon->ntvfs = NULL;
     112             :         }
     113             : 
     114        2690 :         if (tcon->smb2.session) {
     115        1697 :                 tcons_ctx = &tcon->smb2.session->smb2_tcons;
     116             :         } else {
     117         993 :                 tcons_ctx = &tcon->smb_conn->smb_tcons;
     118             :         }
     119             : 
     120        2690 :         idr_remove(tcons_ctx->idtree_tid, tcon->tid);
     121        2690 :         DLIST_REMOVE(tcons_ctx->list, tcon);
     122        2690 :         return 0;
     123             : }
     124             : 
     125             : /*
     126             :   find first available connection slot
     127             : */
     128        2690 : static struct smbsrv_tcon *smbsrv_tcon_new(struct smbsrv_connection *smb_conn,
     129             :                                            struct smbsrv_session *smb_sess,
     130             :                                            const char *share_name)
     131             : {
     132             :         TALLOC_CTX *mem_ctx;
     133             :         struct smbsrv_tcons_context *tcons_ctx;
     134             :         uint32_t handle_uint_max;
     135             :         struct smbsrv_tcon *tcon;
     136             :         NTSTATUS status;
     137             :         int i;
     138             : 
     139        2690 :         if (smb_sess) {
     140        1697 :                 mem_ctx = smb_sess;
     141        1697 :                 tcons_ctx = &smb_sess->smb2_tcons;
     142        1697 :                 handle_uint_max = UINT32_MAX;
     143             :         } else {
     144         993 :                 mem_ctx = smb_conn;
     145         993 :                 tcons_ctx = &smb_conn->smb_tcons;
     146         993 :                 handle_uint_max = UINT16_MAX;
     147             :         }
     148             : 
     149        2690 :         tcon = talloc_zero(mem_ctx, struct smbsrv_tcon);
     150        2690 :         if (!tcon) return NULL;
     151        2690 :         tcon->smb_conn               = smb_conn;
     152        2690 :         tcon->smb2.session   = smb_sess;
     153        2690 :         tcon->share_name     = talloc_strdup(tcon, share_name);
     154        2690 :         if (!tcon->share_name) goto failed;
     155             : 
     156             :         /*
     157             :          * the use -1 here, because we don't want to give away the wildcard
     158             :          * fnum used in SMBflush
     159             :          */
     160        2690 :         status = smbsrv_init_handles(tcon, handle_uint_max - 1);
     161        2690 :         if (!NT_STATUS_IS_OK(status)) {
     162           0 :                 DEBUG(1,("ERROR! failed to init handles: %s\n", nt_errstr(status)));
     163           0 :                 goto failed;
     164             :         }
     165             : 
     166        2690 :         i = idr_get_new_random(tcons_ctx->idtree_tid, tcon, tcons_ctx->idtree_limit);
     167        2690 :         if (i == -1) {
     168           0 :                 DEBUG(1,("ERROR! Out of connection structures\n"));
     169           0 :                 goto failed;
     170             :         }
     171        2690 :         tcon->tid = i;
     172             : 
     173        2690 :         DLIST_ADD(tcons_ctx->list, tcon);
     174        2690 :         talloc_set_destructor(tcon, smbsrv_tcon_destructor);
     175             : 
     176             :         /* now fill in some statistics */
     177        2690 :         tcon->statistics.connect_time = timeval_current();
     178             : 
     179        2690 :         return tcon;
     180             : 
     181           0 : failed:
     182           0 :         talloc_free(tcon);
     183           0 :         return NULL;
     184             : }
     185             : 
     186         993 : struct smbsrv_tcon *smbsrv_smb_tcon_new(struct smbsrv_connection *smb_conn, const char *share_name)
     187             : {
     188         993 :         return smbsrv_tcon_new(smb_conn, NULL, share_name);
     189             : }
     190             : 
     191        1697 : struct smbsrv_tcon *smbsrv_smb2_tcon_new(struct smbsrv_session *smb_sess, const char *share_name)
     192             : {
     193        1697 :         return smbsrv_tcon_new(smb_sess->smb_conn, smb_sess, share_name);
     194             : }

Generated by: LCOV version 1.13