1 /* init.c - initialize ldap backend */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/init.c,v 1.99.2.8 2008/07/09 23:36:23 quanah Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2008 The OpenLDAP Foundation.
6 * Portions Copyright 1999-2003 Howard Chu.
7 * Portions Copyright 2000-2003 Pierangelo Masarati.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
19 * This work was initially developed by the Howard Chu for inclusion
20 * in OpenLDAP Software and subsequently enhanced by Pierangelo
28 #include <ac/string.h>
29 #include <ac/socket.h>
33 #include "back-ldap.h"
35 static const ldap_extra_t ldap_extra
= {
36 ldap_back_proxy_authz_ctrl
,
37 ldap_back_controls_free
,
38 slap_idassert_authzfrom_parse_cf
,
39 slap_idassert_parse_cf
,
40 slap_retry_info_destroy
,
41 slap_retry_info_parse
,
42 slap_retry_info_unparse
46 ldap_back_open( BackendInfo
*bi
)
48 bi
->bi_controls
= slap_known_controls
;
53 ldap_back_initialize( BackendInfo
*bi
)
58 #ifdef LDAP_DYNAMIC_OBJECTS
59 /* this is set because all the support a proxy has to provide
60 * is the capability to forward the refresh exop, and to
61 * pass thru entries that contain the dynamicObject class
62 * and the entryTtl attribute */
64 #endif /* LDAP_DYNAMIC_OBJECTS */
67 bi
->bi_open
= ldap_back_open
;
72 bi
->bi_db_init
= ldap_back_db_init
;
73 bi
->bi_db_config
= config_generic_wrapper
;
74 bi
->bi_db_open
= ldap_back_db_open
;
75 bi
->bi_db_close
= ldap_back_db_close
;
76 bi
->bi_db_destroy
= ldap_back_db_destroy
;
78 bi
->bi_op_bind
= ldap_back_bind
;
80 bi
->bi_op_search
= ldap_back_search
;
81 bi
->bi_op_compare
= ldap_back_compare
;
82 bi
->bi_op_modify
= ldap_back_modify
;
83 bi
->bi_op_modrdn
= ldap_back_modrdn
;
84 bi
->bi_op_add
= ldap_back_add
;
85 bi
->bi_op_delete
= ldap_back_delete
;
86 bi
->bi_op_abandon
= 0;
88 bi
->bi_extended
= ldap_back_extended
;
90 bi
->bi_chk_referrals
= 0;
91 bi
->bi_entry_get_rw
= ldap_back_entry_get
;
93 bi
->bi_connection_init
= 0;
94 bi
->bi_connection_destroy
= ldap_back_conn_destroy
;
96 bi
->bi_extra
= (void *)&ldap_extra
;
98 rc
= chain_initialize();
104 rc
= distproc_initialize();
110 return ldap_back_init_cf( bi
);
114 ldap_back_db_init( Backend
*be
, ConfigReply
*cr
)
120 li
= (ldapinfo_t
*)ch_calloc( 1, sizeof( ldapinfo_t
) );
125 li
->li_rebind_f
= ldap_back_default_rebind
;
126 li
->li_urllist_f
= ldap_back_default_urllist
;
127 li
->li_urllist_p
= li
;
128 ldap_pvt_thread_mutex_init( &li
->li_uri_mutex
);
130 BER_BVZERO( &li
->li_acl_authcID
);
131 BER_BVZERO( &li
->li_acl_authcDN
);
132 BER_BVZERO( &li
->li_acl_passwd
);
134 li
->li_acl_authmethod
= LDAP_AUTH_NONE
;
135 BER_BVZERO( &li
->li_acl_sasl_mech
);
136 li
->li_acl
.sb_tls
= SB_TLS_DEFAULT
;
138 li
->li_idassert_mode
= LDAP_BACK_IDASSERT_LEGACY
;
140 BER_BVZERO( &li
->li_idassert_authcID
);
141 BER_BVZERO( &li
->li_idassert_authcDN
);
142 BER_BVZERO( &li
->li_idassert_passwd
);
144 BER_BVZERO( &li
->li_idassert_authzID
);
146 li
->li_idassert_authmethod
= LDAP_AUTH_NONE
;
147 BER_BVZERO( &li
->li_idassert_sasl_mech
);
148 li
->li_idassert_tls
= SB_TLS_DEFAULT
;
150 /* by default, use proxyAuthz control on each operation */
151 li
->li_idassert_flags
= LDAP_BACK_AUTH_PRESCRIPTIVE
;
153 li
->li_idassert_authz
= NULL
;
155 /* initialize flags */
156 li
->li_flags
= LDAP_BACK_F_CHASE_REFERRALS
;
158 /* initialize version */
159 li
->li_version
= LDAP_VERSION3
;
161 ldap_pvt_thread_mutex_init( &li
->li_conninfo
.lai_mutex
);
163 for ( i
= LDAP_BACK_PCONN_FIRST
; i
< LDAP_BACK_PCONN_LAST
; i
++ ) {
164 li
->li_conn_priv
[ i
].lic_num
= 0;
165 LDAP_TAILQ_INIT( &li
->li_conn_priv
[ i
].lic_priv
);
167 li
->li_conn_priv_max
= LDAP_BACK_CONN_PRIV_DEFAULT
;
170 SLAP_DBFLAGS( be
) |= SLAP_DBFLAG_NOLASTMOD
;
172 be
->be_cf_ocs
= be
->bd_info
->bi_cf_ocs
;
174 rc
= ldap_back_monitor_db_init( be
);
184 ldap_back_db_open( BackendDB
*be
, ConfigReply
*cr
)
186 ldapinfo_t
*li
= (ldapinfo_t
*)be
->be_private
;
188 slap_bindconf sb
= { BER_BVNULL
};
191 Debug( LDAP_DEBUG_TRACE
,
192 "ldap_back_db_open: URI=%s\n",
193 li
->li_uri
!= NULL
? li
->li_uri
: "", 0, 0 );
195 /* by default, use proxyAuthz control on each operation */
196 switch ( li
->li_idassert_mode
) {
197 case LDAP_BACK_IDASSERT_LEGACY
:
198 case LDAP_BACK_IDASSERT_SELF
:
199 /* however, since admin connections are pooled and shared,
200 * only static authzIDs can be native */
201 li
->li_idassert_flags
&= ~LDAP_BACK_AUTH_NATIVE_AUTHZ
;
208 ber_str2bv( li
->li_uri
, 0, 0, &sb
.sb_uri
);
209 sb
.sb_version
= li
->li_version
;
210 sb
.sb_method
= LDAP_AUTH_SIMPLE
;
211 BER_BVSTR( &sb
.sb_binddn
, "" );
213 if ( LDAP_BACK_T_F_DISCOVER( li
) && !LDAP_BACK_T_F( li
) ) {
214 rc
= slap_discover_feature( &sb
,
215 slap_schema
.si_ad_supportedFeatures
->ad_cname
.bv_val
,
216 LDAP_FEATURE_ABSOLUTE_FILTERS
);
217 if ( rc
== LDAP_COMPARE_TRUE
) {
218 li
->li_flags
|= LDAP_BACK_F_T_F
;
222 if ( LDAP_BACK_CANCEL_DISCOVER( li
) && !LDAP_BACK_CANCEL( li
) ) {
223 rc
= slap_discover_feature( &sb
,
224 slap_schema
.si_ad_supportedExtension
->ad_cname
.bv_val
,
226 if ( rc
== LDAP_COMPARE_TRUE
) {
227 li
->li_flags
|= LDAP_BACK_F_CANCEL_EXOP
;
232 rc
= ldap_back_monitor_db_open( be
);
241 li
->li_flags
|= LDAP_BACK_F_ISOPEN
;
248 ldap_back_conn_free( void *v_lc
)
250 ldapconn_t
*lc
= v_lc
;
252 if ( lc
->lc_ld
!= NULL
) {
253 ldap_unbind_ext( lc
->lc_ld
, NULL
, NULL
);
255 if ( !BER_BVISNULL( &lc
->lc_bound_ndn
) ) {
256 ch_free( lc
->lc_bound_ndn
.bv_val
);
258 if ( !BER_BVISNULL( &lc
->lc_cred
) ) {
259 memset( lc
->lc_cred
.bv_val
, 0, lc
->lc_cred
.bv_len
);
260 ch_free( lc
->lc_cred
.bv_val
);
262 if ( !BER_BVISNULL( &lc
->lc_local_ndn
) ) {
263 ch_free( lc
->lc_local_ndn
.bv_val
);
265 lc
->lc_q
.tqe_prev
= NULL
;
266 lc
->lc_q
.tqe_next
= NULL
;
271 ldap_back_db_close( Backend
*be
, ConfigReply
*cr
)
275 if ( be
->be_private
) {
276 rc
= ldap_back_monitor_db_close( be
);
283 ldap_back_db_destroy( Backend
*be
, ConfigReply
*cr
)
285 if ( be
->be_private
) {
286 ldapinfo_t
*li
= ( ldapinfo_t
* )be
->be_private
;
289 (void)ldap_back_monitor_db_destroy( be
);
291 ldap_pvt_thread_mutex_lock( &li
->li_conninfo
.lai_mutex
);
293 if ( li
->li_uri
!= NULL
) {
294 ch_free( li
->li_uri
);
297 assert( li
->li_bvuri
!= NULL
);
298 ber_bvarray_free( li
->li_bvuri
);
301 if ( !BER_BVISNULL( &li
->li_acl_authcID
) ) {
302 ch_free( li
->li_acl_authcID
.bv_val
);
303 BER_BVZERO( &li
->li_acl_authcID
);
305 if ( !BER_BVISNULL( &li
->li_acl_authcDN
) ) {
306 ch_free( li
->li_acl_authcDN
.bv_val
);
307 BER_BVZERO( &li
->li_acl_authcDN
);
309 if ( !BER_BVISNULL( &li
->li_acl_passwd
) ) {
310 ch_free( li
->li_acl_passwd
.bv_val
);
311 BER_BVZERO( &li
->li_acl_passwd
);
313 if ( !BER_BVISNULL( &li
->li_acl_sasl_mech
) ) {
314 ch_free( li
->li_acl_sasl_mech
.bv_val
);
315 BER_BVZERO( &li
->li_acl_sasl_mech
);
317 if ( !BER_BVISNULL( &li
->li_acl_sasl_realm
) ) {
318 ch_free( li
->li_acl_sasl_realm
.bv_val
);
319 BER_BVZERO( &li
->li_acl_sasl_realm
);
321 if ( !BER_BVISNULL( &li
->li_idassert_authcID
) ) {
322 ch_free( li
->li_idassert_authcID
.bv_val
);
323 BER_BVZERO( &li
->li_idassert_authcID
);
325 if ( !BER_BVISNULL( &li
->li_idassert_authcDN
) ) {
326 ch_free( li
->li_idassert_authcDN
.bv_val
);
327 BER_BVZERO( &li
->li_idassert_authcDN
);
329 if ( !BER_BVISNULL( &li
->li_idassert_passwd
) ) {
330 ch_free( li
->li_idassert_passwd
.bv_val
);
331 BER_BVZERO( &li
->li_idassert_passwd
);
333 if ( !BER_BVISNULL( &li
->li_idassert_authzID
) ) {
334 ch_free( li
->li_idassert_authzID
.bv_val
);
335 BER_BVZERO( &li
->li_idassert_authzID
);
337 if ( !BER_BVISNULL( &li
->li_idassert_sasl_mech
) ) {
338 ch_free( li
->li_idassert_sasl_mech
.bv_val
);
339 BER_BVZERO( &li
->li_idassert_sasl_mech
);
341 if ( !BER_BVISNULL( &li
->li_idassert_sasl_realm
) ) {
342 ch_free( li
->li_idassert_sasl_realm
.bv_val
);
343 BER_BVZERO( &li
->li_idassert_sasl_realm
);
345 if ( li
->li_idassert_authz
!= NULL
) {
346 ber_bvarray_free( li
->li_idassert_authz
);
347 li
->li_idassert_authz
= NULL
;
349 if ( li
->li_conninfo
.lai_tree
) {
350 avl_free( li
->li_conninfo
.lai_tree
, ldap_back_conn_free
);
352 for ( i
= LDAP_BACK_PCONN_FIRST
; i
< LDAP_BACK_PCONN_LAST
; i
++ ) {
353 while ( !LDAP_TAILQ_EMPTY( &li
->li_conn_priv
[ i
].lic_priv
) ) {
354 ldapconn_t
*lc
= LDAP_TAILQ_FIRST( &li
->li_conn_priv
[ i
].lic_priv
);
356 LDAP_TAILQ_REMOVE( &li
->li_conn_priv
[ i
].lic_priv
, lc
, lc_q
);
357 ldap_back_conn_free( lc
);
360 if ( LDAP_BACK_QUARANTINE( li
) ) {
361 slap_retry_info_destroy( &li
->li_quarantine
);
362 ldap_pvt_thread_mutex_destroy( &li
->li_quarantine_mutex
);
365 ldap_pvt_thread_mutex_unlock( &li
->li_conninfo
.lai_mutex
);
366 ldap_pvt_thread_mutex_destroy( &li
->li_conninfo
.lai_mutex
);
367 ldap_pvt_thread_mutex_destroy( &li
->li_uri_mutex
);
370 ch_free( be
->be_private
);
375 #if SLAPD_LDAP == SLAPD_MOD_DYNAMIC
377 /* conditionally define the init_module() function */
378 SLAP_BACKEND_INIT_MODULE( ldap
)
380 #endif /* SLAPD_LDAP == SLAPD_MOD_DYNAMIC */