2013-02-21 23:32:37 +04:00
/*
* Unix SMB / CIFS implementation .
*
* Id mapping using LDAP records as defined in RFC 2307
*
* The SID < - > uid / gid mapping is performed in two steps : 1 ) Query the
* AD server for the name < - > sid mapping . 2 ) Query an LDAP server
* according to RFC 2307 for the name < - > uid / gid mapping .
*
* Copyright ( C ) Christof Schmitt 2012 , 2013
*
* 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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "winbindd.h"
2017-05-11 22:38:50 +03:00
# include "winbindd_ads.h"
2013-02-21 23:32:37 +04:00
# include "idmap.h"
# include "smbldap.h"
# include "nsswitch/winbind_client.h"
# include "lib/winbind_util.h"
2018-12-11 13:03:02 +03:00
# include "libcli/security/dom_sid.h"
2021-01-03 23:53:49 +03:00
# include "lib/global_contexts.h"
2013-02-21 23:32:37 +04:00
/*
* Config and connection info per domain .
*/
struct idmap_rfc2307_context {
const char * bind_path_user ;
const char * bind_path_group ;
const char * ldap_domain ;
bool user_cn ;
const char * realm ;
/*
* Pointer to ldap struct in ads or smbldap_state , has to be
* updated after connecting to server
*/
LDAP * ldap ;
/* Optional function to check connection to server */
NTSTATUS ( * check_connection ) ( struct idmap_domain * dom ) ;
/* Issue ldap query */
NTSTATUS ( * search ) ( struct idmap_rfc2307_context * ctx ,
const char * bind_path , const char * expr ,
const char * * attrs , LDAPMessage * * res ) ;
/* Access to LDAP in AD server */
ADS_STRUCT * ads ;
/* Access to stand-alone LDAP server */
struct smbldap_state * smbldap_state ;
} ;
/*
* backend functions for LDAP queries through ADS
*/
static NTSTATUS idmap_rfc2307_ads_check_connection ( struct idmap_domain * dom )
{
struct idmap_rfc2307_context * ctx ;
const char * dom_name = dom - > name ;
ADS_STATUS status ;
DEBUG ( 10 , ( " ad_idmap_cached_connection: called for domain '%s' \n " ,
dom - > name ) ) ;
ctx = talloc_get_type ( dom - > private_data , struct idmap_rfc2307_context ) ;
dom_name = ctx - > ldap_domain ? ctx - > ldap_domain : dom - > name ;
2022-05-25 14:25:32 +03:00
status = ads_idmap_cached_connection ( dom_name , ctx , & ctx - > ads ) ;
2013-02-21 23:32:37 +04:00
if ( ADS_ERR_OK ( status ) ) {
ctx - > ldap = ctx - > ads - > ldap . ld ;
} else {
DEBUG ( 1 , ( " Could not connect to domain %s: %s \n " , dom - > name ,
ads_errstr ( status ) ) ) ;
}
return ads_ntstatus ( status ) ;
}
static NTSTATUS idmap_rfc2307_ads_search ( struct idmap_rfc2307_context * ctx ,
const char * bind_path ,
const char * expr ,
const char * * attrs ,
LDAPMessage * * result )
{
ADS_STATUS status ;
status = ads_do_search_retry ( ctx - > ads , bind_path ,
LDAP_SCOPE_SUBTREE , expr , attrs , result ) ;
2016-04-27 16:10:45 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
return ads_ntstatus ( status ) ;
}
2014-09-18 00:23:11 +04:00
ctx - > ldap = ctx - > ads - > ldap . ld ;
2013-02-21 23:32:37 +04:00
return ads_ntstatus ( status ) ;
}
static NTSTATUS idmap_rfc2307_init_ads ( struct idmap_rfc2307_context * ctx ,
2017-03-18 20:48:46 +03:00
const char * domain_name )
2013-02-21 23:32:37 +04:00
{
const char * ldap_domain ;
ctx - > search = idmap_rfc2307_ads_search ;
ctx - > check_connection = idmap_rfc2307_ads_check_connection ;
2017-03-18 20:48:46 +03:00
ldap_domain = idmap_config_const_string ( domain_name , " ldap_domain " ,
NULL ) ;
2013-02-21 23:32:37 +04:00
if ( ldap_domain ) {
ctx - > ldap_domain = talloc_strdup ( ctx , ldap_domain ) ;
if ( ctx - > ldap_domain = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
}
return NT_STATUS_OK ;
}
/*
* backend function for LDAP queries through stand - alone LDAP server
*/
static NTSTATUS idmap_rfc2307_ldap_search ( struct idmap_rfc2307_context * ctx ,
const char * bind_path ,
const char * expr ,
const char * * attrs ,
LDAPMessage * * result )
{
int ret ;
ret = smbldap_search ( ctx - > smbldap_state , bind_path , LDAP_SCOPE_SUBTREE ,
expr , attrs , 0 , result ) ;
2017-04-19 14:29:31 +03:00
ctx - > ldap = smbldap_get_ldap ( ctx - > smbldap_state ) ;
2013-02-21 23:32:37 +04:00
if ( ret = = LDAP_SUCCESS ) {
return NT_STATUS_OK ;
}
return NT_STATUS_LDAP ( ret ) ;
}
static bool idmap_rfc2307_get_uint32 ( LDAP * ldap , LDAPMessage * entry ,
2015-04-24 05:04:23 +03:00
const char * field , uint32_t * value )
2013-02-21 23:32:37 +04:00
{
bool b ;
char str [ 20 ] ;
b = smbldap_get_single_attribute ( ldap , entry , field , str , sizeof ( str ) ) ;
if ( b ) {
* value = atoi ( str ) ;
}
return b ;
}
static NTSTATUS idmap_rfc2307_init_ldap ( struct idmap_rfc2307_context * ctx ,
2017-03-18 20:48:46 +03:00
const char * domain_name )
2013-02-21 23:32:37 +04:00
{
NTSTATUS ret ;
char * url ;
char * secret = NULL ;
2015-12-08 21:52:41 +03:00
const char * ldap_url , * user_dn ;
2013-02-21 23:32:37 +04:00
TALLOC_CTX * mem_ctx = ctx ;
2017-03-18 20:48:46 +03:00
ldap_url = idmap_config_const_string ( domain_name , " ldap_url " , NULL ) ;
2013-02-21 23:32:37 +04:00
if ( ! ldap_url ) {
DEBUG ( 1 , ( " ERROR: missing idmap ldap url \n " ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
url = talloc_strdup ( talloc_tos ( ) , ldap_url ) ;
2017-03-18 20:48:46 +03:00
user_dn = idmap_config_const_string ( domain_name , " ldap_user_dn " , NULL ) ;
2013-02-21 23:32:37 +04:00
if ( user_dn ) {
2017-03-18 20:48:46 +03:00
secret = idmap_fetch_secret ( " ldap " , domain_name , user_dn ) ;
2013-02-21 23:32:37 +04:00
if ( ! secret ) {
ret = NT_STATUS_ACCESS_DENIED ;
goto done ;
}
}
/* assume anonymous if we don't have a specified user */
2018-08-21 21:06:16 +03:00
ret = smbldap_init ( mem_ctx , global_event_context ( ) , url ,
2013-02-21 23:32:37 +04:00
( user_dn = = NULL ) , user_dn , secret ,
& ctx - > smbldap_state ) ;
2022-08-05 12:09:37 +03:00
BURN_FREE_STR ( secret ) ;
2013-02-21 23:32:37 +04:00
if ( ! NT_STATUS_IS_OK ( ret ) ) {
DEBUG ( 1 , ( " ERROR: smbldap_init (%s) failed! \n " , url ) ) ;
goto done ;
}
ctx - > search = idmap_rfc2307_ldap_search ;
done :
talloc_free ( url ) ;
return ret ;
}
/*
* common code for stand - alone LDAP and ADS
*/
static void idmap_rfc2307_map_sid_results ( struct idmap_rfc2307_context * ctx ,
TALLOC_CTX * mem_ctx ,
struct id_map * * ids ,
LDAPMessage * result ,
const char * dom_name ,
const char * * attrs , int type )
{
int count , i ;
LDAPMessage * entry ;
count = ldap_count_entries ( ctx - > ldap , result ) ;
for ( i = 0 ; i < count ; i + + ) {
char * name ;
2021-03-06 02:01:13 +03:00
struct dom_sid sid ;
2013-02-21 23:32:37 +04:00
enum lsa_SidType lsa_type ;
struct id_map * map ;
uint32_t id ;
bool b ;
if ( i = = 0 ) {
entry = ldap_first_entry ( ctx - > ldap , result ) ;
} else {
2017-03-31 18:23:39 +03:00
entry = ldap_next_entry ( ctx - > ldap , entry ) ;
2013-02-21 23:32:37 +04:00
}
if ( ! entry ) {
DEBUG ( 2 , ( " Unable to fetch entry. \n " ) ) ;
break ;
}
name = smbldap_talloc_single_attribute ( ctx - > ldap , entry ,
attrs [ 0 ] , mem_ctx ) ;
if ( ! name ) {
DEBUG ( 1 , ( " Could not get user name \n " ) ) ;
continue ;
}
b = idmap_rfc2307_get_uint32 ( ctx - > ldap , entry , attrs [ 1 ] , & id ) ;
if ( ! b ) {
DEBUG ( 1 , ( " Could not pull id for record %s \n " , name ) ) ;
continue ;
}
map = idmap_find_map_by_id ( ids , type , id ) ;
if ( ! map ) {
DEBUG ( 1 , ( " Could not find id %d, name %s \n " , id , name ) ) ;
continue ;
}
2015-12-08 21:52:41 +03:00
if ( ctx - > realm ! = NULL ) {
2013-02-21 23:32:37 +04:00
/* Strip @realm from user or group name */
char * delim ;
delim = strchr ( name , ' @ ' ) ;
if ( delim ) {
* delim = ' \0 ' ;
}
}
/* by default calls to winbindd are disabled
the following call will not recurse so this is safe */
( void ) winbind_on ( ) ;
/* Lookup name from PDC using lsa_lookup_names() */
2021-03-06 02:01:13 +03:00
b = winbind_lookup_name ( dom_name , name , & sid , & lsa_type ) ;
2013-02-21 23:32:37 +04:00
( void ) winbind_off ( ) ;
if ( ! b ) {
DEBUG ( 1 , ( " SID lookup failed for id %d, %s \n " ,
id , name ) ) ;
continue ;
}
if ( type = = ID_TYPE_UID & & lsa_type ! = SID_NAME_USER ) {
DEBUG ( 1 , ( " Wrong type %d for user name %s \n " ,
type , name ) ) ;
continue ;
}
if ( type = = ID_TYPE_GID & & lsa_type ! = SID_NAME_DOM_GRP & &
lsa_type ! = SID_NAME_ALIAS & &
lsa_type ! = SID_NAME_WKN_GRP ) {
DEBUG ( 1 , ( " Wrong type %d for group name %s \n " ,
type , name ) ) ;
continue ;
}
map - > status = ID_MAPPED ;
2021-03-06 02:01:13 +03:00
sid_copy ( map - > sid , & sid ) ;
2013-02-21 23:32:37 +04:00
}
}
/*
* Map unixids to names and then to sids .
*/
static NTSTATUS idmap_rfc2307_unixids_to_sids ( struct idmap_domain * dom ,
struct id_map * * ids )
{
struct idmap_rfc2307_context * ctx ;
char * fltr_usr = NULL , * fltr_grp = NULL ;
TALLOC_CTX * mem_ctx ;
int cnt_usr = 0 , cnt_grp = 0 , idx = 0 , bidx = 0 ;
LDAPMessage * result = NULL ;
NTSTATUS ret ;
ctx = talloc_get_type ( dom - > private_data , struct idmap_rfc2307_context ) ;
mem_ctx = talloc_new ( ctx ) ;
if ( ! mem_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ctx - > check_connection ) {
ret = ctx - > check_connection ( dom ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto out ;
}
}
again :
bidx = idx ;
if ( ! fltr_usr ) {
/* prepare new user query, see getpwuid() in RFC2307 */
fltr_usr = talloc_asprintf ( mem_ctx ,
" (&(objectClass=posixAccount)(| " ) ;
}
if ( ! fltr_grp ) {
/* prepare new group query, see getgrgid() in RFC2307 */
fltr_grp = talloc_asprintf ( mem_ctx ,
" (&(objectClass=posixGroup)(| " ) ;
}
if ( ! fltr_usr | | ! fltr_grp ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
while ( cnt_usr < IDMAP_LDAP_MAX_IDS & &
cnt_grp < IDMAP_LDAP_MAX_IDS & & ids [ idx ] ) {
switch ( ids [ idx ] - > xid . type ) {
case ID_TYPE_UID :
fltr_usr = talloc_asprintf_append_buffer ( fltr_usr ,
" (uidNumber=%d) " , ids [ idx ] - > xid . id ) ;
cnt_usr + + ;
break ;
case ID_TYPE_GID :
fltr_grp = talloc_asprintf_append_buffer ( fltr_grp ,
2015-06-04 22:11:27 +03:00
" (gidNumber=%d) " , ids [ idx ] - > xid . id ) ;
2013-02-21 23:32:37 +04:00
cnt_grp + + ;
break ;
default :
DEBUG ( 3 , ( " Error: unknown ID type %d \n " ,
ids [ idx ] - > xid . type ) ) ;
ret = NT_STATUS_UNSUCCESSFUL ;
goto out ;
}
if ( ! fltr_usr | | ! fltr_grp ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
idx + + ;
}
if ( cnt_usr = = IDMAP_LDAP_MAX_IDS | | ( cnt_usr ! = 0 & & ! ids [ idx ] ) ) {
const char * attrs [ ] = { NULL , /* uid or cn */
" uidNumber " ,
NULL } ;
fltr_usr = talloc_strdup_append ( fltr_usr , " )) " ) ;
if ( ! fltr_usr ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
attrs [ 0 ] = ctx - > user_cn ? " cn " : " uid " ;
ret = ctx - > search ( ctx , ctx - > bind_path_user , fltr_usr , attrs ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto out ;
}
idmap_rfc2307_map_sid_results ( ctx , mem_ctx , & ids [ bidx ] , result ,
dom - > name , attrs , ID_TYPE_UID ) ;
cnt_usr = 0 ;
TALLOC_FREE ( fltr_usr ) ;
}
if ( cnt_grp = = IDMAP_LDAP_MAX_IDS | | ( cnt_grp ! = 0 & & ! ids [ idx ] ) ) {
const char * attrs [ ] = { " cn " , " gidNumber " , NULL } ;
fltr_grp = talloc_strdup_append ( fltr_grp , " )) " ) ;
if ( ! fltr_grp ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
ret = ctx - > search ( ctx , ctx - > bind_path_group , fltr_grp , attrs ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto out ;
}
idmap_rfc2307_map_sid_results ( ctx , mem_ctx , & ids [ bidx ] , result ,
dom - > name , attrs , ID_TYPE_GID ) ;
cnt_grp = 0 ;
TALLOC_FREE ( fltr_grp ) ;
}
if ( ids [ idx ] ) {
goto again ;
}
ret = NT_STATUS_OK ;
out :
talloc_free ( mem_ctx ) ;
return ret ;
}
struct idmap_rfc2307_map {
struct id_map * map ;
const char * name ;
enum id_type type ;
} ;
/*
* Lookup names for SIDS and store the data in the local mapping
* array .
*/
static NTSTATUS idmap_rfc_2307_sids_to_names ( TALLOC_CTX * mem_ctx ,
struct id_map * * ids ,
struct idmap_rfc2307_map * maps ,
struct idmap_rfc2307_context * ctx )
{
int i ;
for ( i = 0 ; ids [ i ] ; i + + ) {
const char * domain , * name ;
enum lsa_SidType lsa_type ;
struct id_map * id = ids [ i ] ;
struct idmap_rfc2307_map * map = & maps [ i ] ;
2018-12-11 13:03:02 +03:00
struct dom_sid_buf buf ;
2013-02-21 23:32:37 +04:00
bool b ;
/* by default calls to winbindd are disabled
the following call will not recurse so this is safe */
( void ) winbind_on ( ) ;
b = winbind_lookup_sid ( mem_ctx , ids [ i ] - > sid , & domain , & name ,
& lsa_type ) ;
( void ) winbind_off ( ) ;
if ( ! b ) {
DEBUG ( 1 , ( " Lookup sid %s failed. \n " ,
2018-12-11 13:03:02 +03:00
dom_sid_str_buf ( ids [ i ] - > sid , & buf ) ) ) ;
2013-02-21 23:32:37 +04:00
continue ;
}
switch ( lsa_type ) {
case SID_NAME_USER :
id - > xid . type = map - > type = ID_TYPE_UID ;
2015-12-08 21:52:41 +03:00
if ( ctx - > user_cn & & ctx - > realm ! = NULL ) {
2013-02-21 23:32:37 +04:00
name = talloc_asprintf ( mem_ctx , " %s@%s " ,
name , ctx - > realm ) ;
}
id - > xid . type = map - > type = ID_TYPE_UID ;
break ;
case SID_NAME_DOM_GRP :
case SID_NAME_ALIAS :
case SID_NAME_WKN_GRP :
2015-12-08 21:52:41 +03:00
if ( ctx - > realm ! = NULL ) {
2013-02-21 23:32:37 +04:00
name = talloc_asprintf ( mem_ctx , " %s@%s " ,
name , ctx - > realm ) ;
}
id - > xid . type = map - > type = ID_TYPE_GID ;
break ;
default :
DEBUG ( 1 , ( " Unknown lsa type %d for sid %s \n " ,
2018-12-11 13:03:02 +03:00
lsa_type ,
dom_sid_str_buf ( id - > sid , & buf ) ) ) ;
2013-02-21 23:32:37 +04:00
id - > status = ID_UNMAPPED ;
continue ;
}
map - > map = id ;
id - > status = ID_UNKNOWN ;
map - > name = strupper_talloc ( mem_ctx , name ) ;
if ( ! map - > name ) {
return NT_STATUS_NO_MEMORY ;
}
}
return NT_STATUS_OK ;
}
/*
* Find id_map entry by looking up the name in the internal
* mapping array .
*/
static struct id_map * idmap_rfc2307_find_map ( struct idmap_rfc2307_map * maps ,
enum id_type type ,
const char * name )
{
int i ;
DEBUG ( 10 , ( " Looking for name %s, type %d \n " , name , type ) ) ;
2017-03-31 18:20:07 +03:00
for ( i = 0 ; maps [ i ] . map ! = NULL ; i + + ) {
2013-02-21 23:32:37 +04:00
DEBUG ( 10 , ( " Entry %d: name %s, type %d \n " ,
i , maps [ i ] . name , maps [ i ] . type ) ) ;
if ( type = = maps [ i ] . type & & strcmp ( name , maps [ i ] . name ) = = 0 ) {
return maps [ i ] . map ;
}
}
return NULL ;
}
static void idmap_rfc2307_map_xid_results ( struct idmap_rfc2307_context * ctx ,
TALLOC_CTX * mem_ctx ,
struct idmap_rfc2307_map * maps ,
LDAPMessage * result ,
struct idmap_domain * dom ,
const char * * attrs , enum id_type type )
{
int count , i ;
LDAPMessage * entry ;
count = ldap_count_entries ( ctx - > ldap , result ) ;
for ( i = 0 ; i < count ; i + + ) {
uint32_t id ;
char * name ;
bool b ;
struct id_map * id_map ;
if ( i = = 0 ) {
entry = ldap_first_entry ( ctx - > ldap , result ) ;
} else {
2017-03-31 18:23:39 +03:00
entry = ldap_next_entry ( ctx - > ldap , entry ) ;
2013-02-21 23:32:37 +04:00
}
if ( ! entry ) {
DEBUG ( 2 , ( " Unable to fetch entry. \n " ) ) ;
break ;
}
name = smbldap_talloc_single_attribute ( ctx - > ldap , entry ,
attrs [ 0 ] , mem_ctx ) ;
if ( ! name ) {
DEBUG ( 1 , ( " Could not get user name \n " ) ) ;
continue ;
}
b = idmap_rfc2307_get_uint32 ( ctx - > ldap , entry , attrs [ 1 ] , & id ) ;
if ( ! b ) {
DEBUG ( 5 , ( " Could not pull id for record %s \n " , name ) ) ;
continue ;
}
if ( ! idmap_unix_id_is_in_range ( id , dom ) ) {
DEBUG ( 5 , ( " Requested id (%u) out of range (%u - %u). \n " ,
id , dom - > low_id , dom - > high_id ) ) ;
continue ;
}
if ( ! strupper_m ( name ) ) {
DEBUG ( 5 , ( " Could not convert %s to uppercase \n " , name ) ) ;
continue ;
}
id_map = idmap_rfc2307_find_map ( maps , type , name ) ;
if ( ! id_map ) {
DEBUG ( 0 , ( " Could not find mapping entry for name %s \n " ,
name ) ) ;
continue ;
}
id_map - > xid . id = id ;
id_map - > status = ID_MAPPED ;
}
}
/*
* Map sids to names and then to unixids .
*/
static NTSTATUS idmap_rfc2307_sids_to_unixids ( struct idmap_domain * dom ,
struct id_map * * ids )
{
struct idmap_rfc2307_context * ctx ;
TALLOC_CTX * mem_ctx ;
struct idmap_rfc2307_map * int_maps ;
2014-09-18 00:28:19 +04:00
int cnt_usr = 0 , cnt_grp = 0 , idx = 0 ;
2013-02-21 23:32:37 +04:00
char * fltr_usr = NULL , * fltr_grp = NULL ;
NTSTATUS ret ;
int i ;
ctx = talloc_get_type ( dom - > private_data , struct idmap_rfc2307_context ) ;
mem_ctx = talloc_new ( talloc_tos ( ) ) ;
if ( ! mem_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
if ( ctx - > check_connection ) {
ret = ctx - > check_connection ( dom ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto out ;
}
}
for ( i = 0 ; ids [ i ] ; i + + ) ;
int_maps = talloc_zero_array ( mem_ctx , struct idmap_rfc2307_map , i ) ;
if ( ! int_maps ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
ret = idmap_rfc_2307_sids_to_names ( mem_ctx , ids , int_maps , ctx ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto out ;
}
again :
if ( ! fltr_usr ) {
/* prepare new user query, see getpwuid() in RFC2307 */
fltr_usr = talloc_asprintf ( mem_ctx ,
" (&(objectClass=posixAccount)(| " ) ;
}
if ( ! fltr_grp ) {
/* prepare new group query, see getgrgid() in RFC2307 */
fltr_grp = talloc_asprintf ( mem_ctx ,
" (&(objectClass=posixGroup)(| " ) ;
}
if ( ! fltr_usr | | ! fltr_grp ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
while ( cnt_usr < IDMAP_LDAP_MAX_IDS & &
cnt_grp < IDMAP_LDAP_MAX_IDS & & ids [ idx ] ) {
struct id_map * id = ids [ idx ] ;
struct idmap_rfc2307_map * map = & int_maps [ idx ] ;
switch ( id - > xid . type ) {
case ID_TYPE_UID :
fltr_usr = talloc_asprintf_append_buffer ( fltr_usr ,
" (%s=%s) " , ( ctx - > user_cn ? " cn " : " uid " ) ,
map - > name ) ;
cnt_usr + + ;
break ;
case ID_TYPE_GID :
fltr_grp = talloc_asprintf_append_buffer ( fltr_grp ,
" (cn=%s) " , map - > name ) ;
cnt_grp + + ;
break ;
default :
2016-06-24 19:31:45 +03:00
break ;
2013-02-21 23:32:37 +04:00
}
if ( ! fltr_usr | | ! fltr_grp ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
idx + + ;
}
if ( cnt_usr = = IDMAP_LDAP_MAX_IDS | | ( cnt_usr ! = 0 & & ! ids [ idx ] ) ) {
const char * attrs [ ] = { NULL , /* uid or cn */
" uidNumber " ,
NULL } ;
LDAPMessage * result ;
fltr_usr = talloc_strdup_append ( fltr_usr , " )) " ) ;
if ( ! fltr_usr ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
attrs [ 0 ] = ctx - > user_cn ? " cn " : " uid " ;
ret = ctx - > search ( ctx , ctx - > bind_path_user , fltr_usr , attrs ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto out ;
}
2014-09-18 00:28:19 +04:00
idmap_rfc2307_map_xid_results ( ctx , mem_ctx , int_maps ,
result , dom , attrs , ID_TYPE_UID ) ;
2013-02-21 23:32:37 +04:00
cnt_usr = 0 ;
TALLOC_FREE ( fltr_usr ) ;
}
if ( cnt_grp = = IDMAP_LDAP_MAX_IDS | | ( cnt_grp ! = 0 & & ! ids [ idx ] ) ) {
const char * attrs [ ] = { " cn " , " gidNumber " , NULL } ;
LDAPMessage * result ;
fltr_grp = talloc_strdup_append ( fltr_grp , " )) " ) ;
if ( ! fltr_grp ) {
ret = NT_STATUS_NO_MEMORY ;
goto out ;
}
ret = ctx - > search ( ctx , ctx - > bind_path_group , fltr_grp , attrs ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( ret ) ) {
goto out ;
}
2014-09-18 00:28:19 +04:00
idmap_rfc2307_map_xid_results ( ctx , mem_ctx , int_maps , result ,
dom , attrs , ID_TYPE_GID ) ;
2013-02-21 23:32:37 +04:00
cnt_grp = 0 ;
TALLOC_FREE ( fltr_grp ) ;
}
if ( ids [ idx ] ) {
goto again ;
}
ret = NT_STATUS_OK ;
out :
talloc_free ( mem_ctx ) ;
return ret ;
}
static int idmap_rfc2307_context_destructor ( struct idmap_rfc2307_context * ctx )
{
2022-05-26 18:28:34 +03:00
TALLOC_FREE ( ctx - > ads ) ;
2013-02-21 23:32:37 +04:00
if ( ctx - > smbldap_state ! = NULL ) {
smbldap_free_struct ( & ctx - > smbldap_state ) ;
}
return 0 ;
}
static NTSTATUS idmap_rfc2307_initialize ( struct idmap_domain * domain )
{
struct idmap_rfc2307_context * ctx ;
2015-12-08 21:52:41 +03:00
const char * bind_path_user , * bind_path_group , * ldap_server , * realm ;
2013-02-21 23:32:37 +04:00
NTSTATUS status ;
ctx = talloc_zero ( domain , struct idmap_rfc2307_context ) ;
if ( ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
talloc_set_destructor ( ctx , idmap_rfc2307_context_destructor ) ;
2017-03-18 20:48:46 +03:00
bind_path_user = idmap_config_const_string (
domain - > name , " bind_path_user " , NULL ) ;
2017-03-21 17:52:37 +03:00
if ( bind_path_user = = NULL ) {
2013-02-21 23:32:37 +04:00
status = NT_STATUS_INVALID_PARAMETER ;
goto err ;
}
2017-03-21 17:52:37 +03:00
ctx - > bind_path_user = talloc_strdup ( ctx , bind_path_user ) ;
if ( ctx - > bind_path_user = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto err ;
}
2013-02-21 23:32:37 +04:00
2017-03-18 20:48:46 +03:00
bind_path_group = idmap_config_const_string (
domain - > name , " bind_path_group " , NULL ) ;
2017-03-21 17:52:37 +03:00
if ( bind_path_group = = NULL ) {
2013-02-21 23:32:37 +04:00
status = NT_STATUS_INVALID_PARAMETER ;
goto err ;
}
2017-03-21 17:52:37 +03:00
ctx - > bind_path_group = talloc_strdup ( ctx , bind_path_group ) ;
if ( ctx - > bind_path_group = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto err ;
}
2013-02-21 23:32:37 +04:00
2017-03-18 20:48:46 +03:00
ldap_server = idmap_config_const_string (
domain - > name , " ldap_server " , NULL ) ;
2013-02-21 23:32:37 +04:00
if ( ! ldap_server ) {
status = NT_STATUS_INVALID_PARAMETER ;
goto err ;
}
if ( strcmp ( ldap_server , " stand-alone " ) = = 0 ) {
2017-03-18 20:48:46 +03:00
status = idmap_rfc2307_init_ldap ( ctx , domain - > name ) ;
2013-02-21 23:32:37 +04:00
} else if ( strcmp ( ldap_server , " ad " ) = = 0 ) {
2017-03-18 20:48:46 +03:00
status = idmap_rfc2307_init_ads ( ctx , domain - > name ) ;
2013-02-21 23:32:37 +04:00
} else {
status = NT_STATUS_INVALID_PARAMETER ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto err ;
}
2017-03-18 20:48:46 +03:00
realm = idmap_config_const_string ( domain - > name , " realm " , NULL ) ;
2015-12-08 21:52:41 +03:00
if ( realm ) {
ctx - > realm = talloc_strdup ( ctx , realm ) ;
if ( ctx - > realm = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto err ;
}
}
2017-03-18 20:57:03 +03:00
ctx - > user_cn = idmap_config_bool ( domain - > name , " user_cn " , false ) ;
2013-02-21 23:32:37 +04:00
domain - > private_data = ctx ;
return NT_STATUS_OK ;
err :
talloc_free ( ctx ) ;
return status ;
}
2019-03-21 14:30:37 +03:00
static const struct idmap_methods rfc2307_methods = {
2013-02-21 23:32:37 +04:00
. init = idmap_rfc2307_initialize ,
. unixids_to_sids = idmap_rfc2307_unixids_to_sids ,
. sids_to_unixids = idmap_rfc2307_sids_to_unixids ,
} ;
2015-08-13 19:16:20 +03:00
static_decl_idmap ;
2017-04-20 22:24:43 +03:00
NTSTATUS idmap_rfc2307_init ( TALLOC_CTX * ctx )
2013-02-21 23:32:37 +04:00
{
return smb_register_idmap ( SMB_IDMAP_INTERFACE_VERSION , " rfc2307 " ,
& rfc2307_methods ) ;
}