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
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 .
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 .
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 ;
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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-24 07:44:27 +03:00
NTSTATUS smb_register_idmap_nss ( int version , const char * name , struct nss_info_methods * methods )
2007-01-24 04:48:08 +03:00
{
struct nss_function_entry * entry ;
if ( ( version ! = SMB_NSS_INFO_INTERFACE_VERSION ) ) {
DEBUG ( 0 , ( " smb_register_idmap_nss: Failed to register idmap_nss module. \n "
" 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 " ,
version , SMB_NSS_INFO_INTERFACE_VERSION ) ) ;
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
}
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 ) ) {
DEBUG ( 0 , ( " smb_register_idmap_nss: idmap module %s "
" 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 ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_nss_parm ( const char * config , char * * backend , char * * domain )
{
char * p ;
char * q ;
int len ;
* backend = * domain = NULL ;
if ( ! config )
return False ;
p = strchr ( config , ' : ' ) ;
/* if no : then the string must be the backend name only */
if ( ! p ) {
* backend = SMB_STRDUP ( config ) ;
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 ) {
* domain = SMB_STRDUP ( p + 1 ) ;
2006-05-18 20:08:28 +04:00
}
2007-01-24 04:48:08 +03:00
len = PTR_DIFF ( p , config ) + 1 ;
if ( ( q = SMB_MALLOC_ARRAY ( char , len ) ) = = NULL ) {
SAFE_FREE ( * backend ) ;
return False ;
}
StrnCpy ( q , config , len - 1 ) ;
q [ len - 1 ] = ' \0 ' ;
* backend = q ;
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
return True ;
}
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
/********************************************************************
Each nss backend must not store global state , but rather be able
to initialize the state on a per domain basis .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-24 07:44:27 +03:00
NTSTATUS nss_init ( const char * * nss_list )
2007-01-24 04:48:08 +03:00
{
NTSTATUS status ;
2007-03-01 06:16:38 +03:00
static NTSTATUS nss_initialized = NT_STATUS_UNSUCCESSFUL ;
2007-01-24 04:48:08 +03:00
int i ;
char * backend , * domain ;
struct nss_function_entry * nss_backend ;
struct nss_domain_entry * nss_domain ;
2006-05-18 20:08:28 +04:00
2007-03-01 06:16:38 +03:00
/* check for previous successful initializations */
if ( NT_STATUS_IS_OK ( nss_initialized ) )
return NT_STATUS_OK ;
2007-01-24 04:48:08 +03:00
/* The "template" backend should alqays be registered as it
is a static module */
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
if ( ( nss_backend = nss_get_backend ( " template " ) ) = = NULL ) {
static_init_nss_info ;
}
/* Create the list of nss_domains (loading any shared plugins
as necessary ) */
for ( i = 0 ; nss_list & & nss_list [ i ] ; i + + ) {
if ( ! parse_nss_parm ( nss_list [ i ] , & backend , & domain ) ) {
DEBUG ( 0 , ( " nss_init: failed to parse \" %s \" ! \n " ,
2007-07-31 09:11:40 +04:00
nss_list [ i ] ) ) ;
2007-01-24 04:48:08 +03:00
continue ;
2006-05-18 20:08:28 +04:00
}
2007-01-24 04:48:08 +03:00
/* validate the backend */
if ( ( nss_backend = nss_get_backend ( backend ) ) = = NULL ) {
/* attempt to register the backend */
status = smb_probe_module ( " nss_info " , backend ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
continue ;
}
2006-05-18 20:08:28 +04:00
2007-01-24 04:48:08 +03:00
/* try again */
if ( ( nss_backend = nss_get_backend ( backend ) ) = = NULL ) {
DEBUG ( 0 , ( " nss_init: unregistered backend %s!. Skipping \n " ,
backend ) ) ;
2006-05-18 20:08:28 +04:00
continue ;
}
}
2007-01-24 04:48:08 +03:00
/* fill in the nss_domain_entry and add it to the
list of domains */
nss_domain = TALLOC_ZERO_P ( nss_domain_list , struct nss_domain_entry ) ;
if ( ! nss_domain ) {
DEBUG ( 0 , ( " nss_init: talloc() failure! \n " ) ) ;
return NT_STATUS_NO_MEMORY ;
}
nss_domain - > backend = nss_backend ;
nss_domain - > domain = talloc_strdup ( nss_domain , domain ) ;
2007-05-07 01:31:19 +04:00
/* Try to init and ave the result */
nss_domain - > init_status = nss_domain - > backend - > methods - > init ( nss_domain ) ;
2007-01-24 04:48:08 +03:00
DLIST_ADD ( nss_domain_list , nss_domain ) ;
2007-05-07 01:31:19 +04:00
if ( ! NT_STATUS_IS_OK ( nss_domain - > init_status ) ) {
2007-01-24 04:48:08 +03:00
DEBUG ( 0 , ( " nss_init: Failed to init backend for %s domain! \n " ,
nss_domain - > domain ) ) ;
}
/* cleanup */
SAFE_FREE ( backend ) ;
SAFE_FREE ( domain ) ;
2006-05-18 20:08:28 +04: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 " ) ) ;
/* we shouild default to use template here */
}
2007-03-01 06:16:38 +03:00
nss_initialized = NT_STATUS_OK ;
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
{
2007-03-01 06:16:38 +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 ) ) {
DEBUG ( 4 , ( " nss_get_info: Failed to init nss_info API (%s)! \n " ,
nt_errstr ( status ) ) ) ;
return NULL ;
}
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 ;
}
2007-01-24 04:48:08 +03:00
/* If we didn't find a match, then use the default nss info */
if ( ! p ) {
if ( ! nss_domain_list ) {
2007-03-01 06:16:38 +03:00
return NULL ;
2007-01-24 04:48:08 +03:00
}
p = nss_domain_list ;
}
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 ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS nss_get_info ( const char * domain , const DOM_SID * user_sid ,
TALLOC_CTX * ctx ,
ADS_STRUCT * ads , LDAPMessage * msg ,
char * * homedir , char * * shell , char * * gecos ,
gid_t * p_gid )
{
struct nss_domain_entry * p ;
struct nss_info_methods * m ;
if ( ( p = find_nss_domain ( domain ) ) = = NULL ) {
DEBUG ( 4 , ( " nss_get_info: Failed to find nss domain pointer for %s \n " ,
domain ) ) ;
return NT_STATUS_NOT_FOUND ;
}
2007-01-24 04:48:08 +03:00
m = p - > backend - > methods ;
return m - > get_nss_info ( p , user_sid , ctx , ads , msg ,
homedir , shell , gecos , p_gid ) ;
2006-05-18 20:08:28 +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 ;
}