2008-02-17 03:47:01 +03:00
/*
2005-11-10 23:28:23 +03:00
Unix SMB / CIFS implementation .
Net_sam_logon info3 helpers
Copyright ( C ) Alexander Bokovoy 2002.
Copyright ( C ) Andrew Bartlett 2002.
Copyright ( C ) Gerald Carter 2003.
Copyright ( C ) Tim Potter 2003.
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2008.
2008-02-17 03:47:01 +03:00
2005-11-10 23:28:23 +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
2005-11-10 23:28:23 +03:00
( at your option ) any later version .
2008-02-17 03:47:01 +03:00
2005-11-10 23:28:23 +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 .
2008-02-17 03:47:01 +03:00
2005-11-10 23:28:23 +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/>.
2005-11-10 23:28:23 +03:00
*/
# include "includes.h"
# define NETSAMLOGON_TDB "netsamlogon_cache.tdb"
static TDB_CONTEXT * netsamlogon_tdb = NULL ;
/***********************************************************************
open the tdb
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-17 03:47:01 +03:00
2007-10-19 04:40:25 +04:00
bool netsamlogon_cache_init ( void )
2005-11-10 23:28:23 +03:00
{
if ( ! netsamlogon_tdb ) {
netsamlogon_tdb = tdb_open_log ( lock_path ( NETSAMLOGON_TDB ) , 0 ,
2008-02-17 03:47:01 +03:00
TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
2005-11-10 23:28:23 +03:00
}
return ( netsamlogon_tdb ! = NULL ) ;
}
/***********************************************************************
Shutdown samlogon_cache database
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
bool netsamlogon_cache_shutdown ( void )
2005-11-10 23:28:23 +03:00
{
2008-02-17 03:47:01 +03:00
if ( netsamlogon_tdb ) {
2005-11-10 23:28:23 +03:00
return ( tdb_close ( netsamlogon_tdb ) = = 0 ) ;
2008-02-17 03:47:01 +03:00
}
return true ;
2005-11-10 23:28:23 +03:00
}
/***********************************************************************
Clear cache getpwnam and getgroups entries from the winbindd cache
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-17 03:47:01 +03:00
void netsamlogon_clear_cached_user ( TDB_CONTEXT * tdb , struct netr_SamInfo3 * info3 )
2005-11-10 23:28:23 +03:00
{
2008-02-17 03:47:01 +03:00
bool got_tdb = false ;
2007-03-28 14:00:42 +04:00
DOM_SID sid ;
fstring key_str , sid_string ;
2005-11-10 23:28:23 +03:00
/* We may need to call this function from smbd which will not have
2008-02-17 03:47:01 +03:00
winbindd_cache . tdb open . Open the tdb if a NULL is passed . */
2005-11-10 23:28:23 +03:00
if ( ! tdb ) {
2008-02-17 03:47:01 +03:00
tdb = tdb_open_log ( lock_path ( " winbindd_cache.tdb " ) ,
2006-10-17 16:06:17 +04:00
WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE ,
2005-11-10 23:28:23 +03:00
TDB_DEFAULT , O_RDWR , 0600 ) ;
if ( ! tdb ) {
DEBUG ( 5 , ( " netsamlogon_clear_cached_user: failed to open cache \n " ) ) ;
return ;
}
2008-02-17 03:47:01 +03:00
got_tdb = true ;
2005-11-10 23:28:23 +03:00
}
2008-02-17 03:47:01 +03:00
sid_copy ( & sid , info3 - > base . domain_sid ) ;
sid_append_rid ( & sid , info3 - > base . rid ) ;
2005-11-10 23:28:23 +03:00
2007-03-28 14:00:42 +04:00
/* Clear U/SID cache entry */
2005-11-10 23:28:23 +03:00
2007-12-16 00:47:30 +03:00
fstr_sprintf ( key_str , " U/%s " , sid_to_fstring ( sid_string , & sid ) ) ;
2005-11-10 23:28:23 +03:00
2007-03-28 14:00:42 +04:00
DEBUG ( 10 , ( " netsamlogon_clear_cached_user: clearing %s \n " , key_str ) ) ;
2005-11-10 23:28:23 +03:00
2007-03-28 14:00:42 +04:00
tdb_delete ( tdb , string_tdb_data ( key_str ) ) ;
2005-11-10 23:28:23 +03:00
2007-03-28 14:00:42 +04:00
/* Clear UG/SID cache entry */
2005-11-10 23:28:23 +03:00
2007-12-16 00:47:30 +03:00
fstr_sprintf ( key_str , " UG/%s " , sid_to_fstring ( sid_string , & sid ) ) ;
2005-11-10 23:28:23 +03:00
2007-04-05 15:13:25 +04:00
DEBUG ( 10 , ( " netsamlogon_clear_cached_user: clearing %s \n " , key_str ) ) ;
2005-11-10 23:28:23 +03:00
2007-03-28 14:00:42 +04:00
tdb_delete ( tdb , string_tdb_data ( key_str ) ) ;
2005-11-10 23:28:23 +03:00
2008-02-17 03:47:01 +03:00
if ( got_tdb ) {
2005-11-10 23:28:23 +03:00
tdb_close ( tdb ) ;
2008-02-17 03:47:01 +03:00
}
2005-11-10 23:28:23 +03:00
}
/***********************************************************************
2008-02-17 03:47:01 +03:00
Store a netr_SamInfo3 structure in a tdb for later user
2005-11-10 23:28:23 +03:00
username should be in UTF - 8 format
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-17 03:47:01 +03:00
bool netsamlogon_cache_store ( const char * username , struct netr_SamInfo3 * info3 )
2005-11-10 23:28:23 +03:00
{
2008-02-17 03:47:01 +03:00
TDB_DATA data ;
fstring keystr , tmp ;
bool result = false ;
DOM_SID user_sid ;
time_t t = time ( NULL ) ;
TALLOC_CTX * mem_ctx ;
DATA_BLOB blob ;
enum ndr_err_code ndr_err ;
struct netsamlogoncache_entry r ;
if ( ! info3 ) {
return false ;
}
2005-11-10 23:28:23 +03:00
if ( ! netsamlogon_cache_init ( ) ) {
2008-02-17 03:47:01 +03:00
DEBUG ( 0 , ( " netsamlogon_cache_store: cannot open %s for write! \n " ,
NETSAMLOGON_TDB ) ) ;
return false ;
2005-11-10 23:28:23 +03:00
}
2008-02-17 03:47:01 +03:00
sid_copy ( & user_sid , info3 - > base . domain_sid ) ;
sid_append_rid ( & user_sid , info3 - > base . rid ) ;
2005-11-10 23:28:23 +03:00
/* Prepare key as DOMAIN-SID/USER-RID string */
2007-12-16 00:47:30 +03:00
slprintf ( keystr , sizeof ( keystr ) , " %s " , sid_to_fstring ( tmp , & user_sid ) ) ;
2005-11-10 23:28:23 +03:00
DEBUG ( 10 , ( " netsamlogon_cache_store: SID [%s] \n " , keystr ) ) ;
2008-02-17 03:47:01 +03:00
/* Prepare data */
if ( ! ( mem_ctx = TALLOC_P ( NULL , int ) ) ) {
DEBUG ( 0 , ( " netsamlogon_cache_store: talloc() failed! \n " ) ) ;
return false ;
}
2005-11-10 23:28:23 +03:00
/* only Samba fills in the username, not sure why NT doesn't */
/* so we fill it in since winbindd_getpwnam() makes use of it */
2008-02-17 03:47:01 +03:00
if ( ! info3 - > base . account_name . string ) {
info3 - > base . account_name . string = talloc_strdup ( mem_ctx , username ) ;
2005-11-10 23:28:23 +03:00
}
2008-02-17 03:47:01 +03:00
r . timestamp = t ;
r . info3 = * info3 ;
if ( DEBUGLEVEL > = 10 ) {
NDR_PRINT_DEBUG ( netsamlogoncache_entry , & r ) ;
2005-11-11 06:03:41 +03:00
}
2008-02-17 03:47:01 +03:00
ndr_err = ndr_push_struct_blob ( & blob , mem_ctx , & r ,
( ndr_push_flags_fn_t ) ndr_push_netsamlogoncache_entry ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 0 , ( " netsamlogon_cache_store: failed to push entry to cache \n " ) ) ;
TALLOC_FREE ( mem_ctx ) ;
return false ;
2005-12-03 09:46:46 +03:00
}
2005-11-10 23:28:23 +03:00
2008-02-17 03:47:01 +03:00
data . dsize = blob . length ;
data . dptr = blob . data ;
if ( tdb_store_bystring ( netsamlogon_tdb , keystr , data , TDB_REPLACE ) ! = - 1 ) {
result = true ;
2005-11-10 23:28:23 +03:00
}
2005-11-11 06:03:41 +03:00
2008-02-17 03:47:01 +03:00
TALLOC_FREE ( mem_ctx ) ;
2005-11-10 23:28:23 +03:00
return result ;
}
/***********************************************************************
2008-02-17 03:47:01 +03:00
Retrieves a netr_SamInfo3 structure from a tdb . Caller must
2005-11-10 23:28:23 +03:00
free the user_info struct ( malloc ( ) ' d memory )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-17 03:47:01 +03:00
struct netr_SamInfo3 * netsamlogon_cache_get ( TALLOC_CTX * mem_ctx , const DOM_SID * user_sid )
2005-11-10 23:28:23 +03:00
{
2008-02-17 03:47:01 +03:00
struct netr_SamInfo3 * info3 = NULL ;
TDB_DATA data ;
fstring keystr , tmp ;
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
struct netsamlogoncache_entry r ;
2005-11-10 23:28:23 +03:00
if ( ! netsamlogon_cache_init ( ) ) {
2008-02-17 03:47:01 +03:00
DEBUG ( 0 , ( " netsamlogon_cache_get: cannot open %s for write! \n " ,
NETSAMLOGON_TDB ) ) ;
return false ;
2005-11-10 23:28:23 +03:00
}
/* Prepare key as DOMAIN-SID/USER-RID string */
2007-12-16 00:47:30 +03:00
slprintf ( keystr , sizeof ( keystr ) , " %s " , sid_to_fstring ( tmp , user_sid ) ) ;
2005-11-10 23:28:23 +03:00
DEBUG ( 10 , ( " netsamlogon_cache_get: SID [%s] \n " , keystr ) ) ;
2007-03-27 13:30:40 +04:00
data = tdb_fetch_bystring ( netsamlogon_tdb , keystr ) ;
2007-05-03 16:29:32 +04:00
2008-02-17 03:47:01 +03:00
if ( ! data . dptr ) {
return NULL ;
}
2007-05-03 16:29:32 +04:00
2008-02-17 03:47:01 +03:00
info3 = TALLOC_ZERO_P ( mem_ctx , struct netr_SamInfo3 ) ;
if ( ! info3 ) {
goto done ;
}
blob . data = ( uint8 * ) data . dptr ;
blob . length = data . dsize ;
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_netsamlogoncache_entry ) ;
2005-11-10 23:28:23 +03:00
2008-02-17 03:47:01 +03:00
if ( DEBUGLEVEL > = 10 ) {
NDR_PRINT_DEBUG ( netsamlogoncache_entry , & r ) ;
}
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 0 , ( " netsamlogon_cache_get: failed to pull entry from cache \n " ) ) ;
tdb_delete ( netsamlogon_tdb , data ) ;
goto done ;
}
2008-02-23 12:50:12 +03:00
info3 = ( struct netr_SamInfo3 * ) talloc_memdup ( mem_ctx , & r . info3 ,
sizeof ( r . info3 ) ) ;
2008-02-17 03:47:01 +03:00
done :
SAFE_FREE ( data . dptr ) ;
return info3 ;
#if 0 /* The netsamlogon cache needs to hang around. Something about
2005-11-10 23:28:23 +03:00
this feels wrong , but it is the only way we can get all of the
groups . The old universal groups cache didn ' t expire either .
- - jerry */
{
time_t now = time ( NULL ) ;
uint32 time_diff ;
2008-02-17 03:47:01 +03:00
2005-11-10 23:28:23 +03:00
/* is the entry expired? */
time_diff = now - t ;
2008-02-17 03:47:01 +03:00
2005-11-10 23:28:23 +03:00
if ( ( time_diff < 0 ) | | ( time_diff > lp_winbind_cache_time ( ) ) ) {
DEBUG ( 10 , ( " netsamlogon_cache_get: cache entry expired \n " ) ) ;
tdb_delete ( netsamlogon_tdb , key ) ;
2007-05-04 00:12:00 +04:00
TALLOC_FREE ( user ) ;
2005-11-10 23:28:23 +03:00
}
}
2008-02-17 03:47:01 +03:00
# endif
2005-11-10 23:28:23 +03:00
}
2007-10-19 04:40:25 +04:00
bool netsamlogon_cache_have ( const DOM_SID * user_sid )
2005-11-10 23:28:23 +03:00
{
TALLOC_CTX * mem_ctx = talloc_init ( " netsamlogon_cache_have " ) ;
2008-02-17 03:47:01 +03:00
struct netr_SamInfo3 * info3 = NULL ;
2007-10-19 04:40:25 +04:00
bool result ;
2005-11-10 23:28:23 +03:00
if ( ! mem_ctx )
return False ;
2008-02-17 03:47:01 +03:00
info3 = netsamlogon_cache_get ( mem_ctx , user_sid ) ;
2005-11-10 23:28:23 +03:00
2008-02-17 03:47:01 +03:00
result = ( info3 ! = NULL ) ;
2005-11-10 23:28:23 +03:00
talloc_destroy ( mem_ctx ) ;
return result ;
}