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