2010-10-19 21:04:27 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-08-17 10:13:32 +04:00
Manage connections_struct structures
Copyright ( C ) Andrew Tridgell 1998
2002-08-17 19:27:10 +04:00
Copyright ( C ) Alexander Bokovoy 2002
2010-10-19 21:04:27 +04:00
Copyright ( C ) Jeremy Allison 2010
1998-08-17 10:13:32 +04:00
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1998-08-17 10:13:32 +04:00
( at your option ) any later version .
2010-10-19 21:04:27 +04:00
1998-08-17 10:13:32 +04:00
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 .
2010-10-19 21:04:27 +04:00
1998-08-17 10:13:32 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-08-17 10:13:32 +04:00
*/
# include "includes.h"
2011-03-22 18:57:01 +03:00
# include "smbd/smbd.h"
2009-01-08 14:03:45 +03:00
# include "smbd/globals.h"
2011-07-07 15:04:31 +04:00
# include "lib/util/bitmap.h"
1998-08-17 10:13:32 +04:00
/****************************************************************************
2010-10-19 21:04:27 +04:00
Return the number of open connections .
1998-08-17 10:13:32 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-19 21:04:27 +04:00
2009-05-27 13:15:44 +04:00
int conn_num_open ( struct smbd_server_connection * sconn )
1998-08-17 10:13:32 +04:00
{
2012-03-03 08:43:31 +04:00
return sconn - > num_connections ;
1998-08-17 10:13:32 +04:00
}
/****************************************************************************
2010-10-19 21:04:27 +04:00
Check if a snum is in use .
1998-08-17 10:13:32 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-19 21:04:27 +04:00
2011-05-25 07:00:22 +04:00
bool conn_snum_used ( struct smbd_server_connection * sconn ,
int snum )
1998-08-17 10:13:32 +04:00
{
2012-03-03 08:43:31 +04:00
struct connection_struct * conn ;
for ( conn = sconn - > connections ; conn ; conn = conn - > next ) {
if ( conn - > params - > service = = snum ) {
return true ;
1998-08-17 10:13:32 +04:00
}
}
2012-03-03 08:43:31 +04:00
2010-10-19 21:12:42 +04:00
return false ;
1998-08-17 10:13:32 +04:00
}
/****************************************************************************
2010-10-19 21:04:27 +04:00
Find first available connection slot , starting from a random position .
The randomisation stops problems with the server dieing and clients
thinking the server is still available .
1998-08-17 10:13:32 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-19 21:04:27 +04:00
2009-05-27 13:15:44 +04:00
connection_struct * conn_new ( struct smbd_server_connection * sconn )
1998-08-17 10:13:32 +04:00
{
connection_struct * conn ;
2006-10-18 07:34:31 +04:00
2011-06-07 05:44:43 +04:00
if ( ! ( conn = talloc_zero ( NULL , connection_struct ) ) | |
2012-07-23 09:21:34 +04:00
! ( conn - > params = talloc ( conn , struct share_params ) ) | |
! ( conn - > connectpath = talloc_strdup ( conn , " " ) ) | |
! ( conn - > origpath = talloc_strdup ( conn , " " ) ) ) {
2007-04-28 03:18:41 +04:00
DEBUG ( 0 , ( " TALLOC_ZERO() failed! \n " ) ) ;
2008-04-28 12:31:49 +04:00
TALLOC_FREE ( conn ) ;
2003-05-12 03:34:18 +04:00
return NULL ;
}
2009-08-06 15:22:33 +04:00
conn - > sconn = sconn ;
2009-03-04 03:08:56 +03:00
conn - > force_group_gid = ( gid_t ) - 1 ;
1998-08-17 10:13:32 +04:00
2012-03-03 08:43:31 +04:00
DLIST_ADD ( sconn - > connections , conn ) ;
sconn - > num_connections + + ;
1998-08-17 10:13:32 +04:00
return conn ;
}
/****************************************************************************
2011-05-25 08:58:24 +04:00
Clear a vuid out of the connection ' s vuid cache
1998-08-17 10:13:32 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-19 21:04:27 +04:00
2012-06-05 17:50:21 +04:00
static void conn_clear_vuid_cache ( connection_struct * conn , uint64_t vuid )
1998-08-17 10:13:32 +04:00
{
2011-05-25 08:58:24 +04:00
int i ;
2010-10-19 22:11:56 +04:00
2011-05-25 08:58:24 +04:00
for ( i = 0 ; i < VUID_CACHE_SIZE ; i + + ) {
struct vuid_cache_entry * ent ;
ent = & conn - > vuid_cache . array [ i ] ;
if ( ent - > vuid = = vuid ) {
ent - > vuid = UID_FIELD_INVALID ;
/*
* We need to keep conn - > session_info around
* if it ' s equal to ent - > session_info as a SMBulogoff
* is often followed by a SMBtdis ( with an invalid
* vuid ) . The debug code ( or regular code in
* vfs_full_audit ) wants to refer to the
* conn - > session_info pointer to print debug
* statements . Theoretically this is a bug ,
* as once the vuid is gone the session_info
* on the conn struct isn ' t valid any more ,
* but there ' s enough code that assumes
* conn - > session_info is never null that
* it ' s easier to hold onto the old pointer
* until we get a new sessionsetupX .
* As everything is hung off the
* conn pointer as a talloc context we ' re not
* leaking memory here . See bug # 6315. JRA .
*/
if ( conn - > session_info = = ent - > session_info ) {
ent - > session_info = NULL ;
} else {
TALLOC_FREE ( ent - > session_info ) ;
2010-10-19 22:11:56 +04:00
}
2011-05-25 08:58:24 +04:00
ent - > read_only = False ;
2006-04-15 08:07:10 +04:00
}
1998-08-17 10:13:32 +04:00
}
}
2002-09-25 19:19:00 +04:00
/****************************************************************************
2004-02-13 22:05:25 +03:00
Clear a vuid out of the validity cache , and as the ' owner ' of a connection .
2011-05-25 08:58:24 +04:00
Called from invalidate_vuid ( )
2002-09-25 19:19:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-02-13 22:05:25 +03:00
2012-06-05 17:50:21 +04:00
void conn_clear_vuid_caches ( struct smbd_server_connection * sconn , uint64_t vuid )
2002-09-25 19:19:00 +04:00
{
connection_struct * conn ;
2012-03-03 08:43:31 +04:00
for ( conn = sconn - > connections ; conn ; conn = conn - > next ) {
if ( conn - > vuid = = vuid ) {
conn - > vuid = UID_FIELD_INVALID ;
2002-09-25 19:19:00 +04:00
}
2012-03-03 08:43:31 +04:00
conn_clear_vuid_cache ( conn , vuid ) ;
2002-09-25 19:19:00 +04:00
}
}
1998-08-17 10:13:32 +04:00
/****************************************************************************
2005-08-03 03:55:38 +04:00
Free a conn structure - internal part .
1998-08-17 10:13:32 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-08-04 02:38:43 +04:00
2009-08-07 13:48:03 +04:00
static void conn_free_internal ( connection_struct * conn )
1998-08-17 10:13:32 +04:00
{
2009-08-07 13:48:03 +04:00
vfs_handle_struct * handle = NULL , * thandle = NULL ;
2006-12-15 03:49:12 +03:00
struct trans_state * state = NULL ;
2002-08-17 19:27:10 +04:00
2000-04-29 01:09:26 +04:00
/* Free vfs_connection_struct */
2003-05-12 03:34:18 +04:00
handle = conn - > vfs_handles ;
2002-08-17 19:27:10 +04:00
while ( handle ) {
thandle = handle - > next ;
2008-10-02 00:15:54 +04:00
DLIST_REMOVE ( conn - > vfs_handles , handle ) ;
2003-05-12 03:34:18 +04:00
if ( handle - > free_data )
handle - > free_data ( & handle - > data ) ;
2002-08-17 19:27:10 +04:00
handle = thandle ;
2000-04-29 01:09:26 +04:00
}
2006-12-15 03:49:12 +03:00
/* Free any pending transactions stored on this conn. */
for ( state = conn - > pending_trans ; state ; state = state - > next ) {
/* state->setup is a talloc child of state. */
SAFE_FREE ( state - > param ) ;
SAFE_FREE ( state - > data ) ;
}
1998-08-17 10:13:32 +04:00
free_namearray ( conn - > veto_list ) ;
free_namearray ( conn - > hide_list ) ;
free_namearray ( conn - > veto_oplock_list ) ;
2007-10-11 00:34:30 +04:00
free_namearray ( conn - > aio_write_behind_list ) ;
2010-10-19 21:04:27 +04:00
1998-09-05 17:24:20 +04:00
ZERO_STRUCTP ( conn ) ;
2008-04-28 12:31:49 +04:00
talloc_destroy ( conn ) ;
1998-08-17 10:13:32 +04:00
}
2001-06-20 07:05:09 +04:00
2005-08-03 03:55:38 +04:00
/****************************************************************************
Free a conn structure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-06 15:22:33 +04:00
void conn_free ( connection_struct * conn )
2005-08-03 03:55:38 +04:00
{
2009-08-06 15:22:33 +04:00
if ( conn - > sconn = = NULL ) {
conn_free_internal ( conn ) ;
return ;
}
2012-03-03 08:43:31 +04:00
DLIST_REMOVE ( conn - > sconn - > connections , conn ) ;
SMB_ASSERT ( conn - > sconn - > num_connections > 0 ) ;
conn - > sconn - > num_connections - - ;
2005-08-03 03:55:38 +04:00
conn_free_internal ( conn ) ;
}