s3/smbd: Ensure quota code is only called when quota support detected
[vlendec/samba-autobuild/.git] / lib / ldb / ldb_tdb / ldb_search.c
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_tdb.h"
35 #include "ldb_private.h"
36 #include <tdb.h>
37
38 /*
39   add one element to a message
40 */
41 static int msg_add_element(struct ldb_message *ret, 
42                            const struct ldb_message_element *el,
43                            int check_duplicates)
44 {
45         unsigned int i;
46         struct ldb_message_element *e2, *elnew;
47
48         if (check_duplicates && ldb_msg_find_element(ret, el->name)) {
49                 /* its already there */
50                 return 0;
51         }
52
53         e2 = talloc_realloc(ret, ret->elements, struct ldb_message_element, ret->num_elements+1);
54         if (!e2) {
55                 return -1;
56         }
57         ret->elements = e2;
58         
59         elnew = &e2[ret->num_elements];
60
61         elnew->name = talloc_strdup(ret->elements, el->name);
62         if (!elnew->name) {
63                 return -1;
64         }
65
66         if (el->num_values) {
67                 elnew->values = talloc_array(ret->elements, struct ldb_val, el->num_values);
68                 if (!elnew->values) {
69                         return -1;
70                 }
71         } else {
72                 elnew->values = NULL;
73         }
74
75         for (i=0;i<el->num_values;i++) {
76                 elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]);
77                 if (elnew->values[i].length != el->values[i].length) {
78                         return -1;
79                 }
80         }
81
82         elnew->num_values = el->num_values;
83         elnew->flags = el->flags;
84
85         ret->num_elements++;
86
87         return 0;
88 }
89
90 /*
91   add the special distinguishedName element
92 */
93 static int msg_add_distinguished_name(struct ldb_message *msg)
94 {
95         struct ldb_message_element el;
96         struct ldb_val val;
97         int ret;
98
99         el.flags = 0;
100         el.name = "distinguishedName";
101         el.num_values = 1;
102         el.values = &val;
103         el.flags = 0;
104         val.data = (uint8_t *)ldb_dn_alloc_linearized(msg, msg->dn);
105         if (val.data == NULL) {
106                 return -1;
107         }
108         val.length = strlen((char *)val.data);
109
110         ret = msg_add_element(msg, &el, 1);
111         return ret;
112 }
113
114 /*
115   search the database for a single simple dn.
116   return LDB_ERR_NO_SUCH_OBJECT on record-not-found
117   and LDB_SUCCESS on success
118 */
119 int ltdb_search_base(struct ldb_module *module,
120                      TALLOC_CTX *mem_ctx,
121                      struct ldb_dn *dn,
122                      struct ldb_dn **ret_dn)
123 {
124         int exists;
125         int ret;
126         struct ldb_message *msg = NULL;
127
128         if (ldb_dn_is_null(dn)) {
129                 return LDB_ERR_NO_SUCH_OBJECT;
130         }
131
132         /*
133          * We can't use tdb_exists() directly on a key when the TDB
134          * key is the GUID one, not the DN based one.  So we just do a
135          * normal search and avoid most of the allocation with the
136          * LDB_UNPACK_DATA_FLAG_NO_DN and
137          * LDB_UNPACK_DATA_FLAG_NO_ATTRS flags
138          */
139         msg = ldb_msg_new(module);
140         if (msg == NULL) {
141                 return LDB_ERR_OPERATIONS_ERROR;
142         }
143
144         ret = ltdb_search_dn1(module, dn,
145                               msg,
146                               LDB_UNPACK_DATA_FLAG_NO_ATTRS);
147         if (ret == LDB_SUCCESS) {
148                 const char *dn_linearized
149                         = ldb_dn_get_linearized(dn);
150                 const char *msg_dn_linearlized
151                         = ldb_dn_get_linearized(msg->dn);
152
153                 if (strcmp(dn_linearized, msg_dn_linearlized) == 0) {
154                         /*
155                          * Re-use the full incoming DN for
156                          * subtree checks
157                          */
158                         *ret_dn = dn;
159                 } else {
160                         /*
161                          * Use the string DN from the unpack, so that
162                          * we have a case-exact match of the base
163                          */
164                         *ret_dn = talloc_steal(mem_ctx, msg->dn);
165                 }
166                 exists = true;
167         } else if (ret == LDB_ERR_NO_SUCH_OBJECT) {
168                 exists = false;
169         } else {
170                 talloc_free(msg);
171                 return ret;
172         }
173         talloc_free(msg);
174         if (exists) {
175                 return LDB_SUCCESS;
176         }
177         return LDB_ERR_NO_SUCH_OBJECT;
178 }
179
180 struct ltdb_parse_data_unpack_ctx {
181         struct ldb_message *msg;
182         struct ldb_module *module;
183         unsigned int unpack_flags;
184 };
185
186 static int ltdb_parse_data_unpack(TDB_DATA key, TDB_DATA data,
187                                   void *private_data)
188 {
189         struct ltdb_parse_data_unpack_ctx *ctx = private_data;
190         unsigned int nb_elements_in_db;
191         int ret;
192         struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
193         struct ldb_val data_parse = {
194                 .data = data.dptr,
195                 .length = data.dsize
196         };
197
198         if (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
199                 /*
200                  * If we got LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
201                  * we need at least do a memdup on the whole
202                  * data buffer as that may change later
203                  * and the caller needs a stable result.
204                  */
205                 data_parse.data = talloc_memdup(ctx->msg,
206                                                 data.dptr,
207                                                 data.dsize);
208                 if (data_parse.data == NULL) {
209                         ldb_debug(ldb, LDB_DEBUG_ERROR,
210                                   "Unable to allocate data(%d) for %*.*s\n",
211                                   (int)data.dsize,
212                                   (int)key.dsize, (int)key.dsize, key.dptr);
213                         return LDB_ERR_OPERATIONS_ERROR;
214                 }
215         }
216
217         ret = ldb_unpack_data_only_attr_list_flags(ldb, &data_parse,
218                                                    ctx->msg,
219                                                    NULL, 0,
220                                                    ctx->unpack_flags,
221                                                    &nb_elements_in_db);
222         if (ret == -1) {
223                 if (data_parse.data != data.dptr) {
224                         talloc_free(data_parse.data);
225                 }
226
227                 ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n",
228                           (int)key.dsize, (int)key.dsize, key.dptr);
229                 return LDB_ERR_OPERATIONS_ERROR;                
230         }
231         return ret;
232 }
233
234 /*
235   search the database for a single simple dn, returning all attributes
236   in a single message
237
238   return LDB_ERR_NO_SUCH_OBJECT on record-not-found
239   and LDB_SUCCESS on success
240 */
241 int ltdb_search_key(struct ldb_module *module, struct ltdb_private *ltdb,
242                     const struct TDB_DATA tdb_key,
243                     struct ldb_message *msg,
244                     unsigned int unpack_flags)
245 {
246         int ret;
247         struct ltdb_parse_data_unpack_ctx ctx = {
248                 .msg = msg,
249                 .module = module,
250                 .unpack_flags = unpack_flags
251         };
252
253         memset(msg, 0, sizeof(*msg));
254
255         msg->num_elements = 0;
256         msg->elements = NULL;
257
258         ret = tdb_parse_record(ltdb->tdb, tdb_key, 
259                                ltdb_parse_data_unpack, &ctx); 
260         
261         if (ret == -1) {
262                 ret = ltdb_err_map(tdb_error(ltdb->tdb));
263                 if (ret == LDB_SUCCESS) {
264                         /*
265                          * Just to be sure we don't turn errors
266                          * into success
267                          */
268                         return LDB_ERR_OPERATIONS_ERROR;
269                 }
270                 return ret;
271         } else if (ret != LDB_SUCCESS) {
272                 return ret;
273         }
274
275         return LDB_SUCCESS;
276 }
277
278 /*
279   search the database for a single simple dn, returning all attributes
280   in a single message
281
282   return LDB_ERR_NO_SUCH_OBJECT on record-not-found
283   and LDB_SUCCESS on success
284 */
285 int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg,
286                     unsigned int unpack_flags)
287 {
288         void *data = ldb_module_get_private(module);
289         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
290         int ret;
291         uint8_t guid_key[LTDB_GUID_KEY_SIZE];
292         TDB_DATA tdb_key = {
293                 .dptr = guid_key,
294                 .dsize = sizeof(guid_key)
295         };
296         TALLOC_CTX *tdb_key_ctx = NULL;
297
298         if (ltdb->cache->GUID_index_attribute == NULL) {
299                 tdb_key_ctx = talloc_new(msg);
300                 if (!tdb_key_ctx) {
301                         return ldb_module_oom(module);
302                 }
303
304                 /* form the key */
305                 tdb_key = ltdb_key_dn(module, tdb_key_ctx, dn);
306                 if (!tdb_key.dptr) {
307                         TALLOC_FREE(tdb_key_ctx);
308                         return LDB_ERR_OPERATIONS_ERROR;
309                 }
310         } else if (ldb_dn_is_special(dn)) {
311                 tdb_key_ctx = talloc_new(msg);
312                 if (!tdb_key_ctx) {
313                         return ldb_module_oom(module);
314                 }
315
316                 /* form the key */
317                 tdb_key = ltdb_key_dn(module, tdb_key_ctx, dn);
318                 if (!tdb_key.dptr) {
319                         TALLOC_FREE(tdb_key_ctx);
320                         return LDB_ERR_OPERATIONS_ERROR;
321                 }
322         } else {
323                 /*
324                  * Look in the index to find the key for this DN.
325                  *
326                  * the tdb_key memory is allocated above, msg is just
327                  * used for internal memory.
328                  *
329                  */
330                 ret = ltdb_key_dn_from_idx(module, ltdb,
331                                            msg,
332                                            dn, &tdb_key);
333                 if (ret != LDB_SUCCESS) {
334                         return ret;
335                 }
336         }
337
338         ret = ltdb_search_key(module, ltdb, tdb_key, msg, unpack_flags);
339
340         TALLOC_FREE(tdb_key_ctx);
341
342         if (ret != LDB_SUCCESS) {
343                 return ret;
344         }
345
346         if ((unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DN) == 0) {
347                 if (!msg->dn) {
348                         msg->dn = ldb_dn_copy(msg, dn);
349                 }
350                 if (!msg->dn) {
351                         return LDB_ERR_OPERATIONS_ERROR;
352                 }
353         }
354
355         return LDB_SUCCESS;
356 }
357
358 /*
359   filter the specified list of attributes from a message
360   removing not requested attrs from the new message constructed.
361
362   The reason this makes a new message is that the old one may not be
363   individually allocated, which is what our callers expect.
364
365  */
366 int ltdb_filter_attrs(TALLOC_CTX *mem_ctx,
367                       const struct ldb_message *msg, const char * const *attrs,
368                       struct ldb_message **filtered_msg)
369 {
370         unsigned int i;
371         bool keep_all = false;
372         bool add_dn = false;
373         uint32_t num_elements;
374         uint32_t elements_size;
375         struct ldb_message *msg2;
376
377         msg2 = ldb_msg_new(mem_ctx);
378         if (msg2 == NULL) {
379                 goto failed;
380         }
381
382         msg2->dn = ldb_dn_copy(msg2, msg->dn);
383         if (msg2->dn == NULL) {
384                 goto failed;
385         }
386
387         if (attrs) {
388                 /* check for special attrs */
389                 for (i = 0; attrs[i]; i++) {
390                         int cmp = strcmp(attrs[i], "*");
391                         if (cmp == 0) {
392                                 keep_all = true;
393                                 break;
394                         }
395                         cmp = ldb_attr_cmp(attrs[i], "distinguishedName");
396                         if (cmp == 0) {
397                                 add_dn = true;
398                         }
399                 }
400         } else {
401                 keep_all = true;
402         }
403
404         if (keep_all) {
405                 add_dn = true;
406                 elements_size = msg->num_elements + 1;
407
408         /* Shortcuts for the simple cases */
409         } else if (add_dn && i == 1) {
410                 if (msg_add_distinguished_name(msg2) != 0) {
411                         goto failed;
412                 }
413                 *filtered_msg = msg2;
414                 return 0;
415         } else if (i == 0) {
416                 *filtered_msg = msg2;
417                 return 0;
418
419         /* Otherwise we are copying at most as many element as we have attributes */
420         } else {
421                 elements_size = i;
422         }
423
424         msg2->elements = talloc_array(msg2, struct ldb_message_element,
425                                       elements_size);
426         if (msg2->elements == NULL) goto failed;
427
428         num_elements = 0;
429
430         for (i = 0; i < msg->num_elements; i++) {
431                 struct ldb_message_element *el = &msg->elements[i];
432                 struct ldb_message_element *el2 = &msg2->elements[num_elements];
433                 unsigned int j;
434
435                 if (keep_all == false) {
436                         bool found = false;
437                         for (j = 0; attrs[j]; j++) {
438                                 int cmp = ldb_attr_cmp(el->name, attrs[j]);
439                                 if (cmp == 0) {
440                                         found = true;
441                                         break;
442                                 }
443                         }
444                         if (found == false) {
445                                 continue;
446                         }
447                 }
448                 *el2 = *el;
449                 el2->name = talloc_strdup(msg2->elements, el->name);
450                 if (el2->name == NULL) {
451                         goto failed;
452                 }
453                 el2->values = talloc_array(msg2->elements, struct ldb_val, el->num_values);
454                 if (el2->values == NULL) {
455                         goto failed;
456                 }
457                 for (j=0;j<el->num_values;j++) {
458                         el2->values[j] = ldb_val_dup(el2->values, &el->values[j]);
459                         if (el2->values[j].data == NULL && el->values[j].length != 0) {
460                                 goto failed;
461                         }
462                 }
463                 num_elements++;
464
465                 /* Pidginhole principle: we can't have more elements
466                  * than the number of attributes if they are unique in
467                  * the DB */
468                 if (num_elements > elements_size) {
469                         goto failed;
470                 }
471         }
472
473         msg2->num_elements = num_elements;
474
475         if (add_dn) {
476                 if (msg_add_distinguished_name(msg2) != 0) {
477                         goto failed;
478                 }
479         }
480
481         if (msg2->num_elements > 0) {
482                 msg2->elements = talloc_realloc(msg2, msg2->elements,
483                                                 struct ldb_message_element,
484                                                 msg2->num_elements);
485                 if (msg2->elements == NULL) {
486                         goto failed;
487                 }
488         } else {
489                 talloc_free(msg2->elements);
490                 msg2->elements = NULL;
491         }
492
493         *filtered_msg = msg2;
494
495         return 0;
496 failed:
497         TALLOC_FREE(msg2);
498         return -1;
499 }
500
501 /*
502   search function for a non-indexed search
503  */
504 static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
505 {
506         struct ldb_context *ldb;
507         struct ltdb_context *ac;
508         struct ldb_message *msg, *filtered_msg;
509         const struct ldb_val val = {
510                 .data = data.dptr,
511                 .length = data.dsize,
512         };
513         int ret;
514         bool matched;
515         unsigned int nb_elements_in_db;
516
517         ac = talloc_get_type(state, struct ltdb_context);
518         ldb = ldb_module_get_ctx(ac->module);
519
520         if (ltdb_key_is_record(key) == false) {
521                 return 0;
522         }
523
524         msg = ldb_msg_new(ac);
525         if (!msg) {
526                 ac->error = LDB_ERR_OPERATIONS_ERROR;
527                 return -1;
528         }
529
530         /* unpack the record */
531         ret = ldb_unpack_data_only_attr_list_flags(ldb, &val,
532                                                    msg,
533                                                    NULL, 0,
534                                                    LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC|
535                                                    LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC,
536                                                    &nb_elements_in_db);
537         if (ret == -1) {
538                 talloc_free(msg);
539                 ac->error = LDB_ERR_OPERATIONS_ERROR;
540                 return -1;
541         }
542
543         if (!msg->dn) {
544                 msg->dn = ldb_dn_new(msg, ldb,
545                                      (char *)key.dptr + 3);
546                 if (msg->dn == NULL) {
547                         talloc_free(msg);
548                         ac->error = LDB_ERR_OPERATIONS_ERROR;
549                         return -1;
550                 }
551         }
552
553         /* see if it matches the given expression */
554         ret = ldb_match_msg_error(ldb, msg,
555                                   ac->tree, ac->base, ac->scope, &matched);
556         if (ret != LDB_SUCCESS) {
557                 talloc_free(msg);
558                 ac->error = LDB_ERR_OPERATIONS_ERROR;
559                 return -1;
560         }
561         if (!matched) {
562                 talloc_free(msg);
563                 return 0;
564         }
565
566         /* filter the attributes that the user wants */
567         ret = ltdb_filter_attrs(ac, msg, ac->attrs, &filtered_msg);
568         talloc_free(msg);
569
570         if (ret == -1) {
571                 ac->error = LDB_ERR_OPERATIONS_ERROR;
572                 return -1;
573         }
574
575         ret = ldb_module_send_entry(ac->req, filtered_msg, NULL);
576         if (ret != LDB_SUCCESS) {
577                 ac->request_terminated = true;
578                 /* the callback failed, abort the operation */
579                 ac->error = LDB_ERR_OPERATIONS_ERROR;
580                 return -1;
581         }
582
583         return 0;
584 }
585
586
587 /*
588   search the database with a LDAP-like expression.
589   this is the "full search" non-indexed variant
590 */
591 static int ltdb_search_full(struct ltdb_context *ctx)
592 {
593         void *data = ldb_module_get_private(ctx->module);
594         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
595         int ret;
596
597         ctx->error = LDB_SUCCESS;
598         if (ltdb->in_transaction != 0) {
599                 ret = tdb_traverse(ltdb->tdb, search_func, ctx);
600         } else {
601                 ret = tdb_traverse_read(ltdb->tdb, search_func, ctx);
602         }
603
604         if (ret < 0) {
605                 return LDB_ERR_OPERATIONS_ERROR;
606         }
607
608         return ctx->error;
609 }
610
611 static int ltdb_search_and_return_base(struct ltdb_private *ltdb,
612                                        struct ltdb_context *ctx)
613 {
614         struct ldb_message *msg, *filtered_msg;
615         struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
616         const char *dn_linearized;
617         const char *msg_dn_linearlized;
618         int ret;
619         bool matched;
620
621         msg = ldb_msg_new(ctx);
622         if (!msg) {
623                 return LDB_ERR_OPERATIONS_ERROR;
624         }
625         ret = ltdb_search_dn1(ctx->module, ctx->base, msg,
626                               LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC|
627                               LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC);
628
629         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
630                 if (ltdb->check_base == false) {
631                         /*
632                          * In this case, we are done, as no base
633                          * checking is allowed in this DB
634                          */
635                         talloc_free(msg);
636                         return LDB_SUCCESS;
637                 }
638                 ldb_asprintf_errstring(ldb,
639                                        "No such Base DN: %s",
640                                        ldb_dn_get_linearized(ctx->base));
641         }
642         if (ret != LDB_SUCCESS) {
643                 talloc_free(msg);
644                 return ret;
645         }
646
647
648         /*
649          * We use this, not ldb_match_msg_error() as we know
650          * we matched on the scope BASE, as we just fetched
651          * the base DN
652          */
653
654         ret = ldb_match_message(ldb, msg,
655                                 ctx->tree,
656                                 ctx->scope,
657                                 &matched);
658         if (ret != LDB_SUCCESS) {
659                 talloc_free(msg);
660                 return ret;
661         }
662         if (!matched) {
663                 talloc_free(msg);
664                 return LDB_SUCCESS;
665         }
666
667         dn_linearized = ldb_dn_get_linearized(ctx->base);
668         msg_dn_linearlized = ldb_dn_get_linearized(msg->dn);
669
670         if (strcmp(dn_linearized, msg_dn_linearlized) == 0) {
671                 /*
672                  * If the DN is exactly the same string, then
673                  * re-use the full incoming DN for the
674                  * returned result, as it has already been
675                  * casefolded
676                  */
677                 msg->dn = ctx->base;
678         }
679
680         /*
681          * filter the attributes that the user wants.
682          *
683          * This copies msg->dn including the casefolding, so the above
684          * assignment is safe
685          */
686         ret = ltdb_filter_attrs(ctx, msg, ctx->attrs, &filtered_msg);
687
688         /*
689          * Remove any extended components possibly copied in from
690          * msg->dn, we just want the casefold components
691          */
692         ldb_dn_remove_extended_components(filtered_msg->dn);
693         talloc_free(msg);
694
695         if (ret == -1) {
696                 return LDB_ERR_OPERATIONS_ERROR;
697         }
698
699         ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL);
700         if (ret != LDB_SUCCESS) {
701                 /* Regardless of success or failure, the msg
702                  * is the callbacks responsiblity, and should
703                  * not be talloc_free()'ed */
704                 ctx->request_terminated = true;
705                 return ret;
706         }
707
708         return LDB_SUCCESS;
709 }
710
711 /*
712   search the database with a LDAP-like expression.
713   choses a search method
714 */
715 int ltdb_search(struct ltdb_context *ctx)
716 {
717         struct ldb_context *ldb;
718         struct ldb_module *module = ctx->module;
719         struct ldb_request *req = ctx->req;
720         void *data = ldb_module_get_private(module);
721         struct ltdb_private *ltdb = talloc_get_type(data, struct ltdb_private);
722         int ret;
723
724         ldb = ldb_module_get_ctx(module);
725
726         ldb_request_set_state(req, LDB_ASYNC_PENDING);
727
728         if (ltdb_lock_read(module) != 0) {
729                 return LDB_ERR_OPERATIONS_ERROR;
730         }
731
732         if (ltdb_cache_load(module) != 0) {
733                 ltdb_unlock_read(module);
734                 return LDB_ERR_OPERATIONS_ERROR;
735         }
736
737         if (req->op.search.tree == NULL) {
738                 ltdb_unlock_read(module);
739                 return LDB_ERR_OPERATIONS_ERROR;
740         }
741
742         ctx->tree = req->op.search.tree;
743         ctx->scope = req->op.search.scope;
744         ctx->base = req->op.search.base;
745         ctx->attrs = req->op.search.attrs;
746
747         if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) {
748
749                 /* Check what we should do with a NULL dn */
750                 switch (req->op.search.scope) {
751                 case LDB_SCOPE_BASE:
752                         ldb_asprintf_errstring(ldb, 
753                                                "NULL Base DN invalid for a base search");
754                         ret = LDB_ERR_INVALID_DN_SYNTAX;
755                         break;
756                 case LDB_SCOPE_ONELEVEL:
757                         ldb_asprintf_errstring(ldb, 
758                                                "NULL Base DN invalid for a one-level search");
759                         ret = LDB_ERR_INVALID_DN_SYNTAX;        
760                         break;
761                 case LDB_SCOPE_SUBTREE:
762                 default:
763                         /* We accept subtree searches from a NULL base DN, ie over the whole DB */
764                         ret = LDB_SUCCESS;
765                 }
766         } else if (ldb_dn_is_valid(req->op.search.base) == false) {
767
768                 /* We don't want invalid base DNs here */
769                 ldb_asprintf_errstring(ldb, 
770                                        "Invalid Base DN: %s", 
771                                        ldb_dn_get_linearized(req->op.search.base));
772                 ret = LDB_ERR_INVALID_DN_SYNTAX;
773
774         } else if (req->op.search.scope == LDB_SCOPE_BASE) {
775
776                 /*
777                  * If we are LDB_SCOPE_BASE, do just one search and
778                  * return early.  This is critical to ensure we do not
779                  * go into the index code for special DNs, as that
780                  * will try to look up an index record for a special
781                  * record (which doesn't exist).
782                  */
783                 ret = ltdb_search_and_return_base(ltdb, ctx);
784
785                 ltdb_unlock_read(module);
786
787                 return ret;
788
789         } else if (ltdb->check_base) {
790                 /*
791                  * This database has been marked as
792                  * 'checkBaseOnSearch', so do a spot check of the base
793                  * dn.  Also optimise the subsequent filter by filling
794                  * in the ctx->base to be exactly case correct
795                  */
796                 ret = ltdb_search_base(module, ctx,
797                                        req->op.search.base,
798                                        &ctx->base);
799                 
800                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
801                         ldb_asprintf_errstring(ldb, 
802                                                "No such Base DN: %s", 
803                                                ldb_dn_get_linearized(req->op.search.base));
804                 }
805                         
806         } else {
807                 /* If we are not checking the base DN life is easy */
808                 ret = LDB_SUCCESS;
809         }
810
811         if (ret == LDB_SUCCESS) {
812                 uint32_t match_count = 0;
813
814                 ret = ltdb_search_indexed(ctx, &match_count);
815                 if (ret == LDB_ERR_NO_SUCH_OBJECT) {
816                         /* Not in the index, therefore OK! */
817                         ret = LDB_SUCCESS;
818                         
819                 }
820                 /* Check if we got just a normal error.
821                  * In that case proceed to a full search unless we got a
822                  * callback error */
823                 if ( ! ctx->request_terminated && ret != LDB_SUCCESS) {
824                         /* Not indexed, so we need to do a full scan */
825                         if (ltdb->warn_unindexed || ltdb->disable_full_db_scan) {
826                                 /* useful for debugging when slow performance
827                                  * is caused by unindexed searches */
828                                 char *expression = ldb_filter_from_tree(ctx, ctx->tree);
829                                 ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb FULL SEARCH: %s SCOPE: %s DN: %s",
830                                                         expression,
831                                                         req->op.search.scope==LDB_SCOPE_BASE?"base":
832                                                         req->op.search.scope==LDB_SCOPE_ONELEVEL?"one":
833                                                         req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN",
834                                                         ldb_dn_get_linearized(req->op.search.base));
835
836                                 talloc_free(expression);
837                         }
838
839                         if (match_count != 0) {
840                                 /* the indexing code gave an error
841                                  * after having returned at least one
842                                  * entry. This means the indexes are
843                                  * corrupt or a database record is
844                                  * corrupt. We cannot continue with a
845                                  * full search or we may return
846                                  * duplicate entries
847                                  */
848                                 ltdb_unlock_read(module);
849                                 return LDB_ERR_OPERATIONS_ERROR;
850                         }
851
852                         if (ltdb->disable_full_db_scan) {
853                                 ldb_set_errstring(ldb,
854                                                   "ldb FULL SEARCH disabled");
855                                 ltdb_unlock_read(module);
856                                 return LDB_ERR_INAPPROPRIATE_MATCHING;
857                         }
858
859                         ret = ltdb_search_full(ctx);
860                         if (ret != LDB_SUCCESS) {
861                                 ldb_set_errstring(ldb, "Indexed and full searches both failed!\n");
862                         }
863                 }
864         }
865
866         ltdb_unlock_read(module);
867
868         return ret;
869 }
870