]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldap/init.c
Partially revert prev, redundant.
[openldap] / servers / slapd / back-ldap / init.c
1 /* init.c - initialize ldap backend */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2003-2008 The OpenLDAP Foundation.
6  * Portions Copyright 1999-2003 Howard Chu.
7  * Portions Copyright 2000-2003 Pierangelo Masarati.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
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>.
17  */
18 /* ACKNOWLEDGEMENTS:
19  * This work was initially developed by the Howard Chu for inclusion
20  * in OpenLDAP Software and subsequently enhanced by Pierangelo
21  * Masarati.
22  */
23
24 #include "portable.h"
25
26 #include <stdio.h>
27
28 #include <ac/string.h>
29 #include <ac/socket.h>
30
31 #include "slap.h"
32 #include "config.h"
33 #include "back-ldap.h"
34
35 static const ldap_extra_t ldap_extra = {
36         ldap_back_proxy_authz_ctrl,
37         ldap_back_controls_free
38 };
39
40 int
41 ldap_back_open( BackendInfo     *bi )
42 {
43         bi->bi_controls = slap_known_controls;
44         return 0;
45 }
46
47 int
48 ldap_back_initialize( BackendInfo *bi )
49 {
50         int             rc;
51
52         bi->bi_flags =
53 #ifdef LDAP_DYNAMIC_OBJECTS
54                 /* this is set because all the support a proxy has to provide
55                  * is the capability to forward the refresh exop, and to
56                  * pass thru entries that contain the dynamicObject class
57                  * and the entryTtl attribute */
58                 SLAP_BFLAG_DYNAMIC |
59 #endif /* LDAP_DYNAMIC_OBJECTS */
60                 0;
61
62         bi->bi_open = ldap_back_open;
63         bi->bi_config = 0;
64         bi->bi_close = 0;
65         bi->bi_destroy = 0;
66
67         bi->bi_db_init = ldap_back_db_init;
68         bi->bi_db_config = config_generic_wrapper;
69         bi->bi_db_open = ldap_back_db_open;
70         bi->bi_db_close = ldap_back_db_close;
71         bi->bi_db_destroy = ldap_back_db_destroy;
72
73         bi->bi_op_bind = ldap_back_bind;
74         bi->bi_op_unbind = 0;
75         bi->bi_op_search = ldap_back_search;
76         bi->bi_op_compare = ldap_back_compare;
77         bi->bi_op_modify = ldap_back_modify;
78         bi->bi_op_modrdn = ldap_back_modrdn;
79         bi->bi_op_add = ldap_back_add;
80         bi->bi_op_delete = ldap_back_delete;
81         bi->bi_op_abandon = 0;
82
83         bi->bi_extended = ldap_back_extended;
84
85         bi->bi_chk_referrals = 0;
86         bi->bi_entry_get_rw = ldap_back_entry_get;
87
88         bi->bi_connection_init = 0;
89         bi->bi_connection_destroy = ldap_back_conn_destroy;
90
91         bi->bi_extra = (void *)&ldap_extra;
92
93         rc = chain_initialize();
94         if ( rc ) {
95                 return rc;
96         }
97
98 #ifdef SLAP_DISTPROC
99         rc = distproc_initialize();
100         if ( rc ) {
101                 return rc;
102         }
103 #endif
104
105         return ldap_back_init_cf( bi );
106 }
107
108 int
109 ldap_back_db_init( Backend *be, ConfigReply *cr )
110 {
111         ldapinfo_t      *li;
112         int             rc;
113         unsigned        i;
114
115         li = (ldapinfo_t *)ch_calloc( 1, sizeof( ldapinfo_t ) );
116         if ( li == NULL ) {
117                 return -1;
118         }
119
120         li->li_rebind_f = ldap_back_default_rebind;
121         li->li_urllist_f = ldap_back_default_urllist;
122         li->li_urllist_p = li;
123         ldap_pvt_thread_mutex_init( &li->li_uri_mutex );
124
125         BER_BVZERO( &li->li_acl_authcID );
126         BER_BVZERO( &li->li_acl_authcDN );
127         BER_BVZERO( &li->li_acl_passwd );
128
129         li->li_acl_authmethod = LDAP_AUTH_NONE;
130         BER_BVZERO( &li->li_acl_sasl_mech );
131         li->li_acl.sb_tls = SB_TLS_DEFAULT;
132
133         li->li_idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
134
135         BER_BVZERO( &li->li_idassert_authcID );
136         BER_BVZERO( &li->li_idassert_authcDN );
137         BER_BVZERO( &li->li_idassert_passwd );
138
139         BER_BVZERO( &li->li_idassert_authzID );
140
141         li->li_idassert_authmethod = LDAP_AUTH_NONE;
142         BER_BVZERO( &li->li_idassert_sasl_mech );
143         li->li_idassert_tls = SB_TLS_DEFAULT;
144
145         /* by default, use proxyAuthz control on each operation */
146         li->li_idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE;
147
148         li->li_idassert_authz = NULL;
149
150         /* initialize flags */
151         li->li_flags = LDAP_BACK_F_CHASE_REFERRALS;
152
153         /* initialize version */
154         li->li_version = LDAP_VERSION3;
155
156         ldap_pvt_thread_mutex_init( &li->li_conninfo.lai_mutex );
157
158         for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) {
159                 li->li_conn_priv[ i ].lic_num = 0;
160                 LDAP_TAILQ_INIT( &li->li_conn_priv[ i ].lic_priv );
161         }
162         li->li_conn_priv_max = LDAP_BACK_CONN_PRIV_DEFAULT;
163
164         be->be_private = li;
165         SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD;
166
167         be->be_cf_ocs = be->bd_info->bi_cf_ocs;
168
169         rc = ldap_back_monitor_db_init( be );
170         if ( rc != 0 ) {
171                 /* ignore, by now */
172                 rc = 0;
173         }
174
175         return rc;
176 }
177
178 int
179 ldap_back_db_open( BackendDB *be, ConfigReply *cr )
180 {
181         ldapinfo_t      *li = (ldapinfo_t *)be->be_private;
182
183         slap_bindconf   sb = { BER_BVNULL };
184         int             rc = 0;
185
186         Debug( LDAP_DEBUG_TRACE,
187                 "ldap_back_db_open: URI=%s\n",
188                 li->li_uri != NULL ? li->li_uri : "", 0, 0 );
189
190         /* by default, use proxyAuthz control on each operation */
191         switch ( li->li_idassert_mode ) {
192         case LDAP_BACK_IDASSERT_LEGACY:
193         case LDAP_BACK_IDASSERT_SELF:
194                 /* however, since admin connections are pooled and shared,
195                  * only static authzIDs can be native */
196                 li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
197                 break;
198
199         default:
200                 break;
201         }
202
203         ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri );
204         sb.sb_version = li->li_version;
205         sb.sb_method = LDAP_AUTH_SIMPLE;
206         BER_BVSTR( &sb.sb_binddn, "" );
207
208         if ( LDAP_BACK_T_F_DISCOVER( li ) && !LDAP_BACK_T_F( li ) ) {
209                 rc = slap_discover_feature( &sb,
210                                 slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
211                                 LDAP_FEATURE_ABSOLUTE_FILTERS );
212                 if ( rc == LDAP_COMPARE_TRUE ) {
213                         li->li_flags |= LDAP_BACK_F_T_F;
214                 }
215         }
216
217         if ( LDAP_BACK_CANCEL_DISCOVER( li ) && !LDAP_BACK_CANCEL( li ) ) {
218                 rc = slap_discover_feature( &sb,
219                                 slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
220                                 LDAP_EXOP_CANCEL );
221                 if ( rc == LDAP_COMPARE_TRUE ) {
222                         li->li_flags |= LDAP_BACK_F_CANCEL_EXOP;
223                 }
224         }
225
226         /* monitor setup */
227         rc = ldap_back_monitor_db_open( be );
228         if ( rc != 0 ) {
229                 /* ignore by now */
230                 rc = 0;
231 #if 0
232                 goto fail;
233 #endif
234         }
235
236         li->li_flags |= LDAP_BACK_F_ISOPEN;
237
238 fail:;
239         return rc;
240 }
241
242 void
243 ldap_back_conn_free( void *v_lc )
244 {
245         ldapconn_t      *lc = v_lc;
246
247         if ( lc->lc_ld != NULL ) {      
248                 ldap_unbind_ext( lc->lc_ld, NULL, NULL );
249         }
250         if ( !BER_BVISNULL( &lc->lc_bound_ndn ) ) {
251                 ch_free( lc->lc_bound_ndn.bv_val );
252         }
253         if ( !BER_BVISNULL( &lc->lc_cred ) ) {
254                 memset( lc->lc_cred.bv_val, 0, lc->lc_cred.bv_len );
255                 ch_free( lc->lc_cred.bv_val );
256         }
257         if ( !BER_BVISNULL( &lc->lc_local_ndn ) ) {
258                 ch_free( lc->lc_local_ndn.bv_val );
259         }
260         lc->lc_q.tqe_prev = NULL;
261         lc->lc_q.tqe_next = NULL;
262         ch_free( lc );
263 }
264
265 int
266 ldap_back_db_close( Backend *be, ConfigReply *cr )
267 {
268         int             rc = 0;
269
270         if ( be->be_private ) {
271                 rc = ldap_back_monitor_db_close( be );
272         }
273
274         return rc;
275 }
276
277 int
278 ldap_back_db_destroy( Backend *be, ConfigReply *cr )
279 {
280         if ( be->be_private ) {
281                 ldapinfo_t      *li = ( ldapinfo_t * )be->be_private;
282                 unsigned        i;
283
284                 (void)ldap_back_monitor_db_destroy( be );
285
286                 ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
287
288                 if ( li->li_uri != NULL ) {
289                         ch_free( li->li_uri );
290                         li->li_uri = NULL;
291
292                         assert( li->li_bvuri != NULL );
293                         ber_bvarray_free( li->li_bvuri );
294                         li->li_bvuri = NULL;
295                 }
296                 if ( !BER_BVISNULL( &li->li_acl_authcID ) ) {
297                         ch_free( li->li_acl_authcID.bv_val );
298                         BER_BVZERO( &li->li_acl_authcID );
299                 }
300                 if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) {
301                         ch_free( li->li_acl_authcDN.bv_val );
302                         BER_BVZERO( &li->li_acl_authcDN );
303                 }
304                 if ( !BER_BVISNULL( &li->li_acl_passwd ) ) {
305                         ch_free( li->li_acl_passwd.bv_val );
306                         BER_BVZERO( &li->li_acl_passwd );
307                 }
308                 if ( !BER_BVISNULL( &li->li_acl_sasl_mech ) ) {
309                         ch_free( li->li_acl_sasl_mech.bv_val );
310                         BER_BVZERO( &li->li_acl_sasl_mech );
311                 }
312                 if ( !BER_BVISNULL( &li->li_acl_sasl_realm ) ) {
313                         ch_free( li->li_acl_sasl_realm.bv_val );
314                         BER_BVZERO( &li->li_acl_sasl_realm );
315                 }
316                 if ( !BER_BVISNULL( &li->li_idassert_authcID ) ) {
317                         ch_free( li->li_idassert_authcID.bv_val );
318                         BER_BVZERO( &li->li_idassert_authcID );
319                 }
320                 if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
321                         ch_free( li->li_idassert_authcDN.bv_val );
322                         BER_BVZERO( &li->li_idassert_authcDN );
323                 }
324                 if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) {
325                         ch_free( li->li_idassert_passwd.bv_val );
326                         BER_BVZERO( &li->li_idassert_passwd );
327                 }
328                 if ( !BER_BVISNULL( &li->li_idassert_authzID ) ) {
329                         ch_free( li->li_idassert_authzID.bv_val );
330                         BER_BVZERO( &li->li_idassert_authzID );
331                 }
332                 if ( !BER_BVISNULL( &li->li_idassert_sasl_mech ) ) {
333                         ch_free( li->li_idassert_sasl_mech.bv_val );
334                         BER_BVZERO( &li->li_idassert_sasl_mech );
335                 }
336                 if ( !BER_BVISNULL( &li->li_idassert_sasl_realm ) ) {
337                         ch_free( li->li_idassert_sasl_realm.bv_val );
338                         BER_BVZERO( &li->li_idassert_sasl_realm );
339                 }
340                 if ( li->li_idassert_authz != NULL ) {
341                         ber_bvarray_free( li->li_idassert_authz );
342                         li->li_idassert_authz = NULL;
343                 }
344                 if ( li->li_conninfo.lai_tree ) {
345                         avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free );
346                 }
347                 for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) {
348                         while ( !LDAP_TAILQ_EMPTY( &li->li_conn_priv[ i ].lic_priv ) ) {
349                                 ldapconn_t      *lc = LDAP_TAILQ_FIRST( &li->li_conn_priv[ i ].lic_priv );
350
351                                 LDAP_TAILQ_REMOVE( &li->li_conn_priv[ i ].lic_priv, lc, lc_q );
352                                 ldap_back_conn_free( lc );
353                         }
354                 }
355                 if ( LDAP_BACK_QUARANTINE( li ) ) {
356                         slap_retry_info_destroy( &li->li_quarantine );
357                         ldap_pvt_thread_mutex_destroy( &li->li_quarantine_mutex );
358                 }
359
360                 ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
361                 ldap_pvt_thread_mutex_destroy( &li->li_conninfo.lai_mutex );
362                 ldap_pvt_thread_mutex_destroy( &li->li_uri_mutex );
363         }
364
365         ch_free( be->be_private );
366
367         return 0;
368 }
369
370 #if SLAPD_LDAP == SLAPD_MOD_DYNAMIC
371
372 /* conditionally define the init_module() function */
373 SLAP_BACKEND_INIT_MODULE( ldap )
374
375 #endif /* SLAPD_LDAP == SLAPD_MOD_DYNAMIC */
376