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