2000-05-09 15:43:00 +04:00
/*
Unix SMB / Netbios implementation .
Version 2.0
Winbind daemon - caching related functions
Copyright ( C ) Tim Potter 2000
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 2 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 , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "winbindd.h"
# define CACHE_TYPE_USER "USR"
# define CACHE_TYPE_GROUP "GRP"
2001-11-21 11:36:43 +03:00
# define CACHE_TYPE_NAME "NAM" /* Stores mapping from SID to name. */
# define CACHE_TYPE_SID "SID" /* Stores mapping from name to SID. */
2000-05-09 15:43:00 +04:00
/* Initialise caching system */
static TDB_CONTEXT * cache_tdb ;
struct cache_rec {
uint32 seq_num ;
time_t mod_time ;
} ;
void winbindd_cache_init ( void )
{
/* Open tdb cache */
2001-05-07 08:32:40 +04:00
2001-06-04 09:13:59 +04:00
if ( ! ( cache_tdb = tdb_open_log ( lock_path ( " winbindd_cache.tdb " ) , 0 ,
2001-05-07 08:32:40 +04:00
TDB_NOLOCK , O_RDWR | O_CREAT | O_TRUNC ,
2001-10-14 12:26:45 +04:00
0600 ) ) )
2001-11-21 11:36:43 +03:00
DEBUG ( 0 , ( " Unable to open tdb cache - user and group caching disabled \n " ) ) ;
2000-05-09 15:43:00 +04:00
}
2001-10-05 04:20:06 +04:00
/* find the sequence number for a domain */
2001-10-14 12:26:45 +04:00
static uint32 domain_sequence_number ( struct winbindd_domain * domain )
2001-10-05 04:20:06 +04:00
{
2001-11-21 11:36:43 +03:00
TALLOC_CTX * mem_ctx ;
CLI_POLICY_HND * hnd ;
2001-10-05 04:20:06 +04:00
SAM_UNK_CTR ctr ;
2001-11-21 11:36:43 +03:00
uint16 switch_value = 2 ;
NTSTATUS result ;
uint32 seqnum = DOM_SEQUENCE_NONE ;
POLICY_HND dom_pol ;
BOOL got_dom_pol = False ;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED ;
2001-10-05 04:20:06 +04:00
2001-11-21 11:36:43 +03:00
if ( ! ( mem_ctx = talloc_init ( ) ) )
return DOM_SEQUENCE_NONE ;
2001-10-05 04:20:06 +04:00
2001-11-21 11:36:43 +03:00
/* Get sam handle */
2001-11-15 09:55:56 +03:00
2001-11-21 11:36:43 +03:00
if ( ! ( hnd = cm_get_sam_handle ( domain - > name ) ) )
goto done ;
2001-11-15 09:55:56 +03:00
2001-11-21 11:36:43 +03:00
/* Get domain handle */
2001-11-15 09:55:56 +03:00
2001-11-21 11:36:43 +03:00
result = cli_samr_open_domain ( hnd - > cli , mem_ctx , & hnd - > pol ,
des_access , & domain - > sid , & dom_pol ) ;
2001-11-15 09:55:56 +03:00
2001-11-21 11:36:43 +03:00
if ( ! NT_STATUS_IS_OK ( result ) )
goto done ;
2001-10-05 04:20:06 +04:00
2001-11-21 11:36:43 +03:00
got_dom_pol = True ;
2001-11-15 09:55:56 +03:00
2001-11-21 11:36:43 +03:00
/* Query domain info */
2001-11-15 09:55:56 +03:00
2001-11-21 11:36:43 +03:00
result = cli_samr_query_dom_info ( hnd - > cli , mem_ctx , & dom_pol ,
switch_value , & ctr ) ;
2001-10-05 04:20:06 +04:00
2001-11-21 11:36:43 +03:00
if ( NT_STATUS_IS_OK ( result ) )
seqnum = ctr . info . inf2 . seq_num ;
2001-10-05 04:20:06 +04:00
2001-11-21 11:36:43 +03:00
done :
2001-11-15 09:55:56 +03:00
2001-11-21 11:36:43 +03:00
if ( got_dom_pol )
cli_samr_close ( hnd - > cli , mem_ctx , & dom_pol ) ;
2001-10-05 04:20:06 +04:00
2001-11-21 11:36:43 +03:00
talloc_destroy ( mem_ctx ) ;
return seqnum ;
2001-10-05 04:20:06 +04:00
}
2000-05-09 15:43:00 +04:00
/* get the domain sequence number, possibly re-fetching */
2001-10-14 12:26:45 +04:00
static uint32 cached_sequence_number ( struct winbindd_domain * domain )
2000-05-09 15:43:00 +04:00
{
fstring keystr ;
TDB_DATA dbuf ;
struct cache_rec rec ;
time_t t = time ( NULL ) ;
2001-10-14 12:26:45 +04:00
snprintf ( keystr , sizeof ( keystr ) , " CACHESEQ/%s " , domain - > name ) ;
2000-05-09 15:43:00 +04:00
dbuf = tdb_fetch_by_string ( cache_tdb , keystr ) ;
2001-10-14 12:26:45 +04:00
if ( ! dbuf . dptr | | dbuf . dsize ! = sizeof ( rec ) )
2000-05-09 15:43:00 +04:00
goto refetch ;
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
memcpy ( & rec , dbuf . dptr , sizeof ( rec ) ) ;
2001-09-17 08:52:45 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2000-05-09 15:43:00 +04:00
if ( t < ( rec . mod_time + lp_winbind_cache_time ( ) ) ) {
2001-05-07 08:32:40 +04:00
DEBUG ( 3 , ( " cached sequence number for %s is %u \n " ,
2001-10-14 12:26:45 +04:00
domain - > name , ( unsigned ) rec . seq_num ) ) ;
2000-05-09 15:43:00 +04:00
return rec . seq_num ;
}
refetch :
2001-10-14 12:26:45 +04:00
rec . seq_num = domain_sequence_number ( domain ) ;
2000-05-09 15:43:00 +04:00
rec . mod_time = t ;
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
tdb_store_by_string ( cache_tdb , keystr , & rec , sizeof ( rec ) ) ;
return rec . seq_num ;
}
/* Check whether a seq_num for a cached item has expired */
2001-10-14 12:26:45 +04:00
static BOOL cache_domain_expired ( struct winbindd_domain * domain ,
uint32 seq_num )
2000-05-09 15:43:00 +04:00
{
2001-10-14 12:26:45 +04:00
if ( cached_sequence_number ( domain ) ! = seq_num ) {
2001-05-07 08:32:40 +04:00
DEBUG ( 3 , ( " seq %u for %s has expired \n " , ( unsigned ) seq_num ,
2001-10-14 12:26:45 +04:00
domain - > name ) ) ;
2000-05-09 15:43:00 +04:00
return True ;
}
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
return False ;
}
2001-10-14 12:26:45 +04:00
static void set_cache_sequence_number ( struct winbindd_domain * domain ,
char * cache_type , char * subkey )
2000-05-09 15:43:00 +04:00
{
fstring keystr ;
2001-05-07 08:32:40 +04:00
snprintf ( keystr , sizeof ( keystr ) , " CACHESEQ %s/%s/%s " ,
2001-10-14 12:26:45 +04:00
domain - > name , cache_type , subkey ? subkey : " " ) ;
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
tdb_store_int ( cache_tdb , keystr , cached_sequence_number ( domain ) ) ;
2000-05-09 15:43:00 +04:00
}
2001-10-14 12:26:45 +04:00
static uint32 get_cache_sequence_number ( struct winbindd_domain * domain ,
char * cache_type , char * subkey )
2000-05-09 15:43:00 +04:00
{
fstring keystr ;
uint32 seq_num ;
2001-05-07 08:32:40 +04:00
snprintf ( keystr , sizeof ( keystr ) , " CACHESEQ %s/%s/%s " ,
2001-10-14 12:26:45 +04:00
domain - > name , cache_type , subkey ? subkey : " " ) ;
2000-05-12 10:27:35 +04:00
seq_num = ( uint32 ) tdb_fetch_int ( cache_tdb , keystr ) ;
2001-05-07 08:32:40 +04:00
DEBUG ( 3 , ( " %s is %u \n " , keystr , ( unsigned ) seq_num ) ) ;
2000-05-09 15:43:00 +04:00
return seq_num ;
}
/* Fill the user or group cache with supplied data */
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
static void store_cache ( struct winbindd_domain * domain , char * cache_type ,
2001-05-07 08:32:40 +04:00
void * sam_entries , int buflen )
2000-05-09 15:43:00 +04:00
{
fstring keystr ;
2001-10-14 12:26:45 +04:00
if ( lp_winbind_cache_time ( ) = = 0 )
2001-11-21 11:36:43 +03:00
return ;
2000-05-09 15:43:00 +04:00
/* Error check */
2001-10-14 12:26:45 +04:00
if ( ! sam_entries | | buflen = = 0 )
2001-11-21 11:36:43 +03:00
return ;
2000-05-09 15:43:00 +04:00
/* Store data as a mega-huge chunk in the tdb */
2001-10-14 12:26:45 +04:00
2001-05-07 08:32:40 +04:00
snprintf ( keystr , sizeof ( keystr ) , " %s CACHE DATA/%s " , cache_type ,
2001-10-14 12:26:45 +04:00
domain - > name ) ;
2001-05-07 08:32:40 +04:00
tdb_store_by_string ( cache_tdb , keystr , sam_entries , buflen ) ;
2000-05-09 15:43:00 +04:00
/* Stamp cache with current seq number */
2001-10-14 12:26:45 +04:00
set_cache_sequence_number ( domain , cache_type , NULL ) ;
2000-05-09 15:43:00 +04:00
}
/* Fill the user cache with supplied data */
2001-10-14 12:26:45 +04:00
void winbindd_store_user_cache ( struct winbindd_domain * domain ,
2001-05-07 08:32:40 +04:00
struct getpwent_user * sam_entries ,
int num_sam_entries )
2000-05-09 15:43:00 +04:00
{
2001-10-14 12:26:45 +04:00
DEBUG ( 3 , ( " storing user cache %s/%d entries \n " , domain - > name ,
2001-05-07 08:32:40 +04:00
num_sam_entries ) ) ;
store_cache ( domain , CACHE_TYPE_USER , sam_entries ,
num_sam_entries * sizeof ( struct getpwent_user ) ) ;
2000-05-09 15:43:00 +04:00
}
/* Fill the group cache with supplied data */
2001-10-14 12:26:45 +04:00
void winbindd_store_group_cache ( struct winbindd_domain * domain ,
2001-05-07 08:32:40 +04:00
struct acct_info * sam_entries ,
int num_sam_entries )
2000-05-09 15:43:00 +04:00
{
2001-10-14 12:26:45 +04:00
DEBUG ( 0 , ( " storing group cache %s/%d entries \n " , domain - > name ,
2001-05-07 08:32:40 +04:00
num_sam_entries ) ) ;
store_cache ( domain , CACHE_TYPE_GROUP , sam_entries ,
num_sam_entries * sizeof ( struct acct_info ) ) ;
2000-05-09 15:43:00 +04:00
}
2001-10-14 12:26:45 +04:00
static void store_cache_entry ( struct winbindd_domain * domain , char * cache_type ,
char * name , void * buf , int len )
2000-05-09 15:43:00 +04:00
{
fstring keystr ;
/* Create key for store */
2001-10-14 12:26:45 +04:00
snprintf ( keystr , sizeof ( keystr ) , " %s/%s/%s " , cache_type ,
domain - > name , name ) ;
2000-05-09 15:43:00 +04:00
/* Store it */
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
tdb_store_by_string ( cache_tdb , keystr , buf , len ) ;
}
2001-11-21 11:36:43 +03:00
/* Fill a name cache entry */
void winbindd_store_name_cache_entry ( struct winbindd_domain * domain ,
char * sid , struct winbindd_name * name )
{
if ( lp_winbind_cache_time ( ) = = 0 )
return ;
store_cache_entry ( domain , CACHE_TYPE_NAME , sid , name ,
sizeof ( struct winbindd_name ) ) ;
set_cache_sequence_number ( domain , CACHE_TYPE_NAME , sid ) ;
}
/* Fill a SID cache entry */
void winbindd_store_sid_cache_entry ( struct winbindd_domain * domain ,
char * name , struct winbindd_sid * sid )
{
if ( lp_winbind_cache_time ( ) = = 0 )
return ;
store_cache_entry ( domain , CACHE_TYPE_SID , name , sid ,
sizeof ( struct winbindd_sid ) ) ;
set_cache_sequence_number ( domain , CACHE_TYPE_SID , name ) ;
}
2000-05-09 15:43:00 +04:00
/* Fill a user info cache entry */
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
void winbindd_store_user_cache_entry ( struct winbindd_domain * domain ,
char * user_name , struct winbindd_pw * pw )
2000-05-09 15:43:00 +04:00
{
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
store_cache_entry ( domain , CACHE_TYPE_USER , user_name , pw ,
sizeof ( struct winbindd_pw ) ) ;
2001-05-07 08:32:40 +04:00
2000-05-09 15:43:00 +04:00
set_cache_sequence_number ( domain , CACHE_TYPE_USER , user_name ) ;
}
/* Fill a user uid cache entry */
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
void winbindd_store_uid_cache_entry ( struct winbindd_domain * domain , uid_t uid ,
2000-05-09 15:43:00 +04:00
struct winbindd_pw * pw )
{
2001-11-21 11:36:43 +03:00
fstring uidstr ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
snprintf ( uidstr , sizeof ( uidstr ) , " #%u " , ( unsigned ) uid ) ;
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
DEBUG ( 3 , ( " storing uid cache entry %s/%s \n " , domain - > name , uidstr ) ) ;
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
store_cache_entry ( domain , CACHE_TYPE_USER , uidstr , pw ,
sizeof ( struct winbindd_pw ) ) ;
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
set_cache_sequence_number ( domain , CACHE_TYPE_USER , uidstr ) ;
2000-05-09 15:43:00 +04:00
}
/* Fill a group info cache entry */
2001-10-14 12:26:45 +04:00
void winbindd_store_group_cache_entry ( struct winbindd_domain * domain ,
char * group_name , struct winbindd_gr * gr ,
void * extra_data , int extra_data_len )
2000-05-09 15:43:00 +04:00
{
2001-11-21 11:36:43 +03:00
fstring keystr ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return ;
2000-05-09 15:43:00 +04:00
2001-10-14 12:26:45 +04:00
DEBUG ( 3 , ( " storing group cache entry %s/%s \n " , domain - > name ,
2001-11-21 11:36:43 +03:00
group_name ) ) ;
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
/* Fill group data */
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
store_cache_entry ( domain , CACHE_TYPE_GROUP , group_name , gr ,
sizeof ( struct winbindd_gr ) ) ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Fill extra data */
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
snprintf ( keystr , sizeof ( keystr ) , " %s/%s/%s DATA " , CACHE_TYPE_GROUP ,
domain - > name , group_name ) ;
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
tdb_store_by_string ( cache_tdb , keystr , extra_data , extra_data_len ) ;
2000-05-09 15:43:00 +04:00
set_cache_sequence_number ( domain , CACHE_TYPE_GROUP , group_name ) ;
}
/* Fill a group info cache entry */
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
void winbindd_store_gid_cache_entry ( struct winbindd_domain * domain , gid_t gid ,
2001-05-07 08:32:40 +04:00
struct winbindd_gr * gr , void * extra_data ,
int extra_data_len )
2000-05-09 15:43:00 +04:00
{
2001-11-21 11:36:43 +03:00
fstring keystr ;
2000-05-09 15:43:00 +04:00
fstring gidstr ;
2001-05-07 08:32:40 +04:00
snprintf ( gidstr , sizeof ( gidstr ) , " #%u " , ( unsigned ) gid ) ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return ;
2000-05-09 15:43:00 +04:00
2001-10-14 12:26:45 +04:00
DEBUG ( 3 , ( " storing gid cache entry %s/%s \n " , domain - > name , gidstr ) ) ;
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
/* Fill group data */
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
store_cache_entry ( domain , CACHE_TYPE_GROUP , gidstr , gr ,
sizeof ( struct winbindd_gr ) ) ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Fill extra data */
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
snprintf ( keystr , sizeof ( keystr ) , " %s/%s/%s DATA " , CACHE_TYPE_GROUP ,
domain - > name , gidstr ) ;
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
tdb_store_by_string ( cache_tdb , keystr , extra_data , extra_data_len ) ;
2000-05-09 15:43:00 +04:00
set_cache_sequence_number ( domain , CACHE_TYPE_GROUP , gidstr ) ;
}
/* Fetch some cached user or group data */
2001-10-14 12:26:45 +04:00
static BOOL fetch_cache ( struct winbindd_domain * domain , char * cache_type ,
2001-05-07 08:32:40 +04:00
void * * sam_entries , int * buflen )
2000-05-09 15:43:00 +04:00
{
2001-11-21 11:36:43 +03:00
TDB_DATA data ;
fstring keystr ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return False ;
2000-05-09 15:43:00 +04:00
/* Parameter check */
2001-10-14 12:26:45 +04:00
if ( ! sam_entries | | ! buflen )
2000-05-09 15:43:00 +04:00
return False ;
/* Check cache data is current */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
if ( cache_domain_expired ( domain , get_cache_sequence_number ( domain , cache_type , NULL ) ) )
2000-05-09 15:43:00 +04:00
return False ;
2001-11-21 11:36:43 +03:00
/* Create key */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
snprintf ( keystr , sizeof ( keystr ) , " %s CACHE DATA/%s " , cache_type , domain - > name ) ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Fetch cache information */
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
data = tdb_fetch_by_string ( cache_tdb , keystr ) ;
2001-11-21 11:36:43 +03:00
if ( ! data . dptr )
return False ;
2000-05-09 15:43:00 +04:00
/* Copy across cached data. We can save a memcpy() by directly
assigning the data . dptr to the sam_entries pointer . It will
be freed by the end { pw , gr } ent ( ) function . */
* sam_entries = ( struct acct_info * ) data . dptr ;
2001-05-07 08:32:40 +04:00
* buflen = data . dsize ;
2000-05-09 15:43:00 +04:00
return True ;
}
/* Return cached entries for a domain. Return false if there are no cached
entries , or the cached information has expired for the domain . */
2001-10-14 12:26:45 +04:00
BOOL winbindd_fetch_user_cache ( struct winbindd_domain * domain ,
2001-05-07 08:32:40 +04:00
struct getpwent_user * * sam_entries ,
2000-05-09 15:43:00 +04:00
int * num_entries )
{
2001-05-07 08:32:40 +04:00
BOOL result ;
int buflen ;
2001-10-14 12:26:45 +04:00
result = fetch_cache ( domain , CACHE_TYPE_USER ,
2001-05-07 08:32:40 +04:00
( void * * ) sam_entries , & buflen ) ;
* num_entries = buflen / sizeof ( struct getpwent_user ) ;
DEBUG ( 3 , ( " fetched %d cache entries for %s \n " , * num_entries ,
2001-10-14 12:26:45 +04:00
domain - > name ) ) ;
2001-05-07 08:32:40 +04:00
return result ;
2000-05-09 15:43:00 +04:00
}
/* Return cached entries for a domain. Return false if there are no cached
entries , or the cached information has expired for the domain . */
2001-10-14 12:26:45 +04:00
BOOL winbindd_fetch_group_cache ( struct winbindd_domain * domain ,
2001-05-07 08:32:40 +04:00
struct acct_info * * sam_entries ,
2000-05-09 15:43:00 +04:00
int * num_entries )
{
2001-05-07 08:32:40 +04:00
BOOL result ;
int buflen ;
2001-10-14 12:26:45 +04:00
result = fetch_cache ( domain , CACHE_TYPE_GROUP ,
2001-05-07 08:32:40 +04:00
( void * * ) sam_entries , & buflen ) ;
* num_entries = buflen / sizeof ( struct acct_info ) ;
DEBUG ( 3 , ( " fetched %d cache entries for %s \n " , * num_entries ,
2001-10-14 12:26:45 +04:00
domain - > name ) ) ;
2001-05-07 08:32:40 +04:00
return result ;
2000-05-09 15:43:00 +04:00
}
2001-10-14 12:26:45 +04:00
static BOOL fetch_cache_entry ( struct winbindd_domain * domain ,
char * cache_type , char * name , void * buf , int len )
2000-05-09 15:43:00 +04:00
{
TDB_DATA data ;
fstring keystr ;
/* Create key for lookup */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
snprintf ( keystr , sizeof ( keystr ) , " %s/%s/%s " , cache_type , domain - > name , name ) ;
2000-05-09 15:43:00 +04:00
/* Look up cache entry */
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
data = tdb_fetch_by_string ( cache_tdb , keystr ) ;
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
if ( ! data . dptr )
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Copy found entry into buffer */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
memcpy ( ( char * ) buf , data . dptr , len < data . dsize ? len : data . dsize ) ;
2001-09-17 08:52:45 +04:00
SAFE_FREE ( data . dptr ) ;
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
return True ;
}
2001-11-21 11:36:43 +03:00
/* Fetch an individual SID cache entry */
BOOL winbindd_fetch_sid_cache_entry ( struct winbindd_domain * domain ,
char * name , struct winbindd_sid * sid )
{
uint32 seq_num ;
if ( lp_winbind_cache_time ( ) = = 0 )
return False ;
seq_num = get_cache_sequence_number ( domain , CACHE_TYPE_SID , name ) ;
if ( cache_domain_expired ( domain , seq_num ) )
return False ;
return fetch_cache_entry ( domain , CACHE_TYPE_SID , name , sid ,
sizeof ( struct winbindd_sid ) ) ;
}
/* Fetch an individual name cache entry */
BOOL winbindd_fetch_name_cache_entry ( struct winbindd_domain * domain ,
char * sid , struct winbindd_name * name )
{
uint32 seq_num ;
if ( lp_winbind_cache_time ( ) = = 0 )
return False ;
seq_num = get_cache_sequence_number ( domain , CACHE_TYPE_NAME , sid ) ;
if ( cache_domain_expired ( domain , seq_num ) )
return False ;
return fetch_cache_entry ( domain , CACHE_TYPE_NAME , sid , name ,
sizeof ( struct winbindd_name ) ) ;
}
2000-05-09 15:43:00 +04:00
/* Fetch an individual user cache entry */
2001-10-14 12:26:45 +04:00
BOOL winbindd_fetch_user_cache_entry ( struct winbindd_domain * domain ,
char * user , struct winbindd_pw * pw )
2000-05-09 15:43:00 +04:00
{
uint32 seq_num ;
2001-10-14 12:26:45 +04:00
if ( lp_winbind_cache_time ( ) = = 0 )
2001-11-21 11:36:43 +03:00
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
seq_num = get_cache_sequence_number ( domain , CACHE_TYPE_USER , user ) ;
2000-05-09 15:43:00 +04:00
2001-10-14 12:26:45 +04:00
if ( cache_domain_expired ( domain , seq_num ) )
2001-11-21 11:36:43 +03:00
return False ;
2001-10-14 12:26:45 +04:00
return fetch_cache_entry ( domain , CACHE_TYPE_USER , user , pw ,
2001-11-21 11:36:43 +03:00
sizeof ( struct winbindd_pw ) ) ;
2000-05-09 15:43:00 +04:00
}
/* Fetch an individual uid cache entry */
2001-10-14 12:26:45 +04:00
BOOL winbindd_fetch_uid_cache_entry ( struct winbindd_domain * domain , uid_t uid ,
2000-05-09 15:43:00 +04:00
struct winbindd_pw * pw )
{
fstring uidstr ;
uint32 seq_num ;
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return False ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
snprintf ( uidstr , sizeof ( uidstr ) , " #%u " , ( unsigned ) uid ) ;
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
seq_num = get_cache_sequence_number ( domain , CACHE_TYPE_USER , uidstr ) ;
2000-05-09 15:43:00 +04:00
2001-10-14 12:26:45 +04:00
if ( cache_domain_expired ( domain , seq_num ) )
2001-11-21 11:36:43 +03:00
return False ;
2001-10-14 12:26:45 +04:00
return fetch_cache_entry ( domain , CACHE_TYPE_USER , uidstr , pw ,
2001-05-07 08:32:40 +04:00
sizeof ( struct winbindd_pw ) ) ;
2000-05-09 15:43:00 +04:00
}
/* Fetch an individual group cache entry. This function differs from the
user cache code as we need to store the group membership data . */
2001-10-14 12:26:45 +04:00
BOOL winbindd_fetch_group_cache_entry ( struct winbindd_domain * domain ,
char * group , struct winbindd_gr * gr ,
2000-05-09 15:43:00 +04:00
void * * extra_data , int * extra_data_len )
{
2001-11-21 11:36:43 +03:00
TDB_DATA data ;
fstring keystr ;
2000-05-09 15:43:00 +04:00
uint32 seq_num ;
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
seq_num = get_cache_sequence_number ( domain , CACHE_TYPE_GROUP , group ) ;
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
if ( cache_domain_expired ( domain , seq_num ) )
2001-11-21 11:36:43 +03:00
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Fetch group data */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
if ( ! fetch_cache_entry ( domain , CACHE_TYPE_GROUP , group , gr , sizeof ( struct winbindd_gr ) ) )
2001-05-07 08:32:40 +04:00
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Fetch extra data */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
snprintf ( keystr , sizeof ( keystr ) , " %s/%s/%s DATA " , CACHE_TYPE_GROUP ,
domain - > name , group ) ;
2001-05-07 08:32:40 +04:00
2001-11-21 11:36:43 +03:00
data = tdb_fetch_by_string ( cache_tdb , keystr ) ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
if ( ! data . dptr )
return False ;
2000-05-09 15:43:00 +04:00
/* Extra data freed when data has been sent */
2001-10-14 12:26:45 +04:00
if ( extra_data )
2001-11-21 11:36:43 +03:00
* extra_data = data . dptr ;
2001-10-14 12:26:45 +04:00
if ( extra_data_len )
2001-11-21 11:36:43 +03:00
* extra_data_len = data . dsize ;
2000-05-09 15:43:00 +04:00
return True ;
}
/* Fetch an individual gid cache entry. This function differs from the
user cache code as we need to store the group membership data . */
2001-10-14 12:26:45 +04:00
BOOL winbindd_fetch_gid_cache_entry ( struct winbindd_domain * domain , gid_t gid ,
2000-05-09 15:43:00 +04:00
struct winbindd_gr * gr ,
void * * extra_data , int * extra_data_len )
{
2001-11-21 11:36:43 +03:00
TDB_DATA data ;
fstring keystr ;
2000-05-09 15:43:00 +04:00
fstring gidstr ;
uint32 seq_num ;
2001-05-07 08:32:40 +04:00
snprintf ( gidstr , sizeof ( gidstr ) , " #%u " , ( unsigned ) gid ) ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
if ( lp_winbind_cache_time ( ) = = 0 )
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
seq_num = get_cache_sequence_number ( domain , CACHE_TYPE_GROUP , gidstr ) ;
2001-05-07 08:32:40 +04:00
2001-10-14 12:26:45 +04:00
if ( cache_domain_expired ( domain , seq_num ) )
2001-11-21 11:36:43 +03:00
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Fetch group data */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
if ( ! fetch_cache_entry ( domain , CACHE_TYPE_GROUP ,
gidstr , gr , sizeof ( struct winbindd_gr ) ) )
2001-05-07 08:32:40 +04:00
return False ;
2000-05-09 15:43:00 +04:00
2001-11-21 11:36:43 +03:00
/* Fetch extra data */
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
snprintf ( keystr , sizeof ( keystr ) , " %s/%s/%s DATA " , CACHE_TYPE_GROUP ,
domain - > name , gidstr ) ;
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
data = tdb_fetch_by_string ( cache_tdb , keystr ) ;
2001-10-14 12:26:45 +04:00
2001-11-21 11:36:43 +03:00
if ( ! data . dptr )
return False ;
2000-05-09 15:43:00 +04:00
/* Extra data freed when data has been sent */
2001-10-14 12:26:45 +04:00
if ( extra_data )
2001-11-21 11:36:43 +03:00
* extra_data = data . dptr ;
2001-10-14 12:26:45 +04:00
if ( extra_data_len )
2001-11-21 11:36:43 +03:00
* extra_data_len = data . dsize ;
2000-05-09 15:43:00 +04:00
return True ;
}
/* Flush cache data - easiest to just reopen the tdb */
2001-10-14 12:26:45 +04:00
2000-05-09 15:43:00 +04:00
void winbindd_flush_cache ( void )
{
tdb_close ( cache_tdb ) ;
winbindd_cache_init ( ) ;
}
2001-05-07 08:32:40 +04:00
/* Print cache status information */
2001-10-14 12:26:45 +04:00
2001-11-14 09:18:13 +03:00
void winbindd_cache_status ( void )
2001-05-07 08:32:40 +04:00
{
}