2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
2004-06-28 12:27:36 +04:00
Manage smbsrv_tcon structures
2003-08-13 05:53:07 +04:00
Copyright ( C ) Andrew Tridgell 1998
Copyright ( C ) Alexander Bokovoy 2002
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-02 09:42:15 +03:00
# include "dlinklist.h"
2004-11-02 10:18:24 +03:00
# include "smb_server/smb_server.h"
2005-01-30 03:54:57 +03:00
# include "smbd/service_stream.h"
2005-12-28 01:51:30 +03:00
# include "ntvfs/ntvfs.h"
2004-11-02 10:18:24 +03:00
2003-08-13 05:53:07 +04:00
/****************************************************************************
2004-06-28 12:27:36 +04:00
init the tcon structures
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-12-06 20:59:20 +03:00
static NTSTATUS smbsrv_init_tcons ( struct smbsrv_tcons_context * tcons_ctx , TALLOC_CTX * mem_ctx , uint32_t limit )
2003-08-13 05:53:07 +04:00
{
2005-11-18 15:38:39 +03:00
/*
* the idr_ * functions take ' int ' as limit ,
* and only work with a max limit 0x00FFFFFF
*/
limit & = 0x00FFFFFF ;
2005-12-06 20:59:20 +03:00
tcons_ctx - > idtree_tid = idr_init ( mem_ctx ) ;
NT_STATUS_HAVE_NO_MEMORY ( tcons_ctx - > idtree_tid ) ;
tcons_ctx - > idtree_limit = limit ;
tcons_ctx - > list = NULL ;
2005-11-18 15:38:39 +03:00
2005-11-18 11:44:36 +03:00
return NT_STATUS_OK ;
2003-08-13 05:53:07 +04:00
}
2005-12-06 20:59:20 +03:00
NTSTATUS smbsrv_smb_init_tcons ( struct smbsrv_connection * smb_conn )
{
return smbsrv_init_tcons ( & smb_conn - > smb_tcons , smb_conn , UINT16_MAX ) ;
}
NTSTATUS smbsrv_smb2_init_tcons ( struct smbsrv_session * smb_sess )
{
return smbsrv_init_tcons ( & smb_sess - > smb2_tcons , smb_sess , UINT32_MAX ) ;
}
2003-08-13 05:53:07 +04:00
/****************************************************************************
2005-12-06 20:59:20 +03:00
find a tcon given a tid for SMB
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-12-06 20:59:20 +03:00
static struct smbsrv_tcon * smbsrv_tcon_find ( struct smbsrv_tcons_context * tcons_ctx , uint32_t tid )
2003-08-13 05:53:07 +04:00
{
2005-11-18 15:38:39 +03:00
void * p ;
struct smbsrv_tcon * tcon ;
if ( tid = = 0 ) return NULL ;
2005-12-06 20:59:20 +03:00
if ( tid > tcons_ctx - > idtree_limit ) return NULL ;
2005-11-18 15:38:39 +03:00
2005-12-06 20:59:20 +03:00
p = idr_find ( tcons_ctx - > idtree_tid , tid ) ;
2005-11-18 15:38:39 +03:00
if ( ! p ) return NULL ;
tcon = talloc_get_type ( p , struct smbsrv_tcon ) ;
return tcon ;
2003-08-13 05:53:07 +04:00
}
2005-12-06 20:59:20 +03:00
struct smbsrv_tcon * smbsrv_smb_tcon_find ( struct smbsrv_connection * smb_conn , uint32_t tid )
{
return smbsrv_tcon_find ( & smb_conn - > smb_tcons , tid ) ;
}
struct smbsrv_tcon * smbsrv_smb2_tcon_find ( struct smbsrv_session * smb_sess , uint32_t tid )
{
if ( ! smb_sess ) return NULL ;
return smbsrv_tcon_find ( & smb_sess - > smb2_tcons , tid ) ;
}
2004-10-19 11:08:35 +04:00
/*
destroy a connection structure
*/
2005-01-13 21:49:10 +03:00
static int smbsrv_tcon_destructor ( void * ptr )
2004-10-19 11:08:35 +04:00
{
2005-12-06 20:59:20 +03:00
struct smbsrv_tcon * tcon = talloc_get_type ( ptr , struct smbsrv_tcon ) ;
struct smbsrv_tcons_context * tcons_ctx ;
2005-01-13 21:49:10 +03:00
DEBUG ( 3 , ( " %s closed connection to service %s \n " ,
socket_get_peer_addr ( tcon - > smb_conn - > connection - > socket , tcon ) ,
2005-02-10 10:39:14 +03:00
lp_servicename ( tcon - > service ) ) ) ;
2005-01-13 21:49:10 +03:00
/* tell the ntvfs backend that we are disconnecting */
2005-11-18 15:38:39 +03:00
if ( tcon - > ntvfs_ctx ) {
ntvfs_disconnect ( tcon ) ;
}
2005-01-13 21:49:10 +03:00
2005-12-06 20:59:20 +03:00
if ( tcon - > smb2 . session ) {
tcons_ctx = & tcon - > smb2 . session - > smb2_tcons ;
} else {
tcons_ctx = & tcon - > smb_conn - > smb_tcons ;
}
idr_remove ( tcons_ctx - > idtree_tid , tcon - > tid ) ;
DLIST_REMOVE ( tcons_ctx - > list , tcon ) ;
2004-10-19 11:08:35 +04:00
return 0 ;
}
2003-08-13 05:53:07 +04:00
2004-10-19 11:08:35 +04:00
/*
find first available connection slot
*/
2005-12-06 20:59:20 +03:00
static struct smbsrv_tcon * smbsrv_tcon_new ( struct smbsrv_connection * smb_conn , struct smbsrv_session * smb_sess )
2003-08-13 05:53:07 +04:00
{
2005-12-06 20:59:20 +03:00
TALLOC_CTX * mem_ctx ;
struct smbsrv_tcons_context * tcons_ctx ;
2004-06-28 12:27:36 +04:00
struct smbsrv_tcon * tcon ;
2003-08-13 05:53:07 +04:00
int i ;
2005-12-06 20:59:20 +03:00
if ( smb_sess ) {
mem_ctx = smb_sess ;
tcons_ctx = & smb_sess - > smb2_tcons ;
} else {
mem_ctx = smb_conn ;
tcons_ctx = & smb_conn - > smb_tcons ;
}
tcon = talloc_zero ( mem_ctx , struct smbsrv_tcon ) ;
2004-10-19 11:08:35 +04:00
if ( ! tcon ) return NULL ;
2005-12-06 20:59:20 +03:00
tcon - > smb_conn = smb_conn ;
tcon - > smb2 . session = smb_sess ;
2004-10-19 11:08:35 +04:00
2005-12-06 20:59:20 +03:00
i = idr_get_new_random ( tcons_ctx - > idtree_tid , tcon , tcons_ctx - > idtree_limit ) ;
2003-08-13 05:53:07 +04:00
if ( i = = - 1 ) {
2005-12-06 20:59:20 +03:00
DEBUG ( 1 , ( " ERROR! Out of connection structures \n " ) ) ;
2003-08-13 05:53:07 +04:00
return NULL ;
}
2005-01-13 21:49:10 +03:00
tcon - > tid = i ;
2003-08-13 05:53:07 +04:00
2005-12-06 20:59:20 +03:00
DLIST_ADD ( tcons_ctx - > list , tcon ) ;
2005-01-13 21:49:10 +03:00
talloc_set_destructor ( tcon , smbsrv_tcon_destructor ) ;
2003-08-13 05:53:07 +04:00
2005-11-18 15:38:39 +03:00
/* now fill in some statistics */
tcon - > statistics . connect_time = timeval_current ( ) ;
2003-08-13 05:53:07 +04:00
2004-06-28 12:27:36 +04:00
return tcon ;
2003-08-13 05:53:07 +04:00
}
2005-12-06 20:59:20 +03:00
struct smbsrv_tcon * smbsrv_smb_tcon_new ( struct smbsrv_connection * smb_conn )
{
return smbsrv_tcon_new ( smb_conn , NULL ) ;
}
struct smbsrv_tcon * smbsrv_smb2_tcon_new ( struct smbsrv_session * smb_sess )
{
return smbsrv_tcon_new ( smb_sess - > smb_conn , smb_sess ) ;
}