2000-05-09 15:43:00 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
Winbind cache backend functions
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
Copyright ( C ) Andrew Tridgell 2001
2000-05-09 15:43:00 +04: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
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"
2002-07-15 14:35:28 +04:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_WINBIND
2001-12-10 02:59:42 +03:00
struct winbind_cache {
struct winbindd_methods * backend ;
TDB_CONTEXT * tdb ;
2000-05-09 15:43:00 +04:00
} ;
2001-12-10 02:59:42 +03:00
struct cache_entry {
NTSTATUS status ;
uint32 sequence_number ;
uint8 * data ;
uint32 len , ofs ;
} ;
2000-05-09 15:43:00 +04:00
2002-04-04 07:03:39 +04:00
# define WINBINDD_MAX_CACHE_SIZE (50*1024*1024)
2001-12-10 02:59:42 +03:00
static struct winbind_cache * wcache ;
2001-10-14 12:26:45 +04:00
2001-12-10 03:39:01 +03:00
/* flush the cache */
2001-12-10 02:59:42 +03:00
void wcache_flush_cache ( void )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
extern BOOL opt_nocache ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
if ( ! wcache ) return ;
if ( wcache - > tdb ) {
tdb_close ( wcache - > tdb ) ;
wcache - > tdb = NULL ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
if ( opt_nocache ) return ;
2000-05-09 15:43:00 +04:00
2001-12-10 08:20:55 +03:00
wcache - > tdb = tdb_open_log ( lock_path ( " winbindd_cache.tdb " ) , 5000 ,
2002-07-15 14:35:28 +04:00
TDB_CLEAR_IF_FIRST , O_RDWR | O_CREAT , 0600 ) ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
if ( ! wcache - > tdb ) {
DEBUG ( 0 , ( " Failed to open winbindd_cache.tdb! \n " ) ) ;
}
2000-05-09 15:43:00 +04:00
}
2002-04-04 07:03:39 +04:00
void winbindd_check_cache_size ( time_t t )
{
static time_t last_check_time ;
struct stat st ;
if ( last_check_time = = ( time_t ) 0 )
last_check_time = t ;
if ( t - last_check_time < 60 & & t - last_check_time > 0 )
return ;
if ( wcache = = NULL | | wcache - > tdb = = NULL ) {
DEBUG ( 0 , ( " Unable to check size of tdb cache - cache not open ! \n " ) ) ;
return ;
}
if ( fstat ( wcache - > tdb - > fd , & st ) = = - 1 ) {
DEBUG ( 0 , ( " Unable to check size of tdb cache %s! \n " , strerror ( errno ) ) ) ;
return ;
}
if ( st . st_size > WINBINDD_MAX_CACHE_SIZE ) {
DEBUG ( 10 , ( " flushing cache due to size (%lu) > (%lu) \n " ,
( unsigned long ) st . st_size ,
( unsigned long ) WINBINDD_MAX_CACHE_SIZE ) ) ;
wcache_flush_cache ( ) ;
}
}
2001-12-10 02:59:42 +03:00
/* get the winbind_cache structure */
static struct winbind_cache * get_cache ( struct winbindd_domain * domain )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
extern struct winbindd_methods msrpc_methods ;
struct winbind_cache * ret = wcache ;
if ( ret ) return ret ;
ret = smb_xmalloc ( sizeof ( * ret ) ) ;
ZERO_STRUCTP ( ret ) ;
2003-05-12 22:12:31 +04:00
switch ( lp_security ( ) ) { /* winbind pdc disabled until ready
if ( ! strcmp ( domain - > name , lp_workgroup ( ) ) & & ( lp_security ( ) = = SEC_USER ) ) {
extern struct winbindd_methods passdb_methods ;
ret - > backend = & passdb_methods ;
} else switch ( lp_security ( ) ) { */
2001-12-10 02:59:42 +03:00
# ifdef HAVE_ADS
case SEC_ADS : {
extern struct winbindd_methods ads_methods ;
ret - > backend = & ads_methods ;
break ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
# endif
default :
ret - > backend = & msrpc_methods ;
}
wcache = ret ;
wcache_flush_cache ( ) ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
return ret ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
/*
free a centry structure
*/
static void centry_free ( struct cache_entry * centry )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
if ( ! centry ) return ;
SAFE_FREE ( centry - > data ) ;
free ( centry ) ;
}
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
/*
pull a uint32 from a cache entry
*/
static uint32 centry_uint32 ( struct cache_entry * centry )
{
uint32 ret ;
if ( centry - > len - centry - > ofs < 4 ) {
DEBUG ( 0 , ( " centry corruption? needed 4 bytes, have %d \n " ,
centry - > len - centry - > ofs ) ) ;
smb_panic ( " centry_uint32 " ) ;
}
ret = IVAL ( centry - > data , centry - > ofs ) ;
centry - > ofs + = 4 ;
return ret ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 08:20:55 +03:00
/*
pull a uint8 from a cache entry
*/
static uint8 centry_uint8 ( struct cache_entry * centry )
{
uint8 ret ;
if ( centry - > len - centry - > ofs < 1 ) {
DEBUG ( 0 , ( " centry corruption? needed 1 bytes, have %d \n " ,
centry - > len - centry - > ofs ) ) ;
smb_panic ( " centry_uint32 " ) ;
}
ret = CVAL ( centry - > data , centry - > ofs ) ;
centry - > ofs + = 1 ;
return ret ;
}
2001-12-10 02:59:42 +03:00
/* pull a string from a cache entry, using the supplied
talloc context
*/
static char * centry_string ( struct cache_entry * centry , TALLOC_CTX * mem_ctx )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
uint32 len ;
char * ret ;
2001-12-10 08:20:55 +03:00
len = centry_uint8 ( centry ) ;
2001-12-10 03:07:51 +03:00
2001-12-10 08:20:55 +03:00
if ( len = = 0xFF ) {
2001-12-10 03:07:51 +03:00
/* a deliberate NULL string */
return NULL ;
}
2001-12-10 02:59:42 +03:00
if ( centry - > len - centry - > ofs < len ) {
DEBUG ( 0 , ( " centry corruption? needed %d bytes, have %d \n " ,
len , centry - > len - centry - > ofs ) ) ;
smb_panic ( " centry_string " ) ;
}
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
ret = talloc ( mem_ctx , len + 1 ) ;
if ( ! ret ) {
smb_panic ( " centry_string out of memory \n " ) ;
}
memcpy ( ret , centry - > data + centry - > ofs , len ) ;
ret [ len ] = 0 ;
centry - > ofs + = len ;
return ret ;
2000-05-09 15:43:00 +04:00
}
2003-04-23 15:54:56 +04:00
/* pull a string from a cache entry, using the supplied
talloc context
*/
static DOM_SID * centry_sid ( struct cache_entry * centry , TALLOC_CTX * mem_ctx )
{
DOM_SID * sid ;
char * sid_string ;
sid = talloc ( mem_ctx , sizeof ( * sid ) ) ;
if ( ! sid ) return NULL ;
sid_string = centry_string ( centry , mem_ctx ) ;
if ( ! string_to_sid ( sid , sid_string ) ) {
return NULL ;
}
return sid ;
}
2001-12-10 02:59:42 +03:00
/* the server is considered down if it can't give us a sequence number */
static BOOL wcache_server_down ( struct winbindd_domain * domain )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
if ( ! wcache - > tdb ) return False ;
return ( domain - > sequence_number = = DOM_SEQUENCE_NONE ) ;
}
2000-05-09 15:43:00 +04:00
2003-06-03 20:02:33 +04:00
static NTSTATUS fetch_cache_seqnum ( struct winbindd_domain * domain , time_t now )
{
TDB_DATA data ;
fstring key ;
uint32 time_diff ;
if ( ! wcache - > tdb )
return NT_STATUS_UNSUCCESSFUL ;
snprintf ( key , sizeof ( key ) , " SEQNUM/%s " , domain - > name ) ;
data = tdb_fetch_by_string ( wcache - > tdb , key ) ;
if ( ! data . dptr | | data . dsize ! = 8 )
return NT_STATUS_UNSUCCESSFUL ;
domain - > sequence_number = IVAL ( data . dptr , 0 ) ;
domain - > last_seq_check = IVAL ( data . dptr , 4 ) ;
/* have we expired? */
time_diff = now - domain - > last_seq_check ;
if ( time_diff > lp_winbind_cache_time ( ) )
return NT_STATUS_UNSUCCESSFUL ;
DEBUG ( 10 , ( " fetch_cache_seqnum: success [%s][%u @ %u] \n " ,
domain - > name , domain - > sequence_number ,
( uint32 ) domain - > last_seq_check ) ) ;
return NT_STATUS_OK ;
}
static NTSTATUS store_cache_seqnum ( struct winbindd_domain * domain )
{
TDB_DATA data , key ;
fstring key_str ;
char buf [ 8 ] ;
if ( ! wcache - > tdb )
return NT_STATUS_UNSUCCESSFUL ;
snprintf ( key_str , sizeof ( key_str ) , " SEQNUM/%s " , domain - > name ) ;
key . dptr = key_str ;
key . dsize = strlen ( key_str ) + 1 ;
SIVAL ( buf , 0 , domain - > sequence_number ) ;
SIVAL ( buf , 4 , domain - > last_seq_check ) ;
data . dptr = buf ;
data . dsize = 8 ;
if ( tdb_store ( wcache - > tdb , key , data , TDB_REPLACE ) = = - 1 )
return NT_STATUS_UNSUCCESSFUL ;
DEBUG ( 10 , ( " store_cache_seqnum: success [%s][%u @ %u] \n " ,
domain - > name , domain - > sequence_number ,
( uint32 ) domain - > last_seq_check ) ) ;
return NT_STATUS_OK ;
}
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
/*
refresh the domain sequence number . If force is True
then always refresh it , no matter how recently we fetched it
*/
2003-06-03 20:02:33 +04:00
2001-12-10 02:59:42 +03:00
static void refresh_sequence_number ( struct winbindd_domain * domain , BOOL force )
{
NTSTATUS status ;
2002-01-11 13:05:34 +03:00
unsigned time_diff ;
2003-06-03 20:02:33 +04:00
time_t t = time ( NULL ) ;
2002-07-15 14:35:28 +04:00
unsigned cache_time = lp_winbind_cache_time ( ) ;
/* trying to reconnect is expensive, don't do it too often */
if ( domain - > sequence_number = = DOM_SEQUENCE_NONE ) {
cache_time * = 8 ;
}
2002-01-11 13:05:34 +03:00
2003-06-03 20:02:33 +04:00
time_diff = t - domain - > last_seq_check ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
/* see if we have to refetch the domain sequence number */
2002-07-15 14:35:28 +04:00
if ( ! force & & ( time_diff < cache_time ) ) {
2001-11-21 11:36:43 +03:00
return ;
2001-12-10 02:59:42 +03:00
}
2003-06-03 20:02:33 +04:00
/* try to get the sequence number from the tdb cache first */
/* this will update the timestamp as well */
status = fetch_cache_seqnum ( domain , t ) ;
if ( NT_STATUS_IS_OK ( status ) )
goto done ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
status = wcache - > backend - > sequence_number ( domain , & domain - > sequence_number ) ;
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
domain - > sequence_number = DOM_SEQUENCE_NONE ;
}
2003-06-03 20:02:33 +04:00
2001-12-10 02:59:42 +03:00
domain - > last_seq_check = time ( NULL ) ;
2003-06-03 20:02:33 +04:00
/* save the new sequence number ni the cache */
store_cache_seqnum ( domain ) ;
done :
DEBUG ( 10 , ( " refresh_sequence_number: seq number is now %d \n " ,
domain - > sequence_number ) ) ;
return ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
/*
decide if a cache entry has expired
*/
static BOOL centry_expired ( struct winbindd_domain * domain , struct cache_entry * centry )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
/* if the server is OK and our cache entry came from when it was down then
the entry is invalid */
if ( domain - > sequence_number ! = DOM_SEQUENCE_NONE & &
centry - > sequence_number = = DOM_SEQUENCE_NONE ) {
return True ;
}
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
/* if the server is down or the cache entry is not older than the
current sequence number then it is OK */
if ( wcache_server_down ( domain ) | |
2002-01-11 13:02:28 +03:00
centry - > sequence_number = = domain - > sequence_number ) {
2001-12-10 02:59:42 +03:00
return False ;
}
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
/* it's expired */
return True ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
/*
fetch an entry from the cache , with a varargs key . auto - fetch the sequence
number and return status
*/
2003-04-23 15:54:56 +04:00
static struct cache_entry * wcache_fetch ( struct winbind_cache * cache ,
struct winbindd_domain * domain ,
const char * format , . . . ) PRINTF_ATTRIBUTE ( 3 , 4 ) ;
2001-12-10 02:59:42 +03:00
static struct cache_entry * wcache_fetch ( struct winbind_cache * cache ,
struct winbindd_domain * domain ,
const char * format , . . . )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
va_list ap ;
char * kstr ;
TDB_DATA data ;
struct cache_entry * centry ;
2001-12-10 08:20:55 +03:00
TDB_DATA key ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
refresh_sequence_number ( domain , False ) ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
va_start ( ap , format ) ;
smb_xvasprintf ( & kstr , format , ap ) ;
va_end ( ap ) ;
2001-12-10 08:20:55 +03:00
key . dptr = kstr ;
key . dsize = strlen ( kstr ) ;
data = tdb_fetch ( wcache - > tdb , key ) ;
2001-12-10 02:59:42 +03:00
free ( kstr ) ;
if ( ! data . dptr ) {
/* a cache miss */
return NULL ;
}
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
centry = smb_xmalloc ( sizeof ( * centry ) ) ;
centry - > data = data . dptr ;
centry - > len = data . dsize ;
centry - > ofs = 0 ;
2001-11-21 11:36:43 +03:00
2001-12-10 02:59:42 +03:00
if ( centry - > len < 8 ) {
/* huh? corrupt cache? */
centry_free ( centry ) ;
return NULL ;
}
centry - > status = NT_STATUS ( centry_uint32 ( centry ) ) ;
centry - > sequence_number = centry_uint32 ( centry ) ;
2001-11-21 11:36:43 +03:00
2001-12-10 02:59:42 +03:00
if ( centry_expired ( domain , centry ) ) {
2002-07-15 14:35:28 +04:00
extern BOOL opt_dual_daemon ;
if ( opt_dual_daemon ) {
2002-10-16 01:34:42 +04:00
extern BOOL background_process ;
background_process = True ;
2002-07-15 14:35:28 +04:00
} else {
centry_free ( centry ) ;
return NULL ;
}
2001-12-10 02:59:42 +03:00
}
2001-11-21 11:36:43 +03:00
2001-12-10 02:59:42 +03:00
return centry ;
2001-11-21 11:36:43 +03:00
}
2001-12-10 02:59:42 +03:00
/*
make sure we have at least len bytes available in a centry
*/
static void centry_expand ( struct cache_entry * centry , uint32 len )
2001-11-21 11:36:43 +03:00
{
2001-12-10 02:59:42 +03:00
uint8 * p ;
if ( centry - > len - centry - > ofs > = len ) return ;
centry - > len * = 2 ;
p = realloc ( centry - > data , centry - > len ) ;
if ( ! p ) {
DEBUG ( 0 , ( " out of memory: needed %d bytes in centry_expand \n " , centry - > len ) ) ;
smb_panic ( " out of memory in centry_expand " ) ;
}
centry - > data = p ;
2001-11-21 11:36:43 +03:00
}
2001-12-10 02:59:42 +03:00
/*
push a uint32 into a centry
*/
static void centry_put_uint32 ( struct cache_entry * centry , uint32 v )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
centry_expand ( centry , 4 ) ;
SIVAL ( centry - > data , centry - > ofs , v ) ;
centry - > ofs + = 4 ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 08:20:55 +03:00
/*
push a uint8 into a centry
*/
static void centry_put_uint8 ( struct cache_entry * centry , uint8 v )
{
centry_expand ( centry , 1 ) ;
SCVAL ( centry - > data , centry - > ofs , v ) ;
centry - > ofs + = 1 ;
}
2001-12-10 02:59:42 +03:00
/*
push a string into a centry
*/
static void centry_put_string ( struct cache_entry * centry , const char * s )
2000-05-09 15:43:00 +04:00
{
2001-12-10 03:07:51 +03:00
int len ;
if ( ! s ) {
/* null strings are marked as len 0xFFFF */
2001-12-10 08:20:55 +03:00
centry_put_uint8 ( centry , 0xFF ) ;
2001-12-10 03:07:51 +03:00
return ;
}
len = strlen ( s ) ;
2001-12-10 08:20:55 +03:00
/* can't handle more than 254 char strings. Truncating is probably best */
if ( len > 254 ) len = 254 ;
centry_put_uint8 ( centry , len ) ;
2001-12-10 02:59:42 +03:00
centry_expand ( centry , len ) ;
memcpy ( centry - > data + centry - > ofs , s , len ) ;
centry - > ofs + = len ;
2000-05-09 15:43:00 +04:00
}
2003-04-23 15:54:56 +04:00
static void centry_put_sid ( struct cache_entry * centry , const DOM_SID * sid )
{
fstring sid_string ;
centry_put_string ( centry , sid_to_string ( sid_string , sid ) ) ;
}
2001-12-10 02:59:42 +03:00
/*
start a centry for output . When finished , call centry_end ( )
*/
struct cache_entry * centry_start ( struct winbindd_domain * domain , NTSTATUS status )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
struct cache_entry * centry ;
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
if ( ! wcache - > tdb ) return NULL ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
centry = smb_xmalloc ( sizeof ( * centry ) ) ;
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
centry - > len = 8192 ; /* reasonable default */
centry - > data = smb_xmalloc ( centry - > len ) ;
centry - > ofs = 0 ;
centry - > sequence_number = domain - > sequence_number ;
centry_put_uint32 ( centry , NT_STATUS_V ( status ) ) ;
centry_put_uint32 ( centry , centry - > sequence_number ) ;
return centry ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
/*
finish a centry and write it to the tdb
*/
2003-04-23 15:54:56 +04:00
static void centry_end ( struct cache_entry * centry , const char * format , . . . ) PRINTF_ATTRIBUTE ( 2 , 3 ) ;
2001-12-10 02:59:42 +03:00
static void centry_end ( struct cache_entry * centry , const char * format , . . . )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
va_list ap ;
char * kstr ;
2001-12-10 08:20:55 +03:00
TDB_DATA key , data ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
va_start ( ap , format ) ;
smb_xvasprintf ( & kstr , format , ap ) ;
va_end ( ap ) ;
2001-05-07 08:32:40 +04:00
2001-12-10 08:20:55 +03:00
key . dptr = kstr ;
key . dsize = strlen ( kstr ) ;
data . dptr = centry - > data ;
data . dsize = centry - > ofs ;
tdb_store ( wcache - > tdb , key , data , TDB_REPLACE ) ;
2001-12-10 02:59:42 +03:00
free ( kstr ) ;
2000-05-09 15:43:00 +04:00
}
2003-04-23 15:54:56 +04:00
static void wcache_save_name_to_sid ( struct winbindd_domain * domain ,
NTSTATUS status ,
const char * name , DOM_SID * sid ,
enum SID_NAME_USE type )
2001-12-10 09:05:21 +03:00
{
struct cache_entry * centry ;
2002-07-15 14:35:28 +04:00
fstring uname ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
2001-12-10 09:05:21 +03:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) return ;
2003-04-23 15:54:56 +04:00
centry_put_sid ( centry , sid ) ;
2002-07-15 14:35:28 +04:00
fstrcpy ( uname , name ) ;
strupper ( uname ) ;
2003-04-23 15:54:56 +04:00
centry_end ( centry , " NS/%s " , sid_to_string ( sid_string , sid ) ) ;
2001-12-10 09:05:21 +03:00
centry_free ( centry ) ;
}
static void wcache_save_sid_to_name ( struct winbindd_domain * domain , NTSTATUS status ,
2003-04-23 15:54:56 +04:00
DOM_SID * sid , const char * name , enum SID_NAME_USE type )
2001-12-10 09:05:21 +03:00
{
struct cache_entry * centry ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
2001-12-10 09:05:21 +03:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) return ;
if ( NT_STATUS_IS_OK ( status ) ) {
centry_put_uint32 ( centry , type ) ;
centry_put_string ( centry , name ) ;
}
2003-04-23 15:54:56 +04:00
centry_end ( centry , " SN/%s " , sid_to_string ( sid_string , sid ) ) ;
2001-12-10 09:05:21 +03:00
centry_free ( centry ) ;
}
static void wcache_save_user ( struct winbindd_domain * domain , NTSTATUS status , WINBIND_USERINFO * info )
{
struct cache_entry * centry ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
2001-12-10 09:05:21 +03:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) return ;
centry_put_string ( centry , info - > acct_name ) ;
centry_put_string ( centry , info - > full_name ) ;
2003-04-23 15:54:56 +04:00
centry_put_sid ( centry , info - > user_sid ) ;
centry_put_sid ( centry , info - > group_sid ) ;
centry_end ( centry , " U/%s " , sid_to_string ( sid_string , info - > user_sid ) ) ;
2001-12-10 09:05:21 +03:00
centry_free ( centry ) ;
}
2001-12-10 02:59:42 +03:00
/* Query display info. This is the basic user list fn */
static NTSTATUS query_user_list ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2001-12-11 03:03:58 +03:00
uint32 * num_entries ,
2001-12-10 02:59:42 +03:00
WINBIND_USERINFO * * info )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2003-04-23 15:54:56 +04:00
unsigned int i ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
if ( ! cache - > tdb ) goto do_query ;
2001-10-14 12:26:45 +04:00
2001-12-11 03:03:58 +03:00
centry = wcache_fetch ( cache , domain , " UL/%s " , domain - > name ) ;
2001-12-10 02:59:42 +03:00
if ( ! centry ) goto do_query ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
* num_entries = centry_uint32 ( centry ) ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
if ( * num_entries = = 0 ) goto do_cached ;
( * info ) = talloc ( mem_ctx , sizeof ( * * info ) * ( * num_entries ) ) ;
if ( ! ( * info ) ) smb_panic ( " query_user_list out of memory " ) ;
for ( i = 0 ; i < ( * num_entries ) ; i + + ) {
( * info ) [ i ] . acct_name = centry_string ( centry , mem_ctx ) ;
( * info ) [ i ] . full_name = centry_string ( centry , mem_ctx ) ;
2003-04-23 15:54:56 +04:00
( * info ) [ i ] . user_sid = centry_sid ( centry , mem_ctx ) ;
( * info ) [ i ] . group_sid = centry_sid ( centry , mem_ctx ) ;
2001-12-10 02:59:42 +03:00
}
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
do_cached :
status = centry - > status ;
centry_free ( centry ) ;
return status ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
do_query :
2001-12-19 11:44:23 +03:00
* num_entries = 0 ;
* info = NULL ;
2001-12-10 02:59:42 +03:00
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
2000-05-09 15:43:00 +04:00
2001-12-11 03:03:58 +03:00
status = cache - > backend - > query_user_list ( domain , mem_ctx , num_entries , info ) ;
2001-12-10 02:59:42 +03:00
/* and save it */
2003-06-03 20:02:33 +04:00
refresh_sequence_number ( domain , False ) ;
2001-12-10 02:59:42 +03:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) goto skip_save ;
centry_put_uint32 ( centry , * num_entries ) ;
for ( i = 0 ; i < ( * num_entries ) ; i + + ) {
centry_put_string ( centry , ( * info ) [ i ] . acct_name ) ;
centry_put_string ( centry , ( * info ) [ i ] . full_name ) ;
2003-04-23 15:54:56 +04:00
centry_put_sid ( centry , ( * info ) [ i ] . user_sid ) ;
centry_put_sid ( centry , ( * info ) [ i ] . group_sid ) ;
2001-12-10 09:05:21 +03:00
if ( cache - > backend - > consistent ) {
/* when the backend is consistent we can pre-prime some mappings */
wcache_save_name_to_sid ( domain , NT_STATUS_OK ,
2002-03-10 00:12:25 +03:00
( * info ) [ i ] . acct_name ,
2003-04-23 15:54:56 +04:00
( * info ) [ i ] . user_sid ,
2001-12-10 09:05:21 +03:00
SID_NAME_USER ) ;
wcache_save_sid_to_name ( domain , NT_STATUS_OK ,
2003-04-23 15:54:56 +04:00
( * info ) [ i ] . user_sid ,
2002-03-10 00:12:25 +03:00
( * info ) [ i ] . acct_name ,
2003-04-23 15:54:56 +04:00
SID_NAME_USER ) ;
2001-12-10 09:05:21 +03:00
wcache_save_user ( domain , NT_STATUS_OK , & ( * info ) [ i ] ) ;
}
2001-12-10 02:59:42 +03:00
}
2001-12-11 03:03:58 +03:00
centry_end ( centry , " UL/%s " , domain - > name ) ;
2001-12-10 02:59:42 +03:00
centry_free ( centry ) ;
skip_save :
return status ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
/* list all domain groups */
static NTSTATUS enum_dom_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2001-12-11 04:04:13 +03:00
uint32 * num_entries ,
2001-12-10 02:59:42 +03:00
struct acct_info * * info )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2003-04-23 15:54:56 +04:00
unsigned int i ;
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
if ( ! cache - > tdb ) goto do_query ;
2000-05-09 15:43:00 +04:00
2002-10-08 22:32:42 +04:00
centry = wcache_fetch ( cache , domain , " GL/%s/domain " , domain - > name ) ;
2001-12-10 02:59:42 +03:00
if ( ! centry ) goto do_query ;
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
* num_entries = centry_uint32 ( centry ) ;
if ( * num_entries = = 0 ) goto do_cached ;
( * info ) = talloc ( mem_ctx , sizeof ( * * info ) * ( * num_entries ) ) ;
if ( ! ( * info ) ) smb_panic ( " enum_dom_groups out of memory " ) ;
for ( i = 0 ; i < ( * num_entries ) ; i + + ) {
fstrcpy ( ( * info ) [ i ] . acct_name , centry_string ( centry , mem_ctx ) ) ;
fstrcpy ( ( * info ) [ i ] . acct_desc , centry_string ( centry , mem_ctx ) ) ;
( * info ) [ i ] . rid = centry_uint32 ( centry ) ;
}
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
do_cached :
status = centry - > status ;
centry_free ( centry ) ;
return status ;
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
do_query :
2001-12-19 11:44:23 +03:00
* num_entries = 0 ;
* info = NULL ;
2001-12-10 02:59:42 +03:00
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
2001-05-07 08:32:40 +04:00
2001-12-11 04:04:13 +03:00
status = cache - > backend - > enum_dom_groups ( domain , mem_ctx , num_entries , info ) ;
2001-12-10 02:59:42 +03:00
/* and save it */
2003-06-03 20:02:33 +04:00
refresh_sequence_number ( domain , False ) ;
2001-12-10 02:59:42 +03:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) goto skip_save ;
centry_put_uint32 ( centry , * num_entries ) ;
for ( i = 0 ; i < ( * num_entries ) ; i + + ) {
centry_put_string ( centry , ( * info ) [ i ] . acct_name ) ;
centry_put_string ( centry , ( * info ) [ i ] . acct_desc ) ;
centry_put_uint32 ( centry , ( * info ) [ i ] . rid ) ;
}
2002-10-08 22:32:42 +04:00
centry_end ( centry , " GL/%s/domain " , domain - > name ) ;
2001-12-10 02:59:42 +03:00
centry_free ( centry ) ;
skip_save :
return status ;
2000-05-09 15:43:00 +04:00
}
2002-10-08 22:32:42 +04:00
/* list all domain groups */
static NTSTATUS enum_local_groups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32 * num_entries ,
struct acct_info * * info )
{
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2003-04-23 15:54:56 +04:00
unsigned int i ;
2002-10-08 22:32:42 +04:00
if ( ! cache - > tdb ) goto do_query ;
centry = wcache_fetch ( cache , domain , " GL/%s/local " , domain - > name ) ;
if ( ! centry ) goto do_query ;
* num_entries = centry_uint32 ( centry ) ;
if ( * num_entries = = 0 ) goto do_cached ;
( * info ) = talloc ( mem_ctx , sizeof ( * * info ) * ( * num_entries ) ) ;
if ( ! ( * info ) ) smb_panic ( " enum_dom_groups out of memory " ) ;
for ( i = 0 ; i < ( * num_entries ) ; i + + ) {
fstrcpy ( ( * info ) [ i ] . acct_name , centry_string ( centry , mem_ctx ) ) ;
fstrcpy ( ( * info ) [ i ] . acct_desc , centry_string ( centry , mem_ctx ) ) ;
( * info ) [ i ] . rid = centry_uint32 ( centry ) ;
}
do_cached :
/* If we are returning cached data and the domain controller
is down then we don ' t know whether the data is up to date
or not . Return NT_STATUS_MORE_PROCESSING_REQUIRED to
indicate this . */
if ( wcache_server_down ( domain ) ) {
DEBUG ( 10 , ( " query_user_list: returning cached user list and server was down \n " ) ) ;
status = NT_STATUS_MORE_PROCESSING_REQUIRED ;
} else
status = centry - > status ;
centry_free ( centry ) ;
return status ;
do_query :
* num_entries = 0 ;
* info = NULL ;
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
status = cache - > backend - > enum_local_groups ( domain , mem_ctx , num_entries , info ) ;
/* and save it */
2003-06-03 20:02:33 +04:00
refresh_sequence_number ( domain , False ) ;
2002-10-08 22:32:42 +04:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) goto skip_save ;
centry_put_uint32 ( centry , * num_entries ) ;
for ( i = 0 ; i < ( * num_entries ) ; i + + ) {
centry_put_string ( centry , ( * info ) [ i ] . acct_name ) ;
centry_put_string ( centry , ( * info ) [ i ] . acct_desc ) ;
centry_put_uint32 ( centry , ( * info ) [ i ] . rid ) ;
2003-04-23 15:54:56 +04:00
}
2002-10-08 22:32:42 +04:00
centry_end ( centry , " GL/%s/local " , domain - > name ) ;
centry_free ( centry ) ;
skip_save :
return status ;
}
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
/* convert a single name to a sid in a domain */
static NTSTATUS name_to_sid ( struct winbindd_domain * domain ,
2003-04-23 15:54:56 +04:00
TALLOC_CTX * mem_ctx ,
2001-12-10 02:59:42 +03:00
const char * name ,
DOM_SID * sid ,
enum SID_NAME_USE * type )
2001-11-21 11:36:43 +03:00
{
2001-12-10 02:59:42 +03:00
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2002-07-15 14:35:28 +04:00
fstring uname ;
2003-04-23 15:54:56 +04:00
DOM_SID * sid2 ;
2001-11-21 11:36:43 +03:00
2001-12-10 02:59:42 +03:00
if ( ! cache - > tdb ) goto do_query ;
2001-11-21 11:36:43 +03:00
2002-07-15 14:35:28 +04:00
fstrcpy ( uname , name ) ;
strupper ( uname ) ;
centry = wcache_fetch ( cache , domain , " NS/%s/%s " , domain - > name , uname ) ;
2001-12-10 02:59:42 +03:00
if ( ! centry ) goto do_query ;
* type = centry_uint32 ( centry ) ;
2003-04-23 15:54:56 +04:00
sid2 = centry_sid ( centry , mem_ctx ) ;
if ( ! sid2 ) {
ZERO_STRUCTP ( sid ) ;
} else {
sid_copy ( sid , sid2 ) ;
}
2001-11-21 11:36:43 +03:00
2001-12-10 02:59:42 +03:00
status = centry - > status ;
centry_free ( centry ) ;
return status ;
2001-11-21 11:36:43 +03:00
2001-12-10 02:59:42 +03:00
do_query :
2001-12-19 11:44:23 +03:00
ZERO_STRUCTP ( sid ) ;
2001-12-10 02:59:42 +03:00
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
2003-04-23 15:54:56 +04:00
status = cache - > backend - > name_to_sid ( domain , mem_ctx , name , sid , type ) ;
2001-12-10 02:59:42 +03:00
/* and save it */
2001-12-10 09:05:21 +03:00
wcache_save_name_to_sid ( domain , status , name , sid , * type ) ;
2001-12-10 02:59:42 +03:00
2002-07-15 14:35:28 +04:00
/* We can't save the sid to name mapping as we don't know the
correct case of the name without looking it up */
2001-12-10 02:59:42 +03:00
return status ;
2001-11-21 11:36:43 +03:00
}
2001-12-10 08:20:55 +03:00
/* convert a sid to a user or group name. The sid is guaranteed to be in the domain
given */
2001-12-10 02:59:42 +03:00
static NTSTATUS sid_to_name ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
DOM_SID * sid ,
char * * name ,
enum SID_NAME_USE * type )
2001-11-21 11:36:43 +03:00
{
2001-12-10 02:59:42 +03:00
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
2001-11-21 11:36:43 +03:00
2001-12-10 08:20:55 +03:00
if ( ! cache - > tdb ) goto do_query ;
2001-11-21 11:36:43 +03:00
2003-04-23 15:54:56 +04:00
centry = wcache_fetch ( cache , domain , " SN/%s " , sid_to_string ( sid_string , sid ) ) ;
2001-12-10 02:59:42 +03:00
if ( ! centry ) goto do_query ;
if ( NT_STATUS_IS_OK ( centry - > status ) ) {
* type = centry_uint32 ( centry ) ;
* name = centry_string ( centry , mem_ctx ) ;
}
status = centry - > status ;
centry_free ( centry ) ;
return status ;
do_query :
2001-12-19 11:44:23 +03:00
* name = NULL ;
2001-12-10 02:59:42 +03:00
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
status = cache - > backend - > sid_to_name ( domain , mem_ctx , sid , name , type ) ;
/* and save it */
2003-06-03 20:02:33 +04:00
refresh_sequence_number ( domain , False ) ;
2003-04-23 15:54:56 +04:00
wcache_save_sid_to_name ( domain , status , sid , * name , * type ) ;
2002-07-15 14:35:28 +04:00
wcache_save_name_to_sid ( domain , status , * name , sid , * type ) ;
2001-11-21 11:36:43 +03:00
2001-12-10 02:59:42 +03:00
return status ;
2001-11-21 11:36:43 +03:00
}
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
/* Lookup user information from a rid */
static NTSTATUS query_user ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2003-04-23 15:54:56 +04:00
DOM_SID * user_sid ,
2001-12-10 02:59:42 +03:00
WINBIND_USERINFO * info )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2003-04-23 15:54:56 +04:00
fstring sid_string ;
2001-12-10 02:59:42 +03:00
if ( ! cache - > tdb ) goto do_query ;
2003-04-23 15:54:56 +04:00
centry = wcache_fetch ( cache , domain , " U/%s " , sid_to_string ( sid_string , user_sid ) ) ;
2001-12-10 02:59:42 +03:00
if ( ! centry ) goto do_query ;
info - > acct_name = centry_string ( centry , mem_ctx ) ;
info - > full_name = centry_string ( centry , mem_ctx ) ;
2003-04-23 15:54:56 +04:00
info - > user_sid = centry_sid ( centry , mem_ctx ) ;
info - > group_sid = centry_sid ( centry , mem_ctx ) ;
2001-12-10 02:59:42 +03:00
status = centry - > status ;
centry_free ( centry ) ;
return status ;
do_query :
2001-12-19 11:44:23 +03:00
ZERO_STRUCTP ( info ) ;
2001-12-10 02:59:42 +03:00
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
2001-12-19 11:44:23 +03:00
2003-04-23 15:54:56 +04:00
status = cache - > backend - > query_user ( domain , mem_ctx , user_sid , info ) ;
2001-12-10 02:59:42 +03:00
/* and save it */
2003-06-03 20:02:33 +04:00
refresh_sequence_number ( domain , False ) ;
2001-12-10 09:05:21 +03:00
wcache_save_user ( domain , status , info ) ;
2001-12-10 02:59:42 +03:00
return status ;
2000-05-09 15:43:00 +04:00
}
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
/* Lookup groups a user is a member of. */
static NTSTATUS lookup_usergroups ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2003-04-23 15:54:56 +04:00
DOM_SID * user_sid ,
uint32 * num_groups , DOM_SID * * * user_gids )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2003-04-23 15:54:56 +04:00
unsigned int i ;
fstring sid_string ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
if ( ! cache - > tdb ) goto do_query ;
2000-05-09 15:43:00 +04:00
2003-04-23 15:54:56 +04:00
centry = wcache_fetch ( cache , domain , " UG/%s " , sid_to_string ( sid_string , user_sid ) ) ;
2001-12-10 02:59:42 +03:00
if ( ! centry ) goto do_query ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
* num_groups = centry_uint32 ( centry ) ;
if ( * num_groups = = 0 ) goto do_cached ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
( * user_gids ) = talloc ( mem_ctx , sizeof ( * * user_gids ) * ( * num_groups ) ) ;
if ( ! ( * user_gids ) ) smb_panic ( " lookup_usergroups out of memory " ) ;
for ( i = 0 ; i < ( * num_groups ) ; i + + ) {
2003-04-23 15:54:56 +04:00
( * user_gids ) [ i ] = centry_sid ( centry , mem_ctx ) ;
2001-12-10 02:59:42 +03:00
}
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
do_cached :
status = centry - > status ;
centry_free ( centry ) ;
return status ;
do_query :
2001-12-19 11:44:23 +03:00
( * num_groups ) = 0 ;
( * user_gids ) = NULL ;
2001-12-10 02:59:42 +03:00
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
2003-04-23 15:54:56 +04:00
status = cache - > backend - > lookup_usergroups ( domain , mem_ctx , user_sid , num_groups , user_gids ) ;
2001-12-10 02:59:42 +03:00
/* and save it */
2003-06-03 20:02:33 +04:00
refresh_sequence_number ( domain , False ) ;
2001-12-10 02:59:42 +03:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) goto skip_save ;
centry_put_uint32 ( centry , * num_groups ) ;
for ( i = 0 ; i < ( * num_groups ) ; i + + ) {
2003-04-23 15:54:56 +04:00
centry_put_sid ( centry , ( * user_gids ) [ i ] ) ;
2001-12-10 02:59:42 +03:00
}
2003-04-23 15:54:56 +04:00
centry_end ( centry , " UG/%s " , sid_to_string ( sid_string , user_sid ) ) ;
2001-12-10 02:59:42 +03:00
centry_free ( centry ) ;
skip_save :
return status ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
static NTSTATUS lookup_groupmem ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
2003-04-23 15:54:56 +04:00
DOM_SID * group_sid , uint32 * num_names ,
DOM_SID * * * sid_mem , char * * * names ,
2001-12-10 02:59:42 +03:00
uint32 * * name_types )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
struct winbind_cache * cache = get_cache ( domain ) ;
struct cache_entry * centry = NULL ;
NTSTATUS status ;
2003-04-23 15:54:56 +04:00
unsigned int i ;
fstring sid_string ;
2001-05-07 08:32:40 +04:00
2001-12-10 02:59:42 +03:00
if ( ! cache - > tdb ) goto do_query ;
2000-05-09 15:43:00 +04:00
2003-04-23 15:54:56 +04:00
centry = wcache_fetch ( cache , domain , " GM/%s " , sid_to_string ( sid_string , group_sid ) ) ;
2001-12-10 02:59:42 +03:00
if ( ! centry ) goto do_query ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
* num_names = centry_uint32 ( centry ) ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
if ( * num_names = = 0 ) goto do_cached ;
2001-05-07 08:32:40 +04:00
2003-04-23 15:54:56 +04:00
( * sid_mem ) = talloc ( mem_ctx , sizeof ( * * sid_mem ) * ( * num_names ) ) ;
2001-12-10 02:59:42 +03:00
( * names ) = talloc ( mem_ctx , sizeof ( * * names ) * ( * num_names ) ) ;
( * name_types ) = talloc ( mem_ctx , sizeof ( * * name_types ) * ( * num_names ) ) ;
2000-05-09 15:43:00 +04:00
2003-04-23 15:54:56 +04:00
if ( ! ( * sid_mem ) | | ! ( * names ) | | ! ( * name_types ) ) {
2001-12-10 02:59:42 +03:00
smb_panic ( " lookup_groupmem out of memory " ) ;
}
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
for ( i = 0 ; i < ( * num_names ) ; i + + ) {
2003-04-23 15:54:56 +04:00
( * sid_mem ) [ i ] = centry_sid ( centry , mem_ctx ) ;
2001-12-10 02:59:42 +03:00
( * names ) [ i ] = centry_string ( centry , mem_ctx ) ;
( * name_types ) [ i ] = centry_uint32 ( centry ) ;
}
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
do_cached :
status = centry - > status ;
centry_free ( centry ) ;
return status ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
do_query :
2001-12-19 11:44:23 +03:00
( * num_names ) = 0 ;
2003-04-23 15:54:56 +04:00
( * sid_mem ) = NULL ;
2001-12-19 11:44:23 +03:00
( * names ) = NULL ;
( * name_types ) = NULL ;
2001-12-10 02:59:42 +03:00
if ( wcache_server_down ( domain ) ) {
return NT_STATUS_SERVER_DISABLED ;
}
2003-04-23 15:54:56 +04:00
status = cache - > backend - > lookup_groupmem ( domain , mem_ctx , group_sid , num_names ,
sid_mem , names , name_types ) ;
2001-12-10 02:59:42 +03:00
/* and save it */
2003-06-03 20:02:33 +04:00
refresh_sequence_number ( domain , False ) ;
2001-12-10 02:59:42 +03:00
centry = centry_start ( domain , status ) ;
if ( ! centry ) goto skip_save ;
centry_put_uint32 ( centry , * num_names ) ;
for ( i = 0 ; i < ( * num_names ) ; i + + ) {
2003-04-23 15:54:56 +04:00
centry_put_sid ( centry , ( * sid_mem ) [ i ] ) ;
2001-12-10 02:59:42 +03:00
centry_put_string ( centry , ( * names ) [ i ] ) ;
centry_put_uint32 ( centry , ( * name_types ) [ i ] ) ;
}
2003-04-23 15:54:56 +04:00
centry_end ( centry , " GM/%s " , sid_to_string ( sid_string , group_sid ) ) ;
2001-12-10 02:59:42 +03:00
centry_free ( centry ) ;
skip_save :
return status ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 02:59:42 +03:00
/* find the sequence number for a domain */
static NTSTATUS sequence_number ( struct winbindd_domain * domain , uint32 * seq )
2000-05-09 15:43:00 +04:00
{
2001-12-10 02:59:42 +03:00
refresh_sequence_number ( domain , False ) ;
2000-05-09 15:43:00 +04:00
2001-12-10 02:59:42 +03:00
* seq = domain - > sequence_number ;
2001-10-14 12:26:45 +04:00
2001-12-10 02:59:42 +03:00
return NT_STATUS_OK ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 05:25:19 +03:00
/* enumerate trusted domains */
static NTSTATUS trusted_domains ( struct winbindd_domain * domain ,
TALLOC_CTX * mem_ctx ,
uint32 * num_domains ,
char * * * names ,
2002-08-17 21:00:51 +04:00
char * * * alt_names ,
2001-12-10 05:25:19 +03:00
DOM_SID * * dom_sids )
{
struct winbind_cache * cache = get_cache ( domain ) ;
2001-12-10 05:30:18 +03:00
/* we don't cache this call */
2001-12-10 05:25:19 +03:00
return cache - > backend - > trusted_domains ( domain , mem_ctx , num_domains ,
2002-08-17 21:00:51 +04:00
names , alt_names , dom_sids ) ;
2001-12-10 05:25:19 +03:00
}
/* find the domain sid */
static NTSTATUS domain_sid ( struct winbindd_domain * domain , DOM_SID * sid )
{
struct winbind_cache * cache = get_cache ( domain ) ;
2001-12-10 05:30:18 +03:00
/* we don't cache this call */
2001-12-10 05:25:19 +03:00
return cache - > backend - > domain_sid ( domain , sid ) ;
}
2002-08-17 21:00:51 +04:00
/* find the alternate names for the domain, if any */
static NTSTATUS alternate_name ( struct winbindd_domain * domain )
{
struct winbind_cache * cache = get_cache ( domain ) ;
/* we don't cache this call */
return cache - > backend - > alternate_name ( domain ) ;
}
2001-12-10 02:59:42 +03:00
/* the ADS backend methods are exposed via this structure */
struct winbindd_methods cache_methods = {
2001-12-10 09:05:21 +03:00
True ,
2001-12-10 02:59:42 +03:00
query_user_list ,
enum_dom_groups ,
2002-10-08 22:32:42 +04:00
enum_local_groups ,
2001-12-10 02:59:42 +03:00
name_to_sid ,
sid_to_name ,
query_user ,
lookup_usergroups ,
lookup_groupmem ,
2001-12-10 05:25:19 +03:00
sequence_number ,
trusted_domains ,
2002-08-17 21:00:51 +04:00
domain_sid ,
alternate_name
2001-12-10 02:59:42 +03:00
} ;