1 /* 2 ldb database library 3 4 Copyright (C) Andrew Tridgell 2004 5 6 ** NOTE! The following LGPL license applies to the ldb 7 ** library. This does NOT imply that all of Samba is released 8 ** under the LGPL 9 10 This library is free software; you can redistribute it and/or 11 modify it under the terms of the GNU Lesser General Public 12 License as published by the Free Software Foundation; either 13 version 3 of the License, or (at your option) any later version. 14 15 This library is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 Lesser General Public License for more details. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this library; if not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 /* 25 * Name: ldb 26 * 27 * Component: ldb search functions 28 * 29 * Description: functions to search ldb+tdb databases 30 * 31 * Author: Andrew Tridgell 32 */ 33 34 #include "ldb_kv.h" 35 #include "ldb_private.h" 36 #include "lib/util/attr.h" 37 /* 38 search the database for a single simple dn. 39 return LDB_ERR_NO_SUCH_OBJECT on record-not-found 40 and LDB_SUCCESS on success 41 */ 42 int ldb_kv_search_base(struct ldb_module *module, 43 TALLOC_CTX *mem_ctx, 44 struct ldb_dn *dn, 45 struct ldb_dn **ret_dn) 46 { 47 int exists; 48 int ret; 49 struct ldb_message *msg = NULL; 50 51 if (ldb_dn_is_null(dn)) { 52 return LDB_ERR_NO_SUCH_OBJECT; 53 } 54 55 /* 56 * We can't use tdb_exists() directly on a key when the TDB 57 * key is the GUID one, not the DN based one. So we just do a 58 * normal search and avoid most of the allocation with the 59 * LDB_UNPACK_DATA_FLAG_NO_ATTRS flag 60 */ 61 msg = ldb_msg_new(module); 62 if (msg == NULL) { 63 return LDB_ERR_OPERATIONS_ERROR; 64 } 65 66 ret = ldb_kv_search_dn1(module, dn, msg, LDB_UNPACK_DATA_FLAG_NO_ATTRS); 67 if (ret == LDB_SUCCESS) { 68 const char *dn_linearized 69 = ldb_dn_get_linearized(dn); 70 const char *msg_dn_linearized 71 = ldb_dn_get_linearized(msg->dn); 72 73 if (strcmp(dn_linearized, msg_dn_linearized) == 0) { 74 /* 75 * Re-use the full incoming DN for 76 * subtree checks 77 */ 78 *ret_dn = dn; 79 } else { 80 /* 81 * Use the string DN from the unpack, so that 82 * we have a case-exact match of the base 83 */ 84 *ret_dn = talloc_steal(mem_ctx, msg->dn); 85 } 86 exists = true; 87 } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { 88 exists = false; 89 } else { 90 talloc_free(msg); 91 return ret; 92 } 93 talloc_free(msg); 94 if (exists) { 95 return LDB_SUCCESS; 96 } 97 return LDB_ERR_NO_SUCH_OBJECT; 98 } 99 100 struct ldb_kv_parse_data_unpack_ctx { 101 struct ldb_message *msg; 102 struct ldb_module *module; 103 struct ldb_kv_private *ldb_kv; 104 unsigned int unpack_flags; 105 }; 106 107 static int ldb_kv_parse_data_unpack(struct ldb_val key, 108 struct ldb_val data, 109 void *private_data) 110 { 111 struct ldb_kv_parse_data_unpack_ctx *ctx = private_data; 112 int ret; 113 struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); 114 struct ldb_val data_parse = data; 115 116 struct ldb_kv_private *ldb_kv = ctx->ldb_kv; 117 118 if ((ldb_kv->kv_ops->options & LDB_KV_OPTION_STABLE_READ_LOCK) && 119 (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_READ_LOCKED) && 120 !ldb_kv->kv_ops->transaction_active(ldb_kv)) { 121 /* 122 * In the case where no transactions are active and 123 * we're in a read-lock, we can point directly into 124 * database memory. 125 * 126 * The database can't be changed underneath us and we 127 * will duplicate this data in the call to filter. 128 * 129 * This is seen in: 130 * - ldb_kv_index_filter 131 * - ldb_kv_search_and_return_base 132 */ 133 } else { 134 /* 135 * In every other case, since unpack doesn't memdup, we need 136 * to at least do a memdup on the whole data buffer as that 137 * may change later and the caller needs a stable result. 138 * 139 * During transactions, pointers could change and in 140 * TDB, there just aren't the same guarantees. 141 */ 142 data_parse.data = talloc_memdup(ctx->msg, 143 data.data, 144 data.length); 145 if (data_parse.data == NULL) { 146 ldb_debug(ldb, LDB_DEBUG_ERROR, 147 "Unable to allocate data(%d) for %*.*s\n", 148 (int)data.length, 149 (int)key.length, (int)key.length, key.data); 150 return LDB_ERR_OPERATIONS_ERROR; 151 } 152 } 153 154 ret = ldb_unpack_data_flags(ldb, &data_parse, 155 ctx->msg, ctx->unpack_flags); 156 if (ret == -1) { 157 if (data_parse.data != data.data) { 158 talloc_free(data_parse.data); 159 } 160 161 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n", 162 (int)key.length, (int)key.length, key.data); 163 return LDB_ERR_OPERATIONS_ERROR; 164 } 165 return ret; 166 } 167 168 /* 169 search the database for a single simple dn, returning all attributes 170 in a single message 171 172 return LDB_ERR_NO_SUCH_OBJECT on record-not-found 173 and LDB_SUCCESS on success 174 */ 175 int ldb_kv_search_key(struct ldb_module *module, 176 struct ldb_kv_private *ldb_kv, 177 const struct ldb_val ldb_key, 178 struct ldb_message *msg, 179 unsigned int unpack_flags) 180 { 181 int ret; 182 struct ldb_kv_parse_data_unpack_ctx ctx = { 183 .msg = msg, 184 .module = module, 185 .unpack_flags = unpack_flags, 186 .ldb_kv = ldb_kv 187 }; 188 189 memset(msg, 0, sizeof(*msg)); 190 191 msg->num_elements = 0; 192 msg->elements = NULL; 193 194 ret = ldb_kv->kv_ops->fetch_and_parse( 195 ldb_kv, ldb_key, ldb_kv_parse_data_unpack, &ctx); 196 197 if (ret == -1) { 198 ret = ldb_kv->kv_ops->error(ldb_kv); 199 if (ret == LDB_SUCCESS) { 200 /* 201 * Just to be sure we don't turn errors 202 * into success 203 */ 204 return LDB_ERR_OPERATIONS_ERROR; 205 } 206 return ret; 207 } else if (ret != LDB_SUCCESS) { 208 return ret; 209 } 210 211 return LDB_SUCCESS; 212 } 213 214 /* 215 search the database for a single simple dn, returning all attributes 216 in a single message 217 218 return LDB_ERR_NO_SUCH_OBJECT on record-not-found 219 and LDB_SUCCESS on success 220 */ 221 int ldb_kv_search_dn1(struct ldb_module *module, 222 struct ldb_dn *dn, 223 struct ldb_message *msg, 224 unsigned int unpack_flags) 225 { 226 void *data = ldb_module_get_private(module); 227 struct ldb_kv_private *ldb_kv = 228 talloc_get_type(data, struct ldb_kv_private); 229 int ret; 230 uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; 231 struct ldb_val key = { 232 .data = guid_key, 233 .length = sizeof(guid_key) 234 }; 235 TALLOC_CTX *tdb_key_ctx = NULL; 236 237 bool valid_dn = ldb_dn_validate(dn); 238 if (valid_dn == false) { 239 ldb_asprintf_errstring(ldb_module_get_ctx(module), 240 "Invalid Base DN: %s", 241 ldb_dn_get_linearized(dn)); 242 return LDB_ERR_INVALID_DN_SYNTAX; 243 } 244 245 if (ldb_kv->cache->GUID_index_attribute == NULL || 246 ldb_dn_is_special(dn)) { 247 248 tdb_key_ctx = talloc_new(msg); 249 if (!tdb_key_ctx) { 250 return ldb_module_oom(module); 251 } 252 253 /* form the key */ 254 key = ldb_kv_key_dn(tdb_key_ctx, dn); 255 if (!key.data) { 256 TALLOC_FREE(tdb_key_ctx); 257 return LDB_ERR_OPERATIONS_ERROR; 258 } 259 } else { 260 /* 261 * Look in the index to find the key for this DN. 262 * 263 * the tdb_key memory is allocated above, msg is just 264 * used for internal memory. 265 * 266 */ 267 ret = ldb_kv_key_dn_from_idx(module, ldb_kv, msg, dn, &key); 268 if (ret != LDB_SUCCESS) { 269 return ret; 270 } 271 } 272 273 ret = ldb_kv_search_key(module, ldb_kv, key, msg, unpack_flags); 274 275 TALLOC_FREE(tdb_key_ctx); 276 277 if (ret != LDB_SUCCESS) { 278 return ret; 279 } 280 281 if ((unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DN) == 0) { 282 if (!msg->dn) { 283 msg->dn = ldb_dn_copy(msg, dn); 284 } 285 if (!msg->dn) { 286 return LDB_ERR_OPERATIONS_ERROR; 287 } 288 } 289 290 return LDB_SUCCESS; 291 } 292 293 /* 294 * filter the specified list of attributes from msg, 295 * adding requested attributes, and perhaps all for *, 296 * but not the DN to filtered_msg. 297 */ 298 int ldb_kv_filter_attrs(struct ldb_context *ldb, 299 const struct ldb_message *msg, 300 const char *const *attrs, 301 struct ldb_message *filtered_msg) 302 { 303 return ldb_filter_attrs(ldb, msg, attrs, filtered_msg); 304 } 305 306 /* 307 search function for a non-indexed search 308 */ 309 static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, 310 struct ldb_val key, 311 struct ldb_val val, 312 void *state) 313 { 314 struct ldb_context *ldb; 315 struct ldb_kv_context *ac; 316 struct ldb_message *msg, *filtered_msg; 317 int ret; 318 bool matched; 319 320 ac = talloc_get_type(state, struct ldb_kv_context); 321 ldb = ldb_module_get_ctx(ac->module); 322 323 /* 324 * We want to skip @ records early in a search full scan 325 * 326 * @ records like @IDXLIST are only available via a base 327 * search on the specific name but the method by which they 328 * were excluded was expensive, after the unpack the DN is 329 * exploded and ldb_match_msg_error() would reject it for 330 * failing to match the scope. 331 * 332 * ldb_kv_key_is_normal_record() uses the fact that @ records 333 * have the DN=@ prefix on their TDB/LMDB key to quickly 334 * exclude them from consideration. 335 * 336 * (any other non-records are also excluded by the same key 337 * match) 338 */ 339 340 if (ldb_kv_key_is_normal_record(key) == false) { 341 return 0; 342 } 343 344 msg = ldb_msg_new(ac); 345 if (!msg) { 346 ac->error = LDB_ERR_OPERATIONS_ERROR; 347 return -1; 348 } 349 350 /* unpack the record */ 351 ret = ldb_unpack_data_flags(ldb, &val, msg, 352 LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC); 353 if (ret == -1) { 354 talloc_free(msg); 355 ac->error = LDB_ERR_OPERATIONS_ERROR; 356 return -1; 357 } 358 359 if (!msg->dn) { 360 msg->dn = ldb_dn_new(msg, ldb, 361 (char *)key.data + 3); 362 if (msg->dn == NULL) { 363 talloc_free(msg); 364 ac->error = LDB_ERR_OPERATIONS_ERROR; 365 return -1; 366 } 367 } 368 369 /* see if it matches the given expression */ 370 ret = ldb_match_msg_error(ldb, msg, 371 ac->tree, ac->base, ac->scope, &matched); 372 if (ret != LDB_SUCCESS) { 373 talloc_free(msg); 374 ac->error = LDB_ERR_OPERATIONS_ERROR; 375 return -1; 376 } 377 if (!matched) { 378 talloc_free(msg); 379 return 0; 380 } 381 382 filtered_msg = ldb_msg_new(ac); 383 if (filtered_msg == NULL) { 384 TALLOC_FREE(msg); 385 return LDB_ERR_OPERATIONS_ERROR; 386 } 387 388 filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); 389 390 /* filter the attributes that the user wants */ 391 ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); 392 talloc_free(msg); 393 394 if (ret == -1) { 395 TALLOC_FREE(filtered_msg); 396 ac->error = LDB_ERR_OPERATIONS_ERROR; 397 return -1; 398 } 399 400 ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); 401 if (ret != LDB_SUCCESS) { 402 ac->request_terminated = true; 403 /* the callback failed, abort the operation */ 404 ac->error = LDB_ERR_OPERATIONS_ERROR; 405 return -1; 406 } 407 408 return 0; 409 } 410 411 /* 412 * Key pointing to just before the first GUID indexed record for 413 * iterate_range 414 */ 415 struct ldb_val start_of_db_key = {.data=discard_const_p(uint8_t, "GUID<"), 416 .length=6}; 417 /* 418 * Key pointing to just after the last GUID indexed record for 419 * iterate_range 420 */ 421 struct ldb_val end_of_db_key = {.data=discard_const_p(uint8_t, "GUID>"), 422 .length=6}; 423 424 /* 425 search the database with a LDAP-like expression. 426 this is the "full search" non-indexed variant 427 */ 428 static int ldb_kv_search_full(struct ldb_kv_context *ctx) 429 { 430 void *data = ldb_module_get_private(ctx->module); 431 struct ldb_kv_private *ldb_kv = 432 talloc_get_type(data, struct ldb_kv_private); 433 int ret; 434 435 /* 436 * If the backend has an iterate_range op, use it to start the search 437 * at the first GUID indexed record, skipping the indexes section. 438 */ 439 ctx->error = LDB_SUCCESS; 440 ret = ldb_kv->kv_ops->iterate_range(ldb_kv, 441 start_of_db_key, 442 end_of_db_key, 443 search_func, 444 ctx); 445 if (ret == LDB_ERR_OPERATIONS_ERROR) { 446 /* 447 * If iterate_range isn't defined, it'll return an error, 448 * so just iterate over the whole DB. 449 */ 450 ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx); 451 } 452 453 if (ret < 0) { 454 return LDB_ERR_OPERATIONS_ERROR; 455 } 456 457 return ctx->error; 458 } 459 460 static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, 461 struct ldb_kv_context *ctx) 462 { 463 struct ldb_message *msg, *filtered_msg; 464 struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); 465 const char *dn_linearized; 466 const char *msg_dn_linearized; 467 int ret; 468 bool matched; 469 470 msg = ldb_msg_new(ctx); 471 if (!msg) { 472 return LDB_ERR_OPERATIONS_ERROR; 473 } 474 ret = ldb_kv_search_dn1(ctx->module, 475 ctx->base, 476 msg, 477 LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | 478 LDB_UNPACK_DATA_FLAG_READ_LOCKED); 479 480 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 481 if (ldb_kv->check_base == false) { 482 /* 483 * In this case, we are done, as no base 484 * checking is allowed in this DB 485 */ 486 talloc_free(msg); 487 return LDB_SUCCESS; 488 } 489 ldb_asprintf_errstring(ldb, 490 "No such Base DN: %s", 491 ldb_dn_get_linearized(ctx->base)); 492 } 493 if (ret != LDB_SUCCESS) { 494 talloc_free(msg); 495 return ret; 496 } 497 498 499 /* 500 * We use this, not ldb_match_msg_error() as we know 501 * we matched on the scope BASE, as we just fetched 502 * the base DN 503 */ 504 505 ret = ldb_match_message(ldb, msg, 506 ctx->tree, 507 ctx->scope, 508 &matched); 509 if (ret != LDB_SUCCESS) { 510 talloc_free(msg); 511 return ret; 512 } 513 if (!matched) { 514 talloc_free(msg); 515 return LDB_SUCCESS; 516 } 517 518 dn_linearized = ldb_dn_get_linearized(ctx->base); 519 msg_dn_linearized = ldb_dn_get_linearized(msg->dn); 520 521 filtered_msg = ldb_msg_new(ctx); 522 if (filtered_msg == NULL) { 523 talloc_free(msg); 524 return LDB_ERR_OPERATIONS_ERROR; 525 } 526 527 if (strcmp(dn_linearized, msg_dn_linearized) == 0) { 528 /* 529 * If the DN is exactly the same string, then 530 * re-use the full incoming DN for the 531 * returned result, as it has already been 532 * casefolded 533 */ 534 filtered_msg->dn = ldb_dn_copy(filtered_msg, ctx->base); 535 } 536 537 /* 538 * If the ldb_dn_copy() failed, or if we did not choose that 539 * optimisation (filtered_msg is zeroed at allocation), 540 * steal the one from the unpack 541 */ 542 if (filtered_msg->dn == NULL) { 543 filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); 544 } 545 546 /* 547 * filter the attributes that the user wants. 548 */ 549 ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg); 550 if (ret == -1) { 551 talloc_free(msg); 552 filtered_msg = NULL; 553 return LDB_ERR_OPERATIONS_ERROR; 554 } 555 556 /* 557 * Remove any extended components possibly copied in from 558 * msg->dn, we just want the casefold components 559 */ 560 ldb_dn_remove_extended_components(filtered_msg->dn); 561 talloc_free(msg); 562 563 ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL); 564 if (ret != LDB_SUCCESS) { 565 /* Regardless of success or failure, the msg 566 * is the callbacks responsiblity, and should 567 * not be talloc_free()'ed */ 568 ctx->request_terminated = true; 569 return ret; 570 } 571 572 return LDB_SUCCESS; 573 } 574 575 /* 576 search the database with a LDAP-like expression. 577 choses a search method 578 */ 579 int ldb_kv_search(struct ldb_kv_context *ctx) 580 { 581 struct ldb_context *ldb; 582 struct ldb_module *module = ctx->module; 583 struct ldb_request *req = ctx->req; 584 void *data = ldb_module_get_private(module); 585 struct ldb_kv_private *ldb_kv = 586 talloc_get_type(data, struct ldb_kv_private); 587 int ret; 588 589 ldb = ldb_module_get_ctx(module); 590 591 ldb_request_set_state(req, LDB_ASYNC_PENDING); 592 593 if (ldb_kv->kv_ops->lock_read(module) != 0) { 594 return LDB_ERR_OPERATIONS_ERROR; 595 } 596 597 if (ldb_kv_cache_load(module) != 0) { 598 ldb_kv->kv_ops->unlock_read(module); 599 return LDB_ERR_OPERATIONS_ERROR; 600 } 601 602 if (req->op.search.tree == NULL) { 603 ldb_kv->kv_ops->unlock_read(module); 604 return LDB_ERR_OPERATIONS_ERROR; 605 } 606 607 ctx->tree = req->op.search.tree; 608 ctx->scope = req->op.search.scope; 609 ctx->base = req->op.search.base; 610 ctx->attrs = req->op.search.attrs; 611 612 if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) { 613 614 /* Check what we should do with a NULL dn */ 615 switch (req->op.search.scope) { 616 case LDB_SCOPE_BASE: 617 ldb_asprintf_errstring(ldb, 618 "NULL Base DN invalid for a base search"); 619 ret = LDB_ERR_INVALID_DN_SYNTAX; 620 break; 621 case LDB_SCOPE_ONELEVEL: 622 ldb_asprintf_errstring(ldb, 623 "NULL Base DN invalid for a one-level search"); 624 ret = LDB_ERR_INVALID_DN_SYNTAX; 625 break; 626 case LDB_SCOPE_SUBTREE: 627 default: 628 /* We accept subtree searches from a NULL base DN, ie over the whole DB */ 629 ret = LDB_SUCCESS; 630 } 631 } else if (req->op.search.scope == LDB_SCOPE_BASE) { 632 633 /* 634 * If we are LDB_SCOPE_BASE, do just one search and 635 * return early. This is critical to ensure we do not 636 * go into the index code for special DNs, as that 637 * will try to look up an index record for a special 638 * record (which doesn't exist). 639 */ 640 ret = ldb_kv_search_and_return_base(ldb_kv, ctx); 641 642 ldb_kv->kv_ops->unlock_read(module); 643 644 return ret; 645 646 } else if (ldb_kv->check_base) { 647 /* 648 * This database has been marked as 649 * 'checkBaseOnSearch', so do a spot check of the base 650 * dn. Also optimise the subsequent filter by filling 651 * in the ctx->base to be exactly case correct 652 */ 653 ret = ldb_kv_search_base( 654 module, ctx, req->op.search.base, &ctx->base); 655 656 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 657 ldb_asprintf_errstring(ldb, 658 "No such Base DN: %s", 659 ldb_dn_get_linearized(req->op.search.base)); 660 } 661 662 } else if (ldb_dn_validate(req->op.search.base) == false) { 663 664 /* We don't want invalid base DNs here */ 665 ldb_asprintf_errstring(ldb, 666 "Invalid Base DN: %s", 667 ldb_dn_get_linearized(req->op.search.base)); 668 ret = LDB_ERR_INVALID_DN_SYNTAX; 669 670 } else { 671 /* If we are not checking the base DN life is easy */ 672 ret = LDB_SUCCESS; 673 } 674 675 if (ret == LDB_SUCCESS) { 676 uint32_t match_count = 0; 677 678 ret = ldb_kv_search_indexed(ctx, &match_count); 679 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 680 /* Not in the index, therefore OK! */ 681 ret = LDB_SUCCESS; 682 683 } 684 /* Check if we got just a normal error. 685 * In that case proceed to a full search unless we got a 686 * callback error */ 687 if (!ctx->request_terminated && ret != LDB_SUCCESS) { 688 /* Not indexed, so we need to do a full scan */ 689 if (ldb_kv->warn_unindexed || 690 ldb_kv->disable_full_db_scan) { 691 /* useful for debugging when slow performance 692 * is caused by unindexed searches */ 693 char *expression = ldb_filter_from_tree(ctx, ctx->tree); 694 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb FULL SEARCH: %s SCOPE: %s DN: %s", 695 expression, 696 req->op.search.scope==LDB_SCOPE_BASE?"base": 697 req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": 698 req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN", 699 ldb_dn_get_linearized(req->op.search.base)); 700 701 talloc_free(expression); 702 } 703 704 if (match_count != 0) { 705 /* the indexing code gave an error 706 * after having returned at least one 707 * entry. This means the indexes are 708 * corrupt or a database record is 709 * corrupt. We cannot continue with a 710 * full search or we may return 711 * duplicate entries 712 */ 713 ldb_kv->kv_ops->unlock_read(module); 714 return LDB_ERR_OPERATIONS_ERROR; 715 } 716 717 if (ldb_kv->disable_full_db_scan) { 718 ldb_set_errstring(ldb, 719 "ldb FULL SEARCH disabled"); 720 ldb_kv->kv_ops->unlock_read(module); 721 return LDB_ERR_INAPPROPRIATE_MATCHING; 722 } 723 724 ret = ldb_kv_search_full(ctx); 725 if (ret != LDB_SUCCESS) { 726 ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); 727 } 728 } 729 } 730 731 ldb_kv->kv_ops->unlock_read(module); 732 733 return ret; 734 } 735