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