1 /* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/init.c,v 1.58.2.10 2008/07/09 23:48:40 quanah Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2008 The OpenLDAP Foundation.
5 * Portions Copyright 2001-2003 Pierangelo Masarati.
6 * Portions Copyright 1999-2003 Howard Chu.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
22 #include <ac/string.h>
23 #include <ac/socket.h>
27 #include "../back-ldap/back-ldap.h"
28 #include "back-meta.h"
34 /* FIXME: need to remove the pagedResults, and likely more... */
35 bi
->bi_controls
= slap_known_controls
;
46 /* this is not (yet) set essentially because back-meta does not
47 * directly support extended operations... */
48 #ifdef LDAP_DYNAMIC_OBJECTS
49 /* this is set because all the support a proxy has to provide
50 * is the capability to forward the refresh exop, and to
51 * pass thru entries that contain the dynamicObject class
52 * and the entryTtl attribute */
54 #endif /* LDAP_DYNAMIC_OBJECTS */
58 bi
->bi_open
= meta_back_open
;
63 bi
->bi_db_init
= meta_back_db_init
;
64 bi
->bi_db_config
= meta_back_db_config
;
65 bi
->bi_db_open
= meta_back_db_open
;
67 bi
->bi_db_destroy
= meta_back_db_destroy
;
69 bi
->bi_op_bind
= meta_back_bind
;
71 bi
->bi_op_search
= meta_back_search
;
72 bi
->bi_op_compare
= meta_back_compare
;
73 bi
->bi_op_modify
= meta_back_modify
;
74 bi
->bi_op_modrdn
= meta_back_modrdn
;
75 bi
->bi_op_add
= meta_back_add
;
76 bi
->bi_op_delete
= meta_back_delete
;
77 bi
->bi_op_abandon
= 0;
81 bi
->bi_chk_referrals
= 0;
83 bi
->bi_connection_init
= 0;
84 bi
->bi_connection_destroy
= meta_back_conn_destroy
;
98 bi
= backend_info( "ldap" );
99 if ( !bi
|| !bi
->bi_extra
) {
100 Debug( LDAP_DEBUG_ANY
,
101 "meta_back_db_init: needs back-ldap\n",
106 mi
= ch_calloc( 1, sizeof( metainfo_t
) );
111 /* set default flags */
113 META_BACK_F_DEFER_ROOTDN_BIND
;
116 * At present the default is no default target;
119 mi
->mi_defaulttarget
= META_DEFAULT_TARGET_NONE
;
120 mi
->mi_bind_timeout
.tv_sec
= 0;
121 mi
->mi_bind_timeout
.tv_usec
= META_BIND_TIMEOUT
;
123 mi
->mi_rebind_f
= meta_back_default_rebind
;
124 mi
->mi_urllist_f
= meta_back_default_urllist
;
126 ldap_pvt_thread_mutex_init( &mi
->mi_conninfo
.lai_mutex
);
127 ldap_pvt_thread_mutex_init( &mi
->mi_cache
.mutex
);
130 mi
->mi_nretries
= META_RETRY_DEFAULT
;
131 mi
->mi_version
= LDAP_VERSION3
;
133 for ( i
= LDAP_BACK_PCONN_FIRST
; i
< LDAP_BACK_PCONN_LAST
; i
++ ) {
134 mi
->mi_conn_priv
[ i
].mic_num
= 0;
135 LDAP_TAILQ_INIT( &mi
->mi_conn_priv
[ i
].mic_priv
);
137 mi
->mi_conn_priv_max
= LDAP_BACK_CONN_PRIV_DEFAULT
;
139 mi
->mi_ldap_extra
= (ldap_extra_t
*)bi
->bi_extra
;
151 metainfo_t
*mi
= (metainfo_t
*)be
->be_private
;
155 not_always_anon_proxyauthz
= 0,
156 not_always_anon_non_prescriptive
= 0,
159 if ( mi
->mi_ntargets
== 0 ) {
160 Debug( LDAP_DEBUG_ANY
,
161 "meta_back_db_open: no targets defined\n",
166 for ( i
= 0; i
< mi
->mi_ntargets
; i
++ ) {
167 slap_bindconf sb
= { BER_BVNULL
};
168 metatarget_t
*mt
= mi
->mi_targets
[ i
];
170 ber_str2bv( mt
->mt_uri
, 0, 0, &sb
.sb_uri
);
171 sb
.sb_version
= mt
->mt_version
;
172 sb
.sb_method
= LDAP_AUTH_SIMPLE
;
173 BER_BVSTR( &sb
.sb_binddn
, "" );
175 if ( META_BACK_TGT_T_F_DISCOVER( mt
) ) {
176 rc
= slap_discover_feature( &sb
,
177 slap_schema
.si_ad_supportedFeatures
->ad_cname
.bv_val
,
178 LDAP_FEATURE_ABSOLUTE_FILTERS
);
179 if ( rc
== LDAP_COMPARE_TRUE
) {
180 mt
->mt_flags
|= LDAP_BACK_F_T_F
;
184 if ( META_BACK_TGT_CANCEL_DISCOVER( mt
) ) {
185 rc
= slap_discover_feature( &sb
,
186 slap_schema
.si_ad_supportedExtension
->ad_cname
.bv_val
,
188 if ( rc
== LDAP_COMPARE_TRUE
) {
189 mt
->mt_flags
|= LDAP_BACK_F_CANCEL_EXOP
;
193 if ( not_always
== 0 ) {
194 if ( !( mt
->mt_idassert_flags
& LDAP_BACK_AUTH_OVERRIDE
)
195 || mt
->mt_idassert_authz
!= NULL
)
201 if ( ( mt
->mt_idassert_flags
& LDAP_BACK_AUTH_AUTHZ_ALL
)
202 && !( mt
->mt_idassert_flags
& LDAP_BACK_AUTH_PRESCRIPTIVE
) )
204 Debug( LDAP_DEBUG_ANY
, "meta_back_db_open(%s): "
205 "target #%d inconsistent idassert configuration "
206 "(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
207 be
->be_suffix
[ 0 ].bv_val
, i
, 0 );
211 if ( not_always_anon_proxyauthz
== 0 ) {
212 if ( !( mt
->mt_idassert_flags
& LDAP_BACK_AUTH_AUTHZ_ALL
) )
214 not_always_anon_proxyauthz
= 1;
218 if ( not_always_anon_non_prescriptive
== 0 ) {
219 if ( ( mt
->mt_idassert_flags
& LDAP_BACK_AUTH_PRESCRIPTIVE
) )
221 not_always_anon_non_prescriptive
= 1;
226 if ( not_always
== 0 ) {
227 mi
->mi_flags
|= META_BACK_F_PROXYAUTHZ_ALWAYS
;
230 if ( not_always_anon_proxyauthz
== 0 ) {
231 mi
->mi_flags
|= META_BACK_F_PROXYAUTHZ_ANON
;
233 } else if ( not_always_anon_non_prescriptive
== 0 ) {
234 mi
->mi_flags
|= META_BACK_F_PROXYAUTHZ_NOANON
;
241 * meta_back_conn_free()
243 * actually frees a connection; the reference count must be 0,
244 * and it must not (or no longer) be in the cache.
250 metaconn_t
*mc
= v_mc
;
253 assert( mc
!= NULL
);
254 assert( mc
->mc_refcnt
== 0 );
256 /* at least one must be present... */
257 ntargets
= mc
->mc_info
->mi_ntargets
;
258 assert( ntargets
> 0 );
260 for ( ; ntargets
--; ) {
261 (void)meta_clear_one_candidate( NULL
, mc
, ntargets
);
264 if ( !BER_BVISNULL( &mc
->mc_local_ndn
) ) {
265 free( mc
->mc_local_ndn
.bv_val
);
275 struct ldapmapping
*mapping
= v_mapping
;
276 ch_free( mapping
->src
.bv_val
);
277 ch_free( mapping
->dst
.bv_val
);
285 struct ldapmapping
*mapping
= v_mapping
;
287 if ( BER_BVISEMPTY( &mapping
->dst
) ) {
288 mapping_free( &mapping
[ -1 ] );
298 ldap_pvt_thread_mutex_destroy( &mt
->mt_uri_mutex
);
300 if ( mt
->mt_subtree_exclude
) {
301 ber_bvarray_free( mt
->mt_subtree_exclude
);
303 if ( !BER_BVISNULL( &mt
->mt_psuffix
) ) {
304 free( mt
->mt_psuffix
.bv_val
);
306 if ( !BER_BVISNULL( &mt
->mt_nsuffix
) ) {
307 free( mt
->mt_nsuffix
.bv_val
);
309 if ( !BER_BVISNULL( &mt
->mt_binddn
) ) {
310 free( mt
->mt_binddn
.bv_val
);
312 if ( !BER_BVISNULL( &mt
->mt_bindpw
) ) {
313 free( mt
->mt_bindpw
.bv_val
);
315 if ( !BER_BVISNULL( &mt
->mt_idassert_authcID
) ) {
316 ch_free( mt
->mt_idassert_authcID
.bv_val
);
318 if ( !BER_BVISNULL( &mt
->mt_idassert_authcDN
) ) {
319 ch_free( mt
->mt_idassert_authcDN
.bv_val
);
321 if ( !BER_BVISNULL( &mt
->mt_idassert_passwd
) ) {
322 ch_free( mt
->mt_idassert_passwd
.bv_val
);
324 if ( !BER_BVISNULL( &mt
->mt_idassert_authzID
) ) {
325 ch_free( mt
->mt_idassert_authzID
.bv_val
);
327 if ( !BER_BVISNULL( &mt
->mt_idassert_sasl_mech
) ) {
328 ch_free( mt
->mt_idassert_sasl_mech
.bv_val
);
330 if ( !BER_BVISNULL( &mt
->mt_idassert_sasl_realm
) ) {
331 ch_free( mt
->mt_idassert_sasl_realm
.bv_val
);
333 if ( mt
->mt_idassert_authz
!= NULL
) {
334 ber_bvarray_free( mt
->mt_idassert_authz
);
336 if ( mt
->mt_rwmap
.rwm_rw
) {
337 rewrite_info_delete( &mt
->mt_rwmap
.rwm_rw
);
339 avl_free( mt
->mt_rwmap
.rwm_oc
.remap
, mapping_dst_free
);
340 avl_free( mt
->mt_rwmap
.rwm_oc
.map
, mapping_free
);
341 avl_free( mt
->mt_rwmap
.rwm_at
.remap
, mapping_dst_free
);
342 avl_free( mt
->mt_rwmap
.rwm_at
.map
, mapping_free
);
348 meta_back_db_destroy(
354 if ( be
->be_private
) {
357 mi
= ( metainfo_t
* )be
->be_private
;
360 * Destroy the connection tree
362 ldap_pvt_thread_mutex_lock( &mi
->mi_conninfo
.lai_mutex
);
364 if ( mi
->mi_conninfo
.lai_tree
) {
365 avl_free( mi
->mi_conninfo
.lai_tree
, meta_back_conn_free
);
367 for ( i
= LDAP_BACK_PCONN_FIRST
; i
< LDAP_BACK_PCONN_LAST
; i
++ ) {
368 while ( !LDAP_TAILQ_EMPTY( &mi
->mi_conn_priv
[ i
].mic_priv
) ) {
369 metaconn_t
*mc
= LDAP_TAILQ_FIRST( &mi
->mi_conn_priv
[ i
].mic_priv
);
371 LDAP_TAILQ_REMOVE( &mi
->mi_conn_priv
[ i
].mic_priv
, mc
, mc_q
);
372 meta_back_conn_free( mc
);
377 * Destroy the per-target stuff (assuming there's at
380 if ( mi
->mi_targets
!= NULL
) {
381 for ( i
= 0; i
< mi
->mi_ntargets
; i
++ ) {
382 metatarget_t
*mt
= mi
->mi_targets
[ i
];
384 if ( META_BACK_TGT_QUARANTINE( mt
) ) {
385 if ( mt
->mt_quarantine
.ri_num
!= mi
->mi_quarantine
.ri_num
)
387 mi
->mi_ldap_extra
->retry_info_destroy( &mt
->mt_quarantine
);
390 ldap_pvt_thread_mutex_destroy( &mt
->mt_quarantine_mutex
);
396 free( mi
->mi_targets
);
399 ldap_pvt_thread_mutex_lock( &mi
->mi_cache
.mutex
);
400 if ( mi
->mi_cache
.tree
) {
401 avl_free( mi
->mi_cache
.tree
, meta_dncache_free
);
404 ldap_pvt_thread_mutex_unlock( &mi
->mi_cache
.mutex
);
405 ldap_pvt_thread_mutex_destroy( &mi
->mi_cache
.mutex
);
407 ldap_pvt_thread_mutex_unlock( &mi
->mi_conninfo
.lai_mutex
);
408 ldap_pvt_thread_mutex_destroy( &mi
->mi_conninfo
.lai_mutex
);
410 if ( mi
->mi_candidates
!= NULL
) {
411 ber_memfree_x( mi
->mi_candidates
, NULL
);
414 if ( META_BACK_QUARANTINE( mi
) ) {
415 mi
->mi_ldap_extra
->retry_info_destroy( &mi
->mi_quarantine
);
419 free( be
->be_private
);
423 #if SLAPD_META == SLAPD_MOD_DYNAMIC
425 /* conditionally define the init_module() function */
426 SLAP_BACKEND_INIT_MODULE( meta
)
428 #endif /* SLAPD_META == SLAPD_MOD_DYNAMIC */