2011-05-25 08:58:24 +04:00
/*
Unix SMB / CIFS implementation .
Manage connections_struct structures
Copyright ( C ) Andrew Tridgell 1998
Copyright ( C ) Alexander Bokovoy 2002
Copyright ( C ) Jeremy Allison 2010
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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "smbd/smbd.h"
# include "smbd/globals.h"
2011-07-21 17:53:10 +04:00
# include "rpc_server/rpc_pipes.h"
2011-05-25 08:58:24 +04:00
/****************************************************************************
Update last used timestamps .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void conn_lastused_update ( struct smbd_server_connection * sconn , time_t t )
{
2012-03-03 08:43:31 +04:00
struct connection_struct * conn ;
for ( conn = sconn - > connections ; conn ; conn = conn - > next ) {
/* Update if connection wasn't idle. */
if ( conn - > lastused ! = conn - > lastused_count ) {
conn - > lastused = t ;
conn - > lastused_count = t ;
2011-05-25 08:58:24 +04:00
}
}
}
/****************************************************************************
Idle inactive connections .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool conn_idle_all ( struct smbd_server_connection * sconn , time_t t )
{
int deadtime = lp_deadtime ( ) * 60 ;
2012-03-03 08:43:31 +04:00
struct connection_struct * conn ;
2011-05-25 08:58:24 +04:00
conn_lastused_update ( sconn , t ) ;
if ( deadtime < = 0 ) {
deadtime = DEFAULT_SMBD_TIMEOUT ;
}
2012-03-03 08:43:31 +04:00
for ( conn = sconn - > connections ; conn ; conn = conn - > next ) {
time_t age = t - conn - > lastused ;
2011-05-25 08:58:24 +04:00
2012-03-03 08:43:31 +04:00
/* close dirptrs on connections that are idle */
if ( age > DPTR_IDLE_TIMEOUT ) {
dptr_idlecnum ( conn ) ;
2011-05-25 08:58:24 +04:00
}
2012-03-03 08:43:31 +04:00
if ( conn - > num_files_open > 0 | | age < deadtime ) {
return false ;
2011-05-25 08:58:24 +04:00
}
}
/*
* Check all pipes for any open handles . We cannot
* idle with a handle open .
*/
if ( check_open_pipes ( ) ) {
return false ;
}
return true ;
}
/****************************************************************************
Forcibly unmount a share .
All instances of the parameter ' sharename ' share are unmounted .
The special sharename ' * ' forces unmount of all shares .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void conn_force_tdis ( struct smbd_server_connection * sconn , const char * sharename )
{
connection_struct * conn , * next ;
2012-03-28 18:14:09 +04:00
bool close_all = false ;
2011-05-25 08:58:24 +04:00
if ( strcmp ( sharename , " * " ) = = 0 ) {
2012-03-28 18:14:09 +04:00
close_all = true ;
DEBUG ( 1 , ( " conn_force_tdis: Forcing close of all shares \n " ) ) ;
2011-05-25 08:58:24 +04:00
}
2012-03-28 18:14:09 +04:00
/* SMB1 and SMB 2*/
for ( conn = sconn - > connections ; conn ; conn = next ) {
struct smbXsrv_tcon * tcon ;
bool do_close = false ;
NTSTATUS status ;
uint64_t vuid = UID_FIELD_INVALID ;
next = conn - > next ;
2012-06-29 14:37:40 +04:00
if ( conn - > tcon = = NULL ) {
continue ;
}
tcon = conn - > tcon ;
2012-03-28 18:14:09 +04:00
if ( close_all ) {
do_close = true ;
2012-07-18 09:37:23 +04:00
} else if ( strequal ( lp_servicename ( talloc_tos ( ) , SNUM ( conn ) ) ,
sharename ) ) {
2012-03-28 18:14:09 +04:00
DEBUG ( 1 , ( " conn_force_tdis: Forcing close of "
" share '%s' (wire_id=0x%08x) \n " ,
tcon - > global - > share_name ,
tcon - > global - > tcon_wire_id ) ) ;
do_close = true ;
}
2012-03-27 13:09:05 +04:00
2012-03-28 18:14:09 +04:00
if ( ! do_close ) {
continue ;
}
2012-03-27 13:09:05 +04:00
2012-03-28 18:14:09 +04:00
if ( sconn - > using_smb2 ) {
vuid = conn - > vuid ;
2011-05-25 08:58:24 +04:00
}
2012-03-28 18:14:09 +04:00
conn = NULL ;
status = smbXsrv_tcon_disconnect ( tcon , vuid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " conn_force_tdis: "
" smbXsrv_tcon_disconnect() of share '%s' "
" (wire_id=0x%08x) failed: %s \n " ,
tcon - > global - > share_name ,
tcon - > global - > tcon_wire_id ,
nt_errstr ( status ) ) ) ;
2011-05-25 08:58:24 +04:00
}
2012-03-28 18:14:09 +04:00
TALLOC_FREE ( tcon ) ;
2011-05-25 08:58:24 +04:00
}
2013-03-22 00:47:07 +04:00
change_to_root_user ( ) ;
reload_services ( sconn , conn_snum_used , true ) ;
2011-05-25 08:58:24 +04:00
}