2003-03-07 23:47:59 +00:00
/*
Unix SMB / CIFS implementation .
2003-04-29 10:54:13 +00:00
ID Mapping
2003-03-07 23:47:59 +00:00
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Anthony Liguori < aliguor @ us . ibm . com > 2003
Copyright ( C ) Simo Sorce 2003
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
2003-04-02 10:36:02 +00:00
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA . */
2003-03-07 23:47:59 +00:00
# include "includes.h"
2003-03-08 00:49:18 +00:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_IDMAP
2003-05-29 19:08:40 +00:00
struct idmap_function_entry {
2003-03-07 23:47:59 +00:00
const char * name ;
struct idmap_methods * methods ;
2003-05-29 19:08:40 +00:00
struct idmap_function_entry * prev , * next ;
2003-03-07 23:47:59 +00:00
} ;
2003-05-29 19:08:40 +00:00
static struct idmap_function_entry * backends = NULL ;
2003-04-02 10:36:02 +00:00
static struct idmap_methods * local_map ;
static struct idmap_methods * remote_map ;
2003-03-07 23:47:59 +00:00
2003-04-30 00:44:45 +00:00
static void lazy_initialize_idmap ( void )
{
static BOOL initialized = False ;
2003-05-29 19:08:40 +00:00
if ( ! initialized ) {
idmap_init ( ) ;
initialized = True ;
}
}
2003-04-30 00:44:45 +00:00
2003-03-08 17:29:40 +00:00
static struct idmap_methods * get_methods ( const char * name )
2003-03-07 23:47:59 +00:00
{
2003-05-29 19:08:40 +00:00
struct idmap_function_entry * entry = backends ;
2003-03-07 23:47:59 +00:00
2003-05-29 19:08:40 +00:00
while ( entry ) {
if ( strcmp ( entry - > name , name ) = = 0 ) return entry - > methods ;
entry = entry - > next ;
2003-03-07 23:47:59 +00:00
}
2003-05-29 19:08:40 +00:00
return NULL ;
}
2003-03-07 23:47:59 +00:00
2003-05-29 19:08:40 +00:00
NTSTATUS smb_register_idmap ( int version , const char * name , struct idmap_methods * methods )
{
2003-06-26 18:26:52 +00:00
struct idmap_function_entry * entry ;
2003-05-29 19:08:40 +00:00
if ( ( version ! = SMB_IDMAP_INTERFACE_VERSION ) ) {
DEBUG ( 0 , ( " Failed to register idmap module. \n "
" The module was compiled against SMB_IDMAP_INTERFACE_VERSION %d, \n "
" current SMB_IDMAP_INTERFACE_VERSION is %d. \n "
" Please recompile against the current version of samba! \n " ,
version , SMB_IDMAP_INTERFACE_VERSION ) ) ;
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
}
if ( ! name | | ! name [ 0 ] | | ! methods ) {
DEBUG ( 0 , ( " smb_register_idmap() called with NULL pointer or empty name! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2003-03-07 23:47:59 +00:00
2003-05-29 19:08:40 +00:00
if ( get_methods ( name ) ) {
DEBUG ( 0 , ( " idmap module %s already registered! \n " , name ) ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
2003-03-07 23:47:59 +00:00
}
2003-05-29 19:08:40 +00:00
entry = smb_xmalloc ( sizeof ( struct idmap_function_entry ) ) ;
entry - > name = smb_xstrdup ( name ) ;
entry - > methods = methods ;
2003-06-26 18:26:52 +00:00
DLIST_ADD ( backends , entry ) ;
2003-05-29 19:08:40 +00:00
DEBUG ( 5 , ( " Successfully added idmap backend '%s' \n " , name ) ) ;
return NT_STATUS_OK ;
2003-03-07 23:47:59 +00:00
}
2003-04-02 10:36:02 +00:00
/* Initialize backend */
2003-04-27 12:07:20 +00:00
BOOL idmap_init ( void )
2003-03-07 23:47:59 +00:00
{
2003-04-27 12:07:20 +00:00
const char * remote_backend = lp_idmap_backend ( ) ;
2003-05-29 19:08:40 +00:00
if ( ! backends )
static_init_idmap ;
2003-04-02 10:36:02 +00:00
if ( ! local_map ) {
2003-05-29 19:08:40 +00:00
local_map = get_methods ( " tdb " ) ;
if ( ! local_map ) {
DEBUG ( 0 , ( " idmap_init: could not find tdb backend! \n " ) ) ;
return False ;
}
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( local_map - > init ( NULL ) ) ) {
2003-04-19 15:29:39 +00:00
DEBUG ( 0 , ( " idmap_init: could not load or create local backend! \n " ) ) ;
return False ;
}
2003-03-08 17:29:40 +00:00
}
2003-04-02 10:36:02 +00:00
if ( ! remote_map & & remote_backend & & * remote_backend ! = 0 ) {
2003-06-06 13:48:39 +00:00
fstring params = " " ;
char * pparams ;
/* get any mode parameters passed in */
if ( ( pparams = strchr ( remote_backend , ' : ' ) ) ! = NULL ) {
2003-06-09 17:28:42 +00:00
* pparams = ' \0 ' ;
2003-06-06 13:48:39 +00:00
pparams + + ;
fstrcpy ( params , pparams ) ;
}
2003-04-19 15:29:39 +00:00
DEBUG ( 3 , ( " idmap_init: using '%s' as remote backend \n " , remote_backend ) ) ;
2003-03-07 23:47:59 +00:00
2003-05-29 19:08:40 +00:00
if ( ( remote_map = get_methods ( remote_backend ) ) | |
( NT_STATUS_IS_OK ( smb_probe_module ( " idmap " , remote_backend ) ) & &
( remote_map = get_methods ( remote_backend ) ) ) ) {
2003-06-06 13:48:39 +00:00
remote_map - > init ( params ) ;
2003-05-29 19:08:40 +00:00
} else {
2003-04-19 15:29:39 +00:00
DEBUG ( 0 , ( " idmap_init: could not load remote backend '%s' \n " , remote_backend ) ) ;
2003-03-07 23:47:59 +00:00
return False ;
}
2003-05-29 19:08:40 +00:00
2003-03-07 23:47:59 +00:00
}
2003-03-08 17:29:40 +00:00
2003-03-07 23:47:59 +00:00
return True ;
}
2003-04-02 10:36:02 +00:00
NTSTATUS idmap_set_mapping ( const DOM_SID * sid , unid_t id , int id_type )
2003-03-07 23:47:59 +00:00
{
NTSTATUS ret ;
2003-04-30 00:44:45 +00:00
lazy_initialize_idmap ( ) ;
2003-04-02 10:36:02 +00:00
ret = local_map - > set_mapping ( sid , id , id_type ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-03-08 17:29:40 +00:00
DEBUG ( 0 , ( " idmap_set_mapping: Error, unable to modify local cache! \n " ) ) ;
2003-04-16 10:24:24 +00:00
DEBUGADD ( 0 , ( " Error: %s " , nt_errstr ( ret ) ) ) ;
2003-03-08 17:29:40 +00:00
return ret ;
}
/* Being able to update the remote cache is seldomly right.
Generally this is a forbidden operation . */
2003-04-02 10:36:02 +00:00
if ( ! ( id_type & ID_CACHE ) & & ( remote_map ! = NULL ) ) {
remote_map - > set_mapping ( sid , id , id_type ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-03-08 17:29:40 +00:00
DEBUG ( 0 , ( " idmap_set_mapping: Error, unable to modify remote cache! \n " ) ) ;
2003-04-16 10:24:24 +00:00
DEBUGADD ( 0 , ( " Error: %s " , nt_errstr ( ret ) ) ) ;
2003-03-08 17:29:40 +00:00
}
}
return ret ;
}
2003-03-07 23:47:59 +00:00
/* Get ID from SID */
2003-04-02 10:36:02 +00:00
NTSTATUS idmap_get_id_from_sid ( unid_t * id , int * id_type , const DOM_SID * sid )
2003-03-07 23:47:59 +00:00
{
NTSTATUS ret ;
2003-03-08 17:29:40 +00:00
int loc_type ;
2003-03-07 23:47:59 +00:00
2003-04-30 00:44:45 +00:00
lazy_initialize_idmap ( ) ;
2003-03-08 17:29:40 +00:00
loc_type = * id_type ;
2003-04-02 10:36:02 +00:00
if ( remote_map ) { /* We have a central remote idmap */
2003-03-08 17:29:40 +00:00
loc_type | = ID_NOMAP ;
}
2003-04-02 10:36:02 +00:00
ret = local_map - > get_id_from_sid ( id , & loc_type , sid ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-04-02 10:36:02 +00:00
if ( remote_map ) {
ret = remote_map - > get_id_from_sid ( id , id_type , sid ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-03-08 17:29:40 +00:00
DEBUG ( 3 , ( " idmap_get_id_from_sid: error fetching id! \n " ) ) ;
2003-04-02 10:36:02 +00:00
return ret ;
2003-03-08 17:29:40 +00:00
} else {
loc_type | = ID_CACHE ;
idmap_set_mapping ( sid , * id , loc_type ) ;
}
}
} else {
* id_type = loc_type & ID_TYPEMASK ;
2003-03-07 23:47:59 +00:00
}
return ret ;
}
/* Get SID from ID */
2003-03-08 17:29:40 +00:00
NTSTATUS idmap_get_sid_from_id ( DOM_SID * sid , unid_t id , int id_type )
2003-03-07 23:47:59 +00:00
{
NTSTATUS ret ;
2003-03-08 17:29:40 +00:00
int loc_type ;
2003-03-07 23:47:59 +00:00
2003-04-30 00:44:45 +00:00
lazy_initialize_idmap ( ) ;
2003-03-08 17:29:40 +00:00
loc_type = id_type ;
2003-04-02 10:36:02 +00:00
if ( remote_map ) {
2003-03-08 17:29:40 +00:00
loc_type = id_type | ID_NOMAP ;
}
2003-04-02 10:36:02 +00:00
ret = local_map - > get_sid_from_id ( sid , id , loc_type ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-04-02 10:36:02 +00:00
if ( remote_map ) {
ret = remote_map - > get_sid_from_id ( sid , id , id_type ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-03-08 17:29:40 +00:00
DEBUG ( 3 , ( " idmap_get_sid_from_id: unable to fetch sid! \n " ) ) ;
2003-04-02 10:36:02 +00:00
return ret ;
2003-03-08 17:29:40 +00:00
} else {
loc_type | = ID_CACHE ;
idmap_set_mapping ( sid , id , loc_type ) ;
}
}
2003-03-07 23:47:59 +00:00
}
return ret ;
}
/* Close backend */
NTSTATUS idmap_close ( void )
{
NTSTATUS ret ;
2003-04-02 10:36:02 +00:00
ret = local_map - > close ( ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-03-08 17:29:40 +00:00
DEBUG ( 3 , ( " idmap_close: failed to close local cache! \n " ) ) ;
}
2003-04-02 10:36:02 +00:00
if ( remote_map ) {
ret = remote_map - > close ( ) ;
2003-06-22 10:09:52 +00:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
2003-03-08 17:29:40 +00:00
DEBUG ( 3 , ( " idmap_close: failed to close remote idmap repository! \n " ) ) ;
}
2003-03-07 23:47:59 +00:00
}
return ret ;
}
/* Dump backend status */
void idmap_status ( void )
{
2003-04-30 00:44:45 +00:00
lazy_initialize_idmap ( ) ;
2003-04-02 10:36:02 +00:00
local_map - > status ( ) ;
if ( remote_map ) remote_map - > status ( ) ;
2003-03-07 23:47:59 +00:00
}