2003-06-25 22:08:00 +04:00
/*
Unix SMB / CIFS implementation .
Winbind daemon connection manager
Copyright ( C ) Tim Potter 2001
Copyright ( C ) Andrew Bartlett 2002
Copyright ( C ) Gerald ( Jerry ) Carter 2003
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
2003-06-25 22:08:00 +04:00
( 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"
# define CONNCACHE_ADDR 1
# define CONNCACHE_NAME 2
/* cache entry contains either a server name **or** and IP address as
the key . This means that a server could have two entries ( one for each key ) */
struct failed_connection_cache {
fstring domain_name ;
fstring controller ;
time_t lookup_time ;
NTSTATUS nt_status ;
struct failed_connection_cache * prev , * next ;
} ;
static struct failed_connection_cache * failed_connection_cache ;
/**********************************************************************
2006-02-04 01:19:41 +03:00
Check for a previously failed connection .
failed_cache_timeout is an a absolute number of seconds after which
we should time this out . If failed_cache_timeout = = 0 then time out
immediately . If failed_cache_timeout = = - 1 then never time out .
2003-06-25 22:08:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-02-04 01:19:41 +03:00
NTSTATUS check_negative_conn_cache_timeout ( const char * domain , const char * server , unsigned int failed_cache_timeout )
2003-06-25 22:08:00 +04:00
{
struct failed_connection_cache * fcc ;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
/* can't check if we don't have strings */
if ( ! domain | | ! server )
return NT_STATUS_OK ;
for ( fcc = failed_connection_cache ; fcc ; fcc = fcc - > next ) {
2006-02-04 01:19:41 +03:00
if ( ! ( strequal ( domain , fcc - > domain_name ) & & strequal ( server , fcc - > controller ) ) ) {
2003-06-25 22:08:00 +04:00
continue ; /* no match; check the next entry */
2006-02-04 01:19:41 +03:00
}
2003-06-25 22:08:00 +04:00
/* we have a match so see if it is still current */
2006-02-04 01:19:41 +03:00
if ( failed_cache_timeout ! = ( unsigned int ) - 1 ) {
if ( failed_cache_timeout = = 0 | |
( time ( NULL ) - fcc - > lookup_time ) > ( time_t ) failed_cache_timeout ) {
/* Cache entry has expired, delete it */
2003-06-25 22:08:00 +04:00
2006-02-04 01:19:41 +03:00
DEBUG ( 10 , ( " check_negative_conn_cache: cache entry expired for %s, %s \n " ,
domain , server ) ) ;
2003-06-25 22:08:00 +04:00
2006-02-04 01:19:41 +03:00
DLIST_REMOVE ( failed_connection_cache , fcc ) ;
SAFE_FREE ( fcc ) ;
2003-06-25 22:08:00 +04:00
2006-02-04 01:19:41 +03:00
return NT_STATUS_OK ;
}
2003-06-25 22:08:00 +04:00
}
/* The timeout hasn't expired yet so return false */
DEBUG ( 10 , ( " check_negative_conn_cache: returning negative entry for %s, %s \n " ,
domain , server ) ) ;
result = fcc - > nt_status ;
return result ;
}
/* end of function means no cache entry */
return NT_STATUS_OK ;
}
2006-02-04 01:19:41 +03:00
NTSTATUS check_negative_conn_cache ( const char * domain , const char * server )
{
return check_negative_conn_cache_timeout ( domain , server , FAILED_CONNECTION_CACHE_TIMEOUT ) ;
}
2003-06-25 22:08:00 +04:00
/**********************************************************************
Add an entry to the failed conneciton cache ( aither a name of dotted
decimal IP
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void add_failed_connection_entry ( const char * domain , const char * server , NTSTATUS result )
{
struct failed_connection_cache * fcc ;
SMB_ASSERT ( ! NT_STATUS_IS_OK ( result ) ) ;
/* Check we already aren't in the cache. We always have to have
a domain , but maybe not a specific DC name . */
for ( fcc = failed_connection_cache ; fcc ; fcc = fcc - > next ) {
2006-01-30 23:20:17 +03:00
if ( strequal ( fcc - > domain_name , domain ) & & strequal ( fcc - > controller , server ) ) {
2003-06-25 23:00:15 +04:00
DEBUG ( 10 , ( " add_failed_connection_entry: domain %s (%s) already tried and failed \n " ,
2003-06-25 22:08:00 +04:00
domain , server ) ) ;
2006-01-30 23:20:17 +03:00
/* Update the failed time. */
fcc - > lookup_time = time ( NULL ) ;
2003-06-25 22:08:00 +04:00
return ;
}
}
/* Create negative lookup cache entry for this domain and controller */
2004-12-07 21:25:53 +03:00
if ( ! ( fcc = SMB_MALLOC_P ( struct failed_connection_cache ) ) ) {
2003-06-25 22:08:00 +04:00
DEBUG ( 0 , ( " malloc failed in add_failed_connection_entry! \n " ) ) ;
return ;
}
ZERO_STRUCTP ( fcc ) ;
fstrcpy ( fcc - > domain_name , domain ) ;
fstrcpy ( fcc - > controller , server ) ;
fcc - > lookup_time = time ( NULL ) ;
fcc - > nt_status = result ;
2003-07-16 06:51:28 +04:00
DEBUG ( 10 , ( " add_failed_connection_entry: added domain %s (%s) to failed conn cache \n " ,
2003-06-25 22:08:00 +04:00
domain , server ) ) ;
DLIST_ADD ( failed_connection_cache , fcc ) ;
}
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void flush_negative_conn_cache ( void )
{
struct failed_connection_cache * fcc ;
fcc = failed_connection_cache ;
while ( fcc ) {
struct failed_connection_cache * fcc_next ;
fcc_next = fcc - > next ;
DLIST_REMOVE ( failed_connection_cache , fcc ) ;
free ( fcc ) ;
fcc = fcc_next ;
}
}
2006-09-14 20:37:13 +04:00
/****************************************************************************
Remove all negative entries for a domain . Used when going to online state in
winbindd .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void flush_negative_conn_cache_for_domain ( const char * domain )
{
struct failed_connection_cache * fcc ;
fcc = failed_connection_cache ;
while ( fcc ) {
struct failed_connection_cache * fcc_next ;
fcc_next = fcc - > next ;
if ( strequal ( fcc - > domain_name , domain ) ) {
DEBUG ( 10 , ( " flush_negative_conn_cache_for_domain: removed server %s "
" from failed cache for domain %s \n " ,
fcc - > controller , domain ) ) ;
DLIST_REMOVE ( failed_connection_cache , fcc ) ;
free ( fcc ) ;
}
fcc = fcc_next ;
}
}