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