ad55e878010d0ac2a7bdce3b9846937b391a00b0
[exim.git] / src / src / search.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2020 - 2024 */
6 /* Copyright (c) University of Cambridge 1995 - 2015 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 /* A set of functions to search databases in various formats. An open
11 database is represented by a void * value which is returned from a lookup-
12 specific "open" function. These are now all held in individual modules in the
13 lookups subdirectory and the functions here form a generic interface.
14
15 Caching is used to improve performance. Open files are cached until a tidyup
16 function is called, and for each file the result of the last lookup is cached.
17 However, if too many files are opened, some of those that are not in use have
18 to be closed. Those open items that use real files are kept on a LRU chain to
19 help with this.
20
21 All the data is held in permanent store so as to be independent of the stacking
22 pool that is reset from time to time. In fact, we use malloc'd store so that it
23 can be freed when the caches are tidied up. It isn't actually clear whether
24 this is a benefit or not, to be honest. */
25
26 #include "exim.h"
27
28
29 /* Tree in which to cache open files until tidyup called. */
30
31 static tree_node *search_tree = NULL;
32
33 /* Two-way chain of open databases that use real files. This is maintained in
34 recently-used order for the purposes of closing the least recently used when
35 too many files are open. */
36
37 static tree_node *open_top = NULL;
38 static tree_node *open_bot = NULL;
39
40 /* Count of open databases that use real files */
41
42 static int open_filecount = 0;
43
44 /* Allow us to reset store used for lookups and lookup caching */
45
46 static rmark search_reset_point = NULL;
47
48
49
50 /*************************************************
51 *      Validate a plain lookup type name         *
52 *************************************************/
53
54 static const lookup_info *
55 internal_search_findtype(const uschar * name)
56 {
57 tree_node * t = tree_search(lookups_tree, name);
58 return t ? t->data.ptr : NULL;
59 }
60
61 /* Only those names that are recognized and whose code is included in the
62 binary give an OK response. Types are held in a binary tree for fast location
63 and dynamic insertion.  If not initially found, try to load a module if
64 any were compiled.
65
66 Arguments:
67   name       lookup type name - not necessarily zero terminated (e.g. dbm*)
68   len        length of the name
69
70 Returns:     ptr to info struct for the lookup,
71              or NULL with message in search_error_message.
72 */
73
74 const lookup_info *
75 search_findtype(const uschar * name, int len)
76 {
77 const lookup_info * li;
78
79 if (name[len])
80   name = string_copyn(name, len);
81 if ((li = internal_search_findtype(name)))
82   return li;
83
84 #ifdef LOOKUP_MODULE_DIR
85     DEBUG(D_lookup)
86       debug_printf_indent("searchtype %s not initially found\n", name);
87
88     if (lookup_one_mod_load(name, NULL))
89       if ((li = internal_search_findtype(name)))
90         return li;
91       else
92         { DEBUG(D_lookup) debug_printf_indent("find retry failed\n"); }
93     else DEBUG(D_lookup)
94       debug_printf_indent("scan modules dir for %s failed\n", name);
95 #endif
96
97 search_error_message  = string_sprintf("unknown lookup type \"%s\"", name);
98 return NULL;
99 }
100
101
102
103 /*************************************************
104 *       Validate a full lookup type name         *
105 *************************************************/
106
107 /* This function recognizes the "partial-" prefix and also terminating * and *@
108 suffixes.
109
110 Arguments:
111   name         the full lookup type name
112   ptypeptr     where to put the partial type
113                  after subtraction of 1024 or 2048:
114                    negative     => no partial matching
115                    non-negative => minimum number of non-wild components
116   ptypeaff     where to put a pointer to the affix
117                  the affix is within name if supplied therein
118                  otherwise it's a literal string
119   afflen       the length of the affix
120   starflags    where to put the SEARCH_STAR and SEARCH_STARAT flags
121   opts         where to put the options
122
123 Returns:     ptr to info struct for the lookup,
124              or NULL with message in search_error_message.
125 */
126
127 const lookup_info *
128 search_findtype_partial(const uschar *name, int *ptypeptr, const uschar **ptypeaff,
129   int *afflen, int *starflags, const uschar ** opts)
130 {
131 const lookup_info * li;
132 int pv = -1, len;
133 const uschar * ss = name, * t;
134
135 *starflags = 0;
136 *ptypeaff = NULL;
137
138 /* Check for a partial matching type. It must start with "partial", optionally
139 followed by a sequence of digits. If this is followed by "-", the affix is the
140 default "*." string. Otherwise we expect an affix in parentheses. Affixes are a
141 limited number of characters, not including parens. */
142
143 if (Ustrncmp(name, "partial", 7) == 0)
144   {
145   ss += 7;
146   if (isdigit (*ss))
147     {
148     pv = 0;
149     while (isdigit(*ss)) pv = pv*10 + *ss++ - '0';
150     }
151   else pv = 2;         /* Default number of wild components */
152
153   if (*ss == '(')
154     {
155     *ptypeaff = ++ss;
156     while (ispunct(*ss) && *ss != ')') ss++;
157     if (*ss != ')') goto BAD_TYPE;
158     *afflen = ss++ - *ptypeaff;
159     }
160   else if (*ss++ == '-')
161     {
162     *ptypeaff = US "*.";
163     *afflen = 2;
164     }
165   else
166     {
167     BAD_TYPE:
168     search_error_message = string_sprintf("format error in lookup type \"%s\"",
169       name);
170     return NULL;
171     }
172   }
173
174 /* Now we are left with a lookup name, possibly followed by * or *@,
175 and then by options starting with a "," */
176
177 len = Ustrlen(ss);
178 if ((t = Ustrchr(ss, '*')))
179   {
180   len = t - ss;
181   *starflags |= (t[1] == '@' ? SEARCH_STARAT : SEARCH_STAR);
182   }
183 else
184   t = ss;
185
186 if ((t = Ustrchr(t, ',')))
187   {
188   int l = t - ss;
189   if (l < len) len = l;
190   *opts = string_copy(t+1);
191   }
192 else
193   *opts = NULL;
194
195 /* Check for the individual search type. Only those that are actually in the
196 binary are valid. For query-style types, "partial" and default types are
197 erroneous. */
198
199 li = search_findtype(ss, len);
200 if (li && mac_islookup(li, lookup_querystyle))
201   {
202   if (pv >= 0)
203     {
204     search_error_message = string_sprintf("\"partial\" is not permitted "
205       "for lookup type \"%s\"", ss);
206     return NULL;
207     }
208   if ((*starflags & (SEARCH_STAR|SEARCH_STARAT)) != 0)
209     {
210     search_error_message = string_sprintf("defaults using \"*\" or \"*@\" are "
211       "not permitted for lookup type \"%s\"", ss);
212     return NULL;
213     }
214   }
215
216 *ptypeptr = pv;
217 return li;
218 }
219
220
221 /* Set the parameters for the three different kinds of lookup.
222 Arguments:
223  li             the info block for the search type
224  search         the search-type string
225  query          argument for the search; filename or query
226  fnamep         pointer to return filename
227  opts           options
228
229 Return: keyquery        the search-type (for single-key) or query (for query-type)
230  */
231 uschar *
232 search_args(const lookup_info * li, uschar * search, uschar * query,
233   uschar ** fnamep, const uschar * opts)
234 {
235 Uskip_whitespace(&query);
236 if (mac_islookup(li, lookup_absfilequery))
237   {                                     /* query-style but with file (sqlite) */
238   int sep = ',';
239
240   /* Check options first for new-style file spec */
241   if (opts) for (uschar * s; s = string_nextinlist(&opts, &sep, NULL, 0); )
242     if (Ustrncmp(s, "file=", 5) == 0)
243       {
244       *fnamep = s+5;
245       return query;
246       }
247
248   /* If no filename from options, use old-tyle space-sep prefix on query */
249   if (*query == '/')
250     {
251     uschar * s = query;
252     Uskip_nonwhite(&query);
253     *fnamep = string_copyn(s, query - s);
254     Uskip_whitespace(&query);
255     }
256   else
257     *fnamep = NULL;
258   return query;         /* remainder after file skipped */
259   }
260 if (!mac_islookup(li, lookup_querystyle))
261   {                                     /* single-key */
262   *fnamep = query;
263   return search;        /* modifiers important so use "keyquery" for them */
264   }
265 *fnamep = NULL;                         /* else query-style */
266 return query;
267 }
268
269
270
271 /*************************************************
272 *               Release cached resources         *
273 *************************************************/
274
275 /* When search_open is called it caches the "file" that it opens in
276 search_tree. The name of the tree node is a concatenation of the search type
277 with the file name. For query-style lookups, the file name is empty. Real files
278 are normally closed only when this tidyup routine is called, typically at the
279 end of sections of code where a number of lookups might occur. However, if too
280 many files are open simultaneously, some get closed beforehand. They can't be
281 removed from the tree. There is also a general tidyup function which is called
282 for the lookup driver, if it exists.
283
284 First, there is an internal, recursive subroutine.
285
286 Argument:    a pointer to a search_openfile tree node
287 Returns:     nothing
288 */
289
290 static void
291 tidyup_subtree(tree_node *t)
292 {
293 search_cache * c = (search_cache *)t->data.ptr;
294 if (t->left)  tidyup_subtree(t->left);
295 if (t->right) tidyup_subtree(t->right);
296 if (c && c->handle && c->li->close)
297   c->li->close(c->handle);
298 }
299
300
301 static void
302 tidy_cb(uschar * name, uschar * ptr, void * ctx)
303 {
304 lookup_info * li = (lookup_info *)ptr;
305 if (li->tidy) (li->tidy)();
306 }
307
308
309 /* The external entry point
310
311 Argument: none
312 Returns:  nothing
313 */
314
315 void
316 search_tidyup(void)
317 {
318 int old_pool = store_pool;
319
320 DEBUG(D_lookup) debug_printf_indent("search_tidyup called\n");
321
322 /* Close individually each cached open file. */
323
324 store_pool = POOL_SEARCH;
325 if (search_tree)
326   {
327   tidyup_subtree(search_tree);
328   search_tree = NULL;
329   }
330 open_top = open_bot = NULL;
331 open_filecount = 0;
332
333 /* Call the general tidyup entry for any drivers that have one. */
334
335 tree_walk(lookups_tree, tidy_cb, NULL);
336
337 if (search_reset_point) search_reset_point = store_reset(search_reset_point);
338 store_pool = old_pool;
339 }
340
341
342
343
344 /*************************************************
345 *             Open search database               *
346 *************************************************/
347
348 /* A mode, and lists of owners and groups, are passed over for checking in
349 the cases where the database is one or more files. Return NULL, with a message
350 pointed to by message, in cases of error.
351
352 For search types that use a file or files, check up on the mode after
353 opening. It is tempting to do a stat before opening the file, and use it as
354 an existence check. However, doing that opens a small security loophole in
355 that the status could be changed before the file is opened. Can't quite see
356 what problems this might lead to, but you can't be too careful where security
357 is concerned. Fstat() on an open file can normally be expected to succeed,
358 but there are some NFS states where it does not.
359
360 There are two styles of query: (1) in the "single-key+file" style, a single
361 key string and a file name are given, for example, for linear searches, DBM
362 files, or for NIS. (2) In the "query" style, no "filename" is given; instead
363 just a single query string is passed. This applies to multiple-key lookup
364 types such as NIS+.
365
366 Before opening, scan the tree of cached files to see if this file is already
367 open for the correct search type. If so, return the saved handle. If not, put
368 the handle in the tree for possible subsequent use. See search_tidyup above for
369 closing all the cached files.
370
371 A count of open databases which use real files is maintained, and if this
372 gets too large, we have to close a cached file. Its entry remains in the tree,
373 but is marked closed.
374
375 Arguments:
376   filename       the name of the file for single-key+file style lookups,
377                  NULL for query-style lookups
378   li             the info block for the type of search required
379   modemask       if a real single file is used, this specifies mode bits that
380                  must not be set; otherwise it is ignored
381   owners         if a real single file is used, this specifies the possible
382                  owners of the file; otherwise it is ignored
383   owngroups      if a real single file is used, this specifies the possible
384                  group owners of the file; otherwise it is ignored
385
386 Returns:         an identifying handle for the open database;
387                  this is the pointer to the tree block in the
388                  cache of open files; return NULL on open failure, with
389                  a message in search_error_message
390 */
391
392 void *
393 search_open(const uschar * filename, const lookup_info * li, int modemask,
394   uid_t * owners, gid_t * owngroups)
395 {
396 void *handle;
397 tree_node *t;
398 search_cache *c;
399 uschar keybuffer[256];
400 int old_pool = store_pool;
401
402 if (filename && is_tainted(filename))
403   {
404   log_write(0, LOG_MAIN|LOG_PANIC,
405     "Tainted filename for search: '%s'", filename);
406   return NULL;
407   }
408
409 /* Change to the search store pool and remember our reset point */
410
411 store_pool = POOL_SEARCH;
412 if (!search_reset_point) search_reset_point = store_mark();
413
414 DEBUG(D_lookup) debug_printf_indent("search_open: %s \"%s\"\n", li->name,
415   filename ? filename : US"NULL");
416
417 /* See if we already have this open for this type of search, and if so,
418 pass back the tree block as the handle. The key for the tree node is the search
419 type plus '0' concatenated with the file name. There may be entries in the tree
420 with closed files if a lot of files have been opened. */
421
422 sprintf(CS keybuffer, "%c%.254s", li->acq_num+ '0',
423   filename ? filename : US"");
424
425 if ((t = tree_search(search_tree, keybuffer)))
426   {
427   if ((c = (search_cache *)t->data.ptr)->handle)
428     {
429     DEBUG(D_lookup) debug_printf_indent("  cached open\n");
430     store_pool = old_pool;
431     return t;
432     }
433   DEBUG(D_lookup) debug_printf_indent("  cached closed\n");
434   }
435
436 /* Otherwise, we need to open the file or database - each search type has its
437 own code, which is now split off into separately compiled modules. Before doing
438 this, if the search type is one that uses real files, check on the number that
439 we are holding open in the cache. If the limit is reached, close the least
440 recently used one. */
441
442 if (li->type == lookup_absfile && open_filecount >= lookup_open_max)
443   if (!open_bot)
444     log_write(0, LOG_MAIN|LOG_PANIC, "too many lookups open, but can't find "
445       "one to close");
446   else
447     {
448     search_cache *c = (search_cache *)(open_bot->data.ptr);
449     DEBUG(D_lookup) debug_printf_indent("Too many lookup files open\n  closing %s\n",
450       open_bot->name);
451     if ((open_bot = c->up))
452       ((search_cache *)(open_bot->data.ptr))->down = NULL;
453     else
454       open_top = NULL;
455     (c->li->close)(c->handle);
456     c->handle = NULL;
457     open_filecount--;
458     }
459
460 /* If opening is successful, call the file-checking function if there is one,
461 and if all is still well, enter the open database into the tree. */
462
463 if (!(handle = (li->open)(filename, &search_error_message)))
464   {
465   store_pool = old_pool;
466   return NULL;
467   }
468
469 if (  li->check
470    && !li->check(handle, filename, modemask, owners, owngroups,
471          &search_error_message))
472   {
473   li->close(handle);
474   store_pool = old_pool;
475   return NULL;
476   }
477
478 /* If this is a search type that uses real files, keep count. */
479
480 if (li->type == lookup_absfile) open_filecount++;
481
482 /* If we found a previously opened entry in the tree, re-use it; otherwise
483 insert a new entry. On re-use, leave any cached lookup data and the lookup
484 count alone. */
485
486 if (!t)
487   {
488   t = store_get(sizeof(tree_node) + Ustrlen(keybuffer), GET_UNTAINTED);
489   t->data.ptr = c = store_get(sizeof(search_cache), GET_UNTAINTED);
490   c->item_cache = NULL;
491   Ustrcpy(t->name, keybuffer);
492   tree_insertnode(&search_tree, t);
493   }
494 else c = t->data.ptr;
495
496 c->handle = handle;
497 c->li = li;
498 c->up = c->down = NULL;
499
500 store_pool = old_pool;
501 return t;
502 }
503
504
505
506
507
508 /*************************************************
509 *  Internal function: Find one item in database  *
510 *************************************************/
511
512 /* The answer is always put into dynamic store. The last lookup for each handle
513 is cached.
514
515 Arguments:
516   handle       the handle from search_open; points to tree node
517   filename     the filename that was handed to search_open, or
518                NULL for query-style searches
519   keystring    the keystring for single-key+file lookups, or
520                the querystring for query-style lookups
521   cache_rd     FALSE to avoid lookup in cache layer
522   opts         type-specific options
523
524 Returns:       a pointer to a dynamic string containing the answer,
525                or NULL if the query failed or was deferred; in the
526                latter case, search_find_defer is set TRUE; after an unusual
527                failure, there may be a message in search_error_message.
528 */
529
530 static uschar *
531 internal_search_find(void * handle, const uschar * filename,
532   const uschar * keystring, BOOL cache_rd, const uschar * opts)
533 {
534 tree_node * t = (tree_node *)handle;
535 search_cache * c = (search_cache *)(t->data.ptr);
536 const lookup_info * li = c->li;
537 expiring_data * e = NULL;       /* compiler quietening */
538 uschar * data = NULL;
539 int required_quoter_id = li->acq_num;
540 int old_pool = store_pool;
541
542 /* Lookups that return DEFER may not always set an error message. So that
543 the callers don't have to test for NULL, set an empty string. */
544
545 search_error_message = US"";
546 f.search_find_defer = FALSE;
547
548 DEBUG(D_lookup) debug_printf_indent("internal_search_find: file=\"%s\"\n  "
549   "type=%s key=\"%s\" opts=%s%s%s\n", filename,
550   li->name, keystring, opts ? "\"" : "", opts, opts ? "\"" : "");
551
552 /* Insurance. If the keystring is empty, just fail. */
553
554 if (keystring[0] == 0) return NULL;
555
556 /* Use the special store pool for search data */
557
558 store_pool = POOL_SEARCH;
559
560 /* Look up the data for the key, unless it is already in the cache for this
561 file. No need to check c->item_cache for NULL, tree_search will do so. Check
562 whether we want to use the cache entry last so that we can always replace it. */
563
564 if (  (t = tree_search(c->item_cache, keystring))
565    && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL))
566    && (!opts && !e->opts  ||  opts && e->opts && Ustrcmp(opts, e->opts) == 0)
567    && cache_rd
568    )
569   { /* Data was in the cache already; set the pointer from the tree node */
570   data = e->data.ptr;
571   DEBUG(D_lookup) debug_printf_indent("cached data used for lookup of %s%s%s\n",
572     keystring,
573     filename ? US"\n  in " : US"", filename ? filename : US"");
574   }
575 else
576   {
577   uint do_cache = UINT_MAX;
578   int keylength = Ustrlen(keystring);
579
580   DEBUG(D_lookup)
581     {
582     if (t)
583       debug_printf_indent("cached data found but %s; ",
584         e->expiry && e->expiry <= time(NULL) ? "out-of-date"
585         : cache_rd ? "wrong opts" : "no_rd option set");
586     debug_printf_indent("%s lookup required for %s%s%s\n",
587       filename ? US"file" : US"database",
588       keystring,
589       filename ? US"\n  in " : US"", filename ? filename : US"");
590     if (!filename && is_tainted(keystring))
591       {
592       debug_printf_indent("                             ");
593       debug_print_taint(keystring);
594       }
595     }
596
597   /* Check that the query, for query-style lookups,
598   is either untainted or properly quoted for the lookup type.
599
600   XXX Should we this move into lf_sqlperform() ?  The server-taint check is there.
601   Also it already knows about looking for a "servers" spec in the query string.
602   Passing required_quoter_id down that far is an issue.
603   */
604
605   if (  !filename && li->quote
606      && is_tainted(keystring) && !is_quoted_like(keystring, required_quoter_id))
607     {
608     const uschar * ks = keystring;
609     uschar * loc = acl_current_verb();
610     if (!loc) loc = authenticator_current_name();       /* must be before transport */
611     if (!loc) loc = transport_current_name();           /* must be before router */
612     if (!loc) loc = router_current_name();              /* GCC ?: would be good, but not in clang */
613     if (!loc) loc = US"";
614
615     if (Ustrncmp(ks, "servers", 7) == 0)        /* Avoid logging server/password */
616       if ((ks = Ustrchr(keystring, ';')))
617         while (isspace(*++ks))
618           ;
619       else
620         ks = US"";
621
622 #ifdef enforce_quote_protection_notyet
623     search_error_message = string_sprintf(
624       "tainted search query is not properly quoted%s: %s%s",
625       loc, ks);
626     f.search_find_defer = TRUE;
627     goto out;
628 #else
629     /* If we're called from a transport, no privs to open the paniclog;
630     the logging punts to using stderr - and that seems to stop the debug
631     stream. */
632     log_write(0,
633       transport_name ? LOG_MAIN : LOG_MAIN|LOG_PANIC,
634       "tainted search query is not properly quoted%s: %s", loc, ks);
635
636     DEBUG(D_lookup)
637       {
638       const uschar * quoter_name;
639       int q = quoter_for_address(ks, &quoter_name);
640
641       debug_printf_indent("required_quoter_id %d (%s) quoting %d (%s)\n",
642         required_quoter_id, li->name,
643         q, quoter_name);
644       }
645 #endif
646     }
647
648   /* Call the code for the different kinds of search. DEFER is handled
649   like FAIL, except that search_find_defer is set so the caller can
650   distinguish if necessary. */
651
652   if (li->find(c->handle, filename, keystring, keylength,
653           &data, &search_error_message, &do_cache, opts) == DEFER)
654     f.search_find_defer = TRUE;
655
656   /* A record that has been found is now in data, which is either NULL
657   or points to a bit of dynamic store. Cache the result of the lookup if
658   caching is permitted. Lookups can disable caching, when they did something
659   that changes their data. The mysql and pgsql lookups do this when an
660   UPDATE/INSERT query was executed.  Lookups can also set a TTL for the
661   cache entry; the dnsdb lookup does.
662   Finally, the caller can request no caching by setting an option. */
663
664   else if (do_cache)
665     {
666     DEBUG(D_lookup) debug_printf_indent("%s cache entry\n",
667       t ? "replacing old" : "creating new");
668     if (!t)     /* No existing entry.  Create new one. */
669       {
670       int len = keylength + 1;
671       /* The cache node value should never be expanded so use tainted mem */
672       e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len, GET_TAINTED);
673       t = (tree_node *)(e+1);
674       memcpy(t->name, keystring, len);
675       t->data.ptr = e;
676       tree_insertnode(&c->item_cache, t);
677       }
678       /* Else previous, out-of-date cache entry.  Update with the */
679       /* new result and forget the old one */
680     e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
681     e->opts = opts ? string_copy(opts) : NULL;
682     e->data.ptr = data;
683     }
684
685 /* If caching was disabled, empty the cache tree. We just set the cache
686 pointer to NULL here, because we cannot release the store at this stage. */
687
688   else
689     {
690     DEBUG(D_lookup) debug_printf_indent("lookup forced cache cleanup\n");
691     c->item_cache = NULL;       /* forget all lookups on this connection */
692     }
693   }
694
695 out:
696 DEBUG(D_lookup)
697   {
698   if (data)
699     debug_printf_indent("lookup yielded: %W\n", data);
700   else if (f.search_find_defer)
701     debug_printf_indent("lookup deferred: %s\n", search_error_message);
702   else debug_printf_indent("lookup failed\n");
703   }
704
705 /* Return it in new dynamic store in the regular pool */
706
707 store_pool = old_pool;
708 return data ? string_copy(data) : NULL;
709 }
710
711
712
713
714 /*************************************************
715 * Find one item in database, possibly wildcarded *
716 *************************************************/
717
718 /* This function calls the internal function above; once only if there
719 is no partial matching, but repeatedly when partial matching is requested.
720
721 Arguments:
722   handle         the handle from search_open
723   filename       the filename that was handed to search_open, or
724                    NULL for query-style searches
725   keystring      the keystring for single-key+file lookups, or
726                    the querystring for query-style lookups
727   partial        -1 means no partial matching;
728                    otherwise it's the minimum number of components;
729   affix          the affix string for partial matching
730   affixlen       the length of the affix string
731   starflags      SEARCH_STAR and SEARCH_STARAT flags
732   expand_setup   pointer to offset for setting up expansion strings;
733                  don't do any if < 0
734   opts           type-specific options
735
736 Returns:         a pointer to a dynamic string containing the answer,
737                  or NULL if the query failed or was deferred; in the
738                  latter case, search_find_defer is set TRUE
739 */
740
741 uschar *
742 search_find(void * handle, const uschar * filename, const uschar * keystring,
743   int partial, const uschar * affix, int affixlen, int starflags,
744   int * expand_setup, const uschar * opts)
745 {
746 tree_node * t = (tree_node *)handle;
747 BOOL set_null_wild = FALSE, cache_rd = TRUE, ret_key = FALSE;
748 uschar * yield;
749
750 DEBUG(D_lookup)
751   {
752   if (partial < 0) affixlen = 99;   /* So that "NULL" prints */
753   debug_printf_indent("search_find: file=\"%s\"\n  key=\"%s\" "
754     "partial=%d affix=%.*s starflags=%x opts=%s%s%s\n",
755     filename ? filename : US"NULL",
756     keystring, partial, affixlen, affix, starflags,
757     opts ? "\"" : "", opts, opts ? "\"" : "");
758
759   }
760
761 /* Parse global lookup options. Also, create a new options list with
762 the global options dropped so that the cache-modifiers are not
763 used in the cache key. */
764
765 if (opts)
766   {
767   int sep = ',';
768   gstring * g = NULL;
769
770   for (uschar * ele; ele = string_nextinlist(&opts, &sep, NULL, 0); )
771     if (Ustrcmp(ele, "ret=key") == 0) ret_key = TRUE;
772     else if (Ustrcmp(ele, "cache=no_rd") == 0) cache_rd = FALSE;
773     else g = string_append_listele(g, ',', ele);
774
775   opts = string_from_gstring(g);
776   }
777
778 /* Arrange to put this database at the top of the LRU chain if it is a type
779 that opens real files. */
780
781 if (open_top != (tree_node *)handle)
782   {
783   const lookup_info * li = lookup_with_acq_num(t->name[0]-'0');
784   if (li && li->type == lookup_absfile)
785     {
786     search_cache *c = (search_cache *)(t->data.ptr);
787     tree_node *up = c->up;
788     tree_node *down = c->down;
789
790     /* Cut it out of the list. A newly opened file will a NULL up pointer.
791     Otherwise there will be a non-NULL up pointer, since we checked above that
792     this block isn't already at the top of the list. */
793
794     if (up)
795       {
796       ((search_cache *)(up->data.ptr))->down = down;
797       if (down)
798         ((search_cache *)(down->data.ptr))->up = up;
799       else
800         open_bot = up;
801       }
802
803     /* Now put it at the head of the list. */
804
805     c->up = NULL;
806     c->down = open_top;
807     if (!open_top) open_bot = t;
808     else ((search_cache *)(open_top->data.ptr))->up = t;
809     open_top = t;
810     }
811   }
812
813 DEBUG(D_lookup)
814   {
815   debug_printf_indent("LRU list:\n");
816   for (tree_node *t = open_top; t; )
817     {
818     search_cache *c = (search_cache *)(t->data.ptr);
819     debug_printf_indent("  %s\n", t->name);
820     if (t == open_bot) debug_printf_indent("  End\n");
821     t = c->down;
822     }
823   }
824
825 /* First of all, try to match the key string verbatim. If matched a complete
826 entry but could have been partial, flag to set up variables. */
827
828 yield = internal_search_find(handle, filename, keystring, cache_rd, opts);
829 if (f.search_find_defer) return NULL;
830
831 if (yield) { if (partial >= 0) set_null_wild = TRUE; }
832
833 /* Not matched a complete entry; handle partial lookups, but only if the full
834 search didn't defer. Don't use string_sprintf() to construct the initial key,
835 just in case the original key is too long for the string_sprintf() buffer (it
836 *has* happened!). The case of a zero-length affix has to be treated specially.
837 */
838
839 else if (partial >= 0)
840   {
841   int len = Ustrlen(keystring);
842   uschar * keystring2;
843
844   /* Try with the affix on the front, except for a zero-length affix */
845
846   if (affixlen == 0)
847     keystring2 = string_copy(keystring);
848   else
849     {
850     keystring2 = store_get(len + affixlen + 1,
851           is_tainted(keystring) || is_tainted(affix) ? GET_TAINTED : GET_UNTAINTED);
852     Ustrncpy(keystring2, affix, affixlen);
853     Ustrcpy(keystring2 + affixlen, keystring);
854     DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring2);
855     yield = internal_search_find(handle, filename, CUS keystring2, cache_rd, opts);
856     if (f.search_find_defer) return NULL;
857     }
858
859   /* The key in its entirety did not match a wild entry; try chopping off
860   leading components. */
861
862   if (!yield)
863     {
864     int dotcount = 0;
865     uschar * keystring3 = keystring2 + affixlen;
866
867     for(uschar * s = keystring3; *s; ) if (*s++ == '.') dotcount++;
868
869     while (dotcount-- >= partial)
870       {
871       while (*keystring3 && *keystring3 != '.') keystring3++;
872
873       /* If we get right to the end of the string (which will be the last time
874       through this loop), we've failed if the affix is null. Otherwise do one
875       last lookup for the affix itself, but if it is longer than 1 character,
876       remove the last character if it is ".". */
877
878       if (!*keystring3)
879         {
880         if (affixlen < 1) break;
881         if (affixlen > 1 && affix[affixlen-1] == '.') affixlen--;
882         Ustrncpy(keystring2, affix, affixlen);
883         keystring2[affixlen] = 0;
884         keystring3 = keystring2;
885         }
886       else
887         {
888         keystring3 -= affixlen - 1;
889         if (affixlen > 0) Ustrncpy(keystring3, affix, affixlen);
890         }
891
892       DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring3);
893       yield = internal_search_find(handle, filename, CUS keystring3,
894                 cache_rd, opts);
895       if (f.search_find_defer) return NULL;
896       if (yield)
897         {
898         /* First variable is the wild part; second is the fixed part. Take care
899         to get it right when keystring3 is just "*".  Return a de-tainted version
900         of the fixed part, on the grounds it has been validated by the lookup. */
901
902         if (expand_setup && *expand_setup >= 0)
903           {
904           int fixedlength = Ustrlen(keystring3) - affixlen;
905           int wildlength = Ustrlen(keystring) - fixedlength - 1;
906           *expand_setup += 1;
907           expand_nstring[*expand_setup] = keystring;
908           expand_nlength[*expand_setup] = wildlength;
909           *expand_setup += 1;
910           if (fixedlength < 0) fixedlength = 0;
911           expand_nstring[*expand_setup] = string_copyn_taint(
912             keystring + wildlength + 1, fixedlength, GET_UNTAINTED);
913           expand_nlength[*expand_setup] = fixedlength;
914           }
915         break;
916         }
917       keystring3 += affixlen;
918       }
919     }
920
921   else set_null_wild = TRUE; /* Matched a wild entry without any wild part */
922   }
923
924 /* If nothing has been matched, but the option to look for "*@" is set, try
925 replacing everything to the left of @ by *. After a match, the wild part
926 is set to the string to the left of the @. */
927
928 if (!yield  &&  starflags & SEARCH_STARAT)
929   {
930   uschar *atat = Ustrrchr(keystring, '@');
931   if (atat && atat > keystring)
932     {
933     int savechar;
934     savechar = *--atat;
935     *atat = '*';
936
937     DEBUG(D_lookup) debug_printf_indent("trying default match %s\n", atat);
938     yield = internal_search_find(handle, filename, atat, cache_rd, opts);
939     *atat = savechar;
940     if (f.search_find_defer) return NULL;
941
942     if (yield && expand_setup && *expand_setup >= 0)
943       {
944       *expand_setup += 1;
945       expand_nstring[*expand_setup] = keystring;
946       expand_nlength[*expand_setup] = atat - keystring + 1;
947       *expand_setup += 1;
948       expand_nstring[*expand_setup] = keystring;
949       expand_nlength[*expand_setup] = 0;
950       }
951     }
952   }
953
954 /* If we still haven't matched anything, and the option to look for "*" is set,
955 try that. If we do match, the first variable (the wild part) is the whole key,
956 and the second is empty. */
957
958 if (!yield  &&  starflags & (SEARCH_STAR|SEARCH_STARAT))
959   {
960   DEBUG(D_lookup) debug_printf_indent("trying to match *\n");
961   yield = internal_search_find(handle, filename, US"*", cache_rd, opts);
962   if (yield && expand_setup && *expand_setup >= 0)
963     {
964     *expand_setup += 1;
965     expand_nstring[*expand_setup] = keystring;
966     expand_nlength[*expand_setup] = Ustrlen(keystring);
967     *expand_setup += 1;
968     expand_nstring[*expand_setup] = keystring;
969     expand_nlength[*expand_setup] = 0;
970     }
971   }
972
973 /* If this was a potentially partial lookup, and we matched either a
974 complete non-wild domain entry, or we matched a wild-carded entry without
975 chopping off any of the domain components, set up the expansion variables
976 (if required) so that the first one is empty, and the second one is the
977 fixed part of the domain. The set_null_wild flag is set only when yield is not
978 NULL.  Return a de-tainted version of the fixed part, on the grounds it has been
979 validated by the lookup. */
980
981 if (set_null_wild && expand_setup && *expand_setup >= 0)
982   {
983   int fixedlength = Ustrlen(keystring);
984   *expand_setup += 1;
985   expand_nstring[*expand_setup] = keystring;
986   expand_nlength[*expand_setup] = 0;
987   *expand_setup += 1;
988   expand_nstring[*expand_setup] = string_copyn_taint(
989             keystring, fixedlength, GET_UNTAINTED);
990   expand_nlength[*expand_setup] = fixedlength;
991   }
992
993 /* If we have a result, check the options to see if the key was wanted rather
994 than the result.  Return a de-tainted version of the key on the grounds that
995 it have been validated by the lookup. */
996
997 if (yield && ret_key)
998   {
999   yield = string_copy_taint(keystring, GET_UNTAINTED);
1000   DEBUG(D_lookup)
1001     debug_printf_indent("lookup yield replace by key: %s\n", yield);
1002   }
1003
1004 return yield;
1005 }
1006
1007 /* End of search.c */
1008 /* vi: aw ai sw=2
1009 */