2002-11-26 14:57:30 +03:00
/*
Unix SMB / CIFS implementation .
Trusted domain names cache on top of gencache .
Copyright ( C ) Rafal Szczesniak 2002
2009-07-10 14:12:30 +04:00
2002-11-26 14:57:30 +03: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
2002-11-26 14:57:30 +03:00
( at your option ) any later version .
2009-07-10 14:12:30 +04:00
2002-11-26 14:57:30 +03: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 .
2009-07-10 14:12:30 +04:00
2002-11-26 14:57:30 +03: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/>.
2002-11-26 14:57:30 +03:00
*/
# include "includes.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2002-11-26 14:57:30 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_ALL /* there's no proper class yet */
# define TDOMKEY_FMT "TDOM / %s"
2003-07-01 07:49:41 +04:00
# define TDOMTSKEY "TDOMCACHE / TIMESTAMP"
2002-11-26 14:57:30 +03:00
/**
* @ file trustdom_cache . c
*
* Implementation of trusted domain names cache useful when
* samba acts as domain member server . In such case , caching
* domain names currently trusted gives a performance gain
* because there ' s no need to query PDC each time we need
* list of trusted domains
* */
/**
* Initialise trustdom name caching system . Call gencache
* initialisation routine to perform necessary activities .
*
* @ return true upon successful cache initialisation or
* false if cache init failed
* */
2009-07-10 14:12:30 +04:00
2007-10-19 04:40:25 +04:00
bool trustdom_cache_enable ( void )
2002-11-26 14:57:30 +03:00
{
return True ;
}
/**
* Shutdown trustdom name caching system . Calls gencache
* shutdown function .
*
* @ return true upon successful cache close or
* false if it failed
* */
2009-07-10 14:12:30 +04:00
2007-10-19 04:40:25 +04:00
bool trustdom_cache_shutdown ( void )
2002-11-26 14:57:30 +03:00
{
return True ;
}
/**
* Form up trustdom name key . It is based only
* on domain name now .
*
* @ param name trusted domain name
* @ return cache key for use in gencache mechanism
* */
static char * trustdom_cache_key ( const char * name )
{
2003-06-08 16:51:31 +04:00
char * keystr = NULL ;
2007-11-24 19:27:54 +03:00
asprintf_strupper_m ( & keystr , TDOMKEY_FMT , name ) ;
2009-07-10 14:12:30 +04:00
2002-11-26 14:57:30 +03:00
return keystr ;
}
/**
* Store trusted domain in gencache as the domain name ( key )
2007-03-21 00:21:04 +03:00
* and trusted domain ' s SID ( value )
2002-11-26 14:57:30 +03:00
*
* @ param name trusted domain name
* @ param alt_name alternative trusted domain name ( used in ADS domains )
* @ param sid trusted domain ' s SID
* @ param timeout cache entry expiration time
* @ return true upon successful value storing or
* false if store attempt failed
* */
2010-05-21 05:25:01 +04:00
bool trustdom_cache_store ( char * name , char * alt_name , const struct dom_sid * sid ,
2002-11-26 14:57:30 +03:00
time_t timeout )
{
char * key , * alt_key ;
fstring sid_string ;
2007-10-19 04:40:25 +04:00
bool ret ;
2002-11-26 14:57:30 +03:00
DEBUG ( 5 , ( " trustdom_store: storing SID %s of domain %s \n " ,
2007-12-15 23:11:36 +03:00
sid_string_dbg ( sid ) , name ) ) ;
2002-11-26 14:57:30 +03:00
key = trustdom_cache_key ( name ) ;
alt_key = alt_name ? trustdom_cache_key ( alt_name ) : NULL ;
/* Generate string representation domain SID */
2007-12-16 00:47:30 +03:00
sid_to_fstring ( sid_string , sid ) ;
2002-11-26 14:57:30 +03:00
/*
* try to put the names in the cache
*/
if ( alt_key ) {
2004-05-20 01:49:58 +04:00
ret = gencache_set ( alt_key , sid_string , timeout ) ;
if ( ret ) {
ret = gencache_set ( key , sid_string , timeout ) ;
}
SAFE_FREE ( alt_key ) ;
SAFE_FREE ( key ) ;
return ret ;
2002-11-26 14:57:30 +03:00
}
2004-05-20 01:49:58 +04:00
ret = gencache_set ( key , sid_string , timeout ) ;
SAFE_FREE ( key ) ;
return ret ;
2002-11-26 14:57:30 +03:00
}
/**
2007-03-21 00:21:04 +03:00
* Fetch trusted domain ' s SID from the gencache .
2002-11-26 14:57:30 +03:00
* This routine can also be used to check whether given
* domain is currently trusted one .
*
* @ param name trusted domain name
* @ param sid trusted domain ' s SID to be returned
* @ return true if entry is found or
* false if has expired / doesn ' t exist
* */
2009-07-10 14:12:30 +04:00
2010-05-21 05:25:01 +04:00
bool trustdom_cache_fetch ( const char * name , struct dom_sid * sid )
2002-11-26 14:57:30 +03:00
{
2004-05-20 01:49:58 +04:00
char * key = NULL , * value = NULL ;
2008-07-11 19:44:25 +04:00
time_t timeout ;
2002-11-26 14:57:30 +03:00
/* exit now if null pointers were passed as they're required further */
2004-05-20 01:49:58 +04:00
if ( ! sid )
return False ;
2002-11-26 14:57:30 +03:00
/* prepare a key and get the value */
key = trustdom_cache_key ( name ) ;
2004-05-20 01:49:58 +04:00
if ( ! key )
return False ;
2009-07-10 14:12:30 +04:00
2008-07-11 19:44:25 +04:00
if ( ! gencache_get ( key , & value , & timeout ) ) {
2002-11-26 14:57:30 +03:00
DEBUG ( 5 , ( " no entry for trusted domain %s found. \n " , name ) ) ;
2003-06-08 16:51:31 +04:00
SAFE_FREE ( key ) ;
2002-11-26 14:57:30 +03:00
return False ;
} else {
2003-06-08 16:51:31 +04:00
SAFE_FREE ( key ) ;
2002-11-26 14:57:30 +03:00
DEBUG ( 5 , ( " trusted domain %s found (%s) \n " , name , value ) ) ;
}
2010-05-21 05:25:01 +04:00
/* convert sid string representation into struct dom_sid structure */
2002-11-26 14:57:30 +03:00
if ( ! string_to_sid ( sid , value ) ) {
sid = NULL ;
2004-05-20 01:49:58 +04:00
SAFE_FREE ( value ) ;
2002-11-26 14:57:30 +03:00
return False ;
}
2009-07-10 14:12:30 +04:00
2004-05-20 01:49:58 +04:00
SAFE_FREE ( value ) ;
2002-11-26 14:57:30 +03:00
return True ;
}
2003-07-01 07:49:41 +04:00
/*******************************************************************
fetch the timestamp from the last update
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 trustdom_cache_fetch_timestamp ( void )
{
2004-05-20 01:49:58 +04:00
char * value = NULL ;
2008-07-11 19:44:25 +04:00
time_t timeout ;
2003-07-01 07:49:41 +04:00
uint32 timestamp ;
2008-07-11 19:44:25 +04:00
if ( ! gencache_get ( TDOMTSKEY , & value , & timeout ) ) {
2003-07-01 07:49:41 +04:00
DEBUG ( 5 , ( " no timestamp for trusted domain cache located. \n " ) ) ;
2004-05-20 01:49:58 +04:00
SAFE_FREE ( value ) ;
2003-07-01 07:49:41 +04:00
return 0 ;
}
timestamp = atoi ( value ) ;
2009-07-10 14:12:30 +04:00
2004-05-20 01:49:58 +04:00
SAFE_FREE ( value ) ;
2003-07-01 07:49:41 +04:00
return timestamp ;
}
/*******************************************************************
store the timestamp from the last update
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool trustdom_cache_store_timestamp ( uint32 t , time_t timeout )
2003-07-01 07:49:41 +04:00
{
fstring value ;
2003-07-23 16:33:59 +04:00
fstr_sprintf ( value , " %d " , t ) ;
2009-07-10 14:12:30 +04:00
2003-07-01 07:49:41 +04:00
if ( ! gencache_set ( TDOMTSKEY , value , timeout ) ) {
DEBUG ( 5 , ( " failed to set timestamp for trustdom_cache \n " ) ) ;
return False ;
}
return True ;
}
2002-11-26 14:57:30 +03:00
/**
* Delete single trustdom entry . Look at the
* gencache_iterate definition .
*
* */
static void flush_trustdom_name ( const char * key , const char * value , time_t timeout , void * dptr )
{
gencache_del ( key ) ;
DEBUG ( 5 , ( " Deleting entry %s \n " , key ) ) ;
}
/**
* Flush all the trusted domains entries from the cache .
* */
void trustdom_cache_flush ( void )
{
/*
* iterate through each TDOM cache ' s entry and flush it
* by flush_trustdom_name function
*/
gencache_iterate ( flush_trustdom_name , NULL , trustdom_cache_key ( " * " ) ) ;
DEBUG ( 5 , ( " Trusted domains cache flushed \n " ) ) ;
}
2003-07-01 07:49:41 +04:00
/********************************************************************
update the trustdom_cache if needed
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define TRUSTDOM_UPDATE_INTERVAL 600
void update_trustdom_cache ( void )
{
char * * domain_names ;
2010-05-21 05:25:01 +04:00
struct dom_sid * dom_sids ;
2003-07-01 07:49:41 +04:00
uint32 num_domains ;
uint32 last_check ;
int time_diff ;
TALLOC_CTX * mem_ctx = NULL ;
time_t now = time ( NULL ) ;
int i ;
2009-07-10 14:12:30 +04:00
2007-01-12 02:10:16 +03:00
/* get the timestamp. We have to initialise it if the last timestamp == 0 */
2003-07-01 07:49:41 +04:00
if ( ( last_check = trustdom_cache_fetch_timestamp ( ) ) = = 0 )
trustdom_cache_store_timestamp ( 0 , now + TRUSTDOM_UPDATE_INTERVAL ) ;
2005-04-19 23:23:49 +04:00
time_diff = ( int ) ( now - last_check ) ;
2009-07-10 14:12:30 +04:00
2003-07-01 07:49:41 +04:00
if ( ( time_diff > 0 ) & & ( time_diff < TRUSTDOM_UPDATE_INTERVAL ) ) {
DEBUG ( 10 , ( " update_trustdom_cache: not time to update trustdom_cache yet \n " ) ) ;
return ;
}
2007-01-12 02:10:16 +03:00
/* note that we don't lock the timestamp. This prevents this
smbd from blocking all other smbd daemons while we
enumerate the trusted domains */
trustdom_cache_store_timestamp ( now , now + TRUSTDOM_UPDATE_INTERVAL ) ;
2009-07-10 14:12:30 +04:00
2003-07-01 07:49:41 +04:00
if ( ! ( mem_ctx = talloc_init ( " update_trustdom_cache " ) ) ) {
DEBUG ( 0 , ( " update_trustdom_cache: talloc_init() failed! \n " ) ) ;
goto done ;
}
/* get the domains and store them */
2009-07-10 14:12:30 +04:00
2003-07-01 07:49:41 +04:00
if ( enumerate_domain_trusts ( mem_ctx , lp_workgroup ( ) , & domain_names ,
2007-01-12 02:10:16 +03:00
& num_domains , & dom_sids ) ) {
2003-07-01 07:49:41 +04:00
for ( i = 0 ; i < num_domains ; i + + ) {
trustdom_cache_store ( domain_names [ i ] , NULL , & dom_sids [ i ] ,
now + TRUSTDOM_UPDATE_INTERVAL ) ;
2007-01-12 02:10:16 +03:00
}
} else {
/* we failed to fetch the list of trusted domains - restore the old
timestamp */
trustdom_cache_store_timestamp ( last_check ,
last_check + TRUSTDOM_UPDATE_INTERVAL ) ;
2003-07-01 07:49:41 +04:00
}
done :
talloc_destroy ( mem_ctx ) ;
2009-07-10 14:12:30 +04:00
2003-07-01 07:49:41 +04:00
return ;
}