LCOV - code coverage report
Current view: top level - lib/ldb/ldb_key_value - ldb_kv_search.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 208 265 78.5 %
Date: 2021-09-23 10:06:22 Functions: 10 10 100.0 %

          Line data    Source code
       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    57662714 : 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    57662714 :         struct ldb_message *msg = NULL;
      50             : 
      51    57662714 :         if (ldb_dn_is_null(dn)) {
      52           0 :                 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    57662714 :         msg = ldb_msg_new(module);
      62    57662714 :         if (msg == NULL) {
      63           0 :                 return LDB_ERR_OPERATIONS_ERROR;
      64             :         }
      65             : 
      66    57662714 :         ret = ldb_kv_search_dn1(module, dn, msg, LDB_UNPACK_DATA_FLAG_NO_ATTRS);
      67    57662714 :         if (ret == LDB_SUCCESS) {
      68    49058752 :                 const char *dn_linearized
      69     8541921 :                         = ldb_dn_get_linearized(dn);
      70    49058752 :                 const char *msg_dn_linearized
      71    57600673 :                         = ldb_dn_get_linearized(msg->dn);
      72             : 
      73    57600673 :                 if (strcmp(dn_linearized, msg_dn_linearized) == 0) {
      74             :                         /*
      75             :                          * Re-use the full incoming DN for
      76             :                          * subtree checks
      77             :                          */
      78    57581547 :                         *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       19126 :                         *ret_dn = talloc_steal(mem_ctx, msg->dn);
      85             :                 }
      86    56679304 :                 exists = true;
      87       62041 :         } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
      88       61817 :                 exists = false;
      89             :         } else {
      90           0 :                 talloc_free(msg);
      91           0 :                 return ret;
      92             :         }
      93    57662714 :         talloc_free(msg);
      94    57662714 :         if (exists) {
      95    56679304 :                 return LDB_SUCCESS;
      96             :         }
      97       62041 :         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   248406723 : static int ldb_kv_parse_data_unpack(struct ldb_val key,
     108             :                                     struct ldb_val data,
     109             :                                     void *private_data)
     110             : {
     111   248406723 :         struct ldb_kv_parse_data_unpack_ctx *ctx = private_data;
     112             :         int ret;
     113   248406723 :         struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
     114   248406723 :         struct ldb_val data_parse = data;
     115             : 
     116   248406723 :         struct ldb_kv_private *ldb_kv = ctx->ldb_kv;
     117             : 
     118   340011984 :         if ((ldb_kv->kv_ops->options & LDB_KV_OPTION_STABLE_READ_LOCK) &&
     119   145970223 :             (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_READ_LOCKED) &&
     120    50304450 :             !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   214760185 :                 data_parse.data = talloc_memdup(ctx->msg,
     143             :                                                 data.data,
     144             :                                                 data.length);
     145   214760185 :                 if (data_parse.data == NULL) {
     146           0 :                         ldb_debug(ldb, LDB_DEBUG_ERROR,
     147             :                                   "Unable to allocate data(%d) for %*.*s\n",
     148           0 :                                   (int)data.length,
     149           0 :                                   (int)key.length, (int)key.length, key.data);
     150           0 :                         return LDB_ERR_OPERATIONS_ERROR;
     151             :                 }
     152             :         }
     153             : 
     154   248406723 :         ret = ldb_unpack_data_flags(ldb, &data_parse,
     155             :                                     ctx->msg, ctx->unpack_flags);
     156   248406723 :         if (ret == -1) {
     157           0 :                 if (data_parse.data != data.data) {
     158           0 :                         talloc_free(data_parse.data);
     159             :                 }
     160             : 
     161           0 :                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n",
     162           0 :                           (int)key.length, (int)key.length, key.data);
     163           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     164             :         }
     165   242231769 :         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   299080088 : 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   299080088 :         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   299080088 :         memset(msg, 0, sizeof(*msg));
     190             : 
     191   299080088 :         msg->num_elements = 0;
     192   299080088 :         msg->elements = NULL;
     193             : 
     194   299080088 :         ret = ldb_kv->kv_ops->fetch_and_parse(
     195             :             ldb_kv, ldb_key, ldb_kv_parse_data_unpack, &ctx);
     196             : 
     197   299080088 :         if (ret == -1) {
     198           0 :                 ret = ldb_kv->kv_ops->error(ldb_kv);
     199           0 :                 if (ret == LDB_SUCCESS) {
     200             :                         /*
     201             :                          * Just to be sure we don't turn errors
     202             :                          * into success
     203             :                          */
     204           0 :                         return LDB_ERR_OPERATIONS_ERROR;
     205             :                 }
     206           0 :                 return ret;
     207   299080088 :         } else if (ret != LDB_SUCCESS) {
     208    49276585 :                 return ret;
     209             :         }
     210             : 
     211   248406723 :         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   206737508 : 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   206737508 :         void *data = ldb_module_get_private(module);
     227   175929671 :         struct ldb_kv_private *ldb_kv =
     228    30807837 :             talloc_get_type(data, struct ldb_kv_private);
     229             :         int ret;
     230             :         uint8_t guid_key[LDB_KV_GUID_KEY_SIZE];
     231   206737508 :         struct ldb_val key = {
     232             :                 .data = guid_key,
     233             :                 .length = sizeof(guid_key)
     234             :         };
     235   206737508 :         TALLOC_CTX *tdb_key_ctx = NULL;
     236             : 
     237   206737508 :         bool valid_dn = ldb_dn_validate(dn);
     238   206737508 :         if (valid_dn == false) {
     239           0 :                 ldb_asprintf_errstring(ldb_module_get_ctx(module),
     240             :                                        "Invalid Base DN: %s",
     241             :                                        ldb_dn_get_linearized(dn));
     242           0 :                 return LDB_ERR_INVALID_DN_SYNTAX;
     243             :         }
     244             : 
     245   410537099 :         if (ldb_kv->cache->GUID_index_attribute == NULL ||
     246   203799591 :             ldb_dn_is_special(dn)) {
     247             : 
     248   129744339 :                 tdb_key_ctx = talloc_new(msg);
     249   129744339 :                 if (!tdb_key_ctx) {
     250           0 :                         return ldb_module_oom(module);
     251             :                 }
     252             : 
     253             :                 /* form the key */
     254   129744339 :                 key = ldb_kv_key_dn(tdb_key_ctx, dn);
     255   235959647 :                 if (!key.data) {
     256           0 :                         TALLOC_FREE(tdb_key_ctx);
     257           0 :                         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    76993169 :                 ret = ldb_kv_key_dn_from_idx(module, ldb_kv, msg, dn, &key);
     268    76993169 :                 if (ret != LDB_SUCCESS) {
     269      357239 :                         return ret;
     270             :                 }
     271             :         }
     272             : 
     273   206334917 :         ret = ldb_kv_search_key(module, ldb_kv, key, msg, unpack_flags);
     274             : 
     275   206334917 :         TALLOC_FREE(tdb_key_ctx);
     276             : 
     277   206334917 :         if (ret != LDB_SUCCESS) {
     278    10285898 :                 return ret;
     279             :         }
     280             : 
     281   195205841 :         if ((unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DN) == 0) {
     282   129688828 :                 if (!msg->dn) {
     283           0 :                         msg->dn = ldb_dn_copy(msg, dn);
     284             :                 }
     285   129688828 :                 if (!msg->dn) {
     286           0 :                         return LDB_ERR_OPERATIONS_ERROR;
     287             :                 }
     288             :         }
     289             : 
     290   189778532 :         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    77249177 : 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    77249177 :         return ldb_filter_attrs(ldb, msg, attrs, filtered_msg);
     304             : }
     305             : 
     306             : /*
     307             :   search function for a non-indexed search
     308             :  */
     309   429311188 : 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   429311188 :         ac = talloc_get_type(state, struct ldb_kv_context);
     321   429311188 :         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   429311188 :         if (ldb_kv_key_is_normal_record(key) == false) {
     341   347259802 :                 return 0;
     342             :         }
     343             : 
     344    81248595 :         msg = ldb_msg_new(ac);
     345    81248595 :         if (!msg) {
     346           0 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     347           0 :                 return -1;
     348             :         }
     349             : 
     350             :         /* unpack the record */
     351    81248595 :         ret = ldb_unpack_data_flags(ldb, &val, msg,
     352             :                                     LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC);
     353    81248595 :         if (ret == -1) {
     354           0 :                 talloc_free(msg);
     355           0 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     356           0 :                 return -1;
     357             :         }
     358             : 
     359    81248595 :         if (!msg->dn) {
     360           0 :                 msg->dn = ldb_dn_new(msg, ldb,
     361           0 :                                      (char *)key.data + 3);
     362           0 :                 if (msg->dn == NULL) {
     363           0 :                         talloc_free(msg);
     364           0 :                         ac->error = LDB_ERR_OPERATIONS_ERROR;
     365           0 :                         return -1;
     366             :                 }
     367             :         }
     368             : 
     369             :         /* see if it matches the given expression */
     370    81248595 :         ret = ldb_match_msg_error(ldb, msg,
     371             :                                   ac->tree, ac->base, ac->scope, &matched);
     372    81248595 :         if (ret != LDB_SUCCESS) {
     373          23 :                 talloc_free(msg);
     374          23 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     375          23 :                 return -1;
     376             :         }
     377    81248572 :         if (!matched) {
     378    78110771 :                 talloc_free(msg);
     379    78110771 :                 return 0;
     380             :         }
     381             : 
     382     3137801 :         filtered_msg = ldb_msg_new(ac);
     383     3137801 :         if (filtered_msg == NULL) {
     384           0 :                 TALLOC_FREE(msg);
     385           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     386             :         }
     387             : 
     388     3137801 :         filtered_msg->dn = talloc_steal(filtered_msg, msg->dn);
     389             : 
     390             :         /* filter the attributes that the user wants */
     391     3137801 :         ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg);
     392     3137801 :         talloc_free(msg);
     393             : 
     394     3137801 :         if (ret == -1) {
     395           0 :                 TALLOC_FREE(filtered_msg);
     396           0 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     397           0 :                 return -1;
     398             :         }
     399             : 
     400     3137801 :         ret = ldb_module_send_entry(ac->req, filtered_msg, NULL);
     401     3137797 :         if (ret != LDB_SUCCESS) {
     402           5 :                 ac->request_terminated = true;
     403             :                 /* the callback failed, abort the operation */
     404           5 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     405           5 :                 return -1;
     406             :         }
     407             : 
     408     2921846 :         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       50212 : static int ldb_kv_search_full(struct ldb_kv_context *ctx)
     429             : {
     430       50212 :         void *data = ldb_module_get_private(ctx->module);
     431       35497 :         struct ldb_kv_private *ldb_kv =
     432       14715 :             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       50212 :         ctx->error = LDB_SUCCESS;
     440       50212 :         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       50212 :         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       40289 :                 ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx);
     451             :         }
     452             : 
     453       50208 :         if (ret < 0) {
     454           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     455             :         }
     456             : 
     457       50208 :         return ctx->error;
     458             : }
     459             : 
     460    24856067 : 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    24856067 :         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    24856067 :         msg = ldb_msg_new(ctx);
     471    24856067 :         if (!msg) {
     472           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     473             :         }
     474    24856067 :         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    24856067 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     481      407832 :                 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       65639 :                         talloc_free(msg);
     487       63252 :                         return LDB_SUCCESS;
     488             :                 }
     489      342193 :                 ldb_asprintf_errstring(ldb,
     490             :                                        "No such Base DN: %s",
     491             :                                        ldb_dn_get_linearized(ctx->base));
     492             :         }
     493    24790428 :         if (ret != LDB_SUCCESS) {
     494      342193 :                 talloc_free(msg);
     495      296954 :                 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    24448235 :         ret = ldb_match_message(ldb, msg,
     506             :                                 ctx->tree,
     507             :                                 ctx->scope,
     508             :                                 &matched);
     509    24448235 :         if (ret != LDB_SUCCESS) {
     510           0 :                 talloc_free(msg);
     511           0 :                 return ret;
     512             :         }
     513    24448235 :         if (!matched) {
     514      306755 :                 talloc_free(msg);
     515      296988 :                 return LDB_SUCCESS;
     516             :         }
     517             : 
     518    24141480 :         dn_linearized = ldb_dn_get_linearized(ctx->base);
     519    24141480 :         msg_dn_linearized = ldb_dn_get_linearized(msg->dn);
     520             : 
     521    24141480 :         filtered_msg = ldb_msg_new(ctx);
     522    24141480 :         if (filtered_msg == NULL) {
     523           0 :                 talloc_free(msg);
     524           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     525             :         }
     526             : 
     527    24141480 :         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    23089513 :                 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    24141480 :         if (filtered_msg->dn == NULL) {
     543     1051967 :                 filtered_msg->dn = talloc_steal(filtered_msg, msg->dn);
     544             :         }
     545             : 
     546             :         /*
     547             :          * filter the attributes that the user wants.
     548             :          */
     549    24141480 :         ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg);
     550    24141480 :         if (ret == -1) {
     551           0 :                 talloc_free(msg);
     552           0 :                 filtered_msg = NULL;
     553           0 :                 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    24141480 :         ldb_dn_remove_extended_components(filtered_msg->dn);
     561    24141480 :         talloc_free(msg);
     562             : 
     563    24141480 :         ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL);
     564    24141478 :         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          46 :                 ctx->request_terminated = true;
     569          27 :                 return ret;
     570             :         }
     571             : 
     572    22769866 :         return LDB_SUCCESS;
     573             : }
     574             : 
     575             : /*
     576             :   search the database with a LDAP-like expression.
     577             :   choses a search method
     578             : */
     579    83097911 : int ldb_kv_search(struct ldb_kv_context *ctx)
     580             : {
     581             :         struct ldb_context *ldb;
     582    83097911 :         struct ldb_module *module = ctx->module;
     583    83097911 :         struct ldb_request *req = ctx->req;
     584    83097911 :         void *data = ldb_module_get_private(module);
     585    70171021 :         struct ldb_kv_private *ldb_kv =
     586    12926890 :             talloc_get_type(data, struct ldb_kv_private);
     587             :         int ret;
     588             : 
     589    83097911 :         ldb = ldb_module_get_ctx(module);
     590             : 
     591    83097911 :         ldb_request_set_state(req, LDB_ASYNC_PENDING);
     592             : 
     593    83097911 :         if (ldb_kv->kv_ops->lock_read(module) != 0) {
     594           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     595             :         }
     596             : 
     597    83097911 :         if (ldb_kv_cache_load(module) != 0) {
     598           0 :                 ldb_kv->kv_ops->unlock_read(module);
     599           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     600             :         }
     601             : 
     602    83097911 :         if (req->op.search.tree == NULL) {
     603           0 :                 ldb_kv->kv_ops->unlock_read(module);
     604           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     605             :         }
     606             : 
     607    83097911 :         ctx->tree = req->op.search.tree;
     608    83097911 :         ctx->scope = req->op.search.scope;
     609    83097911 :         ctx->base = req->op.search.base;
     610    83097911 :         ctx->attrs = req->op.search.attrs;
     611             : 
     612    83097911 :         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      579186 :                 switch (req->op.search.scope) {
     616      108695 :                 case LDB_SCOPE_BASE:
     617      108695 :                         ldb_asprintf_errstring(ldb,
     618             :                                                "NULL Base DN invalid for a base search");
     619      108695 :                         ret = LDB_ERR_INVALID_DN_SYNTAX;
     620      104685 :                         break;
     621           2 :                 case LDB_SCOPE_ONELEVEL:
     622           2 :                         ldb_asprintf_errstring(ldb,
     623             :                                                "NULL Base DN invalid for a one-level search");
     624           2 :                         ret = LDB_ERR_INVALID_DN_SYNTAX;
     625           1 :                         break;
     626      448814 :                 case LDB_SCOPE_SUBTREE:
     627             :                 default:
     628             :                         /* We accept subtree searches from a NULL base DN, ie over the whole DB */
     629      448814 :                         ret = LDB_SUCCESS;
     630             :                 }
     631    15528509 :         } 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    24856067 :                 ret = ldb_kv_search_and_return_base(ldb_kv, ctx);
     641             : 
     642    24856065 :                 ldb_kv->kv_ops->unlock_read(module);
     643             : 
     644    24856065 :                 return ret;
     645             : 
     646    57662658 :         } 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    57601370 :                 ret = ldb_kv_search_base(
     654             :                     module, ctx, req->op.search.base, &ctx->base);
     655             : 
     656    57601370 :                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     657         755 :                         ldb_asprintf_errstring(ldb,
     658             :                                                "No such Base DN: %s",
     659             :                                                ldb_dn_get_linearized(req->op.search.base));
     660             :                 }
     661             : 
     662       61288 :         } else if (ldb_dn_validate(req->op.search.base) == false) {
     663             : 
     664             :                 /* We don't want invalid base DNs here */
     665           0 :                 ldb_asprintf_errstring(ldb,
     666             :                                        "Invalid Base DN: %s",
     667             :                                        ldb_dn_get_linearized(req->op.search.base));
     668           0 :                 ret = LDB_ERR_INVALID_DN_SYNTAX;
     669             : 
     670             :         } else {
     671             :                 /* If we are not checking the base DN life is easy */
     672       58467 :                 ret = LDB_SUCCESS;
     673             :         }
     674             : 
     675    58213337 :         if (ret == LDB_SUCCESS) {
     676    58132392 :                 uint32_t match_count = 0;
     677             : 
     678    58132392 :                 ret = ldb_kv_search_indexed(ctx, &match_count);
     679    58132388 :                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     680             :                         /* Not in the index, therefore OK! */
     681     5066996 :                         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    58132388 :                 if (!ctx->request_terminated && ret != LDB_SUCCESS) {
     688             :                         /* Not indexed, so we need to do a full scan */
     689       85757 :                         if (ldb_kv->warn_unindexed ||
     690       50236 :                             ldb_kv->disable_full_db_scan) {
     691             :                                 /* useful for debugging when slow performance
     692             :                                  * is caused by unindexed searches */
     693          24 :                                 char *expression = ldb_filter_from_tree(ctx, ctx->tree);
     694          72 :                                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb FULL SEARCH: %s SCOPE: %s DN: %s",
     695             :                                                         expression,
     696          24 :                                                         req->op.search.scope==LDB_SCOPE_BASE?"base":
     697          40 :                                                         req->op.search.scope==LDB_SCOPE_ONELEVEL?"one":
     698          16 :                                                         req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN",
     699             :                                                         ldb_dn_get_linearized(req->op.search.base));
     700             : 
     701          24 :                                 talloc_free(expression);
     702             :                         }
     703             : 
     704       50236 :                         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           0 :                                 ldb_kv->kv_ops->unlock_read(module);
     714          24 :                                 return LDB_ERR_OPERATIONS_ERROR;
     715             :                         }
     716             : 
     717       50236 :                         if (ldb_kv->disable_full_db_scan) {
     718          24 :                                 ldb_set_errstring(ldb,
     719             :                                                   "ldb FULL SEARCH disabled");
     720          24 :                                 ldb_kv->kv_ops->unlock_read(module);
     721          24 :                                 return LDB_ERR_INAPPROPRIATE_MATCHING;
     722             :                         }
     723             : 
     724       50212 :                         ret = ldb_kv_search_full(ctx);
     725       50208 :                         if (ret != LDB_SUCCESS) {
     726          28 :                                 ldb_set_errstring(ldb, "Indexed and full searches both failed!\n");
     727             :                         }
     728             :                 }
     729             :         }
     730             : 
     731    58241812 :         ldb_kv->kv_ops->unlock_read(module);
     732             : 
     733    58241812 :         return ret;
     734             : }

Generated by: LCOV version 1.13