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