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 54 ldap_back_open( BackendInfo *bi ) 55 { 56 bi->bi_controls = slap_known_controls; 57 return 0; 58 } 59 60 int 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 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 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 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 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 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