2007-09-10 20:56:51 +04:00
/*
2006-12-12 17:52:13 +03:00
Unix SMB / CIFS implementation .
ID Mapping
Copyright ( C ) Tim Potter 2000
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2003
2007-09-10 20:56:51 +04:00
Copyright ( C ) Simo Sorce 2003 - 2007
2006-12-12 17:52:13 +03:00
Copyright ( C ) Jeremy Allison 2006
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/>.
2007-01-22 19:54:02 +03:00
*/
2006-12-12 17:52:13 +03:00
# include "includes.h"
# include "winbindd.h"
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_IDMAP
static_decl_idmap ;
2008-07-17 15:32:28 +04:00
/**
* Pointer to the backend methods . Modules register themselves here via
* smb_register_idmap .
*/
2006-12-12 17:52:13 +03:00
struct idmap_backend {
const char * name ;
struct idmap_methods * methods ;
struct idmap_backend * prev , * next ;
} ;
2008-07-17 15:32:28 +04:00
static struct idmap_backend * backends = NULL ;
2006-12-12 17:52:13 +03:00
2008-07-17 15:32:28 +04:00
/**
* Pointer to the alloc backend methods . Modules register themselves here via
* smb_register_idmap_alloc .
*/
2006-12-12 17:52:13 +03:00
struct idmap_alloc_backend {
const char * name ;
struct idmap_alloc_methods * methods ;
struct idmap_alloc_backend * prev , * next ;
} ;
2008-07-17 15:32:28 +04:00
static struct idmap_alloc_backend * alloc_backends = NULL ;
2006-12-12 17:52:13 +03:00
2008-07-17 15:32:28 +04:00
/**
* The idmap alloc context that is configured via " idmap alloc
* backend " . Defaults to " idmap backend " in case the module (tdb, ldap) also
* provides alloc methods .
*/
2007-04-19 01:10:37 +04:00
struct idmap_alloc_context {
struct idmap_alloc_methods * methods ;
} ;
2008-07-17 15:32:28 +04:00
static struct idmap_alloc_context * idmap_alloc_ctx = NULL ;
2007-04-19 01:10:37 +04:00
2008-07-17 15:32:28 +04:00
/**
* Default idmap domain configured via " idmap backend " .
2008-07-13 14:07:40 +04:00
*/
static struct idmap_domain * default_idmap_domain ;
2008-07-17 15:32:28 +04:00
/**
* Passdb idmap domain , not configurable . winbind must always give passdb a
* chance to map ids .
*/
2008-07-13 14:07:40 +04:00
static struct idmap_domain * passdb_idmap_domain ;
2008-07-17 15:32:28 +04:00
/**
* List of specially configured idmap domains . This list is filled on demand
* in the winbind idmap child when the parent winbind figures out via the
* special range parameter or via the domain SID that a special " idmap config
* domain " configuration is present.
*/
2006-12-12 17:52:13 +03:00
static struct idmap_domain * * idmap_domains = NULL ;
static int num_domains = 0 ;
2008-09-05 01:35:27 +04:00
static struct idmap_methods * get_methods ( const char * name )
2006-12-12 17:52:13 +03:00
{
struct idmap_backend * b ;
2008-09-05 01:35:27 +04:00
for ( b = backends ; b ; b = b - > next ) {
2006-12-12 17:52:13 +03:00
if ( strequal ( b - > name , name ) ) {
return b - > methods ;
}
}
return NULL ;
}
2008-09-05 01:35:27 +04:00
static struct idmap_alloc_methods * get_alloc_methods ( const char * name )
2006-12-12 17:52:13 +03:00
{
struct idmap_alloc_backend * b ;
2008-09-05 01:35:27 +04:00
for ( b = alloc_backends ; b ; b = b - > next ) {
2006-12-12 17:52:13 +03:00
if ( strequal ( b - > name , name ) ) {
return b - > methods ;
}
}
return NULL ;
}
2007-10-19 04:40:25 +04:00
bool idmap_is_offline ( void )
2007-04-19 01:10:37 +04:00
{
return ( lp_winbind_offline_logon ( ) & &
get_global_winbindd_state_offline ( ) ) ;
}
2008-07-13 14:07:40 +04:00
bool idmap_is_online ( void )
{
return ! idmap_is_offline ( ) ;
}
2006-12-12 17:52:13 +03:00
/**********************************************************************
Allow a module to register itself as a method .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-09-10 20:56:51 +04:00
NTSTATUS smb_register_idmap ( int version , const char * name ,
struct idmap_methods * methods )
2006-12-12 17:52:13 +03:00
{
struct idmap_backend * entry ;
if ( ( version ! = SMB_IDMAP_INTERFACE_VERSION ) ) {
DEBUG ( 0 , ( " Failed to register idmap module. \n "
2007-09-10 20:56:51 +04:00
" The module was compiled against "
" SMB_IDMAP_INTERFACE_VERSION %d, \n "
2006-12-12 17:52:13 +03:00
" current SMB_IDMAP_INTERFACE_VERSION is %d. \n "
2007-09-10 20:56:51 +04:00
" Please recompile against the current version "
" of samba! \n " ,
2006-12-12 17:52:13 +03:00
version , SMB_IDMAP_INTERFACE_VERSION ) ) ;
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
}
if ( ! name | | ! name [ 0 ] | | ! methods ) {
DEBUG ( 0 , ( " Called with NULL pointer or empty name! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2008-07-13 14:07:40 +04:00
for ( entry = backends ; entry ! = NULL ; entry = entry - > next ) {
if ( strequal ( entry - > name , name ) ) {
2008-07-17 15:32:28 +04:00
DEBUG ( 0 , ( " Idmap module %s already registered! \n " ,
name ) ) ;
2008-07-13 14:07:40 +04:00
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
entry = talloc ( NULL , struct idmap_backend ) ;
2006-12-12 17:52:13 +03:00
if ( ! entry ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
2008-07-13 05:13:44 +04:00
TALLOC_FREE ( entry ) ;
2006-12-12 17:52:13 +03:00
return NT_STATUS_NO_MEMORY ;
}
2008-07-13 14:07:40 +04:00
entry - > name = talloc_strdup ( entry , name ) ;
2006-12-12 17:52:13 +03:00
if ( ! entry - > name ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
2008-07-13 05:13:44 +04:00
TALLOC_FREE ( entry ) ;
2006-12-12 17:52:13 +03:00
return NT_STATUS_NO_MEMORY ;
}
entry - > methods = methods ;
DLIST_ADD ( backends , entry ) ;
DEBUG ( 5 , ( " Successfully added idmap backend '%s' \n " , name ) ) ;
return NT_STATUS_OK ;
}
/**********************************************************************
2008-07-17 15:32:28 +04:00
Allow a module to register itself as an alloc method .
2006-12-12 17:52:13 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-09-10 20:56:51 +04:00
NTSTATUS smb_register_idmap_alloc ( int version , const char * name ,
struct idmap_alloc_methods * methods )
2006-12-12 17:52:13 +03:00
{
struct idmap_alloc_methods * test ;
struct idmap_alloc_backend * entry ;
if ( ( version ! = SMB_IDMAP_INTERFACE_VERSION ) ) {
DEBUG ( 0 , ( " Failed to register idmap alloc module. \n "
2007-09-10 20:56:51 +04:00
" The module was compiled against "
" SMB_IDMAP_INTERFACE_VERSION %d, \n "
2006-12-12 17:52:13 +03:00
" current SMB_IDMAP_INTERFACE_VERSION is %d. \n "
2007-09-10 20:56:51 +04:00
" Please recompile against the current version "
" of samba! \n " ,
2006-12-12 17:52:13 +03:00
version , SMB_IDMAP_INTERFACE_VERSION ) ) ;
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
}
if ( ! name | | ! name [ 0 ] | | ! methods ) {
DEBUG ( 0 , ( " Called with NULL pointer or empty name! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2008-09-05 01:35:27 +04:00
test = get_alloc_methods ( name ) ;
2006-12-12 17:52:13 +03:00
if ( test ) {
DEBUG ( 0 , ( " idmap_alloc module %s already registered! \n " , name ) ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
2008-07-13 14:07:40 +04:00
entry = talloc ( NULL , struct idmap_alloc_backend ) ;
2006-12-12 17:52:13 +03:00
if ( ! entry ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
2008-07-13 14:07:40 +04:00
entry - > name = talloc_strdup ( entry , name ) ;
2006-12-12 17:52:13 +03:00
if ( ! entry - > name ) {
DEBUG ( 0 , ( " Out of memory! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
entry - > methods = methods ;
DLIST_ADD ( alloc_backends , entry ) ;
DEBUG ( 5 , ( " Successfully added idmap alloc backend '%s' \n " , name ) ) ;
return NT_STATUS_OK ;
}
static int close_domain_destructor ( struct idmap_domain * dom )
{
NTSTATUS ret ;
ret = dom - > methods - > close_fn ( dom ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 3 , ( " Failed to close idmap domain [%s]! \n " , dom - > name ) ) ;
}
return 0 ;
}
2008-07-13 14:07:40 +04:00
static bool parse_idmap_module ( TALLOC_CTX * mem_ctx , const char * param ,
char * * pmodulename , char * * pargs )
2006-12-12 17:52:13 +03:00
{
2008-07-13 14:07:40 +04:00
char * modulename ;
char * args ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( strncmp ( param , " idmap_ " , 6 ) = = 0 ) {
param + = 6 ;
DEBUG ( 1 , ( " idmap_init: idmap backend uses deprecated "
" 'idmap_' prefix. Please replace 'idmap_%s' by "
" '%s' \n " , param , param ) ) ;
}
2007-03-01 06:16:38 +03:00
2008-07-13 14:07:40 +04:00
modulename = talloc_strdup ( mem_ctx , param ) ;
if ( modulename = = NULL ) {
return false ;
}
2007-03-01 06:16:38 +03:00
2008-07-13 14:07:40 +04:00
args = strchr ( modulename , ' : ' ) ;
if ( args = = NULL ) {
* pmodulename = modulename ;
* pargs = NULL ;
return true ;
2007-09-10 20:56:51 +04:00
}
2008-07-13 14:07:40 +04:00
* args = ' \0 ' ;
args = talloc_strdup ( mem_ctx , args + 1 ) ;
if ( args = = NULL ) {
TALLOC_FREE ( modulename ) ;
return false ;
2007-03-01 06:16:38 +03:00
}
2008-07-13 14:07:40 +04:00
* pmodulename = modulename ;
* pargs = args ;
return true ;
2007-03-01 06:16:38 +03:00
}
2008-07-17 15:32:28 +04:00
/**
* Initialize a domain structure
* @ param [ in ] mem_ctx memory context for the result
* @ param [ in ] domainname which domain is this for
* @ param [ in ] modulename which backend module
* @ param [ in ] params parameter to pass to the init function
* @ result The initialized structure
*/
2008-07-13 14:07:40 +04:00
static struct idmap_domain * idmap_init_domain ( TALLOC_CTX * mem_ctx ,
const char * domainname ,
const char * modulename ,
const char * params )
2007-09-10 20:56:51 +04:00
{
2008-07-13 14:07:40 +04:00
struct idmap_domain * result ;
NTSTATUS status ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
result = talloc_zero ( mem_ctx , struct idmap_domain ) ;
if ( result = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
return NULL ;
2007-05-07 01:04:30 +04:00
}
2007-09-10 20:56:51 +04:00
2008-07-13 14:07:40 +04:00
result - > name = talloc_strdup ( result , domainname ) ;
if ( result - > name = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
goto fail ;
2007-05-07 01:04:30 +04:00
}
2006-12-12 17:52:13 +03:00
2008-09-05 01:35:27 +04:00
result - > methods = get_methods ( modulename ) ;
2008-07-13 14:07:40 +04:00
if ( result - > methods = = NULL ) {
DEBUG ( 3 , ( " idmap backend %s not found \n " , modulename ) ) ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
status = smb_probe_module ( " idmap " , modulename ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 3 , ( " Could not probe idmap module %s \n " ,
modulename ) ) ;
goto fail ;
2007-09-10 20:56:51 +04:00
}
2008-09-05 01:35:27 +04:00
result - > methods = get_methods ( modulename ) ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
if ( result - > methods = = NULL ) {
DEBUG ( 1 , ( " idmap backend %s not found \n " , modulename ) ) ;
goto fail ;
2006-12-12 17:52:13 +03:00
}
2007-09-10 20:56:51 +04:00
2008-07-13 14:07:40 +04:00
status = result - > methods - > init ( result , params ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 1 , ( " idmap initialization returned %s \n " ,
nt_errstr ( status ) ) ) ;
goto fail ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
talloc_set_destructor ( result , close_domain_destructor ) ;
2007-04-19 01:10:37 +04:00
2008-07-13 14:07:40 +04:00
return result ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
fail :
TALLOC_FREE ( result ) ;
return NULL ;
}
2006-12-12 17:52:13 +03:00
2008-07-17 15:32:28 +04:00
/**
* Initialize the default domain structure
* @ param [ in ] mem_ctx memory context for the result
* @ result The default domain structure
*
* This routine takes the module name from the " idmap backend " parameter ,
* passing a possible parameter like ldap : ldap : //ldap-url/ to the module.
*/
2008-07-13 14:07:40 +04:00
static struct idmap_domain * idmap_init_default_domain ( TALLOC_CTX * mem_ctx )
{
struct idmap_domain * result ;
char * modulename ;
char * params ;
2007-11-20 22:24:03 +03:00
2008-07-13 14:07:40 +04:00
DEBUG ( 10 , ( " idmap_init_default_domain: calling static_init_idmap \n " ) ) ;
2007-11-20 22:24:03 +03:00
2008-07-13 14:07:40 +04:00
static_init_idmap ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( ! parse_idmap_module ( talloc_tos ( ) , lp_idmap_backend ( ) , & modulename ,
& params ) ) {
DEBUG ( 1 , ( " parse_idmap_module failed \n " ) ) ;
return NULL ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
DEBUG ( 3 , ( " idmap_init: using '%s' as remote backend \n " , modulename ) ) ;
2008-04-02 02:25:47 +04:00
2008-07-13 14:07:40 +04:00
result = idmap_init_domain ( mem_ctx , " * " , modulename , params ) ;
if ( result = = NULL ) {
goto fail ;
}
2008-04-02 02:25:47 +04:00
2008-07-13 14:07:40 +04:00
TALLOC_FREE ( modulename ) ;
TALLOC_FREE ( params ) ;
return result ;
2008-04-02 02:25:47 +04:00
2008-07-13 14:07:40 +04:00
fail :
TALLOC_FREE ( modulename ) ;
TALLOC_FREE ( params ) ;
TALLOC_FREE ( result ) ;
return NULL ;
}
2008-04-02 02:25:47 +04:00
2008-07-17 15:32:28 +04:00
/**
* Initialize a named domain structure
* @ param [ in ] mem_ctx memory context for the result
* @ param [ in ] domname the domain name
* @ result The default domain structure
*
* This routine looks at the " idmap config <domname> " parameters to figure out
* the configuration .
*/
2008-07-13 14:07:40 +04:00
static struct idmap_domain * idmap_init_named_domain ( TALLOC_CTX * mem_ctx ,
const char * domname )
{
struct idmap_domain * result = NULL ;
char * config_option ;
const char * backend ;
2008-04-02 02:25:47 +04:00
2008-07-13 14:07:40 +04:00
config_option = talloc_asprintf ( talloc_tos ( ) , " idmap config %s " ,
domname ) ;
if ( config_option = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
goto fail ;
}
2008-04-02 02:25:47 +04:00
2008-07-13 14:07:40 +04:00
backend = lp_parm_const_string ( - 1 , config_option , " backend " , NULL ) ;
if ( backend = = NULL ) {
DEBUG ( 1 , ( " no backend defined for %s \n " , config_option ) ) ;
goto fail ;
2008-04-02 02:25:47 +04:00
}
2008-07-13 14:07:40 +04:00
result = idmap_init_domain ( mem_ctx , domname , backend , NULL ) ;
if ( result = = NULL ) {
goto fail ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
TALLOC_FREE ( config_option ) ;
return result ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
fail :
TALLOC_FREE ( config_option ) ;
TALLOC_FREE ( result ) ;
return NULL ;
}
2006-12-12 17:52:13 +03:00
2008-07-17 15:32:28 +04:00
/**
* Initialize the passdb domain structure
* @ param [ in ] mem_ctx memory context for the result
* @ result The default domain structure
*
* No config , passdb has its own configuration .
*/
2008-07-13 14:07:40 +04:00
static struct idmap_domain * idmap_init_passdb_domain ( TALLOC_CTX * mem_ctx )
{
if ( passdb_idmap_domain ! = NULL ) {
return passdb_idmap_domain ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
passdb_idmap_domain = idmap_init_domain ( NULL , get_global_sam_name ( ) ,
" passdb " , NULL ) ;
if ( passdb_idmap_domain = = NULL ) {
DEBUG ( 1 , ( " Could not init passdb idmap domain \n " ) ) ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
return passdb_idmap_domain ;
}
2006-12-12 17:52:13 +03:00
2008-07-17 15:32:28 +04:00
/**
* Find a domain struct according to a domain name
* @ param [ in ] domname Domain name to get the config for
* @ result The default domain structure that fits
*
* This is the central routine in the winbindd - idmap child to pick the correct
* domain for looking up IDs . If domname is NULL or empty , we use the default
* domain . If it contains something , we try to use idmap_init_named_domain ( )
* to fetch the correct backend .
*
* The choice about " domname " is being made by the winbind parent , look at the
* " have_idmap_config " of " struct winbindd_domain " which is set in
* add_trusted_domain .
*/
2008-07-13 14:07:40 +04:00
static struct idmap_domain * idmap_find_domain ( const char * domname )
{
struct idmap_domain * result ;
int i ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
/*
* Always init the default domain , we can ' t go without one
*/
if ( default_idmap_domain = = NULL ) {
default_idmap_domain = idmap_init_default_domain ( NULL ) ;
}
if ( default_idmap_domain = = NULL ) {
return NULL ;
}
2007-04-19 01:10:37 +04:00
2008-07-13 14:07:40 +04:00
if ( ( domname = = NULL ) | | ( domname [ 0 ] = = ' \0 ' ) ) {
return default_idmap_domain ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
for ( i = 0 ; i < num_domains ; i + + ) {
if ( strequal ( idmap_domains [ i ] - > name , domname ) ) {
return idmap_domains [ i ] ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( idmap_domains = = NULL ) {
/*
* talloc context for all idmap domains
*/
idmap_domains = TALLOC_ARRAY ( NULL , struct idmap_domain * , 1 ) ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( idmap_domains = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
return NULL ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
result = idmap_init_named_domain ( idmap_domains , domname ) ;
if ( result = = NULL ) {
/*
* Could not init that domain - - try the default one
*/
return default_idmap_domain ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
ADD_TO_ARRAY ( idmap_domains , struct idmap_domain * , result ,
& idmap_domains , & num_domains ) ;
return result ;
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
void idmap_close ( void )
{
if ( idmap_alloc_ctx ) {
idmap_alloc_ctx - > methods - > close_fn ( ) ;
idmap_alloc_ctx - > methods = NULL ;
}
alloc_backends = NULL ;
TALLOC_FREE ( default_idmap_domain ) ;
TALLOC_FREE ( passdb_idmap_domain ) ;
TALLOC_FREE ( idmap_domains ) ;
num_domains = 0 ;
}
2006-12-12 17:52:13 +03:00
2008-07-17 15:32:28 +04:00
/**
* Initialize the idmap alloc backend
* @ param [ out ] ctx Where to put the alloc_ctx ?
* @ result Did it work fine ?
*
* This routine first looks at " idmap alloc backend " and if that is not
* defined , it uses " idmap backend " for the module name .
*/
2008-07-13 14:07:40 +04:00
static NTSTATUS idmap_alloc_init ( struct idmap_alloc_context * * ctx )
{
const char * backend ;
char * modulename , * params ;
NTSTATUS ret = NT_STATUS_NO_MEMORY ; ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( idmap_alloc_ctx ! = NULL ) {
* ctx = idmap_alloc_ctx ;
return NT_STATUS_OK ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
idmap_alloc_ctx = talloc ( NULL , struct idmap_alloc_context ) ;
if ( idmap_alloc_ctx = = NULL ) {
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
goto fail ;
2007-04-19 01:10:37 +04:00
}
2008-07-13 14:07:40 +04:00
backend = lp_idmap_alloc_backend ( ) ;
if ( ( backend = = NULL ) | | ( backend [ 0 ] = = ' \0 ' ) ) {
backend = lp_idmap_backend ( ) ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
if ( backend = = NULL ) {
DEBUG ( 3 , ( " no idmap alloc backend defined \n " ) ) ;
ret = NT_STATUS_INVALID_PARAMETER ;
goto fail ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
if ( ! parse_idmap_module ( idmap_alloc_ctx , backend , & modulename ,
& params ) ) {
DEBUG ( 1 , ( " parse_idmap_module %s failed \n " , backend ) ) ;
goto fail ;
2006-12-12 17:52:13 +03:00
}
2008-09-05 01:35:27 +04:00
idmap_alloc_ctx - > methods = get_alloc_methods ( modulename ) ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( idmap_alloc_ctx - > methods = = NULL ) {
ret = smb_probe_module ( " idmap " , modulename ) ;
if ( NT_STATUS_IS_OK ( ret ) ) {
idmap_alloc_ctx - > methods =
2008-09-05 01:35:27 +04:00
get_alloc_methods ( modulename ) ;
2006-12-12 17:52:13 +03:00
}
}
2007-04-11 02:59:42 +04:00
2008-07-13 14:07:40 +04:00
if ( idmap_alloc_ctx - > methods = = NULL ) {
DEBUG ( 1 , ( " could not find idmap alloc module %s \n " , backend ) ) ;
ret = NT_STATUS_INVALID_PARAMETER ;
goto fail ;
2007-04-11 02:59:42 +04:00
}
2007-09-10 20:56:51 +04:00
2008-07-13 14:07:40 +04:00
ret = idmap_alloc_ctx - > methods - > init ( params ) ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 0 , ( " ERROR: Initialization failed for alloc "
" backend, deferred! \n " ) ) ;
goto fail ;
2007-04-19 01:10:37 +04:00
}
2008-07-13 14:07:40 +04:00
TALLOC_FREE ( modulename ) ;
TALLOC_FREE ( params ) ;
2007-04-19 01:10:37 +04:00
2008-07-13 14:07:40 +04:00
* ctx = idmap_alloc_ctx ;
2007-04-19 01:10:37 +04:00
return NT_STATUS_OK ;
2008-07-13 14:07:40 +04:00
fail :
TALLOC_FREE ( idmap_alloc_ctx ) ;
return ret ;
2007-04-19 01:10:37 +04:00
}
2006-12-12 17:52:13 +03:00
/**************************************************************************
idmap allocator interface functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS idmap_allocate_uid ( struct unixid * id )
{
2008-07-13 14:07:40 +04:00
struct idmap_alloc_context * ctx ;
2006-12-12 17:52:13 +03:00
NTSTATUS ret ;
2008-07-13 14:07:40 +04:00
if ( ! NT_STATUS_IS_OK ( ret = idmap_alloc_init ( & ctx ) ) ) {
2006-12-12 17:52:13 +03:00
return ret ;
}
id - > type = ID_TYPE_UID ;
2008-07-13 14:07:40 +04:00
return ctx - > methods - > allocate_id ( id ) ;
2006-12-12 17:52:13 +03:00
}
NTSTATUS idmap_allocate_gid ( struct unixid * id )
{
2008-07-13 14:07:40 +04:00
struct idmap_alloc_context * ctx ;
2006-12-12 17:52:13 +03:00
NTSTATUS ret ;
2008-07-13 14:07:40 +04:00
if ( ! NT_STATUS_IS_OK ( ret = idmap_alloc_init ( & ctx ) ) ) {
2006-12-12 17:52:13 +03:00
return ret ;
}
id - > type = ID_TYPE_GID ;
2008-07-13 14:07:40 +04:00
return ctx - > methods - > allocate_id ( id ) ;
2006-12-12 17:52:13 +03:00
}
NTSTATUS idmap_set_uid_hwm ( struct unixid * id )
{
2008-07-13 14:07:40 +04:00
struct idmap_alloc_context * ctx ;
2006-12-12 17:52:13 +03:00
NTSTATUS ret ;
2008-07-13 14:07:40 +04:00
if ( ! NT_STATUS_IS_OK ( ret = idmap_alloc_init ( & ctx ) ) ) {
2006-12-12 17:52:13 +03:00
return ret ;
}
id - > type = ID_TYPE_UID ;
2008-07-13 14:07:40 +04:00
return ctx - > methods - > set_id_hwm ( id ) ;
2006-12-12 17:52:13 +03:00
}
NTSTATUS idmap_set_gid_hwm ( struct unixid * id )
{
2008-07-13 14:07:40 +04:00
struct idmap_alloc_context * ctx ;
2006-12-12 17:52:13 +03:00
NTSTATUS ret ;
2008-07-13 14:07:40 +04:00
if ( ! NT_STATUS_IS_OK ( ret = idmap_alloc_init ( & ctx ) ) ) {
2006-12-12 17:52:13 +03:00
return ret ;
}
id - > type = ID_TYPE_GID ;
2008-07-13 14:07:40 +04:00
return ctx - > methods - > set_id_hwm ( id ) ;
2007-01-22 19:54:02 +03:00
}
2008-07-13 14:07:40 +04:00
NTSTATUS idmap_new_mapping ( const struct dom_sid * psid , enum id_type type ,
struct unixid * pxid )
2006-12-12 17:52:13 +03:00
{
2008-07-13 14:07:40 +04:00
struct dom_sid sid ;
2006-12-12 17:52:13 +03:00
struct idmap_domain * dom ;
2008-07-13 14:07:40 +04:00
struct id_map map ;
NTSTATUS status ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
dom = idmap_find_domain ( NULL ) ;
if ( dom = = NULL ) {
DEBUG ( 3 , ( " no default domain, no place to write \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
if ( dom - > methods - > set_mapping = = NULL ) {
DEBUG ( 3 , ( " default domain not writable \n " ) ) ;
return NT_STATUS_MEDIA_WRITE_PROTECTED ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
sid_copy ( & sid , psid ) ;
map . sid = & sid ;
map . xid . type = type ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
switch ( type ) {
2007-04-20 02:26:09 +04:00
case ID_TYPE_UID :
2008-07-13 14:07:40 +04:00
status = idmap_allocate_uid ( & map . xid ) ;
2007-04-20 02:26:09 +04:00
break ;
case ID_TYPE_GID :
2008-07-13 14:07:40 +04:00
status = idmap_allocate_gid ( & map . xid ) ;
2007-04-20 02:26:09 +04:00
break ;
default :
2008-07-13 14:07:40 +04:00
status = NT_STATUS_INVALID_PARAMETER ;
break ;
2007-04-20 02:26:09 +04:00
}
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 3 , ( " Could not allocate id: %s \n " , nt_errstr ( status ) ) ) ;
return status ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
map . status = ID_MAPPED ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
DEBUG ( 10 , ( " Setting mapping: %s <-> %s %lu \n " ,
sid_string_dbg ( map . sid ) ,
( map . xid . type = = ID_TYPE_UID ) ? " UID " : " GID " ,
( unsigned long ) map . xid . id ) ) ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
status = dom - > methods - > set_mapping ( dom , & map ) ;
2006-12-12 17:52:13 +03:00
2008-08-07 04:03:22 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_OBJECT_NAME_COLLISION ) ) {
struct id_map * ids [ 2 ] ;
DEBUG ( 5 , ( " Mapping for %s exists - retrying to map sid \n " ,
sid_string_dbg ( map . sid ) ) ) ;
ids [ 0 ] = & map ;
ids [ 1 ] = NULL ;
status = dom - > methods - > sids_to_unixids ( dom , ids ) ;
}
2008-07-13 14:07:40 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 3 , ( " Could not store the new mapping: %s \n " ,
nt_errstr ( status ) ) ) ;
return status ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
* pxid = map . xid ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
return NT_STATUS_OK ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
NTSTATUS idmap_backends_unixid_to_sid ( const char * domname , struct id_map * id )
2008-07-14 14:32:18 +04:00
{
2008-07-13 14:07:40 +04:00
struct idmap_domain * dom ;
2008-07-14 14:32:18 +04:00
struct id_map * maps [ 2 ] ;
maps [ 0 ] = id ;
maps [ 1 ] = NULL ;
2008-07-13 14:07:40 +04:00
/*
* Always give passdb a chance first
*/
2008-07-14 14:32:18 +04:00
2008-07-13 14:07:40 +04:00
dom = idmap_init_passdb_domain ( NULL ) ;
if ( ( dom ! = NULL )
& & NT_STATUS_IS_OK ( dom - > methods - > unixids_to_sids ( dom , maps ) ) ) {
return NT_STATUS_OK ;
}
2008-07-14 14:32:18 +04:00
2008-07-13 14:07:40 +04:00
dom = idmap_find_domain ( domname ) ;
if ( dom = = NULL ) {
return NT_STATUS_NONE_MAPPED ;
2008-07-14 14:32:18 +04:00
}
2008-07-13 14:07:40 +04:00
return dom - > methods - > unixids_to_sids ( dom , maps ) ;
2008-07-14 14:32:18 +04:00
}
2008-07-13 14:07:40 +04:00
NTSTATUS idmap_backends_sid_to_unixid ( const char * domain , struct id_map * id )
2008-07-14 14:32:18 +04:00
{
struct idmap_domain * dom ;
struct id_map * maps [ 2 ] ;
maps [ 0 ] = id ;
maps [ 1 ] = NULL ;
2008-07-13 14:07:40 +04:00
if ( sid_check_is_in_builtin ( id - > sid )
| | ( sid_check_is_in_our_domain ( id - > sid ) ) ) {
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
dom = idmap_init_passdb_domain ( NULL ) ;
if ( dom = = NULL ) {
return NT_STATUS_NONE_MAPPED ;
}
return dom - > methods - > sids_to_unixids ( dom , maps ) ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
dom = idmap_find_domain ( domain ) ;
if ( dom = = NULL ) {
return NT_STATUS_NONE_MAPPED ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
return dom - > methods - > sids_to_unixids ( dom , maps ) ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
NTSTATUS idmap_set_mapping ( const struct id_map * map )
2006-12-12 17:52:13 +03:00
{
2008-07-13 14:07:40 +04:00
struct idmap_domain * dom ;
2006-12-12 17:52:13 +03:00
2008-07-13 14:07:40 +04:00
dom = idmap_find_domain ( NULL ) ;
if ( dom = = NULL ) {
DEBUG ( 3 , ( " no default domain, no place to write \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
if ( dom - > methods - > set_mapping = = NULL ) {
DEBUG ( 3 , ( " default domain not writable \n " ) ) ;
return NT_STATUS_MEDIA_WRITE_PROTECTED ;
2006-12-12 17:52:13 +03:00
}
2008-07-13 14:07:40 +04:00
return dom - > methods - > set_mapping ( dom , map ) ;
2006-12-12 17:52:13 +03:00
}
2008-10-28 09:37:55 +03:00
NTSTATUS idmap_remove_mapping ( const struct id_map * map )
{
struct idmap_domain * dom ;
dom = idmap_find_domain ( NULL ) ;
if ( dom = = NULL ) {
DEBUG ( 3 , ( " no default domain, no place to write \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
if ( dom - > methods - > remove_mapping = = NULL ) {
DEBUG ( 3 , ( " default domain not writable \n " ) ) ;
return NT_STATUS_MEDIA_WRITE_PROTECTED ;
}
return dom - > methods - > remove_mapping ( dom , map ) ;
}