2008-07-11 19:42:58 +04:00
/*
2006-12-12 17:52:13 +03:00
Unix SMB / CIFS implementation .
ID Mapping Cache
2008-07-11 19:42:58 +04:00
based on gencache
2006-12-12 17:52:13 +03:00
Copyright ( C ) Simo Sorce 2006
Copyright ( C ) Rafal Szczesniak 2002
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
2006-12-12 17:52:13 +03: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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.*/
2006-12-12 17:52:13 +03:00
# include "includes.h"
2007-03-01 06:16:38 +03:00
# include "winbindd.h"
2006-12-12 17:52:13 +03:00
2008-07-11 19:42:58 +04:00
# define TIMEOUT_LEN 12
# define IDMAP_CACHE_DATA_FMT "%12u / %s"
2008-07-11 19:43:17 +04:00
# define IDMAP_READ_CACHE_DATA_FMT_TEMPLATE "%%12u / %%%us"
2008-07-11 19:42:58 +04:00
struct idmap_cache_ctx {
TDB_CONTEXT * tdb ;
} ;
static int idmap_cache_destructor ( struct idmap_cache_ctx * cache )
{
int ret = 0 ;
if ( cache & & cache - > tdb ) {
ret = tdb_close ( cache - > tdb ) ;
cache - > tdb = NULL ;
}
return ret ;
}
struct idmap_cache_ctx * idmap_cache_init ( TALLOC_CTX * memctx )
{
struct idmap_cache_ctx * cache ;
char * cache_fname = NULL ;
cache = talloc ( memctx , struct idmap_cache_ctx ) ;
if ( ! cache ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NULL ;
}
cache_fname = lock_path ( " idmap_cache.tdb " ) ;
DEBUG ( 10 , ( " Opening cache file at %s \n " , cache_fname ) ) ;
cache - > tdb = tdb_open_log ( cache_fname , 0 , TDB_DEFAULT , O_RDWR | O_CREAT , 0600 ) ;
if ( ! cache - > tdb ) {
DEBUG ( 5 , ( " Attempt to open %s has failed. \n " , cache_fname ) ) ;
return NULL ;
}
talloc_set_destructor ( cache , idmap_cache_destructor ) ;
return cache ;
}
2008-07-11 19:43:42 +04:00
static NTSTATUS idmap_cache_build_sidkey ( TALLOC_CTX * ctx , char * * sidkey ,
const struct id_map * id )
2006-12-12 17:52:13 +03:00
{
2007-12-16 00:00:39 +03:00
fstring sidstr ;
2008-07-11 19:43:42 +04:00
* sidkey = talloc_asprintf ( ctx , " IDMAP/SID/%s " ,
sid_to_fstring ( sidstr , id - > sid ) ) ;
if ( ! * sidkey ) {
DEBUG ( 1 , ( " failed to build sidkey, OOM? \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:43:42 +04:00
static NTSTATUS idmap_cache_build_idkey ( TALLOC_CTX * ctx , char * * idkey ,
const struct id_map * id )
2006-12-12 17:52:13 +03:00
{
2008-07-11 19:43:42 +04:00
* idkey = talloc_asprintf ( ctx , " IDMAP/%s/%lu " ,
( id - > xid . type = = ID_TYPE_UID ) ? " UID " : " GID " ,
( unsigned long ) id - > xid . id ) ;
if ( ! * idkey ) {
DEBUG ( 1 , ( " failed to build idkey, OOM? \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
NTSTATUS idmap_cache_set ( struct idmap_cache_ctx * cache , const struct id_map * id )
2006-12-12 17:52:13 +03:00
{
NTSTATUS ret ;
2007-03-21 18:21:28 +03:00
time_t timeout = time ( NULL ) + lp_idmap_cache_time ( ) ;
2008-07-11 19:42:58 +04:00
TDB_DATA databuf ;
2006-12-12 17:52:13 +03:00
char * sidkey ;
char * idkey ;
2008-07-11 19:42:58 +04:00
char * valstr ;
2006-12-12 17:52:13 +03:00
2007-04-07 01:05:55 +04:00
/* Don't cache lookups in the S-1-22-{1,2} domain */
2008-07-11 19:43:25 +04:00
if ( ( id - > xid . type = = ID_TYPE_UID ) & &
sid_check_is_in_unix_users ( id - > sid ) )
{
return NT_STATUS_OK ;
}
if ( ( id - > xid . type = = ID_TYPE_GID ) & &
sid_check_is_in_unix_groups ( id - > sid ) )
{
2007-04-07 01:05:55 +04:00
return NT_STATUS_OK ;
}
2008-07-11 19:45:31 +04:00
2007-04-07 01:05:55 +04:00
2008-07-11 19:43:42 +04:00
ret = idmap_cache_build_sidkey ( cache , & sidkey , id ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) return ret ;
2006-12-12 17:52:13 +03:00
/* use sidkey as the local memory ctx */
2008-07-11 19:43:42 +04:00
ret = idmap_cache_build_idkey ( sidkey , & idkey , id ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2006-12-12 17:52:13 +03:00
goto done ;
}
2008-07-11 19:42:58 +04:00
/* save SID -> ID */
/* use sidkey as the local memory ctx */
valstr = talloc_asprintf ( sidkey , IDMAP_CACHE_DATA_FMT , ( int ) timeout , idkey ) ;
if ( ! valstr ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
databuf = string_term_tdb_data ( valstr ) ;
DEBUG ( 10 , ( " Adding cache entry with key = %s; value = %s and timeout = "
" %s (%d seconds %s) \n " , sidkey , valstr , ctime ( & timeout ) ,
( int ) ( timeout - time ( NULL ) ) ,
timeout > time ( NULL ) ? " ahead " : " in the past " ) ) ;
if ( tdb_store_bystring ( cache - > tdb , sidkey , databuf , TDB_REPLACE ) ! = 0 ) {
DEBUG ( 3 , ( " Failed to store cache entry! \n " ) ) ;
ret = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* save ID -> SID */
/* use sidkey as the local memory ctx */
valstr = talloc_asprintf ( sidkey , IDMAP_CACHE_DATA_FMT , ( int ) timeout , sidkey ) ;
if ( ! valstr ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
databuf = string_term_tdb_data ( valstr ) ;
DEBUG ( 10 , ( " Adding cache entry with key = %s; value = %s and timeout = "
" %s (%d seconds %s) \n " , idkey , valstr , ctime ( & timeout ) ,
( int ) ( timeout - time ( NULL ) ) ,
timeout > time ( NULL ) ? " ahead " : " in the past " ) ) ;
if ( tdb_store_bystring ( cache - > tdb , idkey , databuf , TDB_REPLACE ) ! = 0 ) {
2006-12-12 17:52:13 +03:00
DEBUG ( 3 , ( " Failed to store cache entry! \n " ) ) ;
2008-07-11 19:42:58 +04:00
ret = NT_STATUS_UNSUCCESSFUL ;
2006-12-12 17:52:13 +03:00
goto done ;
}
ret = NT_STATUS_OK ;
done :
2008-07-11 19:42:58 +04:00
talloc_free ( sidkey ) ;
2006-12-12 17:52:13 +03:00
return ret ;
}
2008-07-11 19:42:58 +04:00
NTSTATUS idmap_cache_set_negative_sid ( struct idmap_cache_ctx * cache , const struct id_map * id )
2006-12-12 17:52:13 +03:00
{
2008-07-11 19:43:42 +04:00
NTSTATUS ret ;
2008-07-11 19:42:58 +04:00
time_t timeout = time ( NULL ) + lp_idmap_negative_cache_time ( ) ;
TDB_DATA databuf ;
2006-12-12 17:52:13 +03:00
char * sidkey ;
2008-07-11 19:42:58 +04:00
char * valstr ;
2006-12-12 17:52:13 +03:00
2008-07-11 19:43:42 +04:00
ret = idmap_cache_build_sidkey ( cache , & sidkey , id ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) return ret ;
2006-12-12 17:52:13 +03:00
2008-07-11 19:42:58 +04:00
/* use sidkey as the local memory ctx */
valstr = talloc_asprintf ( sidkey , IDMAP_CACHE_DATA_FMT , ( int ) timeout , " IDMAP/NEGATIVE " ) ;
if ( ! valstr ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
databuf = string_term_tdb_data ( valstr ) ;
DEBUG ( 10 , ( " Adding cache entry with key = %s; value = %s and timeout = "
" %s (%d seconds %s) \n " , sidkey , valstr , ctime ( & timeout ) ,
( int ) ( timeout - time ( NULL ) ) ,
timeout > time ( NULL ) ? " ahead " : " in the past " ) ) ;
if ( tdb_store_bystring ( cache - > tdb , sidkey , databuf , TDB_REPLACE ) ! = 0 ) {
2006-12-12 17:52:13 +03:00
DEBUG ( 3 , ( " Failed to store cache entry! \n " ) ) ;
2008-07-11 19:42:58 +04:00
ret = NT_STATUS_UNSUCCESSFUL ;
2006-12-12 17:52:13 +03:00
goto done ;
}
done :
2008-07-11 19:42:58 +04:00
talloc_free ( sidkey ) ;
2006-12-12 17:52:13 +03:00
return ret ;
}
2008-07-11 19:42:58 +04:00
NTSTATUS idmap_cache_set_negative_id ( struct idmap_cache_ctx * cache , const struct id_map * id )
2006-12-12 17:52:13 +03:00
{
2008-07-11 19:43:42 +04:00
NTSTATUS ret ;
2008-07-11 19:42:58 +04:00
time_t timeout = time ( NULL ) + lp_idmap_negative_cache_time ( ) ;
TDB_DATA databuf ;
2006-12-12 17:52:13 +03:00
char * idkey ;
2008-07-11 19:42:58 +04:00
char * valstr ;
2006-12-12 17:52:13 +03:00
2008-07-11 19:43:42 +04:00
ret = idmap_cache_build_idkey ( cache , & idkey , id ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) return ret ;
2006-12-12 17:52:13 +03:00
2008-07-11 19:42:58 +04:00
/* use idkey as the local memory ctx */
valstr = talloc_asprintf ( idkey , IDMAP_CACHE_DATA_FMT , ( int ) timeout , " IDMAP/NEGATIVE " ) ;
if ( ! valstr ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
ret = NT_STATUS_NO_MEMORY ;
goto done ;
}
databuf = string_term_tdb_data ( valstr ) ;
DEBUG ( 10 , ( " Adding cache entry with key = %s; value = %s and timeout = "
" %s (%d seconds %s) \n " , idkey , valstr , ctime ( & timeout ) ,
( int ) ( timeout - time ( NULL ) ) ,
timeout > time ( NULL ) ? " ahead " : " in the past " ) ) ;
if ( tdb_store_bystring ( cache - > tdb , idkey , databuf , TDB_REPLACE ) ! = 0 ) {
2006-12-12 17:52:13 +03:00
DEBUG ( 3 , ( " Failed to store cache entry! \n " ) ) ;
2008-07-11 19:42:58 +04:00
ret = NT_STATUS_UNSUCCESSFUL ;
2006-12-12 17:52:13 +03:00
goto done ;
}
done :
2008-07-11 19:42:58 +04:00
talloc_free ( idkey ) ;
2006-12-12 17:52:13 +03:00
return ret ;
}
2008-07-11 19:42:58 +04:00
static NTSTATUS idmap_cache_fill_map ( struct id_map * id , const char * value )
{
char * rem ;
/* see if it is a sid */
if ( ! strncmp ( " IDMAP/SID/ " , value , 10 ) ) {
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
if ( ! string_to_sid ( id - > sid , & value [ 10 ] ) ) {
goto failed ;
}
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
id - > status = ID_MAPPED ;
return NT_STATUS_OK ;
}
/* not a SID see if it is an UID or a GID */
if ( ! strncmp ( " IDMAP/UID/ " , value , 10 ) ) {
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
/* a uid */
id - > xid . type = ID_TYPE_UID ;
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
} else if ( ! strncmp ( " IDMAP/GID/ " , value , 10 ) ) {
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
/* a gid */
id - > xid . type = ID_TYPE_GID ;
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
} else {
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
/* a completely bogus value bail out */
goto failed ;
}
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
id - > xid . id = strtol ( & value [ 10 ] , & rem , 0 ) ;
if ( * rem ! = ' \0 ' ) {
goto failed ;
}
id - > status = ID_MAPPED ;
return NT_STATUS_OK ;
failed :
DEBUG ( 1 , ( " invalid value: %s \n " , value ) ) ;
id - > status = ID_UNKNOWN ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2008-07-11 19:45:54 +04:00
/* search the cahce for the SID an return a mapping if found *
2008-07-11 19:42:58 +04:00
*
* 4 cases are possible
*
* 1 map found
* in this case id - > status = ID_MAPPED and NT_STATUS_OK is returned
* 2 map not found
* in this case id - > status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned
* 3 negative cache found
* in this case id - > status = ID_UNMAPPED and NT_STATUS_OK is returned
* 4 map found but timer expired
* in this case id - > status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED
* is returned . In this case revalidation of the cache is needed .
2006-12-12 17:52:13 +03:00
*/
2008-07-11 19:42:58 +04:00
NTSTATUS idmap_cache_map_sid ( struct idmap_cache_ctx * cache , struct id_map * id )
2006-12-12 17:52:13 +03:00
{
2008-07-11 19:43:42 +04:00
NTSTATUS ret ;
2008-07-11 19:42:58 +04:00
TDB_DATA databuf ;
time_t t ;
2006-12-12 17:52:13 +03:00
char * sidkey ;
2008-07-11 19:42:58 +04:00
char * endptr ;
struct winbindd_domain * our_domain = find_our_domain ( ) ;
time_t now = time ( NULL ) ;
/* make sure it is marked as not mapped by default */
id - > status = ID_UNKNOWN ;
2008-07-11 19:45:31 +04:00
2008-07-11 19:43:42 +04:00
ret = idmap_cache_build_sidkey ( cache , & sidkey , id ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) return ret ;
2006-12-12 17:52:13 +03:00
2008-07-11 19:42:58 +04:00
databuf = tdb_fetch_bystring ( cache - > tdb , sidkey ) ;
if ( databuf . dptr = = NULL ) {
DEBUG ( 10 , ( " Cache entry with key = %s couldn't be found \n " , sidkey ) ) ;
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
t = strtol ( ( const char * ) databuf . dptr , & endptr , 10 ) ;
if ( ( endptr = = NULL ) | | ( * endptr ! = ' / ' ) ) {
2008-07-11 19:45:46 +04:00
DEBUG ( 2 , ( " Invalid gencache data format: %s \n " , ( const char * ) databuf . dptr ) ) ;
2008-07-11 19:42:58 +04:00
/* remove the entry */
tdb_delete_bystring ( cache - > tdb , sidkey ) ;
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
/* check it is not negative */
if ( strcmp ( " IDMAP/NEGATIVE " , endptr + 1 ) ! = 0 ) {
DEBUG ( 10 , ( " Returning %s cache entry: key = %s, value = %s, "
" timeout = %s " , t > now ? " valid " :
" expired " , sidkey , endptr + 1 , ctime ( & t ) ) ) ;
/* this call if successful will also mark the entry as mapped */
ret = idmap_cache_fill_map ( id , endptr + 1 ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
/* if not valid form delete the entry */
tdb_delete_bystring ( cache - > tdb , sidkey ) ;
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
/* here ret == NT_STATUS_OK and id->status = ID_MAPPED */
if ( t < = now ) {
/* If we've been told to be offline - stay in
that state . . . */
if ( IS_DOMAIN_OFFLINE ( our_domain ) ) {
DEBUG ( 10 , ( " idmap_cache_map_sid: idmap is offline \n " ) ) ;
goto done ;
}
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
/* We're expired, set an error code
for upper layer */
ret = NT_STATUS_SYNCHRONIZATION_REQUIRED ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
goto done ;
2007-05-07 01:04:30 +04:00
}
2008-07-11 19:42:58 +04:00
/* Was a negative cache hit */
/* Ignore the negative cache when offline */
if ( IS_DOMAIN_OFFLINE ( our_domain ) ) {
DEBUG ( 10 , ( " idmap_cache_map_sid: idmap is offline \n " ) ) ;
goto done ;
}
2007-05-07 01:04:30 +04:00
2008-07-02 16:06:09 +04:00
2008-07-11 19:42:58 +04:00
/* Check for valid or expired cache hits */
2008-07-11 19:45:40 +04:00
if ( t < = now ) {
2008-07-11 19:42:58 +04:00
/* We're expired. Return not mapped */
2008-07-11 19:45:40 +04:00
ret = NT_STATUS_NONE_MAPPED ;
} else {
/* this is not mapped as it was a negative cache hit */
id - > status = ID_UNMAPPED ;
ret = NT_STATUS_OK ;
}
2008-07-11 19:42:58 +04:00
done :
SAFE_FREE ( databuf . dptr ) ;
talloc_free ( sidkey ) ;
2006-12-12 17:52:13 +03:00
return ret ;
}
2008-07-11 19:45:54 +04:00
/* search the cahce for the ID an return a mapping if found *
2008-07-11 19:42:58 +04:00
*
* 4 cases are possible
*
* 1 map found
* in this case id - > status = ID_MAPPED and NT_STATUS_OK is returned
* 2 map not found
* in this case id - > status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned
* 3 negative cache found
* in this case id - > status = ID_UNMAPPED and NT_STATUS_OK is returned
* 4 map found but timer expired
* in this case id - > status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED
* is returned . In this case revalidation of the cache is needed .
2006-12-12 17:52:13 +03:00
*/
2008-07-11 19:42:58 +04:00
NTSTATUS idmap_cache_map_id ( struct idmap_cache_ctx * cache , struct id_map * id )
2006-12-12 17:52:13 +03:00
{
2008-07-11 19:42:58 +04:00
NTSTATUS ret ;
TDB_DATA databuf ;
time_t t ;
2006-12-12 17:52:13 +03:00
char * idkey ;
2008-07-11 19:42:58 +04:00
char * endptr ;
struct winbindd_domain * our_domain = find_our_domain ( ) ;
time_t now = time ( NULL ) ;
2006-12-12 17:52:13 +03:00
2008-07-11 19:42:58 +04:00
/* make sure it is marked as unknown by default */
id - > status = ID_UNKNOWN ;
2008-07-11 19:45:31 +04:00
2008-07-11 19:43:42 +04:00
ret = idmap_cache_build_idkey ( cache , & idkey , id ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) return ret ;
2006-12-12 17:52:13 +03:00
2008-07-11 19:42:58 +04:00
databuf = tdb_fetch_bystring ( cache - > tdb , idkey ) ;
if ( databuf . dptr = = NULL ) {
DEBUG ( 10 , ( " Cache entry with key = %s couldn't be found \n " , idkey ) ) ;
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
t = strtol ( ( const char * ) databuf . dptr , & endptr , 10 ) ;
if ( ( endptr = = NULL ) | | ( * endptr ! = ' / ' ) ) {
2008-07-11 19:45:46 +04:00
DEBUG ( 2 , ( " Invalid gencache data format: %s \n " , ( const char * ) databuf . dptr ) ) ;
2008-07-11 19:42:58 +04:00
/* remove the entry */
tdb_delete_bystring ( cache - > tdb , idkey ) ;
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
/* check it is not negative */
if ( strcmp ( " IDMAP/NEGATIVE " , endptr + 1 ) ! = 0 ) {
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
DEBUG ( 10 , ( " Returning %s cache entry: key = %s, value = %s, "
" timeout = %s " , t > now ? " valid " :
" expired " , idkey , endptr + 1 , ctime ( & t ) ) ) ;
/* this call if successful will also mark the entry as mapped */
ret = idmap_cache_fill_map ( id , endptr + 1 ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
/* if not valid form delete the entry */
tdb_delete_bystring ( cache - > tdb , idkey ) ;
ret = NT_STATUS_NONE_MAPPED ;
goto done ;
2006-12-12 17:52:13 +03:00
}
2008-07-11 19:42:58 +04:00
/* here ret == NT_STATUS_OK and id->mapped = ID_MAPPED */
if ( t < = now ) {
/* If we've been told to be offline - stay in
that state . . . */
if ( IS_DOMAIN_OFFLINE ( our_domain ) ) {
DEBUG ( 10 , ( " idmap_cache_map_sid: idmap is offline \n " ) ) ;
goto done ;
}
/* We're expired, set an error code
for upper layer */
ret = NT_STATUS_SYNCHRONIZATION_REQUIRED ;
}
goto done ;
2007-05-07 01:04:30 +04:00
}
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
/* Was a negative cache hit */
/* Ignore the negative cache when offline */
if ( IS_DOMAIN_OFFLINE ( our_domain ) ) {
DEBUG ( 10 , ( " idmap_cache_map_sid: idmap is offline \n " ) ) ;
ret = NT_STATUS_NONE_MAPPED ;
2008-07-11 19:45:31 +04:00
2008-07-11 19:42:58 +04:00
goto done ;
2007-05-07 01:04:30 +04:00
}
2008-07-11 19:42:58 +04:00
/* Process the negative cache hit */
2007-05-07 01:04:30 +04:00
2008-07-11 19:45:40 +04:00
if ( t < = now ) {
2008-07-11 19:42:58 +04:00
/* We're expired. Return not mapped */
2008-07-11 19:45:40 +04:00
ret = NT_STATUS_NONE_MAPPED ;
} else {
2008-07-11 19:42:58 +04:00
/* this is not mapped is it was a negative cache hit */
2008-07-11 19:45:40 +04:00
id - > status = ID_UNMAPPED ;
ret = NT_STATUS_OK ;
}
2008-07-11 19:42:58 +04:00
done :
SAFE_FREE ( databuf . dptr ) ;
talloc_free ( idkey ) ;
2006-12-12 17:52:13 +03:00
return ret ;
}
2008-07-08 00:09:39 +04:00
bool idmap_cache_find_sid2uid ( const struct dom_sid * sid , uid_t * puid ,
bool * expired )
{
fstring sidstr ;
char * key ;
char * value ;
char * endptr ;
time_t timeout ;
uid_t uid ;
bool ret ;
key = talloc_asprintf ( talloc_tos ( ) , " IDMAP/SID2UID/%s " ,
sid_to_fstring ( sidstr , sid ) ) ;
if ( key = = NULL ) {
return false ;
}
ret = gencache_get ( key , & value , & timeout ) ;
TALLOC_FREE ( key ) ;
if ( ! ret ) {
return false ;
}
uid = strtol ( value , & endptr , 10 ) ;
ret = ( * endptr = = ' \0 ' ) ;
SAFE_FREE ( value ) ;
if ( ret ) {
* puid = uid ;
* expired = ( timeout < = time ( NULL ) ) ;
}
return ret ;
}
bool idmap_cache_find_uid2sid ( uid_t uid , struct dom_sid * sid , bool * expired )
{
char * key ;
char * value ;
time_t timeout ;
bool ret ;
key = talloc_asprintf ( talloc_tos ( ) , " IDMAP/UID2SID/%d " , ( int ) uid ) ;
if ( key = = NULL ) {
return false ;
}
ret = gencache_get ( key , & value , & timeout ) ;
TALLOC_FREE ( key ) ;
if ( ! ret ) {
return false ;
}
ZERO_STRUCTP ( sid ) ;
ret = string_to_sid ( sid , value ) ;
SAFE_FREE ( value ) ;
if ( ret ) {
* expired = ( timeout < = time ( NULL ) ) ;
}
return ret ;
}
void idmap_cache_set_sid2uid ( const struct dom_sid * sid , uid_t uid )
{
time_t now = time ( NULL ) ;
time_t timeout ;
fstring sidstr , key , value ;
if ( ! is_null_sid ( sid ) ) {
fstr_sprintf ( key , " IDMAP/SID2UID/%s " ,
sid_to_fstring ( sidstr , sid ) ) ;
fstr_sprintf ( value , " %d " , ( int ) uid ) ;
timeout = ( uid = = - 1 )
? lp_idmap_negative_cache_time ( )
: lp_idmap_cache_time ( ) ;
gencache_set ( key , value , now + timeout ) ;
}
if ( uid ! = - 1 ) {
fstr_sprintf ( key , " IDMAP/UID2SID/%d " , ( int ) uid ) ;
sid_to_fstring ( value , sid ) ;
timeout = is_null_sid ( sid )
? lp_idmap_negative_cache_time ( )
: lp_idmap_cache_time ( ) ;
gencache_set ( key , value , now + timeout ) ;
}
}