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 v4-17-test 1498b464 Lines: 226 291 77.7 %
Date: 2024-06-13 04:01:37 Functions: 9 9 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    61911519 : 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    61911519 :         struct ldb_message *msg = NULL;
      50             : 
      51    61911519 :         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    61911519 :         msg = ldb_msg_new(module);
      62    61911519 :         if (msg == NULL) {
      63           0 :                 return LDB_ERR_OPERATIONS_ERROR;
      64             :         }
      65             : 
      66    61911519 :         ret = ldb_kv_search_dn1(module, dn, msg, LDB_UNPACK_DATA_FLAG_NO_ATTRS);
      67    61911519 :         if (ret == LDB_SUCCESS) {
      68    53305694 :                 const char *dn_linearized
      69     8549180 :                         = ldb_dn_get_linearized(dn);
      70    53305694 :                 const char *msg_dn_linearized
      71    61854874 :                         = ldb_dn_get_linearized(msg->dn);
      72             : 
      73    61854874 :                 if (strcmp(dn_linearized, msg_dn_linearized) == 0) {
      74             :                         /*
      75             :                          * Re-use the full incoming DN for
      76             :                          * subtree checks
      77             :                          */
      78    61836000 :                         *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       18874 :                         *ret_dn = talloc_steal(mem_ctx, msg->dn);
      85             :                 }
      86    61854874 :                 exists = true;
      87       56645 :         } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
      88       56645 :                 exists = false;
      89             :         } else {
      90           0 :                 talloc_free(msg);
      91           0 :                 return ret;
      92             :         }
      93    61911519 :         talloc_free(msg);
      94    61911519 :         if (exists) {
      95    61854874 :                 return LDB_SUCCESS;
      96             :         }
      97       56645 :         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   244140467 : static int ldb_kv_parse_data_unpack(struct ldb_val key,
     108             :                                     struct ldb_val data,
     109             :                                     void *private_data)
     110             : {
     111   244140467 :         struct ldb_kv_parse_data_unpack_ctx *ctx = private_data;
     112             :         int ret;
     113   244140467 :         struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
     114   244140467 :         struct ldb_val data_parse = data;
     115             : 
     116   244140467 :         struct ldb_kv_private *ldb_kv = ctx->ldb_kv;
     117             : 
     118   328934258 :         if ((ldb_kv->kv_ops->options & LDB_KV_OPTION_STABLE_READ_LOCK) &&
     119   127089773 :             (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_READ_LOCKED) &&
     120    41696858 :             !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   218248433 :                 data_parse.data = talloc_memdup(ctx->msg,
     143             :                                                 data.data,
     144             :                                                 data.length);
     145   218248433 :                 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   244140467 :         ret = ldb_unpack_data_flags(ldb, &data_parse,
     155             :                                     ctx->msg, ctx->unpack_flags);
     156   244140467 :         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   244140467 :         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   297549388 : 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   297549388 :         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   297549388 :         memset(msg, 0, sizeof(*msg));
     190             : 
     191   297549388 :         msg->num_elements = 0;
     192   297549388 :         msg->elements = NULL;
     193             : 
     194   297549388 :         ret = ldb_kv->kv_ops->fetch_and_parse(
     195             :             ldb_kv, ldb_key, ldb_kv_parse_data_unpack, &ctx);
     196             : 
     197   297549388 :         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   297549388 :         } else if (ret != LDB_SUCCESS) {
     208    53408921 :                 return ret;
     209             :         }
     210             : 
     211   244140467 :         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   201440850 : 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   201440850 :         void *data = ldb_module_get_private(module);
     227   176338453 :         struct ldb_kv_private *ldb_kv =
     228    25102397 :             talloc_get_type(data, struct ldb_kv_private);
     229             :         int ret;
     230             :         uint8_t guid_key[LDB_KV_GUID_KEY_SIZE];
     231   201440850 :         struct ldb_val key = {
     232             :                 .data = guid_key,
     233             :                 .length = sizeof(guid_key)
     234             :         };
     235   201440850 :         TALLOC_CTX *tdb_key_ctx = NULL;
     236             : 
     237   201440850 :         bool valid_dn = ldb_dn_validate(dn);
     238   201440850 :         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   400474159 :         if (ldb_kv->cache->GUID_index_attribute == NULL ||
     246   199033309 :             ldb_dn_is_special(dn)) {
     247             : 
     248   119918509 :                 tdb_key_ctx = talloc_new(msg);
     249   119918509 :                 if (!tdb_key_ctx) {
     250           0 :                         return ldb_module_oom(module);
     251             :                 }
     252             : 
     253             :                 /* form the key */
     254   119918509 :                 key = ldb_kv_key_dn(tdb_key_ctx, dn);
     255   225838560 :                 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    81522341 :                 ret = ldb_kv_key_dn_from_idx(module, ldb_kv, msg, dn, &key);
     268    81522341 :                 if (ret != LDB_SUCCESS) {
     269      887202 :                         return ret;
     270             :                 }
     271             :         }
     272             : 
     273   200553648 :         ret = ldb_kv_search_key(module, ldb_kv, key, msg, unpack_flags);
     274             : 
     275   200553648 :         TALLOC_FREE(tdb_key_ctx);
     276             : 
     277   200553648 :         if (ret != LDB_SUCCESS) {
     278    10124691 :                 return ret;
     279             :         }
     280             : 
     281   190428957 :         if ((unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DN) == 0) {
     282   122560356 :                 if (!msg->dn) {
     283           0 :                         msg->dn = ldb_dn_copy(msg, dn);
     284             :                 }
     285   122560356 :                 if (!msg->dn) {
     286           0 :                         return LDB_ERR_OPERATIONS_ERROR;
     287             :                 }
     288             :         }
     289             : 
     290   190428957 :         return LDB_SUCCESS;
     291             : }
     292             : 
     293             : /*
     294             :  * filter the specified list of attributes from msg,
     295             :  * adding requested attributes, and perhaps all for *.
     296             :  * The DN will not be added if it is missing.
     297             :  */
     298    69333648 : int ldb_kv_filter_attrs_in_place(struct ldb_message *msg,
     299             :                                  const char *const *attrs)
     300             : {
     301    69333648 :         return ldb_filter_attrs_in_place(msg, attrs);
     302             : }
     303             : 
     304             : /*
     305             :   search function for a non-indexed search
     306             :  */
     307   369291251 : static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv,
     308             :                        struct ldb_val key,
     309             :                        struct ldb_val val,
     310             :                        void *state)
     311             : {
     312             :         struct ldb_context *ldb;
     313             :         struct ldb_kv_context *ac;
     314             :         struct ldb_message *msg;
     315             :         struct timeval now;
     316             :         int ret, timeval_cmp;
     317             :         bool matched;
     318             : 
     319   369291251 :         ac = talloc_get_type(state, struct ldb_kv_context);
     320   369291251 :         ldb = ldb_module_get_ctx(ac->module);
     321             : 
     322             :         /*
     323             :          * We want to skip @ records early in a search full scan
     324             :          *
     325             :          * @ records like @IDXLIST are only available via a base
     326             :          * search on the specific name but the method by which they
     327             :          * were excluded was expensive, after the unpack the DN is
     328             :          * exploded and ldb_match_msg_error() would reject it for
     329             :          * failing to match the scope.
     330             :          *
     331             :          * ldb_kv_key_is_normal_record() uses the fact that @ records
     332             :          * have the DN=@ prefix on their TDB/LMDB key to quickly
     333             :          * exclude them from consideration.
     334             :          *
     335             :          * (any other non-records are also excluded by the same key
     336             :          * match)
     337             :          */
     338             : 
     339   369291251 :         if (ldb_kv_key_is_normal_record(key) == false) {
     340   292433025 :                 return 0;
     341             :         }
     342             : 
     343             :         /*
     344             :          * Check the time every 64 records, to reduce calls to
     345             :          * gettimeofday().  This is a compromise, not all calls to
     346             :          * ldb_match_message() will take the same time, most will fail
     347             :          * quickly but by luck it might be possible to have 64 records
     348             :          * that are slow, doing a recursive search via
     349             :          * LDAP_MATCHING_RULE_IN_CHAIN.
     350             :          */
     351    76858226 :         if (ac->timeout_counter++ % 64 == 0) {
     352     1229944 :                 now = tevent_timeval_current();
     353     1229944 :                 timeval_cmp = tevent_timeval_compare(&ac->timeout_timeval,
     354             :                                                      &now);
     355             : 
     356             :                 /*
     357             :                  * The search has taken too long.  This is the most
     358             :                  * likely place for our time to expire, as we are in
     359             :                  * an un-indexed search and we return the data from
     360             :                  * within this loop.  The tevent based timeout is not
     361             :                  * likely to be hit, sadly.
     362             :                  *
     363             :                  * ldb_match_msg_error() can be quite expensive if a
     364             :                  * LDAP_MATCHING_RULE_IN_CHAIN extended match was
     365             :                  * specified.
     366             :                  */
     367     1229944 :                 if (timeval_cmp <= 0) {
     368           5 :                         ac->error = LDB_ERR_TIME_LIMIT_EXCEEDED;
     369           5 :                         return -1;
     370             :                 }
     371             :         }
     372             : 
     373    76858221 :         msg = ldb_msg_new(ac);
     374    76858221 :         if (!msg) {
     375           0 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     376           0 :                 return -1;
     377             :         }
     378             : 
     379             :         /* unpack the record */
     380    76858221 :         ret = ldb_unpack_data_flags(ldb, &val, msg,
     381             :                                     LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC);
     382    76858221 :         if (ret == -1) {
     383           0 :                 talloc_free(msg);
     384           0 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     385           0 :                 return -1;
     386             :         }
     387             : 
     388    76858221 :         if (!msg->dn) {
     389           0 :                 msg->dn = ldb_dn_new(msg, ldb,
     390           0 :                                      (char *)key.data + 3);
     391           0 :                 if (msg->dn == NULL) {
     392           0 :                         talloc_free(msg);
     393           0 :                         ac->error = LDB_ERR_OPERATIONS_ERROR;
     394           0 :                         return -1;
     395             :                 }
     396             :         }
     397             : 
     398             :         /*
     399             :          * The redaction callback may be expensive to call if it fetches a
     400             :          * security descriptor. Check the DN early and bail out if it doesn't
     401             :          * match the base.
     402             :          */
     403    76858221 :         if (!ldb_match_scope(ldb, ac->base, msg->dn, ac->scope)) {
     404    65736352 :                 talloc_free(msg);
     405    65736352 :                 return 0;
     406             :         }
     407             : 
     408    11121869 :         if (ldb->redact.callback != NULL) {
     409    11061857 :                 ret = ldb->redact.callback(ldb->redact.module, ac->req, msg);
     410    11061857 :                 if (ret != LDB_SUCCESS) {
     411           0 :                         talloc_free(msg);
     412           0 :                         return ret;
     413             :                 }
     414             :         }
     415             : 
     416             :         /* see if it matches the given expression */
     417    11121869 :         ret = ldb_match_message(ldb, msg,
     418             :                                 ac->tree, ac->scope, &matched);
     419    11121869 :         if (ret != LDB_SUCCESS) {
     420          15 :                 talloc_free(msg);
     421          15 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     422          15 :                 return -1;
     423             :         }
     424    11121854 :         if (!matched) {
     425     8464829 :                 talloc_free(msg);
     426     8464829 :                 return 0;
     427             :         }
     428             : 
     429     2657025 :         ret = ldb_msg_add_distinguished_name(msg);
     430     2657025 :         if (ret == -1) {
     431           0 :                 talloc_free(msg);
     432           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     433             :         }
     434             : 
     435             :         /* filter the attributes that the user wants */
     436     2657025 :         ret = ldb_kv_filter_attrs_in_place(msg, ac->attrs);
     437     2657025 :         if (ret != LDB_SUCCESS) {
     438           0 :                 talloc_free(msg);
     439           0 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     440           0 :                 return -1;
     441             :         }
     442             : 
     443     2657025 :         ldb_msg_shrink_to_fit(msg);
     444             : 
     445             :         /* Ensure the message elements are all talloc'd. */
     446     2657025 :         ret = ldb_msg_elements_take_ownership(msg);
     447     2657025 :         if (ret != LDB_SUCCESS) {
     448           0 :                 talloc_free(msg);
     449           0 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     450           0 :                 return -1;
     451             :         }
     452             : 
     453     2657025 :         ret = ldb_module_send_entry(ac->req, msg, NULL);
     454     2657021 :         if (ret != LDB_SUCCESS) {
     455           5 :                 ac->request_terminated = true;
     456             :                 /* the callback failed, abort the operation */
     457           5 :                 ac->error = LDB_ERR_OPERATIONS_ERROR;
     458           5 :                 return -1;
     459             :         }
     460             : 
     461     2657016 :         return 0;
     462             : }
     463             : 
     464             : /*
     465             :  * Key pointing to just before the first GUID indexed record for
     466             :  * iterate_range
     467             :  */
     468             : struct ldb_val start_of_db_key = {.data=discard_const_p(uint8_t, "GUID<"),
     469             :                                   .length=6};
     470             : /*
     471             :  * Key pointing to just after the last GUID indexed record for
     472             :  * iterate_range
     473             :  */
     474             : struct ldb_val end_of_db_key = {.data=discard_const_p(uint8_t, "GUID>"),
     475             :                                 .length=6};
     476             : 
     477             : /*
     478             :   search the database with a LDAP-like expression.
     479             :   this is the "full search" non-indexed variant
     480             : */
     481       55227 : static int ldb_kv_search_full(struct ldb_kv_context *ctx)
     482             : {
     483       55227 :         void *data = ldb_module_get_private(ctx->module);
     484       38578 :         struct ldb_kv_private *ldb_kv =
     485       16649 :             talloc_get_type(data, struct ldb_kv_private);
     486             :         int ret;
     487             : 
     488             :         /*
     489             :          * If the backend has an iterate_range op, use it to start the search
     490             :          * at the first GUID indexed record, skipping the indexes section.
     491             :          */
     492       55227 :         ctx->error = LDB_SUCCESS;
     493       55227 :         ret = ldb_kv->kv_ops->iterate_range(ldb_kv,
     494             :                                             start_of_db_key,
     495             :                                             end_of_db_key,
     496             :                                             search_func,
     497             :                                             ctx);
     498       55227 :         if (ret == LDB_ERR_OPERATIONS_ERROR) {
     499             :                 /*
     500             :                  * If iterate_range isn't defined, it'll return an error,
     501             :                  * so just iterate over the whole DB.
     502             :                  */
     503       44124 :                 ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx);
     504             :         }
     505             : 
     506       55223 :         if (ret < 0) {
     507           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     508             :         }
     509             : 
     510       55223 :         return ctx->error;
     511             : }
     512             : 
     513    20701650 : static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv,
     514             :                                          struct ldb_kv_context *ctx)
     515             : {
     516             :         struct ldb_message *msg;
     517    20701650 :         struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
     518             :         const char *dn_linearized;
     519             :         const char *msg_dn_linearized;
     520             :         int ret;
     521             :         bool matched;
     522             : 
     523    20701650 :         msg = ldb_msg_new(ctx);
     524    20701650 :         if (!msg) {
     525           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     526             :         }
     527    20701650 :         ret = ldb_kv_search_dn1(ctx->module,
     528             :                                 ctx->base,
     529             :                                 msg,
     530             :                                 LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC |
     531             :                                 LDB_UNPACK_DATA_FLAG_READ_LOCKED);
     532             : 
     533    20701650 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     534      886060 :                 if (ldb_kv->check_base == false) {
     535             :                         /*
     536             :                          * In this case, we are done, as no base
     537             :                          * checking is allowed in this DB
     538             :                          */
     539       54065 :                         talloc_free(msg);
     540       54065 :                         return LDB_SUCCESS;
     541             :                 }
     542      831995 :                 ldb_asprintf_errstring(ldb,
     543             :                                        "No such Base DN: %s",
     544             :                                        ldb_dn_get_linearized(ctx->base));
     545             :         }
     546    20647585 :         if (ret != LDB_SUCCESS) {
     547      831995 :                 talloc_free(msg);
     548      831995 :                 return ret;
     549             :         }
     550             : 
     551    19815590 :         if (ldb->redact.callback != NULL) {
     552    18452854 :                 ret = ldb->redact.callback(ldb->redact.module, ctx->req, msg);
     553    18452854 :                 if (ret != LDB_SUCCESS) {
     554           0 :                         talloc_free(msg);
     555           0 :                         return ret;
     556             :                 }
     557             :         }
     558             : 
     559             :         /*
     560             :          * We use this, not ldb_match_msg_error() as we know
     561             :          * we matched on the scope BASE, as we just fetched
     562             :          * the base DN
     563             :          */
     564             : 
     565    19815590 :         ret = ldb_match_message(ldb, msg,
     566             :                                 ctx->tree,
     567             :                                 ctx->scope,
     568             :                                 &matched);
     569    19815590 :         if (ret != LDB_SUCCESS) {
     570           0 :                 talloc_free(msg);
     571           0 :                 return ret;
     572             :         }
     573    19815590 :         if (!matched) {
     574      291207 :                 talloc_free(msg);
     575      291207 :                 return LDB_SUCCESS;
     576             :         }
     577             : 
     578    19524383 :         dn_linearized = ldb_dn_get_linearized(ctx->base);
     579    19524383 :         msg_dn_linearized = ldb_dn_get_linearized(msg->dn);
     580             : 
     581    19524383 :         if (strcmp(dn_linearized, msg_dn_linearized) == 0) {
     582             :                 /*
     583             :                  * If the DN is exactly the same string, then
     584             :                  * re-use the full incoming DN for the
     585             :                  * returned result, as it has already been
     586             :                  * casefolded
     587             :                  */
     588    18648570 :                 struct ldb_dn *dn = ldb_dn_copy(msg, ctx->base);
     589    18648570 :                 if (dn != NULL) {
     590    18648570 :                         msg->dn = dn;
     591             :                 }
     592             :         }
     593             : 
     594    19524383 :         ret = ldb_msg_add_distinguished_name(msg);
     595    19524383 :         if (ret == -1) {
     596           0 :                 talloc_free(msg);
     597           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     598             :         }
     599             : 
     600             :         /*
     601             :          * filter the attributes that the user wants.
     602             :          */
     603    19524383 :         ret = ldb_kv_filter_attrs_in_place(msg, ctx->attrs);
     604    19524383 :         if (ret != LDB_SUCCESS) {
     605           0 :                 talloc_free(msg);
     606           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     607             :         }
     608             : 
     609    19524383 :         ldb_msg_shrink_to_fit(msg);
     610             : 
     611             :         /* Ensure the message elements are all talloc'd. */
     612    19524383 :         ret = ldb_msg_elements_take_ownership(msg);
     613    19524383 :         if (ret != LDB_SUCCESS) {
     614           0 :                 talloc_free(msg);
     615           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     616             :         }
     617             : 
     618             :         /*
     619             :          * Remove any extended components, we just want the casefold components
     620             :          */
     621    19524383 :         ldb_dn_remove_extended_components(msg->dn);
     622             : 
     623    19524383 :         ret = ldb_module_send_entry(ctx->req, msg, NULL);
     624    19524381 :         if (ret != LDB_SUCCESS) {
     625             :                 /* Regardless of success or failure, the msg
     626             :                  * is the callbacks responsiblity, and should
     627             :                  * not be talloc_free()'ed */
     628          10 :                 ctx->request_terminated = true;
     629          10 :                 return ret;
     630             :         }
     631             : 
     632    19524371 :         return LDB_SUCCESS;
     633             : }
     634             : 
     635             : /*
     636             :   search the database with a LDAP-like expression.
     637             :   choses a search method
     638             : */
     639    83112902 : int ldb_kv_search(struct ldb_kv_context *ctx)
     640             : {
     641             :         struct ldb_context *ldb;
     642    83112902 :         struct ldb_module *module = ctx->module;
     643    83112902 :         struct ldb_request *req = ctx->req;
     644    83112902 :         void *data = ldb_module_get_private(module);
     645    71579488 :         struct ldb_kv_private *ldb_kv =
     646    11533414 :             talloc_get_type(data, struct ldb_kv_private);
     647             :         int ret;
     648             : 
     649    83112902 :         ldb = ldb_module_get_ctx(module);
     650             : 
     651    83112902 :         ldb_request_set_state(req, LDB_ASYNC_PENDING);
     652             : 
     653    83112902 :         if (ldb_kv->kv_ops->lock_read(module) != 0) {
     654           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     655             :         }
     656             : 
     657    83112902 :         if (ldb_kv_cache_load(module) != 0) {
     658           0 :                 ldb_kv->kv_ops->unlock_read(module);
     659           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     660             :         }
     661             : 
     662    83112902 :         if (req->op.search.tree == NULL) {
     663           0 :                 ldb_kv->kv_ops->unlock_read(module);
     664           0 :                 return LDB_ERR_OPERATIONS_ERROR;
     665             :         }
     666             : 
     667    83112902 :         ctx->tree = req->op.search.tree;
     668    83112902 :         ctx->scope = req->op.search.scope;
     669    83112902 :         ctx->base = req->op.search.base;
     670    83112902 :         ctx->attrs = req->op.search.attrs;
     671             : 
     672    83112902 :         if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) {
     673             : 
     674             :                 /* Check what we should do with a NULL dn */
     675      503050 :                 switch (req->op.search.scope) {
     676       87736 :                 case LDB_SCOPE_BASE:
     677       87736 :                         ldb_asprintf_errstring(ldb,
     678             :                                                "NULL Base DN invalid for a base search");
     679       87736 :                         ret = LDB_ERR_INVALID_DN_SYNTAX;
     680       87736 :                         break;
     681           1 :                 case LDB_SCOPE_ONELEVEL:
     682           1 :                         ldb_asprintf_errstring(ldb,
     683             :                                                "NULL Base DN invalid for a one-level search");
     684           1 :                         ret = LDB_ERR_INVALID_DN_SYNTAX;
     685           1 :                         break;
     686      415313 :                 case LDB_SCOPE_SUBTREE:
     687             :                 default:
     688             :                         /* We accept subtree searches from a NULL base DN, ie over the whole DB */
     689      415313 :                         ret = LDB_SUCCESS;
     690             :                 }
     691    11829618 :         } else if (req->op.search.scope == LDB_SCOPE_BASE) {
     692             : 
     693             :                 /*
     694             :                  * If we are LDB_SCOPE_BASE, do just one search and
     695             :                  * return early.  This is critical to ensure we do not
     696             :                  * go into the index code for special DNs, as that
     697             :                  * will try to look up an index record for a special
     698             :                  * record (which doesn't exist).
     699             :                  */
     700    20701650 :                 ret = ldb_kv_search_and_return_base(ldb_kv, ctx);
     701             : 
     702    20701648 :                 ldb_kv->kv_ops->unlock_read(module);
     703             : 
     704    20701648 :                 return ret;
     705             : 
     706    61908202 :         } else if (ldb_kv->check_base) {
     707             :                 /*
     708             :                  * This database has been marked as
     709             :                  * 'checkBaseOnSearch', so do a spot check of the base
     710             :                  * dn.  Also optimise the subsequent filter by filling
     711             :                  * in the ctx->base to be exactly case correct
     712             :                  */
     713    61855441 :                 ret = ldb_kv_search_base(
     714             :                     module, ctx, req->op.search.base, &ctx->base);
     715             : 
     716    61855441 :                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     717         625 :                         ldb_asprintf_errstring(ldb,
     718             :                                                "No such Base DN: %s",
     719             :                                                ldb_dn_get_linearized(req->op.search.base));
     720             :                 }
     721             : 
     722       52761 :         } else if (ldb_dn_validate(req->op.search.base) == false) {
     723             : 
     724             :                 /* We don't want invalid base DNs here */
     725           0 :                 ldb_asprintf_errstring(ldb,
     726             :                                        "Invalid Base DN: %s",
     727             :                                        ldb_dn_get_linearized(req->op.search.base));
     728           0 :                 ret = LDB_ERR_INVALID_DN_SYNTAX;
     729             : 
     730             :         } else {
     731             :                 /* If we are not checking the base DN life is easy */
     732       52761 :                 ret = LDB_SUCCESS;
     733             :         }
     734             : 
     735    62411252 :         if (ret == LDB_SUCCESS) {
     736    62322890 :                 uint32_t match_count = 0;
     737             : 
     738    62322890 :                 ret = ldb_kv_search_indexed(ctx, &match_count);
     739    62322886 :                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     740             :                         /* Not in the index, therefore OK! */
     741     4908438 :                         ret = LDB_SUCCESS;
     742             : 
     743             :                 }
     744             :                 /* Check if we got just a normal error.
     745             :                  * In that case proceed to a full search unless we got a
     746             :                  * callback error */
     747    62322886 :                 if (!ctx->request_terminated && ret != LDB_SUCCESS) {
     748             :                         /* Not indexed, so we need to do a full scan */
     749       93853 :                         if (ldb_kv->warn_unindexed ||
     750       55251 :                             ldb_kv->disable_full_db_scan) {
     751             :                                 /* useful for debugging when slow performance
     752             :                                  * is caused by unindexed searches */
     753          24 :                                 char *expression = ldb_filter_from_tree(ctx, ctx->tree);
     754          72 :                                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb FULL SEARCH: %s SCOPE: %s DN: %s",
     755             :                                                         expression,
     756          24 :                                                         req->op.search.scope==LDB_SCOPE_BASE?"base":
     757          40 :                                                         req->op.search.scope==LDB_SCOPE_ONELEVEL?"one":
     758          16 :                                                         req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN",
     759             :                                                         ldb_dn_get_linearized(req->op.search.base));
     760             : 
     761          24 :                                 talloc_free(expression);
     762             :                         }
     763             : 
     764       55251 :                         if (match_count != 0) {
     765             :                                 /* the indexing code gave an error
     766             :                                  * after having returned at least one
     767             :                                  * entry. This means the indexes are
     768             :                                  * corrupt or a database record is
     769             :                                  * corrupt. We cannot continue with a
     770             :                                  * full search or we may return
     771             :                                  * duplicate entries
     772             :                                  */
     773           0 :                                 ldb_kv->kv_ops->unlock_read(module);
     774          24 :                                 return LDB_ERR_OPERATIONS_ERROR;
     775             :                         }
     776             : 
     777       55251 :                         if (ldb_kv->disable_full_db_scan) {
     778          24 :                                 ldb_set_errstring(ldb,
     779             :                                                   "ldb FULL SEARCH disabled");
     780          24 :                                 ldb_kv->kv_ops->unlock_read(module);
     781          24 :                                 return LDB_ERR_INAPPROPRIATE_MATCHING;
     782             :                         }
     783             : 
     784       55227 :                         ret = ldb_kv_search_full(ctx);
     785       55223 :                         if (ret != LDB_SUCCESS) {
     786          25 :                                 ldb_set_errstring(ldb, "Indexed and full searches both failed!\n");
     787             :                         }
     788             :                 }
     789             :         }
     790             : 
     791    62411220 :         ldb_kv->kv_ops->unlock_read(module);
     792             : 
     793    62411220 :         return ret;
     794             : }

Generated by: LCOV version 1.13