1 /* $NetBSD: search.c,v 1.1.1.5 2014/05/28 09:58:50 tron Exp $ */ 2 3 /* $OpenLDAP$ */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1999-2014 The OpenLDAP Foundation. 7 * Portions Copyright 2001-2003 Pierangelo Masarati. 8 * Portions Copyright 1999-2003 Howard Chu. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted only as authorized by the OpenLDAP 13 * Public License. 14 * 15 * A copy of this license is available in the file LICENSE in the 16 * top-level directory of the distribution or, alternatively, at 17 * <http://www.OpenLDAP.org/license.html>. 18 */ 19 /* ACKNOWLEDGEMENTS: 20 * This work was initially developed by the Howard Chu for inclusion 21 * in OpenLDAP Software and subsequently enhanced by Pierangelo 22 * Masarati. 23 */ 24 25 #include "portable.h" 26 27 #include <stdio.h> 28 29 #include <ac/socket.h> 30 #include <ac/string.h> 31 #include <ac/time.h> 32 33 #include "lutil.h" 34 #include "slap.h" 35 #include "../back-ldap/back-ldap.h" 36 #include "back-meta.h" 37 #include "../../../libraries/liblber/lber-int.h" 38 39 /* IGNORE means that target does not (no longer) participate 40 * in the search; 41 * NOTREADY means the search on that target has not been initialized yet 42 */ 43 #define META_MSGID_IGNORE (-1) 44 #define META_MSGID_NEED_BIND (-2) 45 #define META_MSGID_CONNECTING (-3) 46 47 static int 48 meta_send_entry( 49 Operation *op, 50 SlapReply *rs, 51 metaconn_t *mc, 52 int i, 53 LDAPMessage *e ); 54 55 typedef enum meta_search_candidate_t { 56 META_SEARCH_UNDEFINED = -2, 57 META_SEARCH_ERR = -1, 58 META_SEARCH_NOT_CANDIDATE, 59 META_SEARCH_CANDIDATE, 60 META_SEARCH_BINDING, 61 META_SEARCH_NEED_BIND, 62 META_SEARCH_CONNECTING 63 } meta_search_candidate_t; 64 65 /* 66 * meta_search_dobind_init() 67 * 68 * initiates bind for a candidate target of a search. 69 */ 70 static meta_search_candidate_t 71 meta_search_dobind_init( 72 Operation *op, 73 SlapReply *rs, 74 metaconn_t **mcp, 75 int candidate, 76 SlapReply *candidates ) 77 { 78 metaconn_t *mc = *mcp; 79 metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; 80 metatarget_t *mt = mi->mi_targets[ candidate ]; 81 metasingleconn_t *msc = &mc->mc_conns[ candidate ]; 82 83 struct berval binddn = msc->msc_bound_ndn, 84 cred = msc->msc_cred; 85 int method; 86 87 int rc; 88 89 meta_search_candidate_t retcode; 90 91 Debug( LDAP_DEBUG_TRACE, "%s >>> meta_search_dobind_init[%d]\n", 92 op->o_log_prefix, candidate, 0 ); 93 94 /* 95 * all the targets are already bound as pseudoroot 96 */ 97 if ( mc->mc_authz_target == META_BOUND_ALL ) { 98 return META_SEARCH_CANDIDATE; 99 } 100 101 retcode = META_SEARCH_BINDING; 102 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 103 if ( LDAP_BACK_CONN_ISBOUND( msc ) || LDAP_BACK_CONN_ISANON( msc ) ) { 104 /* already bound (or anonymous) */ 105 106 #ifdef DEBUG_205 107 char buf[ SLAP_TEXT_BUFLEN ] = { '\0' }; 108 int bound = 0; 109 110 if ( LDAP_BACK_CONN_ISBOUND( msc ) ) { 111 bound = 1; 112 } 113 114 snprintf( buf, sizeof( buf ), " mc=%p ld=%p%s DN=\"%s\"", 115 (void *)mc, (void *)msc->msc_ld, 116 bound ? " bound" : " anonymous", 117 bound == 0 ? "" : msc->msc_bound_ndn.bv_val ); 118 Debug( LDAP_DEBUG_ANY, "### %s meta_search_dobind_init[%d]%s\n", 119 op->o_log_prefix, candidate, buf ); 120 #endif /* DEBUG_205 */ 121 122 retcode = META_SEARCH_CANDIDATE; 123 124 } else if ( META_BACK_CONN_CREATING( msc ) || LDAP_BACK_CONN_BINDING( msc ) ) { 125 /* another thread is binding the target for this conn; wait */ 126 127 #ifdef DEBUG_205 128 char buf[ SLAP_TEXT_BUFLEN ] = { '\0' }; 129 130 snprintf( buf, sizeof( buf ), " mc=%p ld=%p needbind", 131 (void *)mc, (void *)msc->msc_ld ); 132 Debug( LDAP_DEBUG_ANY, "### %s meta_search_dobind_init[%d]%s\n", 133 op->o_log_prefix, candidate, buf ); 134 #endif /* DEBUG_205 */ 135 136 candidates[ candidate ].sr_msgid = META_MSGID_NEED_BIND; 137 retcode = META_SEARCH_NEED_BIND; 138 139 } else { 140 /* we'll need to bind the target for this conn */ 141 142 #ifdef DEBUG_205 143 char buf[ SLAP_TEXT_BUFLEN ]; 144 145 snprintf( buf, sizeof( buf ), " mc=%p ld=%p binding", 146 (void *)mc, (void *)msc->msc_ld ); 147 Debug( LDAP_DEBUG_ANY, "### %s meta_search_dobind_init[%d]%s\n", 148 op->o_log_prefix, candidate, buf ); 149 #endif /* DEBUG_205 */ 150 151 if ( msc->msc_ld == NULL ) { 152 /* for some reason (e.g. because formerly in "binding" 153 * state, with eventual connection expiration or invalidation) 154 * it was not initialized as expected */ 155 156 Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p ld=NULL\n", 157 op->o_log_prefix, candidate, (void *)mc ); 158 159 rc = meta_back_init_one_conn( op, rs, *mcp, candidate, 160 LDAP_BACK_CONN_ISPRIV( *mcp ), LDAP_BACK_DONTSEND, 0 ); 161 switch ( rc ) { 162 case LDAP_SUCCESS: 163 assert( msc->msc_ld != NULL ); 164 break; 165 166 case LDAP_SERVER_DOWN: 167 case LDAP_UNAVAILABLE: 168 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 169 goto down; 170 171 default: 172 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 173 goto other; 174 } 175 } 176 177 LDAP_BACK_CONN_BINDING_SET( msc ); 178 } 179 180 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 181 182 if ( retcode != META_SEARCH_BINDING ) { 183 return retcode; 184 } 185 186 /* NOTE: this obsoletes pseudorootdn */ 187 if ( op->o_conn != NULL && 188 !op->o_do_not_cache && 189 ( BER_BVISNULL( &msc->msc_bound_ndn ) || 190 BER_BVISEMPTY( &msc->msc_bound_ndn ) || 191 ( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) ) 192 { 193 rc = meta_back_proxy_authz_cred( mc, candidate, op, rs, LDAP_BACK_DONTSEND, &binddn, &cred, &method ); 194 switch ( rc ) { 195 case LDAP_SUCCESS: 196 break; 197 case LDAP_UNAVAILABLE: 198 goto down; 199 default: 200 goto other; 201 } 202 203 /* NOTE: we copy things here, even if bind didn't succeed yet, 204 * because the connection is not shared until bind is over */ 205 if ( !BER_BVISNULL( &binddn ) ) { 206 ber_bvreplace( &msc->msc_bound_ndn, &binddn ); 207 if ( META_BACK_TGT_SAVECRED( mt ) && !BER_BVISNULL( &cred ) ) { 208 if ( !BER_BVISNULL( &msc->msc_cred ) ) { 209 memset( msc->msc_cred.bv_val, 0, 210 msc->msc_cred.bv_len ); 211 } 212 ber_bvreplace( &msc->msc_cred, &cred ); 213 } 214 } 215 216 if ( LDAP_BACK_CONN_ISBOUND( msc ) ) { 217 /* apparently, idassert was configured with SASL bind, 218 * so bind occurred inside meta_back_proxy_authz_cred() */ 219 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 220 LDAP_BACK_CONN_BINDING_CLEAR( msc ); 221 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 222 return META_SEARCH_CANDIDATE; 223 } 224 225 /* paranoid */ 226 switch ( method ) { 227 case LDAP_AUTH_NONE: 228 case LDAP_AUTH_SIMPLE: 229 /* do a simple bind with binddn, cred */ 230 break; 231 232 default: 233 assert( 0 ); 234 break; 235 } 236 } 237 238 assert( msc->msc_ld != NULL ); 239 240 /* connect must be async only the first time... */ 241 ldap_set_option( msc->msc_ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_ON ); 242 243 retry:; 244 if ( !BER_BVISEMPTY( &binddn ) && BER_BVISEMPTY( &cred ) ) { 245 /* bind anonymously? */ 246 Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p: " 247 "non-empty dn with empty cred; binding anonymously\n", 248 op->o_log_prefix, candidate, (void *)mc ); 249 cred = slap_empty_bv; 250 251 } else if ( BER_BVISEMPTY( &binddn ) && !BER_BVISEMPTY( &cred ) ) { 252 /* error */ 253 Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p: " 254 "empty dn with non-empty cred: error\n", 255 op->o_log_prefix, candidate, (void *)mc ); 256 goto other; 257 } 258 259 rc = ldap_sasl_bind( msc->msc_ld, binddn.bv_val, LDAP_SASL_SIMPLE, &cred, 260 NULL, NULL, &candidates[ candidate ].sr_msgid ); 261 262 #ifdef DEBUG_205 263 { 264 char buf[ SLAP_TEXT_BUFLEN ]; 265 266 snprintf( buf, sizeof( buf ), "meta_search_dobind_init[%d] mc=%p ld=%p rc=%d", 267 candidate, (void *)mc, (void *)mc->mc_conns[ candidate ].msc_ld, rc ); 268 Debug( LDAP_DEBUG_ANY, "### %s %s\n", 269 op->o_log_prefix, buf, 0 ); 270 } 271 #endif /* DEBUG_205 */ 272 273 switch ( rc ) { 274 case LDAP_SUCCESS: 275 assert( candidates[ candidate ].sr_msgid >= 0 ); 276 META_BINDING_SET( &candidates[ candidate ] ); 277 return META_SEARCH_BINDING; 278 279 case LDAP_X_CONNECTING: 280 /* must retry, same conn */ 281 candidates[ candidate ].sr_msgid = META_MSGID_CONNECTING; 282 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 283 LDAP_BACK_CONN_BINDING_CLEAR( msc ); 284 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 285 return META_SEARCH_CONNECTING; 286 287 case LDAP_SERVER_DOWN: 288 down:; 289 /* This is the worst thing that could happen: 290 * the search will wait until the retry is over. */ 291 if ( !META_IS_RETRYING( &candidates[ candidate ] ) ) { 292 META_RETRYING_SET( &candidates[ candidate ] ); 293 294 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 295 296 assert( mc->mc_refcnt > 0 ); 297 if ( LogTest( LDAP_DEBUG_ANY ) ) { 298 char buf[ SLAP_TEXT_BUFLEN ]; 299 300 /* this lock is required; however, 301 * it's invoked only when logging is on */ 302 ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex ); 303 snprintf( buf, sizeof( buf ), 304 "retrying URI=\"%s\" DN=\"%s\"", 305 mt->mt_uri, 306 BER_BVISNULL( &msc->msc_bound_ndn ) ? 307 "" : msc->msc_bound_ndn.bv_val ); 308 ldap_pvt_thread_mutex_unlock( &mt->mt_uri_mutex ); 309 310 Debug( LDAP_DEBUG_ANY, 311 "%s meta_search_dobind_init[%d]: %s.\n", 312 op->o_log_prefix, candidate, buf ); 313 } 314 315 meta_clear_one_candidate( op, mc, candidate ); 316 LDAP_BACK_CONN_ISBOUND_CLEAR( msc ); 317 318 ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn ); 319 320 /* mc here must be the regular mc, reset and ready for init */ 321 rc = meta_back_init_one_conn( op, rs, mc, candidate, 322 LDAP_BACK_CONN_ISPRIV( mc ), LDAP_BACK_DONTSEND, 0 ); 323 324 if ( rc == LDAP_SUCCESS ) { 325 LDAP_BACK_CONN_BINDING_SET( msc ); 326 } 327 328 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 329 330 if ( rc == LDAP_SUCCESS ) { 331 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 332 binddn = msc->msc_bound_ndn; 333 cred = msc->msc_cred; 334 goto retry; 335 } 336 } 337 338 if ( *mcp == NULL ) { 339 retcode = META_SEARCH_ERR; 340 rs->sr_err = LDAP_UNAVAILABLE; 341 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 342 break; 343 } 344 /* fall thru */ 345 346 default: 347 other:; 348 rs->sr_err = rc; 349 rc = slap_map_api2result( rs ); 350 351 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 352 meta_clear_one_candidate( op, mc, candidate ); 353 candidates[ candidate ].sr_err = rc; 354 if ( META_BACK_ONERR_STOP( mi ) ) { 355 LDAP_BACK_CONN_TAINTED_SET( mc ); 356 meta_back_release_conn_lock( mi, mc, 0 ); 357 *mcp = NULL; 358 rs->sr_err = rc; 359 360 retcode = META_SEARCH_ERR; 361 362 } else { 363 retcode = META_SEARCH_NOT_CANDIDATE; 364 } 365 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 366 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 367 break; 368 } 369 370 return retcode; 371 } 372 373 static meta_search_candidate_t 374 meta_search_dobind_result( 375 Operation *op, 376 SlapReply *rs, 377 metaconn_t **mcp, 378 int candidate, 379 SlapReply *candidates, 380 LDAPMessage *res ) 381 { 382 metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; 383 metatarget_t *mt = mi->mi_targets[ candidate ]; 384 metaconn_t *mc = *mcp; 385 metasingleconn_t *msc = &mc->mc_conns[ candidate ]; 386 387 meta_search_candidate_t retcode = META_SEARCH_NOT_CANDIDATE; 388 int rc; 389 390 assert( msc->msc_ld != NULL ); 391 392 /* FIXME: matched? referrals? response controls? */ 393 rc = ldap_parse_result( msc->msc_ld, res, 394 &candidates[ candidate ].sr_err, 395 NULL, NULL, NULL, NULL, 0 ); 396 if ( rc != LDAP_SUCCESS ) { 397 candidates[ candidate ].sr_err = rc; 398 } 399 rc = slap_map_api2result( &candidates[ candidate ] ); 400 401 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 402 LDAP_BACK_CONN_BINDING_CLEAR( msc ); 403 if ( rc != LDAP_SUCCESS ) { 404 meta_clear_one_candidate( op, mc, candidate ); 405 candidates[ candidate ].sr_err = rc; 406 if ( META_BACK_ONERR_STOP( mi ) ) { 407 LDAP_BACK_CONN_TAINTED_SET( mc ); 408 meta_back_release_conn_lock( mi, mc, 0 ); 409 *mcp = NULL; 410 retcode = META_SEARCH_ERR; 411 rs->sr_err = rc; 412 } 413 414 } else { 415 /* FIXME: check if bound as idassert authcDN! */ 416 if ( BER_BVISNULL( &msc->msc_bound_ndn ) 417 || BER_BVISEMPTY( &msc->msc_bound_ndn ) ) 418 { 419 LDAP_BACK_CONN_ISANON_SET( msc ); 420 421 } else { 422 if ( META_BACK_TGT_SAVECRED( mt ) && 423 !BER_BVISNULL( &msc->msc_cred ) && 424 !BER_BVISEMPTY( &msc->msc_cred ) ) 425 { 426 ldap_set_rebind_proc( msc->msc_ld, mt->mt_rebind_f, msc ); 427 } 428 LDAP_BACK_CONN_ISBOUND_SET( msc ); 429 } 430 retcode = META_SEARCH_CANDIDATE; 431 432 /* connect must be async */ 433 ldap_set_option( msc->msc_ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_OFF ); 434 } 435 436 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 437 META_BINDING_CLEAR( &candidates[ candidate ] ); 438 439 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 440 441 return retcode; 442 } 443 444 static meta_search_candidate_t 445 meta_back_search_start( 446 Operation *op, 447 SlapReply *rs, 448 dncookie *dc, 449 metaconn_t **mcp, 450 int candidate, 451 SlapReply *candidates, 452 struct berval *prcookie, 453 ber_int_t prsize ) 454 { 455 metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; 456 metatarget_t *mt = mi->mi_targets[ candidate ]; 457 metasingleconn_t *msc = &(*mcp)->mc_conns[ candidate ]; 458 struct berval realbase = op->o_req_dn; 459 int realscope = op->ors_scope; 460 struct berval mbase = BER_BVNULL; 461 struct berval mfilter = BER_BVNULL; 462 char **mapped_attrs = NULL; 463 int rc; 464 meta_search_candidate_t retcode; 465 struct timeval tv, *tvp = NULL; 466 int nretries = 1; 467 LDAPControl **ctrls = NULL; 468 #ifdef SLAPD_META_CLIENT_PR 469 LDAPControl **save_ctrls = NULL; 470 #endif /* SLAPD_META_CLIENT_PR */ 471 472 /* this should not happen; just in case... */ 473 if ( msc->msc_ld == NULL ) { 474 Debug( LDAP_DEBUG_ANY, 475 "%s: meta_back_search_start candidate=%d ld=NULL%s.\n", 476 op->o_log_prefix, candidate, 477 META_BACK_ONERR_STOP( mi ) ? "" : " (ignored)" ); 478 candidates[ candidate ].sr_err = LDAP_OTHER; 479 if ( META_BACK_ONERR_STOP( mi ) ) { 480 return META_SEARCH_ERR; 481 } 482 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 483 return META_SEARCH_NOT_CANDIDATE; 484 } 485 486 Debug( LDAP_DEBUG_TRACE, "%s >>> meta_back_search_start[%d]\n", op->o_log_prefix, candidate, 0 ); 487 488 /* 489 * modifies the base according to the scope, if required 490 */ 491 if ( mt->mt_nsuffix.bv_len > op->o_req_ndn.bv_len ) { 492 switch ( op->ors_scope ) { 493 case LDAP_SCOPE_SUBTREE: 494 /* 495 * make the target suffix the new base 496 * FIXME: this is very forgiving, because 497 * "illegal" searchBases may be turned 498 * into the suffix of the target; however, 499 * the requested searchBase already passed 500 * thru the candidate analyzer... 501 */ 502 if ( dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) ) { 503 realbase = mt->mt_nsuffix; 504 if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) { 505 realscope = LDAP_SCOPE_SUBORDINATE; 506 } 507 508 } else { 509 /* 510 * this target is no longer candidate 511 */ 512 retcode = META_SEARCH_NOT_CANDIDATE; 513 goto doreturn; 514 } 515 break; 516 517 case LDAP_SCOPE_SUBORDINATE: 518 case LDAP_SCOPE_ONELEVEL: 519 { 520 struct berval rdn = mt->mt_nsuffix; 521 rdn.bv_len -= op->o_req_ndn.bv_len + STRLENOF( "," ); 522 if ( dnIsOneLevelRDN( &rdn ) 523 && dnIsSuffix( &mt->mt_nsuffix, &op->o_req_ndn ) ) 524 { 525 /* 526 * if there is exactly one level, 527 * make the target suffix the new 528 * base, and make scope "base" 529 */ 530 realbase = mt->mt_nsuffix; 531 if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) { 532 if ( mt->mt_scope == LDAP_SCOPE_SUBORDINATE ) { 533 realscope = LDAP_SCOPE_SUBORDINATE; 534 } else { 535 realscope = LDAP_SCOPE_SUBTREE; 536 } 537 } else { 538 realscope = LDAP_SCOPE_BASE; 539 } 540 break; 541 } /* else continue with the next case */ 542 } 543 544 case LDAP_SCOPE_BASE: 545 /* 546 * this target is no longer candidate 547 */ 548 retcode = META_SEARCH_NOT_CANDIDATE; 549 goto doreturn; 550 } 551 } 552 553 /* check filter expression */ 554 if ( mt->mt_filter ) { 555 metafilter_t *mf; 556 for ( mf = mt->mt_filter; mf; mf = mf->mf_next ) { 557 if ( regexec( &mf->mf_regex, op->ors_filterstr.bv_val, 0, NULL, 0 ) == 0 ) 558 break; 559 } 560 /* nothing matched, this target is no longer a candidate */ 561 if ( !mf ) { 562 retcode = META_SEARCH_NOT_CANDIDATE; 563 goto doreturn; 564 } 565 } 566 567 /* initiate dobind */ 568 retcode = meta_search_dobind_init( op, rs, mcp, candidate, candidates ); 569 570 Debug( LDAP_DEBUG_TRACE, "%s <<< meta_search_dobind_init[%d]=%d\n", op->o_log_prefix, candidate, retcode ); 571 572 if ( retcode != META_SEARCH_CANDIDATE ) { 573 goto doreturn; 574 } 575 576 /* 577 * Rewrite the search base, if required 578 */ 579 dc->target = mt; 580 dc->ctx = "searchBase"; 581 switch ( ldap_back_dn_massage( dc, &realbase, &mbase ) ) { 582 case LDAP_SUCCESS: 583 break; 584 585 case LDAP_UNWILLING_TO_PERFORM: 586 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 587 rs->sr_text = "Operation not allowed"; 588 send_ldap_result( op, rs ); 589 retcode = META_SEARCH_ERR; 590 goto doreturn; 591 592 default: 593 594 /* 595 * this target is no longer candidate 596 */ 597 retcode = META_SEARCH_NOT_CANDIDATE; 598 goto doreturn; 599 } 600 601 /* 602 * Maps filter 603 */ 604 rc = ldap_back_filter_map_rewrite( dc, op->ors_filter, 605 &mfilter, BACKLDAP_MAP, op->o_tmpmemctx ); 606 switch ( rc ) { 607 case LDAP_SUCCESS: 608 break; 609 610 case LDAP_COMPARE_FALSE: 611 default: 612 /* 613 * this target is no longer candidate 614 */ 615 retcode = META_SEARCH_NOT_CANDIDATE; 616 goto done; 617 } 618 619 /* 620 * Maps required attributes 621 */ 622 rc = ldap_back_map_attrs( op, &mt->mt_rwmap.rwm_at, 623 op->ors_attrs, BACKLDAP_MAP, &mapped_attrs ); 624 if ( rc != LDAP_SUCCESS ) { 625 /* 626 * this target is no longer candidate 627 */ 628 retcode = META_SEARCH_NOT_CANDIDATE; 629 goto done; 630 } 631 632 if ( op->ors_tlimit != SLAP_NO_LIMIT ) { 633 tv.tv_sec = op->ors_tlimit > 0 ? op->ors_tlimit : 1; 634 tv.tv_usec = 0; 635 tvp = &tv; 636 } 637 638 #ifdef SLAPD_META_CLIENT_PR 639 save_ctrls = op->o_ctrls; 640 { 641 LDAPControl *pr_c = NULL; 642 int i = 0, nc = 0; 643 644 if ( save_ctrls ) { 645 for ( ; save_ctrls[i] != NULL; i++ ); 646 nc = i; 647 pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, save_ctrls, NULL ); 648 } 649 650 if ( pr_c != NULL ) nc--; 651 if ( mt->mt_ps > 0 || prcookie != NULL ) nc++; 652 653 if ( mt->mt_ps > 0 || prcookie != NULL || pr_c != NULL ) { 654 int src = 0, dst = 0; 655 BerElementBuffer berbuf; 656 BerElement *ber = (BerElement *)&berbuf; 657 struct berval val = BER_BVNULL; 658 ber_len_t len; 659 660 len = sizeof( LDAPControl * )*( nc + 1 ) + sizeof( LDAPControl ); 661 662 if ( mt->mt_ps > 0 || prcookie != NULL ) { 663 struct berval nullcookie = BER_BVNULL; 664 ber_tag_t tag; 665 666 if ( prsize == 0 && mt->mt_ps > 0 ) prsize = mt->mt_ps; 667 if ( prcookie == NULL ) prcookie = &nullcookie; 668 669 ber_init2( ber, NULL, LBER_USE_DER ); 670 tag = ber_printf( ber, "{iO}", prsize, prcookie ); 671 if ( tag == LBER_ERROR ) { 672 /* error */ 673 (void) ber_free_buf( ber ); 674 goto done_pr; 675 } 676 677 tag = ber_flatten2( ber, &val, 0 ); 678 if ( tag == LBER_ERROR ) { 679 /* error */ 680 (void) ber_free_buf( ber ); 681 goto done_pr; 682 } 683 684 len += val.bv_len + 1; 685 } 686 687 op->o_ctrls = op->o_tmpalloc( len, op->o_tmpmemctx ); 688 if ( save_ctrls ) { 689 for ( ; save_ctrls[ src ] != NULL; src++ ) { 690 if ( save_ctrls[ src ] != pr_c ) { 691 op->o_ctrls[ dst ] = save_ctrls[ src ]; 692 dst++; 693 } 694 } 695 } 696 697 if ( mt->mt_ps > 0 || prcookie != NULL ) { 698 op->o_ctrls[ dst ] = (LDAPControl *)&op->o_ctrls[ nc + 1 ]; 699 700 op->o_ctrls[ dst ]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; 701 op->o_ctrls[ dst ]->ldctl_iscritical = 1; 702 703 op->o_ctrls[ dst ]->ldctl_value.bv_val = (char *)&op->o_ctrls[ dst ][ 1 ]; 704 AC_MEMCPY( op->o_ctrls[ dst ]->ldctl_value.bv_val, val.bv_val, val.bv_len + 1 ); 705 op->o_ctrls[ dst ]->ldctl_value.bv_len = val.bv_len; 706 dst++; 707 708 (void)ber_free_buf( ber ); 709 } 710 711 op->o_ctrls[ dst ] = NULL; 712 } 713 done_pr:; 714 } 715 #endif /* SLAPD_META_CLIENT_PR */ 716 717 retry:; 718 ctrls = op->o_ctrls; 719 if ( meta_back_controls_add( op, rs, *mcp, candidate, &ctrls ) 720 != LDAP_SUCCESS ) 721 { 722 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 723 retcode = META_SEARCH_NOT_CANDIDATE; 724 goto done; 725 } 726 727 /* 728 * Starts the search 729 */ 730 assert( msc->msc_ld != NULL ); 731 rc = ldap_pvt_search( msc->msc_ld, 732 mbase.bv_val, realscope, mfilter.bv_val, 733 mapped_attrs, op->ors_attrsonly, 734 ctrls, NULL, tvp, op->ors_slimit, op->ors_deref, 735 &candidates[ candidate ].sr_msgid ); 736 switch ( rc ) { 737 case LDAP_SUCCESS: 738 retcode = META_SEARCH_CANDIDATE; 739 break; 740 741 case LDAP_SERVER_DOWN: 742 if ( nretries && meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) { 743 nretries = 0; 744 /* if the identity changed, there might be need to re-authz */ 745 (void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls ); 746 goto retry; 747 } 748 749 if ( *mcp == NULL ) { 750 retcode = META_SEARCH_ERR; 751 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 752 break; 753 } 754 /* fall thru */ 755 756 default: 757 candidates[ candidate ].sr_msgid = META_MSGID_IGNORE; 758 retcode = META_SEARCH_NOT_CANDIDATE; 759 } 760 761 done:; 762 (void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls ); 763 #ifdef SLAPD_META_CLIENT_PR 764 if ( save_ctrls != op->o_ctrls ) { 765 op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx ); 766 op->o_ctrls = save_ctrls; 767 } 768 #endif /* SLAPD_META_CLIENT_PR */ 769 770 if ( mapped_attrs ) { 771 ber_memfree_x( mapped_attrs, op->o_tmpmemctx ); 772 } 773 if ( mfilter.bv_val != op->ors_filterstr.bv_val ) { 774 ber_memfree_x( mfilter.bv_val, op->o_tmpmemctx ); 775 } 776 if ( mbase.bv_val != realbase.bv_val ) { 777 free( mbase.bv_val ); 778 } 779 780 doreturn:; 781 Debug( LDAP_DEBUG_TRACE, "%s <<< meta_back_search_start[%d]=%d\n", op->o_log_prefix, candidate, retcode ); 782 783 return retcode; 784 } 785 786 int 787 meta_back_search( Operation *op, SlapReply *rs ) 788 { 789 metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; 790 metaconn_t *mc; 791 struct timeval save_tv = { 0, 0 }, 792 tv; 793 time_t stoptime = (time_t)(-1), 794 lastres_time = slap_get_time(), 795 timeout = 0; 796 int rc = 0, sres = LDAP_SUCCESS; 797 char *matched = NULL; 798 int last = 0, ncandidates = 0, 799 initial_candidates = 0, candidate_match = 0, 800 needbind = 0; 801 ldap_back_send_t sendok = LDAP_BACK_SENDERR; 802 long i; 803 dncookie dc; 804 int is_ok = 0; 805 void *savepriv; 806 SlapReply *candidates = NULL; 807 int do_taint = 0; 808 809 rs_assert_ready( rs ); 810 rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */ 811 812 /* 813 * controls are set in ldap_back_dobind() 814 * 815 * FIXME: in case of values return filter, we might want 816 * to map attrs and maybe rewrite value 817 */ 818 getconn:; 819 mc = meta_back_getconn( op, rs, NULL, sendok ); 820 if ( !mc ) { 821 return rs->sr_err; 822 } 823 824 dc.conn = op->o_conn; 825 dc.rs = rs; 826 827 if ( candidates == NULL ) candidates = meta_back_candidates_get( op ); 828 /* 829 * Inits searches 830 */ 831 for ( i = 0; i < mi->mi_ntargets; i++ ) { 832 /* reset sr_msgid; it is used in most loops 833 * to check if that target is still to be considered */ 834 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 835 836 /* a target is marked as candidate by meta_back_getconn(); 837 * if for any reason (an error, it's over or so) it is 838 * no longer active, sr_msgid is set to META_MSGID_IGNORE 839 * but it remains candidate, which means it has been active 840 * at some point during the operation. This allows to 841 * use its response code and more to compute the final 842 * response */ 843 if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) { 844 continue; 845 } 846 847 candidates[ i ].sr_matched = NULL; 848 candidates[ i ].sr_text = NULL; 849 candidates[ i ].sr_ref = NULL; 850 candidates[ i ].sr_ctrls = NULL; 851 candidates[ i ].sr_nentries = 0; 852 853 /* get largest timeout among candidates */ 854 if ( mi->mi_targets[ i ]->mt_timeout[ SLAP_OP_SEARCH ] 855 && mi->mi_targets[ i ]->mt_timeout[ SLAP_OP_SEARCH ] > timeout ) 856 { 857 timeout = mi->mi_targets[ i ]->mt_timeout[ SLAP_OP_SEARCH ]; 858 } 859 } 860 861 for ( i = 0; i < mi->mi_ntargets; i++ ) { 862 if ( !META_IS_CANDIDATE( &candidates[ i ] ) 863 || candidates[ i ].sr_err != LDAP_SUCCESS ) 864 { 865 continue; 866 } 867 868 switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ) ) 869 { 870 case META_SEARCH_NOT_CANDIDATE: 871 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 872 break; 873 874 case META_SEARCH_NEED_BIND: 875 ++needbind; 876 /* fallthru */ 877 878 case META_SEARCH_CONNECTING: 879 case META_SEARCH_CANDIDATE: 880 case META_SEARCH_BINDING: 881 candidates[ i ].sr_type = REP_INTERMEDIATE; 882 ++ncandidates; 883 break; 884 885 case META_SEARCH_ERR: 886 savepriv = op->o_private; 887 op->o_private = (void *)i; 888 send_ldap_result( op, rs ); 889 op->o_private = savepriv; 890 rc = -1; 891 goto finish; 892 893 default: 894 assert( 0 ); 895 break; 896 } 897 } 898 899 if ( ncandidates > 0 && needbind == ncandidates ) { 900 /* 901 * give up the second time... 902 * 903 * NOTE: this should not occur the second time, since a fresh 904 * connection has ben created; however, targets may also 905 * need bind because the bind timed out or so. 906 */ 907 if ( sendok & LDAP_BACK_BINDING ) { 908 Debug( LDAP_DEBUG_ANY, 909 "%s meta_back_search: unable to initialize conn\n", 910 op->o_log_prefix, 0, 0 ); 911 rs->sr_err = LDAP_UNAVAILABLE; 912 rs->sr_text = "unable to initialize connection to remote targets"; 913 send_ldap_result( op, rs ); 914 rc = -1; 915 goto finish; 916 } 917 918 /* FIXME: better create a separate connection? */ 919 sendok |= LDAP_BACK_BINDING; 920 921 #ifdef DEBUG_205 922 Debug( LDAP_DEBUG_ANY, "*** %s drop mc=%p create new connection\n", 923 op->o_log_prefix, (void *)mc, 0 ); 924 #endif /* DEBUG_205 */ 925 926 meta_back_release_conn( mi, mc ); 927 mc = NULL; 928 929 needbind = 0; 930 ncandidates = 0; 931 932 goto getconn; 933 } 934 935 initial_candidates = ncandidates; 936 937 if ( LogTest( LDAP_DEBUG_TRACE ) ) { 938 char cnd[ SLAP_TEXT_BUFLEN ]; 939 int c; 940 941 for ( c = 0; c < mi->mi_ntargets; c++ ) { 942 if ( META_IS_CANDIDATE( &candidates[ c ] ) ) { 943 cnd[ c ] = '*'; 944 } else { 945 cnd[ c ] = ' '; 946 } 947 } 948 cnd[ c ] = '\0'; 949 950 Debug( LDAP_DEBUG_TRACE, "%s meta_back_search: ncandidates=%d " 951 "cnd=\"%s\"\n", op->o_log_prefix, ncandidates, cnd ); 952 } 953 954 if ( initial_candidates == 0 ) { 955 /* NOTE: here we are not sending any matchedDN; 956 * this is intended, because if the back-meta 957 * is serving this search request, but no valid 958 * candidate could be looked up, it means that 959 * there is a hole in the mapping of the targets 960 * and thus no knowledge of any remote superior 961 * is available */ 962 Debug( LDAP_DEBUG_ANY, "%s meta_back_search: " 963 "base=\"%s\" scope=%d: " 964 "no candidate could be selected\n", 965 op->o_log_prefix, op->o_req_dn.bv_val, 966 op->ors_scope ); 967 968 /* FIXME: we're sending the first error we encounter; 969 * maybe we should pick the worst... */ 970 rc = LDAP_NO_SUCH_OBJECT; 971 for ( i = 0; i < mi->mi_ntargets; i++ ) { 972 if ( META_IS_CANDIDATE( &candidates[ i ] ) 973 && candidates[ i ].sr_err != LDAP_SUCCESS ) 974 { 975 rc = candidates[ i ].sr_err; 976 break; 977 } 978 } 979 980 send_ldap_error( op, rs, rc, NULL ); 981 982 goto finish; 983 } 984 985 /* We pull apart the ber result, stuff it into a slapd entry, and 986 * let send_search_entry stuff it back into ber format. Slow & ugly, 987 * but this is necessary for version matching, and for ACL processing. 988 */ 989 990 if ( op->ors_tlimit != SLAP_NO_LIMIT ) { 991 stoptime = op->o_time + op->ors_tlimit; 992 } 993 994 /* 995 * In case there are no candidates, no cycle takes place... 996 * 997 * FIXME: we might use a queue, to better balance the load 998 * among the candidates 999 */ 1000 for ( rc = 0; ncandidates > 0; ) { 1001 int gotit = 0, 1002 doabandon = 0, 1003 alreadybound = ncandidates; 1004 1005 /* check timeout */ 1006 if ( timeout && lastres_time > 0 1007 && ( slap_get_time() - lastres_time ) > timeout ) 1008 { 1009 doabandon = 1; 1010 rs->sr_text = "Operation timed out"; 1011 rc = rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? 1012 LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER; 1013 savepriv = op->o_private; 1014 op->o_private = (void *)i; 1015 send_ldap_result( op, rs ); 1016 op->o_private = savepriv; 1017 goto finish; 1018 } 1019 1020 /* check time limit */ 1021 if ( op->ors_tlimit != SLAP_NO_LIMIT 1022 && slap_get_time() > stoptime ) 1023 { 1024 doabandon = 1; 1025 rc = rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; 1026 savepriv = op->o_private; 1027 op->o_private = (void *)i; 1028 send_ldap_result( op, rs ); 1029 op->o_private = savepriv; 1030 goto finish; 1031 } 1032 1033 for ( i = 0; i < mi->mi_ntargets; i++ ) { 1034 meta_search_candidate_t retcode = META_SEARCH_UNDEFINED; 1035 metasingleconn_t *msc = &mc->mc_conns[ i ]; 1036 LDAPMessage *res = NULL, *msg; 1037 1038 /* if msgid is invalid, don't ldap_result() */ 1039 if ( candidates[ i ].sr_msgid == META_MSGID_IGNORE ) { 1040 continue; 1041 } 1042 1043 /* if target still needs bind, retry */ 1044 if ( candidates[ i ].sr_msgid == META_MSGID_NEED_BIND 1045 || candidates[ i ].sr_msgid == META_MSGID_CONNECTING ) 1046 { 1047 /* initiate dobind */ 1048 retcode = meta_search_dobind_init( op, rs, &mc, i, candidates ); 1049 1050 Debug( LDAP_DEBUG_TRACE, "%s <<< meta_search_dobind_init[%ld]=%d\n", 1051 op->o_log_prefix, i, retcode ); 1052 1053 switch ( retcode ) { 1054 case META_SEARCH_NEED_BIND: 1055 alreadybound--; 1056 /* fallthru */ 1057 1058 case META_SEARCH_CONNECTING: 1059 case META_SEARCH_BINDING: 1060 break; 1061 1062 case META_SEARCH_ERR: 1063 candidates[ i ].sr_err = rs->sr_err; 1064 if ( META_BACK_ONERR_STOP( mi ) ) { 1065 savepriv = op->o_private; 1066 op->o_private = (void *)i; 1067 send_ldap_result( op, rs ); 1068 op->o_private = savepriv; 1069 goto finish; 1070 } 1071 /* fallthru */ 1072 1073 case META_SEARCH_NOT_CANDIDATE: 1074 /* 1075 * When no candidates are left, 1076 * the outer cycle finishes 1077 */ 1078 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1079 assert( ncandidates > 0 ); 1080 --ncandidates; 1081 break; 1082 1083 case META_SEARCH_CANDIDATE: 1084 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1085 switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ) ) 1086 { 1087 case META_SEARCH_CANDIDATE: 1088 assert( candidates[ i ].sr_msgid >= 0 ); 1089 break; 1090 1091 case META_SEARCH_ERR: 1092 candidates[ i ].sr_err = rs->sr_err; 1093 if ( META_BACK_ONERR_STOP( mi ) ) { 1094 savepriv = op->o_private; 1095 op->o_private = (void *)i; 1096 send_ldap_result( op, rs ); 1097 op->o_private = savepriv; 1098 goto finish; 1099 } 1100 /* fallthru */ 1101 1102 case META_SEARCH_NOT_CANDIDATE: 1103 /* means that meta_back_search_start() 1104 * failed but onerr == continue */ 1105 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1106 assert( ncandidates > 0 ); 1107 --ncandidates; 1108 break; 1109 1110 default: 1111 /* impossible */ 1112 assert( 0 ); 1113 break; 1114 } 1115 break; 1116 1117 default: 1118 /* impossible */ 1119 assert( 0 ); 1120 break; 1121 } 1122 continue; 1123 } 1124 1125 /* check for abandon */ 1126 if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) { 1127 break; 1128 } 1129 1130 #ifdef DEBUG_205 1131 if ( msc->msc_ld == NULL ) { 1132 char buf[ SLAP_TEXT_BUFLEN ]; 1133 1134 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 1135 snprintf( buf, sizeof( buf ), 1136 "%s meta_back_search[%ld] mc=%p msgid=%d%s%s%s\n", 1137 op->o_log_prefix, (long)i, (void *)mc, 1138 candidates[ i ].sr_msgid, 1139 META_IS_BINDING( &candidates[ i ] ) ? " binding" : "", 1140 LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ? " connbinding" : "", 1141 META_BACK_CONN_CREATING( &mc->mc_conns[ i ] ) ? " conncreating" : "" ); 1142 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 1143 1144 Debug( LDAP_DEBUG_ANY, "!!! %s\n", buf, 0, 0 ); 1145 } 1146 #endif /* DEBUG_205 */ 1147 1148 /* 1149 * FIXME: handle time limit as well? 1150 * Note that target servers are likely 1151 * to handle it, so at some time we'll 1152 * get a LDAP_TIMELIMIT_EXCEEDED from 1153 * one of them ... 1154 */ 1155 tv = save_tv; 1156 rc = ldap_result( msc->msc_ld, candidates[ i ].sr_msgid, 1157 LDAP_MSG_RECEIVED, &tv, &res ); 1158 switch ( rc ) { 1159 case 0: 1160 /* FIXME: res should not need to be freed */ 1161 assert( res == NULL ); 1162 continue; 1163 1164 case -1: 1165 really_bad:; 1166 /* something REALLY bad happened! */ 1167 if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { 1168 candidates[ i ].sr_type = REP_RESULT; 1169 1170 if ( meta_back_retry( op, rs, &mc, i, LDAP_BACK_DONTSEND ) ) { 1171 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1172 switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ) ) 1173 { 1174 /* means that failed but onerr == continue */ 1175 case META_SEARCH_NOT_CANDIDATE: 1176 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1177 1178 assert( ncandidates > 0 ); 1179 --ncandidates; 1180 1181 candidates[ i ].sr_err = rs->sr_err; 1182 if ( META_BACK_ONERR_STOP( mi ) ) { 1183 savepriv = op->o_private; 1184 op->o_private = (void *)i; 1185 send_ldap_result( op, rs ); 1186 op->o_private = savepriv; 1187 goto finish; 1188 } 1189 /* fall thru */ 1190 1191 case META_SEARCH_CANDIDATE: 1192 /* get back into business... */ 1193 continue; 1194 1195 case META_SEARCH_BINDING: 1196 case META_SEARCH_CONNECTING: 1197 case META_SEARCH_NEED_BIND: 1198 case META_SEARCH_UNDEFINED: 1199 assert( 0 ); 1200 1201 default: 1202 /* unrecoverable error */ 1203 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1204 rc = rs->sr_err = LDAP_OTHER; 1205 goto finish; 1206 } 1207 } 1208 1209 candidates[ i ].sr_err = rs->sr_err; 1210 if ( META_BACK_ONERR_STOP( mi ) ) { 1211 savepriv = op->o_private; 1212 op->o_private = (void *)i; 1213 send_ldap_result( op, rs ); 1214 op->o_private = savepriv; 1215 goto finish; 1216 } 1217 } 1218 1219 /* 1220 * When no candidates are left, 1221 * the outer cycle finishes 1222 */ 1223 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1224 assert( ncandidates > 0 ); 1225 --ncandidates; 1226 rs->sr_err = candidates[ i ].sr_err; 1227 continue; 1228 1229 default: 1230 lastres_time = slap_get_time(); 1231 1232 /* only touch when activity actually took place... */ 1233 if ( mi->mi_idle_timeout != 0 && msc->msc_time < lastres_time ) { 1234 msc->msc_time = lastres_time; 1235 } 1236 break; 1237 } 1238 1239 for ( msg = ldap_first_message( msc->msc_ld, res ); 1240 msg != NULL; 1241 msg = ldap_next_message( msc->msc_ld, msg ) ) 1242 { 1243 rc = ldap_msgtype( msg ); 1244 if ( rc == LDAP_RES_SEARCH_ENTRY ) { 1245 LDAPMessage *e; 1246 1247 if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { 1248 /* don't retry any more... */ 1249 candidates[ i ].sr_type = REP_RESULT; 1250 } 1251 1252 /* count entries returned by target */ 1253 candidates[ i ].sr_nentries++; 1254 1255 is_ok++; 1256 1257 e = ldap_first_entry( msc->msc_ld, msg ); 1258 savepriv = op->o_private; 1259 op->o_private = (void *)i; 1260 rs->sr_err = meta_send_entry( op, rs, mc, i, e ); 1261 1262 switch ( rs->sr_err ) { 1263 case LDAP_SIZELIMIT_EXCEEDED: 1264 savepriv = op->o_private; 1265 op->o_private = (void *)i; 1266 send_ldap_result( op, rs ); 1267 op->o_private = savepriv; 1268 rs->sr_err = LDAP_SUCCESS; 1269 ldap_msgfree( res ); 1270 res = NULL; 1271 goto finish; 1272 1273 case LDAP_UNAVAILABLE: 1274 rs->sr_err = LDAP_OTHER; 1275 ldap_msgfree( res ); 1276 res = NULL; 1277 goto finish; 1278 } 1279 op->o_private = savepriv; 1280 1281 /* don't wait any longer... */ 1282 gotit = 1; 1283 save_tv.tv_sec = 0; 1284 save_tv.tv_usec = 0; 1285 1286 } else if ( rc == LDAP_RES_SEARCH_REFERENCE ) { 1287 char **references = NULL; 1288 int cnt; 1289 1290 if ( META_BACK_TGT_NOREFS( mi->mi_targets[ i ] ) ) { 1291 continue; 1292 } 1293 1294 if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { 1295 /* don't retry any more... */ 1296 candidates[ i ].sr_type = REP_RESULT; 1297 } 1298 1299 is_ok++; 1300 1301 rc = ldap_parse_reference( msc->msc_ld, msg, 1302 &references, &rs->sr_ctrls, 0 ); 1303 1304 if ( rc != LDAP_SUCCESS ) { 1305 continue; 1306 } 1307 1308 if ( references == NULL ) { 1309 continue; 1310 } 1311 1312 #ifdef ENABLE_REWRITE 1313 dc.ctx = "referralDN"; 1314 #else /* ! ENABLE_REWRITE */ 1315 dc.tofrom = 0; 1316 dc.normalized = 0; 1317 #endif /* ! ENABLE_REWRITE */ 1318 1319 /* FIXME: merge all and return at the end */ 1320 1321 for ( cnt = 0; references[ cnt ]; cnt++ ) 1322 ; 1323 1324 rs->sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ), 1325 op->o_tmpmemctx ); 1326 1327 for ( cnt = 0; references[ cnt ]; cnt++ ) { 1328 ber_str2bv_x( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ], 1329 op->o_tmpmemctx ); 1330 } 1331 BER_BVZERO( &rs->sr_ref[ cnt ] ); 1332 1333 ( void )ldap_back_referral_result_rewrite( &dc, rs->sr_ref, 1334 op->o_tmpmemctx ); 1335 1336 if ( rs->sr_ref != NULL && !BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) { 1337 /* ignore return value by now */ 1338 savepriv = op->o_private; 1339 op->o_private = (void *)i; 1340 ( void )send_search_reference( op, rs ); 1341 op->o_private = savepriv; 1342 1343 ber_bvarray_free_x( rs->sr_ref, op->o_tmpmemctx ); 1344 rs->sr_ref = NULL; 1345 } 1346 1347 /* cleanup */ 1348 if ( references ) { 1349 ber_memvfree( (void **)references ); 1350 } 1351 1352 if ( rs->sr_ctrls ) { 1353 ldap_controls_free( rs->sr_ctrls ); 1354 rs->sr_ctrls = NULL; 1355 } 1356 1357 } else if ( rc == LDAP_RES_INTERMEDIATE ) { 1358 if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { 1359 /* don't retry any more... */ 1360 candidates[ i ].sr_type = REP_RESULT; 1361 } 1362 1363 /* FIXME: response controls 1364 * are passed without checks */ 1365 rs->sr_err = ldap_parse_intermediate( msc->msc_ld, 1366 msg, 1367 (char **)&rs->sr_rspoid, 1368 &rs->sr_rspdata, 1369 &rs->sr_ctrls, 1370 0 ); 1371 if ( rs->sr_err != LDAP_SUCCESS ) { 1372 candidates[ i ].sr_type = REP_RESULT; 1373 ldap_msgfree( res ); 1374 res = NULL; 1375 goto really_bad; 1376 } 1377 1378 slap_send_ldap_intermediate( op, rs ); 1379 1380 if ( rs->sr_rspoid != NULL ) { 1381 ber_memfree( (char *)rs->sr_rspoid ); 1382 rs->sr_rspoid = NULL; 1383 } 1384 1385 if ( rs->sr_rspdata != NULL ) { 1386 ber_bvfree( rs->sr_rspdata ); 1387 rs->sr_rspdata = NULL; 1388 } 1389 1390 if ( rs->sr_ctrls != NULL ) { 1391 ldap_controls_free( rs->sr_ctrls ); 1392 rs->sr_ctrls = NULL; 1393 } 1394 1395 } else if ( rc == LDAP_RES_SEARCH_RESULT ) { 1396 char buf[ SLAP_TEXT_BUFLEN ]; 1397 char **references = NULL; 1398 LDAPControl **ctrls = NULL; 1399 1400 if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { 1401 /* don't retry any more... */ 1402 candidates[ i ].sr_type = REP_RESULT; 1403 } 1404 1405 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1406 1407 /* NOTE: ignores response controls 1408 * (and intermediate response controls 1409 * as well, except for those with search 1410 * references); this may not be correct, 1411 * but if they're not ignored then 1412 * back-meta would need to merge them 1413 * consistently (think of pagedResults...) 1414 */ 1415 /* FIXME: response controls? */ 1416 rs->sr_err = ldap_parse_result( msc->msc_ld, 1417 msg, 1418 &candidates[ i ].sr_err, 1419 (char **)&candidates[ i ].sr_matched, 1420 (char **)&candidates[ i ].sr_text, 1421 &references, 1422 &ctrls /* &candidates[ i ].sr_ctrls (unused) */ , 1423 0 ); 1424 if ( rs->sr_err != LDAP_SUCCESS ) { 1425 candidates[ i ].sr_err = rs->sr_err; 1426 sres = slap_map_api2result( &candidates[ i ] ); 1427 candidates[ i ].sr_type = REP_RESULT; 1428 ldap_msgfree( res ); 1429 res = NULL; 1430 goto really_bad; 1431 } 1432 1433 rs->sr_err = candidates[ i ].sr_err; 1434 1435 /* massage matchedDN if need be */ 1436 if ( candidates[ i ].sr_matched != NULL ) { 1437 struct berval match, mmatch; 1438 1439 ber_str2bv( candidates[ i ].sr_matched, 1440 0, 0, &match ); 1441 candidates[ i ].sr_matched = NULL; 1442 1443 dc.ctx = "matchedDN"; 1444 dc.target = mi->mi_targets[ i ]; 1445 if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) { 1446 if ( mmatch.bv_val == match.bv_val ) { 1447 candidates[ i ].sr_matched 1448 = ch_strdup( mmatch.bv_val ); 1449 1450 } else { 1451 candidates[ i ].sr_matched = mmatch.bv_val; 1452 } 1453 1454 candidate_match++; 1455 } 1456 ldap_memfree( match.bv_val ); 1457 } 1458 1459 /* add references to array */ 1460 /* RFC 4511: referrals can only appear 1461 * if result code is LDAP_REFERRAL */ 1462 if ( references != NULL 1463 && references[ 0 ] != NULL 1464 && references[ 0 ][ 0 ] != '\0' ) 1465 { 1466 if ( rs->sr_err != LDAP_REFERRAL ) { 1467 Debug( LDAP_DEBUG_ANY, 1468 "%s meta_back_search[%ld]: " 1469 "got referrals with err=%d\n", 1470 op->o_log_prefix, 1471 i, rs->sr_err ); 1472 1473 } else { 1474 BerVarray sr_ref; 1475 int cnt; 1476 1477 for ( cnt = 0; references[ cnt ]; cnt++ ) 1478 ; 1479 1480 sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ), 1481 op->o_tmpmemctx ); 1482 1483 for ( cnt = 0; references[ cnt ]; cnt++ ) { 1484 ber_str2bv_x( references[ cnt ], 0, 1, &sr_ref[ cnt ], 1485 op->o_tmpmemctx ); 1486 } 1487 BER_BVZERO( &sr_ref[ cnt ] ); 1488 1489 ( void )ldap_back_referral_result_rewrite( &dc, sr_ref, 1490 op->o_tmpmemctx ); 1491 1492 if ( rs->sr_v2ref == NULL ) { 1493 rs->sr_v2ref = sr_ref; 1494 1495 } else { 1496 for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) { 1497 ber_bvarray_add_x( &rs->sr_v2ref, &sr_ref[ cnt ], 1498 op->o_tmpmemctx ); 1499 } 1500 ber_memfree_x( sr_ref, op->o_tmpmemctx ); 1501 } 1502 } 1503 1504 } else if ( rs->sr_err == LDAP_REFERRAL ) { 1505 Debug( LDAP_DEBUG_ANY, 1506 "%s meta_back_search[%ld]: " 1507 "got err=%d with null " 1508 "or empty referrals\n", 1509 op->o_log_prefix, 1510 i, rs->sr_err ); 1511 1512 rs->sr_err = LDAP_NO_SUCH_OBJECT; 1513 } 1514 1515 /* cleanup */ 1516 ber_memvfree( (void **)references ); 1517 1518 sres = slap_map_api2result( rs ); 1519 1520 if ( LogTest( LDAP_DEBUG_TRACE | LDAP_DEBUG_ANY ) ) { 1521 snprintf( buf, sizeof( buf ), 1522 "%s meta_back_search[%ld] " 1523 "match=\"%s\" err=%ld", 1524 op->o_log_prefix, i, 1525 candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "", 1526 (long) candidates[ i ].sr_err ); 1527 if ( candidates[ i ].sr_err == LDAP_SUCCESS ) { 1528 Debug( LDAP_DEBUG_TRACE, "%s.\n", buf, 0, 0 ); 1529 1530 } else { 1531 Debug( LDAP_DEBUG_ANY, "%s (%s).\n", 1532 buf, ldap_err2string( candidates[ i ].sr_err ), 0 ); 1533 } 1534 } 1535 1536 switch ( sres ) { 1537 case LDAP_NO_SUCH_OBJECT: 1538 /* is_ok is touched any time a valid 1539 * (even intermediate) result is 1540 * returned; as a consequence, if 1541 * a candidate returns noSuchObject 1542 * it is ignored and the candidate 1543 * is simply demoted. */ 1544 if ( is_ok ) { 1545 sres = LDAP_SUCCESS; 1546 } 1547 break; 1548 1549 case LDAP_SUCCESS: 1550 if ( ctrls != NULL && ctrls[0] != NULL ) { 1551 #ifdef SLAPD_META_CLIENT_PR 1552 LDAPControl *pr_c; 1553 1554 pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL ); 1555 if ( pr_c != NULL ) { 1556 BerElementBuffer berbuf; 1557 BerElement *ber = (BerElement *)&berbuf; 1558 ber_tag_t tag; 1559 ber_int_t prsize; 1560 struct berval prcookie; 1561 1562 /* unsolicited, do not accept */ 1563 if ( mi->mi_targets[i]->mt_ps == 0 ) { 1564 rs->sr_err = LDAP_OTHER; 1565 goto err_pr; 1566 } 1567 1568 ber_init2( ber, &pr_c->ldctl_value, LBER_USE_DER ); 1569 1570 tag = ber_scanf( ber, "{im}", &prsize, &prcookie ); 1571 if ( tag == LBER_ERROR ) { 1572 rs->sr_err = LDAP_OTHER; 1573 goto err_pr; 1574 } 1575 1576 /* more pages? new search request */ 1577 if ( !BER_BVISNULL( &prcookie ) && !BER_BVISEMPTY( &prcookie ) ) { 1578 if ( mi->mi_targets[i]->mt_ps > 0 ) { 1579 /* ignore size if specified */ 1580 prsize = 0; 1581 1582 } else if ( prsize == 0 ) { 1583 /* guess the page size from the entries returned so far */ 1584 prsize = candidates[ i ].sr_nentries; 1585 } 1586 1587 candidates[ i ].sr_nentries = 0; 1588 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1589 candidates[ i ].sr_type = REP_INTERMEDIATE; 1590 1591 assert( candidates[ i ].sr_matched == NULL ); 1592 assert( candidates[ i ].sr_text == NULL ); 1593 assert( candidates[ i ].sr_ref == NULL ); 1594 1595 switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, &prcookie, prsize ) ) 1596 { 1597 case META_SEARCH_CANDIDATE: 1598 assert( candidates[ i ].sr_msgid >= 0 ); 1599 ldap_controls_free( ctrls ); 1600 goto free_message; 1601 1602 case META_SEARCH_ERR: 1603 err_pr:; 1604 candidates[ i ].sr_err = rs->sr_err; 1605 if ( META_BACK_ONERR_STOP( mi ) ) { 1606 savepriv = op->o_private; 1607 op->o_private = (void *)i; 1608 send_ldap_result( op, rs ); 1609 op->o_private = savepriv; 1610 ldap_controls_free( ctrls ); 1611 goto finish; 1612 } 1613 /* fallthru */ 1614 1615 case META_SEARCH_NOT_CANDIDATE: 1616 /* means that meta_back_search_start() 1617 * failed but onerr == continue */ 1618 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1619 assert( ncandidates > 0 ); 1620 --ncandidates; 1621 break; 1622 1623 default: 1624 /* impossible */ 1625 assert( 0 ); 1626 break; 1627 } 1628 break; 1629 } 1630 } 1631 #endif /* SLAPD_META_CLIENT_PR */ 1632 1633 ldap_controls_free( ctrls ); 1634 } 1635 /* fallthru */ 1636 1637 case LDAP_REFERRAL: 1638 is_ok++; 1639 break; 1640 1641 case LDAP_SIZELIMIT_EXCEEDED: 1642 /* if a target returned sizelimitExceeded 1643 * and the entry count is equal to the 1644 * proxy's limit, the target would have 1645 * returned more, and the error must be 1646 * propagated to the client; otherwise, 1647 * the target enforced a limit lower 1648 * than what requested by the proxy; 1649 * ignore it */ 1650 candidates[ i ].sr_err = rs->sr_err; 1651 if ( rs->sr_nentries == op->ors_slimit 1652 || META_BACK_ONERR_STOP( mi ) ) 1653 { 1654 const char *save_text = rs->sr_text; 1655 savepriv = op->o_private; 1656 op->o_private = (void *)i; 1657 rs->sr_text = candidates[ i ].sr_text; 1658 send_ldap_result( op, rs ); 1659 rs->sr_text = save_text; 1660 op->o_private = savepriv; 1661 ldap_msgfree( res ); 1662 res = NULL; 1663 goto finish; 1664 } 1665 break; 1666 1667 default: 1668 candidates[ i ].sr_err = rs->sr_err; 1669 if ( META_BACK_ONERR_STOP( mi ) ) { 1670 const char *save_text = rs->sr_text; 1671 savepriv = op->o_private; 1672 op->o_private = (void *)i; 1673 rs->sr_text = candidates[ i ].sr_text; 1674 send_ldap_result( op, rs ); 1675 rs->sr_text = save_text; 1676 op->o_private = savepriv; 1677 ldap_msgfree( res ); 1678 res = NULL; 1679 goto finish; 1680 } 1681 break; 1682 } 1683 1684 last = i; 1685 rc = 0; 1686 1687 /* 1688 * When no candidates are left, 1689 * the outer cycle finishes 1690 */ 1691 assert( ncandidates > 0 ); 1692 --ncandidates; 1693 1694 } else if ( rc == LDAP_RES_BIND ) { 1695 meta_search_candidate_t retcode; 1696 1697 retcode = meta_search_dobind_result( op, rs, &mc, i, candidates, msg ); 1698 if ( retcode == META_SEARCH_CANDIDATE ) { 1699 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1700 retcode = meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ); 1701 } 1702 1703 switch ( retcode ) { 1704 case META_SEARCH_CANDIDATE: 1705 break; 1706 1707 /* means that failed but onerr == continue */ 1708 case META_SEARCH_NOT_CANDIDATE: 1709 case META_SEARCH_ERR: 1710 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1711 assert( ncandidates > 0 ); 1712 --ncandidates; 1713 1714 candidates[ i ].sr_err = rs->sr_err; 1715 if ( META_BACK_ONERR_STOP( mi ) ) { 1716 savepriv = op->o_private; 1717 op->o_private = (void *)i; 1718 send_ldap_result( op, rs ); 1719 op->o_private = savepriv; 1720 ldap_msgfree( res ); 1721 res = NULL; 1722 goto finish; 1723 } 1724 goto free_message; 1725 1726 default: 1727 assert( 0 ); 1728 break; 1729 } 1730 1731 } else { 1732 Debug( LDAP_DEBUG_ANY, 1733 "%s meta_back_search[%ld]: " 1734 "unrecognized response message tag=%d\n", 1735 op->o_log_prefix, 1736 i, rc ); 1737 1738 ldap_msgfree( res ); 1739 res = NULL; 1740 goto really_bad; 1741 } 1742 } 1743 1744 free_message:; 1745 ldap_msgfree( res ); 1746 res = NULL; 1747 } 1748 1749 /* check for abandon */ 1750 if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( mc ) ) { 1751 for ( i = 0; i < mi->mi_ntargets; i++ ) { 1752 if ( candidates[ i ].sr_msgid >= 0 1753 || candidates[ i ].sr_msgid == META_MSGID_CONNECTING ) 1754 { 1755 if ( META_IS_BINDING( &candidates[ i ] ) 1756 || candidates[ i ].sr_msgid == META_MSGID_CONNECTING ) 1757 { 1758 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 1759 if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) 1760 || candidates[ i ].sr_msgid == META_MSGID_CONNECTING ) 1761 { 1762 /* if still binding, destroy */ 1763 1764 #ifdef DEBUG_205 1765 char buf[ SLAP_TEXT_BUFLEN ]; 1766 1767 snprintf( buf, sizeof( buf), "%s meta_back_search(abandon) " 1768 "ldap_unbind_ext[%ld] mc=%p ld=%p", 1769 op->o_log_prefix, i, (void *)mc, 1770 (void *)mc->mc_conns[i].msc_ld ); 1771 1772 Debug( LDAP_DEBUG_ANY, "### %s\n", buf, 0, 0 ); 1773 #endif /* DEBUG_205 */ 1774 1775 meta_clear_one_candidate( op, mc, i ); 1776 } 1777 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 1778 META_BINDING_CLEAR( &candidates[ i ] ); 1779 1780 } else { 1781 (void)meta_back_cancel( mc, op, rs, 1782 candidates[ i ].sr_msgid, i, 1783 LDAP_BACK_DONTSEND ); 1784 } 1785 1786 candidates[ i ].sr_msgid = META_MSGID_IGNORE; 1787 assert( ncandidates > 0 ); 1788 --ncandidates; 1789 } 1790 } 1791 1792 if ( op->o_abandon ) { 1793 rc = SLAPD_ABANDON; 1794 } 1795 1796 /* let send_ldap_result play cleanup handlers (ITS#4645) */ 1797 break; 1798 } 1799 1800 /* if no entry was found during this loop, 1801 * set a minimal timeout */ 1802 if ( ncandidates > 0 && gotit == 0 ) { 1803 if ( save_tv.tv_sec == 0 && save_tv.tv_usec == 0 ) { 1804 save_tv.tv_usec = LDAP_BACK_RESULT_UTIMEOUT/initial_candidates; 1805 1806 /* arbitrarily limit to something between 1 and 2 minutes */ 1807 } else if ( ( stoptime == -1 && save_tv.tv_sec < 60 ) 1808 || save_tv.tv_sec < ( stoptime - slap_get_time() ) / ( 2 * ncandidates ) ) 1809 { 1810 /* double the timeout */ 1811 lutil_timermul( &save_tv, 2, &save_tv ); 1812 } 1813 1814 if ( alreadybound == 0 ) { 1815 tv = save_tv; 1816 (void)select( 0, NULL, NULL, NULL, &tv ); 1817 1818 } else { 1819 ldap_pvt_thread_yield(); 1820 } 1821 } 1822 } 1823 1824 if ( rc == -1 ) { 1825 /* 1826 * FIXME: need a better strategy to handle errors 1827 */ 1828 if ( mc ) { 1829 rc = meta_back_op_result( mc, op, rs, META_TARGET_NONE, 1830 -1, stoptime != -1 ? (stoptime - slap_get_time()) : 0, 1831 LDAP_BACK_SENDERR ); 1832 } else { 1833 rc = rs->sr_err; 1834 } 1835 goto finish; 1836 } 1837 1838 /* 1839 * Rewrite the matched portion of the search base, if required 1840 * 1841 * FIXME: only the last one gets caught! 1842 */ 1843 savepriv = op->o_private; 1844 op->o_private = (void *)(long)mi->mi_ntargets; 1845 if ( candidate_match > 0 ) { 1846 struct berval pmatched = BER_BVNULL; 1847 1848 /* we use the first one */ 1849 for ( i = 0; i < mi->mi_ntargets; i++ ) { 1850 if ( META_IS_CANDIDATE( &candidates[ i ] ) 1851 && candidates[ i ].sr_matched != NULL ) 1852 { 1853 struct berval bv, pbv; 1854 int rc; 1855 1856 /* if we got success, and this target 1857 * returned noSuchObject, and its suffix 1858 * is a superior of the searchBase, 1859 * ignore the matchedDN */ 1860 if ( sres == LDAP_SUCCESS 1861 && candidates[ i ].sr_err == LDAP_NO_SUCH_OBJECT 1862 && op->o_req_ndn.bv_len > mi->mi_targets[ i ]->mt_nsuffix.bv_len ) 1863 { 1864 free( (char *)candidates[ i ].sr_matched ); 1865 candidates[ i ].sr_matched = NULL; 1866 continue; 1867 } 1868 1869 ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv ); 1870 rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx ); 1871 1872 if ( rc == LDAP_SUCCESS ) { 1873 1874 /* NOTE: if they all are superiors 1875 * of the baseDN, the shorter is also 1876 * superior of the longer... */ 1877 if ( pbv.bv_len > pmatched.bv_len ) { 1878 if ( !BER_BVISNULL( &pmatched ) ) { 1879 op->o_tmpfree( pmatched.bv_val, op->o_tmpmemctx ); 1880 } 1881 pmatched = pbv; 1882 op->o_private = (void *)i; 1883 1884 } else { 1885 op->o_tmpfree( pbv.bv_val, op->o_tmpmemctx ); 1886 } 1887 } 1888 1889 if ( candidates[ i ].sr_matched != NULL ) { 1890 free( (char *)candidates[ i ].sr_matched ); 1891 candidates[ i ].sr_matched = NULL; 1892 } 1893 } 1894 } 1895 1896 if ( !BER_BVISNULL( &pmatched ) ) { 1897 matched = pmatched.bv_val; 1898 } 1899 1900 } else if ( sres == LDAP_NO_SUCH_OBJECT ) { 1901 matched = op->o_bd->be_suffix[ 0 ].bv_val; 1902 } 1903 1904 /* 1905 * In case we returned at least one entry, we return LDAP_SUCCESS 1906 * otherwise, the latter error code we got 1907 */ 1908 1909 if ( sres == LDAP_SUCCESS ) { 1910 if ( rs->sr_v2ref ) { 1911 sres = LDAP_REFERRAL; 1912 } 1913 1914 if ( META_BACK_ONERR_REPORT( mi ) ) { 1915 /* 1916 * Report errors, if any 1917 * 1918 * FIXME: we should handle error codes and return the more 1919 * important/reasonable 1920 */ 1921 for ( i = 0; i < mi->mi_ntargets; i++ ) { 1922 if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) { 1923 continue; 1924 } 1925 1926 if ( candidates[ i ].sr_err != LDAP_SUCCESS 1927 && candidates[ i ].sr_err != LDAP_NO_SUCH_OBJECT ) 1928 { 1929 sres = candidates[ i ].sr_err; 1930 break; 1931 } 1932 } 1933 } 1934 } 1935 1936 rs->sr_err = sres; 1937 rs->sr_matched = ( sres == LDAP_SUCCESS ? NULL : matched ); 1938 rs->sr_ref = ( sres == LDAP_REFERRAL ? rs->sr_v2ref : NULL ); 1939 send_ldap_result( op, rs ); 1940 op->o_private = savepriv; 1941 rs->sr_matched = NULL; 1942 rs->sr_ref = NULL; 1943 1944 finish:; 1945 if ( matched && matched != op->o_bd->be_suffix[ 0 ].bv_val ) { 1946 op->o_tmpfree( matched, op->o_tmpmemctx ); 1947 } 1948 1949 if ( rs->sr_v2ref ) { 1950 ber_bvarray_free_x( rs->sr_v2ref, op->o_tmpmemctx ); 1951 } 1952 1953 for ( i = 0; i < mi->mi_ntargets; i++ ) { 1954 if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) { 1955 continue; 1956 } 1957 1958 if ( mc ) { 1959 if ( META_IS_BINDING( &candidates[ i ] ) 1960 || candidates[ i ].sr_msgid == META_MSGID_CONNECTING ) 1961 { 1962 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 1963 if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) 1964 || candidates[ i ].sr_msgid == META_MSGID_CONNECTING ) 1965 { 1966 assert( candidates[ i ].sr_msgid >= 0 1967 || candidates[ i ].sr_msgid == META_MSGID_CONNECTING ); 1968 assert( mc->mc_conns[ i ].msc_ld != NULL ); 1969 1970 #ifdef DEBUG_205 1971 Debug( LDAP_DEBUG_ANY, "### %s meta_back_search(cleanup) " 1972 "ldap_unbind_ext[%ld] ld=%p\n", 1973 op->o_log_prefix, i, (void *)mc->mc_conns[i].msc_ld ); 1974 #endif /* DEBUG_205 */ 1975 1976 /* if still binding, destroy */ 1977 meta_clear_one_candidate( op, mc, i ); 1978 } 1979 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 1980 META_BINDING_CLEAR( &candidates[ i ] ); 1981 1982 } else if ( candidates[ i ].sr_msgid >= 0 ) { 1983 (void)meta_back_cancel( mc, op, rs, 1984 candidates[ i ].sr_msgid, i, 1985 LDAP_BACK_DONTSEND ); 1986 } 1987 } 1988 1989 if ( candidates[ i ].sr_matched ) { 1990 free( (char *)candidates[ i ].sr_matched ); 1991 candidates[ i ].sr_matched = NULL; 1992 } 1993 1994 if ( candidates[ i ].sr_text ) { 1995 ldap_memfree( (char *)candidates[ i ].sr_text ); 1996 candidates[ i ].sr_text = NULL; 1997 } 1998 1999 if ( candidates[ i ].sr_ref ) { 2000 ber_bvarray_free( candidates[ i ].sr_ref ); 2001 candidates[ i ].sr_ref = NULL; 2002 } 2003 2004 if ( candidates[ i ].sr_ctrls ) { 2005 ldap_controls_free( candidates[ i ].sr_ctrls ); 2006 candidates[ i ].sr_ctrls = NULL; 2007 } 2008 2009 if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) { 2010 meta_back_quarantine( op, &candidates[ i ], i ); 2011 } 2012 2013 /* only in case of timelimit exceeded, if the timelimit exceeded because 2014 * one contacted target never responded, invalidate the connection 2015 * NOTE: should we quarantine the target as well? right now, the connection 2016 * is invalidated; the next time it will be recreated and the target 2017 * will be quarantined if it cannot be contacted */ 2018 if ( mi->mi_idle_timeout != 0 2019 && rs->sr_err == LDAP_TIMELIMIT_EXCEEDED 2020 && op->o_time > mc->mc_conns[ i ].msc_time ) 2021 { 2022 /* don't let anyone else use this expired connection */ 2023 do_taint++; 2024 } 2025 } 2026 2027 if ( mc ) { 2028 ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); 2029 if ( do_taint ) { 2030 LDAP_BACK_CONN_TAINTED_SET( mc ); 2031 } 2032 meta_back_release_conn_lock( mi, mc, 0 ); 2033 ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); 2034 } 2035 2036 return rs->sr_err; 2037 } 2038 2039 static int 2040 meta_send_entry( 2041 Operation *op, 2042 SlapReply *rs, 2043 metaconn_t *mc, 2044 int target, 2045 LDAPMessage *e ) 2046 { 2047 metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; 2048 struct berval a, mapped; 2049 int check_duplicate_attrs = 0; 2050 int check_sorted_attrs = 0; 2051 Entry ent = { 0 }; 2052 BerElement ber = *ldap_get_message_ber( e ); 2053 Attribute *attr, **attrp; 2054 struct berval bdn, 2055 dn = BER_BVNULL; 2056 const char *text; 2057 dncookie dc; 2058 ber_len_t len; 2059 int rc; 2060 2061 if ( ber_scanf( &ber, "l{", &len ) == LBER_ERROR ) { 2062 return LDAP_DECODING_ERROR; 2063 } 2064 2065 if ( ber_set_option( &ber, LBER_OPT_REMAINING_BYTES, &len ) != LBER_OPT_SUCCESS ) { 2066 return LDAP_OTHER; 2067 } 2068 2069 if ( ber_scanf( &ber, "m{", &bdn ) == LBER_ERROR ) { 2070 return LDAP_DECODING_ERROR; 2071 } 2072 2073 /* 2074 * Rewrite the dn of the result, if needed 2075 */ 2076 dc.target = mi->mi_targets[ target ]; 2077 dc.conn = op->o_conn; 2078 dc.rs = rs; 2079 dc.ctx = "searchResult"; 2080 2081 rs->sr_err = ldap_back_dn_massage( &dc, &bdn, &dn ); 2082 if ( rs->sr_err != LDAP_SUCCESS) { 2083 return rs->sr_err; 2084 } 2085 2086 /* 2087 * Note: this may fail if the target host(s) schema differs 2088 * from the one known to the meta, and a DN with unknown 2089 * attributes is returned. 2090 * 2091 * FIXME: should we log anything, or delegate to dnNormalize? 2092 */ 2093 rc = dnPrettyNormal( NULL, &dn, &ent.e_name, &ent.e_nname, 2094 op->o_tmpmemctx ); 2095 if ( dn.bv_val != bdn.bv_val ) { 2096 free( dn.bv_val ); 2097 } 2098 BER_BVZERO( &dn ); 2099 2100 if ( rc != LDAP_SUCCESS ) { 2101 Debug( LDAP_DEBUG_ANY, 2102 "%s meta_send_entry(\"%s\"): " 2103 "invalid DN syntax\n", 2104 op->o_log_prefix, ent.e_name.bv_val, 0 ); 2105 rc = LDAP_INVALID_DN_SYNTAX; 2106 goto done; 2107 } 2108 2109 /* 2110 * cache dn 2111 */ 2112 if ( mi->mi_cache.ttl != META_DNCACHE_DISABLED ) { 2113 ( void )meta_dncache_update_entry( &mi->mi_cache, 2114 &ent.e_nname, target ); 2115 } 2116 2117 attrp = &ent.e_attrs; 2118 2119 dc.ctx = "searchAttrDN"; 2120 while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) { 2121 int last = 0; 2122 slap_syntax_validate_func *validate; 2123 slap_syntax_transform_func *pretty; 2124 2125 if ( ber_pvt_ber_remaining( &ber ) < 0 ) { 2126 Debug( LDAP_DEBUG_ANY, 2127 "%s meta_send_entry(\"%s\"): " 2128 "unable to parse attr \"%s\".\n", 2129 op->o_log_prefix, ent.e_name.bv_val, a.bv_val ); 2130 2131 rc = LDAP_OTHER; 2132 goto done; 2133 } 2134 2135 if ( ber_pvt_ber_remaining( &ber ) == 0 ) { 2136 break; 2137 } 2138 2139 ldap_back_map( &mi->mi_targets[ target ]->mt_rwmap.rwm_at, 2140 &a, &mapped, BACKLDAP_REMAP ); 2141 if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) { 2142 ( void )ber_scanf( &ber, "x" /* [W] */ ); 2143 continue; 2144 } 2145 if ( mapped.bv_val != a.bv_val ) { 2146 /* will need to check for duplicate attrs */ 2147 check_duplicate_attrs++; 2148 } 2149 attr = attr_alloc( NULL ); 2150 if ( attr == NULL ) { 2151 rc = LDAP_OTHER; 2152 goto done; 2153 } 2154 if ( slap_bv2ad( &mapped, &attr->a_desc, &text ) 2155 != LDAP_SUCCESS) { 2156 if ( slap_bv2undef_ad( &mapped, &attr->a_desc, &text, 2157 SLAP_AD_PROXIED ) != LDAP_SUCCESS ) 2158 { 2159 char buf[ SLAP_TEXT_BUFLEN ]; 2160 2161 snprintf( buf, sizeof( buf ), 2162 "%s meta_send_entry(\"%s\"): " 2163 "slap_bv2undef_ad(%s): %s\n", 2164 op->o_log_prefix, ent.e_name.bv_val, 2165 mapped.bv_val, text ); 2166 2167 Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 ); 2168 ( void )ber_scanf( &ber, "x" /* [W] */ ); 2169 attr_free( attr ); 2170 continue; 2171 } 2172 } 2173 2174 if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) 2175 check_sorted_attrs = 1; 2176 2177 /* no subschemaSubentry */ 2178 if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry 2179 || attr->a_desc == slap_schema.si_ad_entryDN ) 2180 { 2181 2182 /* 2183 * We eat target's subschemaSubentry because 2184 * a search for this value is likely not 2185 * to resolve to the appropriate backend; 2186 * later, the local subschemaSubentry is 2187 * added. 2188 * 2189 * We also eat entryDN because the frontend 2190 * will reattach it without checking if already 2191 * present... 2192 */ 2193 ( void )ber_scanf( &ber, "x" /* [W] */ ); 2194 attr_free(attr); 2195 continue; 2196 } 2197 2198 if ( ber_scanf( &ber, "[W]", &attr->a_vals ) == LBER_ERROR 2199 || attr->a_vals == NULL ) 2200 { 2201 attr->a_vals = (struct berval *)&slap_dummy_bv; 2202 2203 } else { 2204 for ( last = 0; !BER_BVISNULL( &attr->a_vals[ last ] ); ++last ) 2205 ; 2206 } 2207 attr->a_numvals = last; 2208 2209 validate = attr->a_desc->ad_type->sat_syntax->ssyn_validate; 2210 pretty = attr->a_desc->ad_type->sat_syntax->ssyn_pretty; 2211 2212 if ( !validate && !pretty ) { 2213 attr_free( attr ); 2214 goto next_attr; 2215 } 2216 2217 if ( attr->a_desc == slap_schema.si_ad_objectClass 2218 || attr->a_desc == slap_schema.si_ad_structuralObjectClass ) 2219 { 2220 struct berval *bv; 2221 2222 for ( bv = attr->a_vals; !BER_BVISNULL( bv ); bv++ ) { 2223 ObjectClass *oc; 2224 2225 ldap_back_map( &mi->mi_targets[ target ]->mt_rwmap.rwm_oc, 2226 bv, &mapped, BACKLDAP_REMAP ); 2227 if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0') { 2228 remove_oc:; 2229 free( bv->bv_val ); 2230 BER_BVZERO( bv ); 2231 if ( --last < 0 ) { 2232 break; 2233 } 2234 *bv = attr->a_vals[ last ]; 2235 BER_BVZERO( &attr->a_vals[ last ] ); 2236 bv--; 2237 2238 } else if ( mapped.bv_val != bv->bv_val ) { 2239 int i; 2240 2241 for ( i = 0; !BER_BVISNULL( &attr->a_vals[ i ] ); i++ ) { 2242 if ( &attr->a_vals[ i ] == bv ) { 2243 continue; 2244 } 2245 2246 if ( ber_bvstrcasecmp( &mapped, &attr->a_vals[ i ] ) == 0 ) { 2247 break; 2248 } 2249 } 2250 2251 if ( !BER_BVISNULL( &attr->a_vals[ i ] ) ) { 2252 goto remove_oc; 2253 } 2254 2255 ber_bvreplace( bv, &mapped ); 2256 2257 } else if ( ( oc = oc_bvfind_undef( bv ) ) == NULL ) { 2258 goto remove_oc; 2259 2260 } else { 2261 ber_bvreplace( bv, &oc->soc_cname ); 2262 } 2263 } 2264 /* 2265 * It is necessary to try to rewrite attributes with 2266 * dn syntax because they might be used in ACLs as 2267 * members of groups; since ACLs are applied to the 2268 * rewritten stuff, no dn-based subecj clause could 2269 * be used at the ldap backend side (see 2270 * http://www.OpenLDAP.org/faq/data/cache/452.html) 2271 * The problem can be overcome by moving the dn-based 2272 * ACLs to the target directory server, and letting 2273 * everything pass thru the ldap backend. 2274 */ 2275 } else { 2276 int i; 2277 2278 if ( attr->a_desc->ad_type->sat_syntax == 2279 slap_schema.si_syn_distinguishedName ) 2280 { 2281 ldap_dnattr_result_rewrite( &dc, attr->a_vals ); 2282 2283 } else if ( attr->a_desc == slap_schema.si_ad_ref ) { 2284 ldap_back_referral_result_rewrite( &dc, attr->a_vals, NULL ); 2285 2286 } 2287 2288 for ( i = 0; i < last; i++ ) { 2289 struct berval pval; 2290 int rc; 2291 2292 if ( pretty ) { 2293 rc = ordered_value_pretty( attr->a_desc, 2294 &attr->a_vals[i], &pval, NULL ); 2295 2296 } else { 2297 rc = ordered_value_validate( attr->a_desc, 2298 &attr->a_vals[i], 0 ); 2299 } 2300 2301 if ( rc ) { 2302 ber_memfree( attr->a_vals[i].bv_val ); 2303 if ( --last == i ) { 2304 BER_BVZERO( &attr->a_vals[ i ] ); 2305 break; 2306 } 2307 attr->a_vals[i] = attr->a_vals[last]; 2308 BER_BVZERO( &attr->a_vals[last] ); 2309 i--; 2310 continue; 2311 } 2312 2313 if ( pretty ) { 2314 ber_memfree( attr->a_vals[i].bv_val ); 2315 attr->a_vals[i] = pval; 2316 } 2317 } 2318 2319 if ( last == 0 && attr->a_vals != &slap_dummy_bv ) { 2320 attr_free( attr ); 2321 goto next_attr; 2322 } 2323 } 2324 2325 if ( last && attr->a_desc->ad_type->sat_equality && 2326 attr->a_desc->ad_type->sat_equality->smr_normalize ) 2327 { 2328 int i; 2329 2330 attr->a_nvals = ch_malloc( ( last + 1 ) * sizeof( struct berval ) ); 2331 for ( i = 0; i<last; i++ ) { 2332 /* if normalizer fails, drop this value */ 2333 if ( ordered_value_normalize( 2334 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, 2335 attr->a_desc, 2336 attr->a_desc->ad_type->sat_equality, 2337 &attr->a_vals[i], &attr->a_nvals[i], 2338 NULL )) { 2339 ber_memfree( attr->a_vals[i].bv_val ); 2340 if ( --last == i ) { 2341 BER_BVZERO( &attr->a_vals[ i ] ); 2342 break; 2343 } 2344 attr->a_vals[i] = attr->a_vals[last]; 2345 BER_BVZERO( &attr->a_vals[last] ); 2346 i--; 2347 } 2348 } 2349 BER_BVZERO( &attr->a_nvals[i] ); 2350 if ( last == 0 ) { 2351 attr_free( attr ); 2352 goto next_attr; 2353 } 2354 2355 } else { 2356 attr->a_nvals = attr->a_vals; 2357 } 2358 2359 attr->a_numvals = last; 2360 *attrp = attr; 2361 attrp = &attr->a_next; 2362 next_attr:; 2363 } 2364 2365 /* only check if some mapping occurred */ 2366 if ( check_duplicate_attrs ) { 2367 Attribute **ap; 2368 2369 for ( ap = &ent.e_attrs; *ap != NULL; ap = &(*ap)->a_next ) { 2370 Attribute **tap; 2371 2372 for ( tap = &(*ap)->a_next; *tap != NULL; ) { 2373 if ( (*tap)->a_desc == (*ap)->a_desc ) { 2374 Entry e = { 0 }; 2375 Modification mod = { 0 }; 2376 const char *text = NULL; 2377 char textbuf[ SLAP_TEXT_BUFLEN ]; 2378 Attribute *next = (*tap)->a_next; 2379 2380 BER_BVSTR( &e.e_name, "" ); 2381 BER_BVSTR( &e.e_nname, "" ); 2382 e.e_attrs = *ap; 2383 mod.sm_op = LDAP_MOD_ADD; 2384 mod.sm_desc = (*ap)->a_desc; 2385 mod.sm_type = mod.sm_desc->ad_cname; 2386 mod.sm_numvals = (*ap)->a_numvals; 2387 mod.sm_values = (*tap)->a_vals; 2388 if ( (*tap)->a_nvals != (*tap)->a_vals ) { 2389 mod.sm_nvalues = (*tap)->a_nvals; 2390 } 2391 2392 (void)modify_add_values( &e, &mod, 2393 /* permissive */ 1, 2394 &text, textbuf, sizeof( textbuf ) ); 2395 2396 /* should not insert new attrs! */ 2397 assert( e.e_attrs == *ap ); 2398 2399 attr_free( *tap ); 2400 *tap = next; 2401 2402 } else { 2403 tap = &(*tap)->a_next; 2404 } 2405 } 2406 } 2407 } 2408 2409 /* Check for sorted attributes */ 2410 if ( check_sorted_attrs ) { 2411 for ( attr = ent.e_attrs; attr; attr = attr->a_next ) { 2412 if ( attr->a_desc->ad_type->sat_flags & SLAP_AT_SORTED_VAL ) { 2413 while ( attr->a_numvals > 1 ) { 2414 int i; 2415 int rc = slap_sort_vals( (Modifications *)attr, &text, &i, op->o_tmpmemctx ); 2416 if ( rc != LDAP_TYPE_OR_VALUE_EXISTS ) 2417 break; 2418 2419 /* Strip duplicate values */ 2420 if ( attr->a_nvals != attr->a_vals ) 2421 ber_memfree( attr->a_nvals[i].bv_val ); 2422 ber_memfree( attr->a_vals[i].bv_val ); 2423 attr->a_numvals--; 2424 if ( (unsigned)i < attr->a_numvals ) { 2425 attr->a_vals[i] = attr->a_vals[attr->a_numvals]; 2426 if ( attr->a_nvals != attr->a_vals ) 2427 attr->a_nvals[i] = attr->a_nvals[attr->a_numvals]; 2428 } 2429 BER_BVZERO(&attr->a_vals[attr->a_numvals]); 2430 if ( attr->a_nvals != attr->a_vals ) 2431 BER_BVZERO(&attr->a_nvals[attr->a_numvals]); 2432 } 2433 attr->a_flags |= SLAP_ATTR_SORTED_VALS; 2434 } 2435 } 2436 } 2437 2438 ldap_get_entry_controls( mc->mc_conns[target].msc_ld, 2439 e, &rs->sr_ctrls ); 2440 rs->sr_entry = &ent; 2441 rs->sr_attrs = op->ors_attrs; 2442 rs->sr_operational_attrs = NULL; 2443 rs->sr_flags = mi->mi_targets[ target ]->mt_rep_flags; 2444 rs->sr_err = LDAP_SUCCESS; 2445 rc = send_search_entry( op, rs ); 2446 switch ( rc ) { 2447 case LDAP_UNAVAILABLE: 2448 rc = LDAP_OTHER; 2449 break; 2450 } 2451 2452 done:; 2453 rs->sr_entry = NULL; 2454 rs->sr_attrs = NULL; 2455 if ( rs->sr_ctrls != NULL ) { 2456 ldap_controls_free( rs->sr_ctrls ); 2457 rs->sr_ctrls = NULL; 2458 } 2459 if ( !BER_BVISNULL( &ent.e_name ) ) { 2460 free( ent.e_name.bv_val ); 2461 BER_BVZERO( &ent.e_name ); 2462 } 2463 if ( !BER_BVISNULL( &ent.e_nname ) ) { 2464 free( ent.e_nname.bv_val ); 2465 BER_BVZERO( &ent.e_nname ); 2466 } 2467 entry_clean( &ent ); 2468 2469 return rc; 2470 } 2471 2472