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