2008-12-01 02:56:50 +03:00
/*
2006-05-18 20:08:28 +04:00
Unix SMB / CIFS implementation .
2007-01-24 04:48:08 +03:00
Idmap NSS headers
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
Copyright ( C ) Gerald Carter 2006
2008-12-01 04:01:44 +03:00
Copyright ( C ) Michael Adam 2008
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
This library is free software ; you can redistribute it and / or
2007-07-10 08:04:46 +04:00
modify it under the terms of the GNU Lesser General Public
2007-01-24 04:48:08 +03:00
License as published by the Free Software Foundation ; either
2007-07-10 06:31:50 +04:00
version 3 of the License , or ( at your option ) any later version .
2008-12-01 02:56:50 +03:00
2007-01-24 04:48:08 +03:00
This library is distributed in the hope that it will be useful ,
2006-05-18 20:08:28 +04:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2007-01-24 04:48:08 +03:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Library General Public License for more details .
2008-12-01 02:56:50 +03:00
2007-07-10 08:04:46 +04:00
You should have received a copy of the GNU Lesser General Public License
2007-07-10 06:31:50 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2007-01-24 04:48:08 +03:00
*/
2006-05-18 20:08:28 +04:00
# include "includes.h"
2007-01-24 04:48:08 +03:00
# include "nss_info.h"
static struct nss_function_entry * backends = NULL ;
2008-12-01 04:01:44 +03:00
static struct nss_function_entry * default_backend = NULL ;
2007-01-24 04:48:08 +03:00
static struct nss_domain_entry * nss_domain_list = NULL ;
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
/**********************************************************************
Get idmap nss methods .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct nss_function_entry * nss_get_backend ( const char * name )
2006-05-18 20:08:28 +04:00
{
2007-01-24 04:48:08 +03:00
struct nss_function_entry * entry = backends ;
for ( entry = backends ; entry ; entry = entry - > next ) {
if ( strequal ( entry - > name , name ) )
return entry ;
}
return NULL ;
}
/*********************************************************************
Allow a module to register itself as a backend .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-03-21 14:30:37 +03:00
NTSTATUS smb_register_idmap_nss ( int version , const char * name ,
const struct nss_info_methods * methods )
2007-01-24 04:48:08 +03:00
{
struct nss_function_entry * entry ;
2008-12-01 02:56:50 +03:00
if ( ( version ! = SMB_NSS_INFO_INTERFACE_VERSION ) ) {
2007-01-24 04:48:08 +03:00
DEBUG ( 0 , ( " smb_register_idmap_nss: Failed to register idmap_nss module. \n "
2008-12-01 02:56:50 +03:00
" The module was compiled against SMB_NSS_INFO_INTERFACE_VERSION %d, \n "
" current SMB_NSS_INFO_INTERFACE_VERSION is %d. \n "
" Please recompile against the current version of samba! \n " ,
2007-01-24 04:48:08 +03:00
version , SMB_NSS_INFO_INTERFACE_VERSION ) ) ;
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
2008-12-01 02:56:50 +03:00
}
2007-01-24 04:48:08 +03:00
if ( ! name | | ! name [ 0 ] | | ! methods ) {
DEBUG ( 0 , ( " smb_register_idmap_nss: called with NULL pointer or empty name! \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
if ( nss_get_backend ( name ) ) {
2012-07-23 16:34:11 +04:00
DEBUG ( 5 , ( " smb_register_idmap_nss: idmap module %s "
2007-01-24 04:48:08 +03:00
" already registered! \n " , name ) ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
}
entry = SMB_XMALLOC_P ( struct nss_function_entry ) ;
entry - > name = smb_xstrdup ( name ) ;
entry - > methods = methods ;
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
DLIST_ADD ( backends , entry ) ;
DEBUG ( 5 , ( " smb_register_idmap_nss: Successfully added idmap "
" nss backend '%s' \n " , name ) ) ;
return NT_STATUS_OK ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-08-09 17:38:49 +03:00
static bool parse_nss_parm ( TALLOC_CTX * mem_ctx ,
const char * config ,
char * * backend ,
char * * domain )
2007-01-24 04:48:08 +03:00
{
char * p ;
* backend = * domain = NULL ;
2008-12-01 02:56:50 +03:00
2007-01-24 04:48:08 +03:00
if ( ! config )
return False ;
2008-12-01 02:56:50 +03:00
2007-01-24 04:48:08 +03:00
p = strchr ( config , ' : ' ) ;
2008-12-01 02:56:50 +03:00
2007-01-24 04:48:08 +03:00
/* if no : then the string must be the backend name only */
if ( ! p ) {
2018-08-09 17:38:49 +03:00
* backend = talloc_strdup ( mem_ctx , config ) ;
2007-01-24 04:48:08 +03:00
return ( * backend ! = NULL ) ;
2006-05-18 20:08:28 +04:00
}
2007-01-24 04:48:08 +03:00
/* split the string and return the two parts */
if ( strlen ( p + 1 ) > 0 ) {
2018-08-09 17:38:49 +03:00
* domain = talloc_strdup ( mem_ctx , p + 1 ) ;
2006-05-18 20:08:28 +04:00
}
2008-12-01 02:56:50 +03:00
2018-08-09 17:38:49 +03:00
* backend = talloc_strndup ( mem_ctx , config , PTR_DIFF ( p , config ) ) ;
2011-02-26 13:53:21 +03:00
return ( * backend ! = NULL ) ;
2007-01-24 04:48:08 +03:00
}
2006-05-18 20:08:28 +04:00
2008-12-01 06:22:02 +03:00
static NTSTATUS nss_domain_list_add_domain ( const char * domain ,
struct nss_function_entry * nss_backend )
2008-12-01 04:01:44 +03:00
{
struct nss_domain_entry * nss_domain ;
2011-06-07 05:44:43 +04:00
nss_domain = talloc_zero ( nss_domain_list , struct nss_domain_entry ) ;
2008-12-01 04:01:44 +03:00
if ( ! nss_domain ) {
DEBUG ( 0 , ( " nss_domain_list_add_domain: talloc() failure! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
nss_domain - > backend = nss_backend ;
if ( domain ) {
nss_domain - > domain = talloc_strdup ( nss_domain , domain ) ;
if ( ! nss_domain - > domain ) {
DEBUG ( 0 , ( " nss_domain_list_add_domain: talloc() "
" failure! \n " ) ) ;
TALLOC_FREE ( nss_domain ) ;
return NT_STATUS_NO_MEMORY ;
}
}
nss_domain - > init_status = nss_domain - > backend - > methods - > init ( nss_domain ) ;
if ( ! NT_STATUS_IS_OK ( nss_domain - > init_status ) ) {
DEBUG ( 0 , ( " nss_init: Failed to init backend '%s' for domain "
" '%s'! \n " , nss_backend - > name , nss_domain - > domain ) ) ;
}
DLIST_ADD ( nss_domain_list , nss_domain ) ;
DEBUG ( 10 , ( " Added domain '%s' with backend '%s' to nss_domain_list. \n " ,
domain , nss_backend - > name ) ) ;
return NT_STATUS_OK ;
}
2007-01-24 04:48:08 +03:00
/********************************************************************
2008-12-01 02:56:50 +03:00
Each nss backend must not store global state , but rather be able
2007-01-24 04:48:08 +03:00
to initialize the state on a per domain basis .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-10-06 00:09:01 +04:00
static NTSTATUS nss_init ( const char * * nss_list )
2007-01-24 04:48:08 +03:00
{
NTSTATUS status ;
2009-10-06 00:09:01 +04:00
static bool nss_initialized = false ;
2007-01-24 04:48:08 +03:00
int i ;
2018-08-09 17:38:49 +03:00
char * backend = NULL , * domain = NULL ;
2007-01-24 04:48:08 +03:00
struct nss_function_entry * nss_backend ;
2018-08-09 17:38:49 +03:00
TALLOC_CTX * frame ;
2006-05-18 20:08:28 +04:00
2007-03-01 06:16:38 +03:00
/* check for previous successful initializations */
2009-10-06 00:09:01 +04:00
if ( nss_initialized ) {
2007-03-01 06:16:38 +03:00
return NT_STATUS_OK ;
2009-10-06 00:09:01 +04:00
}
2008-12-01 02:56:50 +03:00
2018-08-09 17:38:49 +03:00
frame = talloc_stackframe ( ) ;
2009-10-06 00:00:16 +04:00
/* The "template" backend should always be registered as it
2007-01-24 04:48:08 +03:00
is a static module */
2006-05-18 20:08:28 +04:00
2009-10-06 00:09:01 +04:00
nss_backend = nss_get_backend ( " template " ) ;
if ( nss_backend = = NULL ) {
2017-04-20 22:24:43 +03:00
static_init_nss_info ( NULL ) ;
2007-01-24 04:48:08 +03:00
}
/* Create the list of nss_domains (loading any shared plugins
as necessary ) */
for ( i = 0 ; nss_list & & nss_list [ i ] ; i + + ) {
2018-08-09 17:38:49 +03:00
bool ok ;
2007-01-24 04:48:08 +03:00
2018-08-09 17:38:49 +03:00
ok = parse_nss_parm ( frame , nss_list [ i ] , & backend , & domain ) ;
if ( ! ok ) {
2007-01-24 04:48:08 +03:00
DEBUG ( 0 , ( " nss_init: failed to parse \" %s \" ! \n " ,
2007-07-31 09:11:40 +04:00
nss_list [ i ] ) ) ;
2008-12-01 02:56:50 +03:00
continue ;
2006-05-18 20:08:28 +04:00
}
2008-12-01 00:54:42 +03:00
DEBUG ( 10 , ( " parsed backend = '%s', domain = '%s' \n " ,
backend , domain ) ) ;
2007-01-24 04:48:08 +03:00
/* validate the backend */
2011-02-27 21:09:28 +03:00
nss_backend = nss_get_backend ( backend ) ;
if ( nss_backend = = NULL ) {
/*
* This is a freaking hack . We don ' t have proper
* modules for nss_info backends . Right now we have
* our standard nss_info backends in the ad backend .
*/
status = smb_probe_module ( " idmap " , " ad " ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
continue ;
}
}
2009-10-06 00:09:01 +04:00
nss_backend = nss_get_backend ( backend ) ;
if ( nss_backend = = NULL ) {
2007-01-24 04:48:08 +03:00
/* attempt to register the backend */
status = smb_probe_module ( " nss_info " , backend ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
continue ;
}
2009-10-06 00:09:01 +04:00
}
2008-12-01 02:56:50 +03:00
2009-10-06 00:09:01 +04:00
/* try again */
nss_backend = nss_get_backend ( backend ) ;
if ( nss_backend = = NULL ) {
DEBUG ( 0 , ( " nss_init: unregistered backend %s!. "
" Skipping \n " , backend ) ) ;
continue ;
2006-05-18 20:08:28 +04:00
}
2007-01-24 04:48:08 +03:00
2008-12-01 04:01:44 +03:00
/*
* The first config item of the list without an explicit domain
* is treated as the default nss info backend .
*/
if ( ( domain = = NULL ) & & ( default_backend = = NULL ) ) {
DEBUG ( 10 , ( " nss_init: using '%s' as default backend. \n " ,
backend ) ) ;
default_backend = nss_backend ;
2007-01-24 04:48:08 +03:00
}
2008-12-01 02:56:50 +03:00
2008-12-01 04:01:44 +03:00
status = nss_domain_list_add_domain ( domain , nss_backend ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2007-01-24 04:48:08 +03:00
}
/* cleanup */
2018-08-09 17:38:49 +03:00
TALLOC_FREE ( domain ) ;
TALLOC_FREE ( backend ) ;
2006-05-18 20:08:28 +04:00
}
2018-08-09 17:38:49 +03:00
2007-01-24 04:48:08 +03:00
if ( ! nss_domain_list ) {
DEBUG ( 3 , ( " nss_init: no nss backends configured. "
" Defaulting to \" template \" . \n " ) ) ;
2009-10-06 00:00:16 +04:00
/* we should default to use template here */
2007-01-24 04:48:08 +03:00
}
2008-12-01 02:56:50 +03:00
2009-10-06 00:09:01 +04:00
nss_initialized = true ;
2008-12-01 02:56:50 +03:00
2018-08-09 17:38:49 +03:00
TALLOC_FREE ( frame ) ;
2007-01-24 04:48:08 +03:00
return NT_STATUS_OK ;
2006-05-18 20:08:28 +04:00
}
2007-01-24 04:48:08 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-03-01 06:16:38 +03:00
static struct nss_domain_entry * find_nss_domain ( const char * domain )
2006-05-18 20:08:28 +04:00
{
2008-12-01 02:56:50 +03:00
NTSTATUS status ;
2007-01-24 04:48:08 +03:00
struct nss_domain_entry * p ;
2007-03-01 06:16:38 +03:00
status = nss_init ( lp_winbind_nss_info ( ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-10-03 18:36:11 +04:00
DEBUG ( 4 , ( " find_nss_domain: Failed to init nss_info API "
" (%s)! \n " , nt_errstr ( status ) ) ) ;
2007-03-01 06:16:38 +03:00
return NULL ;
}
2008-12-01 02:56:50 +03:00
2007-01-24 04:48:08 +03:00
for ( p = nss_domain_list ; p ; p = p - > next ) {
if ( strequal ( p - > domain , domain ) )
2006-05-18 20:08:28 +04:00
break ;
}
2008-12-01 02:56:50 +03:00
2008-12-01 04:01:44 +03:00
/* If we didn't find a match, then use the default nss backend */
2007-01-24 04:48:08 +03:00
if ( ! p ) {
2008-12-01 04:01:44 +03:00
if ( ! default_backend ) {
return NULL ;
}
status = nss_domain_list_add_domain ( domain , default_backend ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-03-01 06:16:38 +03:00
return NULL ;
2007-01-24 04:48:08 +03:00
}
2008-12-01 02:56:50 +03:00
2008-12-01 04:01:44 +03:00
/*
* HACK ALERT :
* Here , we use the fact that the new domain was added at
* the beginning of the list . . .
*/
2008-12-01 02:56:50 +03:00
p = nss_domain_list ;
2007-01-24 04:48:08 +03:00
}
2007-05-07 01:31:19 +04:00
if ( ! NT_STATUS_IS_OK ( p - > init_status ) ) {
p - > init_status = p - > backend - > methods - > init ( p ) ;
}
2007-03-01 06:16:38 +03:00
return p ;
}
2008-09-16 00:41:37 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS nss_map_to_alias ( TALLOC_CTX * mem_ctx , const char * domain ,
const char * name , char * * alias )
{
struct nss_domain_entry * p ;
2019-03-21 14:30:37 +03:00
const struct nss_info_methods * m ;
2008-09-16 00:41:37 +04:00
if ( ( p = find_nss_domain ( domain ) ) = = NULL ) {
DEBUG ( 4 , ( " nss_map_to_alias: Failed to find nss domain pointer for %s \n " ,
domain ) ) ;
return NT_STATUS_NOT_FOUND ;
}
m = p - > backend - > methods ;
2008-12-01 06:17:55 +03:00
return m - > map_to_alias ( mem_ctx , p , name , alias ) ;
2008-09-16 00:41:37 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS nss_map_from_alias ( TALLOC_CTX * mem_ctx , const char * domain ,
const char * alias , char * * name )
{
struct nss_domain_entry * p ;
2019-03-21 14:30:37 +03:00
const struct nss_info_methods * m ;
2008-09-16 00:41:37 +04:00
if ( ( p = find_nss_domain ( domain ) ) = = NULL ) {
DEBUG ( 4 , ( " nss_map_from_alias: Failed to find nss domain pointer for %s \n " ,
domain ) ) ;
return NT_STATUS_NOT_FOUND ;
}
m = p - > backend - > methods ;
2008-12-01 06:17:55 +03:00
return m - > map_from_alias ( mem_ctx , p , alias , name ) ;
2008-09-16 00:41:37 +04:00
}
2007-01-24 04:48:08 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-24 07:44:27 +03:00
NTSTATUS nss_close ( const char * parameters )
2007-01-24 04:48:08 +03:00
{
struct nss_domain_entry * p = nss_domain_list ;
struct nss_domain_entry * q ;
while ( p & & p - > backend & & p - > backend - > methods ) {
/* close the backend */
p - > backend - > methods - > close_fn ( ) ;
/* free the memory */
q = p ;
p = p - > next ;
TALLOC_FREE ( q ) ;
}
return NT_STATUS_OK ;
}