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