4b128a60944d91b2f4e564ef8959e2ff15dd27b6
[exim.git] / src / src / match.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2020 - 2023 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 /* Functions for matching strings */
11
12
13 #include "exim.h"
14
15
16 /* Argument block for the check_string() function. This is used for general
17 strings, domains, and local parts. */
18
19 typedef struct check_string_block {
20   const uschar *origsubject;           /* caseful; keep these two first, in */
21   const uschar *subject;               /* step with the block below */
22   int    expand_setup;
23   mcs_flags flags;                      /* MCS_* defs in macros.h */
24 } check_string_block;
25
26
27 /* Argument block for the check_address() function. This is used for whole
28 addresses. */
29
30 typedef struct check_address_block {
31   const uschar *origaddress;         /* caseful; keep these two first, in */
32   uschar *address;                   /* step with the block above */
33   int    expand_setup;
34   mcs_flags flags;                      /* MCS_CASELESS, MCS_TEXTONLY_RE */
35 } check_address_block;
36
37
38
39 /*************************************************
40 *           Generalized string match             *
41 *************************************************/
42
43 /* This function does a single match of a subject against a pattern, and
44 optionally sets up the numeric variables according to what it matched. It is
45 called from match_isinlist() via match_check_list() when scanning a list, and
46 from match_check_string() when testing just a single item. The subject and
47 options arguments are passed in a check_string_block so as to make it easier to
48 pass them through match_check_list.
49
50 The possible types of pattern are:
51
52   . regular expression - starts with ^
53   . tail match - starts with *
54   . lookup - starts with search type
55   . if at_is_special is set in the argument block:
56       @              matches the primary host name
57       @[]            matches a local IP address in brackets
58       @mx_any        matches any domain with an MX to the local host
59       @mx_primary    matches any domain with a primary MX to the local host
60       @mx_secondary  matches any domain with a secondary MX to the local host
61   . literal - anything else
62
63 Any of the @mx_xxx options can be followed by "/ignore=<list>" where <list> is
64 a list of IP addresses that are to be ignored (typically 127.0.0.1).
65
66 Arguments:
67   arg            check_string_block pointer - see below
68   pattern        the pattern to be matched
69   valueptr       if not NULL, and a lookup is done, return the result here
70                    instead of discarding it; else set it to point to NULL
71   error          for error messages (not used in this function; it never
72                    returns ERROR)
73
74 Contents of the argument block:
75   origsubject    the subject in its original casing
76   subject        the subject string to be checked, lowercased if caseless
77   expand_setup   if < 0, don't set up any numeric expansion variables;
78                  if = 0, set $0 to whole subject, and either
79                    $1 to what matches * or
80                    $1, $2, ... to r.e. bracketed items
81                  if > 0, don't set $0, but do set either
82                    $n to what matches *, or
83                    $n, $n+1, ... to r.e. bracketed items
84                  (where n = expand_setup)
85   use_partial    if FALSE, override any partial- search types
86   caseless       TRUE for caseless matching where possible
87   at_is_special  enable special handling of items starting with @
88
89 Returns:       OK    if matched
90                FAIL  if not matched
91                DEFER if lookup deferred
92 */
93
94 static int
95 check_string(void * arg, const uschar * pattern, const uschar ** valueptr,
96   uschar ** error)
97 {
98 const check_string_block * cb = arg;
99 int search_type, partial, affixlen, starflags;
100 int expand_setup = cb->expand_setup;
101 const uschar * affix, * opts;
102 uschar *s;
103 uschar *filename = NULL;
104 uschar *keyquery, *result, *semicolon;
105 void *handle;
106
107 if (valueptr) *valueptr = NULL;
108
109 /* For regular expressions, use cb->origsubject rather than cb->subject so that
110 it works if the pattern uses (?-i) to turn off case-independence, overriding
111 "caseless". */
112
113 s = string_copy(pattern[0] == '^' ? cb->origsubject : cb->subject);
114
115 /* If required to set up $0, initialize the data but don't turn on by setting
116 expand_nmax until the match is assured. */
117
118 expand_nmax = -1;
119 if (expand_setup == 0)
120   {
121   expand_nstring[0] = s;        /* $0 (might be) the matched subject in full */
122   expand_nlength[0] = Ustrlen(s);
123   }
124 else if (expand_setup > 0) expand_setup--;
125
126 /* Regular expression match: compile, match, and set up $ variables if
127 required. */
128
129 if (pattern[0] == '^')
130   {
131   const pcre2_code * re = regex_must_compile(pattern,
132       cb->flags & (MCS_CACHEABLE | MCS_CASELESS), FALSE);
133   if (expand_setup < 0
134       ? !regex_match(re, s, -1, NULL)
135       : !regex_match_and_setup(re, s, 0, expand_setup)
136      )
137     return FAIL;
138   if (valueptr) *valueptr = pattern;    /* "value" gets the RE */
139   return OK;
140   }
141
142 /* Tail match */
143
144 if (pattern[0] == '*')
145   {
146   int slen = Ustrlen(s);
147   int patlen;    /* Sun compiler doesn't like non-constant initializer */
148
149   patlen = Ustrlen(++pattern);
150   if (patlen > slen) return FAIL;
151   if (cb->flags & MCS_CASELESS
152       ? strncmpic(s + slen - patlen, pattern, patlen) != 0
153       : Ustrncmp(s + slen - patlen, pattern, patlen) != 0)
154     return FAIL;
155   if (expand_setup >= 0)
156     {
157     expand_nstring[++expand_setup] = s;         /* write a $n, the matched subject variable-part */
158     expand_nlength[expand_setup] = slen - patlen;
159     expand_nmax = expand_setup;                 /* commit also $0, the matched subject */
160     }
161   if (valueptr) *valueptr = pattern - 1;        /* "value" gets the (original) pattern */
162   return OK;
163   }
164
165 /* Match a special item starting with @ if so enabled. On its own, "@" matches
166 the primary host name - implement this by changing the pattern. For the other
167 cases we have to do some more work. If we don't recognize a special pattern,
168 just fall through - the match will fail. */
169
170 if (cb->flags & MCS_AT_SPECIAL && pattern[0] == '@')
171   {
172   if (pattern[1] == 0)
173     {
174     pattern = primary_hostname;
175     goto NOT_AT_SPECIAL;               /* Handle as exact string match */
176     }
177
178   if (Ustrcmp(pattern, "@[]") == 0)
179     {
180     int slen = Ustrlen(s);
181     if (s[0] != '[' && s[slen-1] != ']') return FAIL;           /*XXX should this be || ? */
182     for (ip_address_item * ip = host_find_interfaces(); ip; ip = ip->next)
183       if (Ustrncmp(ip->address, s+1, slen - 2) == 0
184             && ip->address[slen - 2] == 0)
185         {
186         if (expand_setup >= 0) expand_nmax = expand_setup;      /* commit $0, the IP addr */
187         if (valueptr) *valueptr = pattern;      /* "value" gets the pattern */
188         return OK;
189         }
190     return FAIL;
191     }
192
193   if (strncmpic(pattern, US"@mx_", 4) == 0)
194     {
195     int rc;
196     host_item h;
197     BOOL prim = FALSE;
198     BOOL secy = FALSE;
199     BOOL removed = FALSE;
200     const uschar *ss = pattern + 4;
201     const uschar *ignore_target_hosts = NULL;
202
203     if (strncmpic(ss, US"any", 3) == 0) ss += 3;
204     else if (strncmpic(ss, US"primary", 7) == 0)
205       {
206       ss += 7;
207       prim = TRUE;
208       }
209     else if (strncmpic(ss, US"secondary", 9) == 0)
210       {
211       ss += 9;
212       secy = TRUE;
213       }
214     else goto NOT_AT_SPECIAL;
215
216     if (strncmpic(ss, US"/ignore=", 8) == 0) ignore_target_hosts = ss + 8;
217     else if (*ss) goto NOT_AT_SPECIAL;
218
219     h.next = NULL;
220     h.name = s;
221     h.address = NULL;
222
223     rc = host_find_bydns(&h,
224       ignore_target_hosts,
225       HOST_FIND_BY_MX,     /* search only for MX, not SRV or A */
226       NULL,                /* service name not relevant */
227       NULL,                /* srv_fail_domains not relevant */
228       NULL,                /* mx_fail_domains not relevant */
229       NULL,                /* no dnssec request/require XXX ? */
230       NULL,                /* no feedback FQDN */
231       &removed);           /* feedback if local removed */
232
233     if (rc == HOST_FIND_AGAIN)
234       {
235       search_error_message = string_sprintf("DNS lookup of \"%s\" deferred", s);
236       return DEFER;
237       }
238
239     if ((rc != HOST_FOUND_LOCAL || secy) && (prim || !removed))
240       return FAIL;
241
242     if (expand_setup >= 0) expand_nmax = expand_setup;  /* commit $0, the matched subject */
243     if (valueptr) *valueptr = pattern;  /* "value" gets the patterm */
244     return OK;
245
246     /*** The above line used to be the following line, but this is incorrect,
247     because host_find_bydns() may return HOST_NOT_FOUND if it removed some MX
248     hosts, but the remaining ones were non-existent. All we are interested in
249     is whether or not it removed some hosts.
250
251     return (rc == HOST_FOUND && removed)? OK : FAIL;
252     ***/
253     }
254   }
255
256 /* Escape point from code for specials that start with "@" */
257
258 NOT_AT_SPECIAL:
259
260 /* This is an exact string match if there is no semicolon in the pattern. */
261
262 if ((semicolon = Ustrchr(pattern, ';')) == NULL)
263   {
264   if (cb->flags & MCS_CASELESS ? strcmpic(s, pattern) != 0 : Ustrcmp(s, pattern) != 0)
265     return FAIL;
266   if (expand_setup >= 0) expand_nmax = expand_setup;    /* $0 gets the matched subject */
267   if (valueptr) *valueptr = pattern;                    /* "value" gets the pattern */
268   return OK;
269   }
270
271 /* Otherwise we have a lookup item. The lookup type, including partial, etc. is
272 the part of the string preceding the semicolon. */
273
274 *semicolon = 0;
275 search_type = search_findtype_partial(pattern, &partial, &affix, &affixlen,
276   &starflags, &opts);
277 *semicolon = ';';
278 if (search_type < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
279   search_error_message);
280
281 /* Partial matching is not appropriate for certain lookups (e.g. when looking
282 up user@domain for sender rejection). There's a flag to disable it. */
283
284 if (!(cb->flags & MCS_PARTIAL)) partial = -1;
285
286 /* Set the parameters for the three different kinds of lookup. */
287
288 keyquery = search_args(search_type, s, semicolon+1, &filename, opts);
289
290 /* Now do the actual lookup; throw away the data returned unless it was asked
291 for; partial matching is all handled inside search_find(). Note that there is
292 no search_close() because of the caching arrangements. */
293
294 if (!(handle = search_open(filename, search_type, 0, NULL, NULL)))
295   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", search_error_message);
296 result = search_find(handle, filename, keyquery, partial, affix, affixlen,
297   starflags, &expand_setup, opts);
298
299 if (!result) return f.search_find_defer ? DEFER : FAIL;
300 if (valueptr) *valueptr = result;
301
302 expand_nmax = expand_setup;
303 return OK;
304 }
305
306
307
308 /*************************************************
309 *      Public interface to check_string()        *
310 *************************************************/
311
312 /* This function is called from several places where is it most convenient to
313 pass the arguments individually. It places them in a check_string_block
314 structure, and then calls check_string().
315
316 Arguments:
317   s            the subject string to be checked
318   pattern      the pattern to check it against
319   expand_setup expansion setup option (see check_string())
320   flags
321    use_partial  if FALSE, override any partial- search types
322    caseless     TRUE for caseless matching where possible
323    at_is_special TRUE to recognize @, @[], etc.
324   valueptr     if not NULL, and a file lookup was done, return the result
325                  here instead of discarding it; else set it to point to NULL
326
327 Returns:       OK    if matched
328                FAIL  if not matched
329                DEFER if lookup deferred
330 */
331
332 int
333 match_check_string(const uschar * s, const uschar * pattern, int expand_setup,
334   mcs_flags flags, const uschar ** valueptr)
335 {
336 check_string_block cb;
337 cb.origsubject = s;
338 cb.subject = flags & MCS_CASELESS ? string_copylc(s) : string_copy(s);
339 cb.expand_setup = expand_setup;
340 cb.flags = flags;
341 return check_string(&cb, pattern, valueptr, NULL);
342 }
343
344
345
346 /*************************************************
347 *       Get key string from check block          *
348 *************************************************/
349
350 /* When caching the data from a lookup for a named list, we have to save the
351 key that was found, because other lookups of different keys on the same list
352 may occur. This function has knowledge of the different lookup types, and
353 extracts the appropriate key.
354
355 Arguments:
356   arg          the check block
357   type         MCL_STRING, MCL_DOMAIN, MCL_HOST, MCL_ADDRESS, or MCL_LOCALPART
358 */
359
360 static const uschar *
361 get_check_key(void *arg, int type)
362 {
363 switch(type)
364   {
365   case MCL_STRING:
366   case MCL_DOMAIN:
367   case MCL_LOCALPART:   return ((check_string_block *)arg)->subject;
368   case MCL_HOST:        return ((check_host_block *)arg)->host_address;
369   case MCL_ADDRESS:     return ((check_address_block *)arg)->address;
370   }
371 return US"";  /* In practice, should never happen */
372 }
373
374
375
376 /*************************************************
377 *       Scan list and run matching function      *
378 *************************************************/
379
380 /* This function scans a list of patterns, and runs a matching function for
381 each item in the list. It is called from the functions that match domains,
382 local parts, hosts, and addresses, because its overall structure is the same in
383 all cases. However, the details of each particular match is different, so it
384 calls back to a given function do perform an actual match.
385
386 We can't quite keep the different types anonymous here because they permit
387 different special cases. A pity.
388
389 If a list item starts with !, that implies negation if the subject matches the
390 rest of the item (ignoring white space after the !). The result when the end of
391 the list is reached is FALSE unless the last item on the list is negated, in
392 which case it is TRUE. A file name in the list causes its lines to be
393 interpolated as if items in the list. An item starting with + is a named
394 sublist, obtained by searching the tree pointed to by anchorptr, with possible
395 cached match results in cache_bits.
396
397 Arguments:
398   listptr      pointer to the pointer to the list
399   sep          separator character for string_nextinlist();
400                  normally zero for a standard list;
401                  sometimes UCHAR_MAX+1 for single items;
402   anchorptr    -> tree of named items, or NULL if no named items
403   cache_ptr    pointer to pointer to cache bits for named items, or
404                  pointer to NULL if not caching; may get set NULL if an
405                  uncacheable named list is encountered
406   func         function to call back to do one test
407   arg          pointer to pass to the function; the string to be matched is
408                  in the structure it points to
409   type         MCL_STRING, MCL_DOMAIN, MCL_HOST, MCL_ADDRESS, or MCL_LOCALPART
410                  these are used for some special handling
411                MCL_NOEXPAND (whose value is greater than any of them) may
412                  be added to any value to suppress expansion of the list
413   name         string to use in debugging info
414   valueptr     where to pass back data from a lookup
415
416 Returns:       OK    if matched a non-negated item
417                OK    if hit end of list after a negated item
418                FAIL  if expansion force-failed
419                FAIL  if matched a negated item
420                FAIL  if hit end of list after a non-negated item
421                DEFER if a something deferred or expansion failed
422 */
423
424 int
425 match_check_list(const uschar **listptr, int sep, tree_node **anchorptr,
426   unsigned int **cache_ptr, int (*func)(void *,const uschar *,const uschar **,uschar **),
427   void *arg, int type, const uschar *name, const uschar **valueptr)
428 {
429 int yield = OK;
430 unsigned int * original_cache_bits = *cache_ptr;
431 BOOL include_unknown = FALSE, ignore_unknown = FALSE,
432       include_defer = FALSE, ignore_defer = FALSE;
433 const uschar * list;
434 uschar * sss;
435 uschar * ot = NULL;
436 BOOL textonly_re;
437
438 /* Save time by not scanning for the option name when we don't need it. */
439
440 HDEBUG(D_any)   /* always give the query.  Give results only for D_lists */
441   {
442   const uschar * listname = readconf_find_option(listptr);
443   if (*listname) ot = string_sprintf("%s in %s?", name, listname);
444   }
445
446 /* If the list is empty, the answer is no. */
447
448 if (!*listptr)
449   {
450   HDEBUG(D_lists)
451     if (ot) debug_printf_indent("%s no (option unset)\n", ot);
452     else    debug_printf_indent("%s not in empty list (option unset? cannot trace name)\n", name);
453   return FAIL;
454   }
455
456 /* Expand the list before we scan it. A forced expansion gives the answer
457 "not in list"; other expansion errors cause DEFER to be returned. However,
458 if the type value is greater than or equal to than MCL_NOEXPAND, do not expand
459 the list. */
460
461 if (type >= MCL_NOEXPAND)
462   {
463   list = *listptr;
464   type -= MCL_NOEXPAND;       /* Remove the "no expand" flag */
465   textonly_re = TRUE;
466   }
467 else
468   {
469   /* If we are searching a domain list, and $domain is not set, set it to the
470   subject that is being sought for the duration of the expansion. */
471
472   if (type == MCL_DOMAIN && !deliver_domain)
473     {
474     check_string_block *cb = (check_string_block *)arg;
475     deliver_domain = string_copy(cb->subject);
476     list = expand_string_2(*listptr, &textonly_re);
477     deliver_domain = NULL;
478     }
479   else
480     list = expand_string_2(*listptr, &textonly_re);
481
482   if (!list)
483     {
484     if (f.expand_string_forcedfail)
485       {
486       HDEBUG(D_lists) debug_printf_indent("expansion of \"%s\" forced failure: "
487         "assume not in this list\n", *listptr);
488       return FAIL;
489       }
490     log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand \"%s\" while checking "
491       "a list: %s", *listptr, expand_string_message);
492     return DEFER;
493     }
494   }
495
496 if (textonly_re) switch (type)
497   {
498   case MCL_STRING:
499   case MCL_DOMAIN:
500   case MCL_LOCALPART: ((check_string_block *)arg)->flags |= MCS_CACHEABLE; break;
501   case MCL_HOST:     ((check_host_block *)arg)->flags |= MCS_CACHEABLE; break;
502   case MCL_ADDRESS: ((check_address_block *)arg)->flags |= MCS_CACHEABLE; break;
503   }
504
505 /* For an unnamed list, use the expanded version in comments */
506 #define LIST_LIMIT_PR 2048
507
508 HDEBUG(D_any) if (!ot)
509   {     /* We failed to identify an option name, so give the list text */
510   int n, m;
511   gstring * g = string_fmt_append(NULL, "%s in \"%n%.*s%n\"",
512     name, &n, LIST_LIMIT_PR, list, &m);
513   if (m - n >= LIST_LIMIT_PR) g = string_catn(g, US"...", 3);
514   g = string_catn(g, US"?", 1);
515   gstring_release_unused(g);
516   ot = string_from_gstring(g);
517   }
518 HDEBUG(D_lists)
519   {
520   debug_printf_indent("%s\n", ot);
521   expand_level++;
522   }
523
524 /* Now scan the list and process each item in turn, until one of them matches,
525 or we hit an error. */
526
527 while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
528   {
529   uschar * ss = sss;
530
531   HDEBUG(D_lists) debug_printf_indent("list element: %W\n", ss);
532
533   /* Address lists may contain +caseful, to restore caseful matching of the
534   local part. We have to know the layout of the control block, unfortunately.
535   The lower cased address is in a temporary buffer, so we just copy the local
536   part back to the start of it (if a local part exists). */
537
538   if (type == MCL_ADDRESS)
539     {
540     if (Ustrcmp(ss, "+caseful") == 0)
541       {
542       check_address_block *cb = (check_address_block *)arg;
543       uschar *at = Ustrrchr(cb->origaddress, '@');
544
545       if (at)
546         Ustrncpy(cb->address, cb->origaddress, at - cb->origaddress);
547       cb->flags &= ~MCS_CASELESS;
548       continue;
549       }
550     }
551
552   /* Similar processing for local parts */
553
554   else if (type == MCL_LOCALPART)
555     {
556     if (Ustrcmp(ss, "+caseful") == 0)
557       {
558       check_string_block *cb = (check_string_block *)arg;
559       Ustrcpy(US cb->subject, cb->origsubject);
560       cb->flags &= ~MCS_CASELESS;
561       continue;
562       }
563     }
564
565   /* If the host item is "+include_unknown" or "+ignore_unknown", remember it
566   in case there's a subsequent failed reverse lookup. There is similar
567   processing for "defer". */
568
569   else if (type == MCL_HOST && *ss == '+')
570     {
571     if (Ustrcmp(ss, "+include_unknown") == 0)
572       {
573       include_unknown = TRUE;
574       ignore_unknown = FALSE;
575       continue;
576       }
577     if (Ustrcmp(ss, "+ignore_unknown") == 0)
578       {
579       ignore_unknown = TRUE;
580       include_unknown = FALSE;
581       continue;
582       }
583     if (Ustrcmp(ss, "+include_defer") == 0)
584       {
585       include_defer = TRUE;
586       ignore_defer = FALSE;
587       continue;
588       }
589     if (Ustrcmp(ss, "+ignore_defer") == 0)
590       {
591       ignore_defer = TRUE;
592       include_defer = FALSE;
593       continue;
594       }
595     }
596
597   /* Starting with ! specifies a negative item. It is theoretically possible
598   for a local part to start with !. In that case, a regex has to be used. */
599
600   if (*ss == '!')
601     {
602     yield = FAIL;
603     while (isspace(*++ss)) ;
604     }
605   else
606     yield = OK;
607
608   /* If the item does not begin with '/', it might be a + item for a named
609   list. Otherwise, it is just a single list entry that has to be matched.
610   We recognize '+' only when supplied with a tree of named lists. */
611
612   if (*ss != '/')
613     {
614     if (*ss == '+' && anchorptr)
615       {
616       int bits = 0, offset = 0, shift = 0;
617       unsigned int * use_cache_bits = original_cache_bits;
618       uschar * cached = US"";
619       namedlist_block * nb;
620       tree_node * t;
621
622       HDEBUG(D_lists)
623         { debug_printf_indent(" start sublist %s\n", ss+1); expand_level += 2; }
624
625       if (!(t = tree_search(*anchorptr, ss+1)))
626         {
627         log_write(0, LOG_MAIN|LOG_PANIC, "unknown named%s list \"%s\"",
628           type == MCL_DOMAIN ?    " domain" :
629           type == MCL_HOST ?      " host" :
630           type == MCL_ADDRESS ?   " address" :
631           type == MCL_LOCALPART ? " local part" : "",
632           ss);
633         goto DEFER_RETURN;
634         }
635       nb = t->data.ptr;
636
637       /* If the list number is negative, it means that this list is not
638       cacheable because it contains expansion items. */
639
640       if (nb->number < 0) use_cache_bits = NULL;
641
642       /* If we have got a cache pointer, get the bits. This is not an "else"
643       because the pointer may be NULL from the start if caching is not
644       required. */
645
646       if (use_cache_bits)
647         {
648         offset = (nb->number)/16;
649         shift = ((nb->number)%16)*2;
650         bits = use_cache_bits[offset] & (3 << shift);
651         }
652
653       /* Not previously tested or no cache - run the full test */
654
655       if (bits == 0)
656         {
657         int res = match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits,
658                 func, arg, type, name, valueptr);
659         HDEBUG(D_lists)
660           { expand_level -= 2; debug_printf_indent(" end sublist %s\n", ss+1); }
661
662         switch (res)
663           {
664           case OK:   bits = 1; break;
665           case FAIL: bits = 3; break;
666           case DEFER: goto DEFER_RETURN;
667           }
668
669         /* If this list was uncacheable, or a sublist turned out to be
670         uncacheable, the value of use_cache_bits will now be NULL, even if it
671         wasn't before. Ensure that this is passed up to the next level.
672         Otherwise, remember the result of the search in the cache. */
673
674         if (!use_cache_bits)
675           *cache_ptr = NULL;
676         else
677           {
678           use_cache_bits[offset] |= bits << shift;
679
680           if (valueptr)
681             {
682             int old_pool = store_pool;
683             namedlist_cacheblock *p;
684
685             /* Cached data for hosts persists over more than one message,
686             so we use the permanent store pool */
687
688             store_pool = POOL_PERM;
689             p = store_get(sizeof(namedlist_cacheblock), GET_UNTAINTED);
690             p->key = string_copy(get_check_key(arg, type));
691
692
693             p->data = *valueptr ? string_copy(*valueptr) : NULL;
694             store_pool = old_pool;
695
696             p->next = nb->cache_data;
697             nb->cache_data = p;
698             if (*valueptr)
699               HDEBUG(D_lists) debug_printf_indent("data from lookup saved for "
700                 "cache for %s: key '%s' value '%s'\n", ss, p->key, *valueptr);
701             }
702           }
703         }
704
705        /* Previously cached; to find a lookup value, search a chain of values
706        and compare keys. Typically, there is only one such, but it is possible
707        for different keys to have matched the same named list. */
708
709       else
710         {
711         HDEBUG(D_lists)
712           {
713           expand_level -= 2;
714           debug_printf_indent("cached %s match for %s\n",
715             (bits & (-bits)) == bits ? "yes" : "no", ss);
716           }
717
718         cached = US" - cached";
719         if (valueptr)
720           {
721           const uschar *key = get_check_key(arg, type);
722
723           for (namedlist_cacheblock * p = nb->cache_data; p; p = p->next)
724             if (Ustrcmp(key, p->key) == 0)
725               {
726               *valueptr = p->data;
727               break;
728               }
729           HDEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
730           }
731         }
732
733       /* Result of test is indicated by value in bits. For each test, we
734       have 00 => untested, 01 => tested yes, 11 => tested no. */
735
736       if ((bits & (-bits)) == bits)    /* Only one of the two bits is set */
737         {
738         HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\"%s)\n", ot,
739           yield == OK ? "yes" : "no", sss, cached);
740         goto YIELD_RETURN;
741         }
742       }
743
744     /* Run the provided function to do the individual test. */
745
746     else
747       {
748       uschar * error = NULL;
749       switch ((func)(arg, ss, valueptr, &error))
750         {
751         case OK:
752           HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\")\n", ot,
753             yield == OK ? "yes" : "no", sss);
754           goto YIELD_RETURN;
755
756         case DEFER:
757           if (!error)
758             error = string_sprintf("DNS lookup of \"%s\" deferred", ss);
759           if (ignore_defer)
760             {
761             HDEBUG(D_lists)
762               debug_printf_indent("%s: item ignored by +ignore_defer\n", error);
763             break;
764             }
765           if (include_defer)
766             {
767             log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
768             return OK;
769             }
770           if (!search_error_message) search_error_message = error;
771           goto DEFER_RETURN;
772
773         /* The ERROR return occurs when checking hosts, when either a forward
774         or reverse lookup has failed. It can also occur in a match_ip list if a
775         non-IP address item is encountered. The error string gives details of
776         which it was. */
777
778         case ERROR:
779           if (ignore_unknown)
780             {
781             HDEBUG(D_lists) debug_printf_indent(
782               "%s: item ignored by +ignore_unknown\n", error);
783             }
784           else
785             {
786             HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
787               include_unknown? "yes":"no", error);
788             if (!include_unknown)
789               {
790               if (LOGGING(unknown_in_list))
791                 log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
792               return FAIL;
793               }
794             log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
795             return OK;
796             }
797         }
798       }
799     }
800
801   /* If the item is a file name, we read the file and do a match attempt
802   on each line in the file, including possibly more negation processing. */
803
804   else
805     {
806     int file_yield = yield;       /* In case empty file */
807     uschar * filename = ss;
808     FILE * f = Ufopen(filename, "rb");
809     uschar filebuffer[1024];
810
811     /* ot will be null in non-debugging cases, and anyway, we get better
812     wording by reworking it. */
813
814     if (!f)
815       {
816       const uschar * listname = readconf_find_option(listptr);
817       if (!*listname)
818         listname = string_sprintf("\"%s\"", *listptr);
819       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
820         string_open_failed("%s when checking %s", sss, listname));
821       }
822
823     /* Trailing comments are introduced by #, but in an address list or local
824     part list, the # must be preceded by white space or the start of the line,
825     because the # character is a legal character in local parts. */
826
827     while (Ufgets(filebuffer, sizeof(filebuffer), f) != NULL)
828       {
829       uschar * error, * sss = filebuffer;
830
831       while ((ss = Ustrchr(sss, '#')) != NULL)
832         {
833         if ((type != MCL_ADDRESS && type != MCL_LOCALPART) ||
834               ss == filebuffer || isspace(ss[-1]))
835           {
836           *ss = '\0';
837           break;
838           }
839         sss = ss + 1;
840         }
841
842       ss = filebuffer + Ustrlen(filebuffer);            /* trailing space */
843       while (ss > filebuffer && isspace(ss[-1])) ss--;
844       *ss = '\0';
845
846       ss = filebuffer;
847       if (!Uskip_whitespace(&ss))                       /* leading space */
848         continue;                                       /* ignore empty */
849
850       file_yield = yield;                               /* positive yield */
851       sss = ss;                                         /* for debugging */
852
853       if (*ss == '!')                                   /* negation */
854         {
855         file_yield = file_yield == OK ? FAIL : OK;
856         while (isspace(*++ss)) ;
857         }
858
859       switch ((func)(arg, ss, valueptr, &error))
860         {
861         case OK:
862           (void)fclose(f);
863           HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\" in %s)\n",
864             ot, yield == OK ? "yes" : "no", sss, filename);
865
866           /* The "pattern" being matched came from the file; we use a stack-local.
867           Copy it to allocated memory now we know it matched. */
868
869           if (valueptr) *valueptr = string_copy(ss);
870           yield = file_yield;
871           goto YIELD_RETURN;
872
873         case DEFER:
874           if (!error)
875             error = string_sprintf("DNS lookup of %s deferred", ss);
876           if (ignore_defer)
877             {
878             HDEBUG(D_lists)
879               debug_printf_indent("%s: item ignored by +ignore_defer\n", error);
880             break;
881             }
882           (void)fclose(f);
883           if (!include_defer)
884             goto DEFER_RETURN;
885           log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
886           goto OK_RETURN;
887
888         /* The ERROR return occurs when checking hosts, when either a forward
889         or reverse lookup has failed. It can also occur in a match_ip list if a
890         non-IP address item is encountered. The error string gives details of
891         which it was. */
892
893         case ERROR:
894           if (ignore_unknown)
895             {
896             HDEBUG(D_lists) debug_printf_indent(
897               "%s: item ignored by +ignore_unknown\n", error);
898             }
899           else
900             {
901             HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
902               include_unknown ? "yes":"no", error);
903             (void)fclose(f);
904             if (!include_unknown)
905               {
906               if (LOGGING(unknown_in_list))
907                 log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
908               goto FAIL_RETURN;
909               }
910             log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
911             goto OK_RETURN;
912             }
913         }
914       }
915
916     /* At the end of the file, leave the yield setting at the final setting
917     for the file, in case this is the last item in the list. */
918
919     yield = file_yield;
920     (void)fclose(f);
921     }
922   }    /* Loop for the next item on the top-level list */
923
924 /* End of list reached: if the last item was negated yield OK, else FAIL. */
925
926 HDEBUG(D_any)
927   {
928   HDEBUG(D_lists) expand_level--;
929   debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes");
930   }
931 return yield == OK ? FAIL : OK;
932  
933 /* Something deferred */
934
935 DEFER_RETURN:
936   HDEBUG(D_any)
937     {
938     HDEBUG(D_lists) expand_level--;
939     debug_printf_indent("%s list match deferred for %s\n", ot, sss);
940     }
941   return DEFER;
942
943 FAIL_RETURN:
944   yield = FAIL;
945   goto YIELD_RETURN;
946
947 OK_RETURN:
948   yield = OK;
949
950 YIELD_RETURN:
951   HDEBUG(D_lists) expand_level--;
952   return yield;
953 }
954
955
956 /*************************************************
957 *          Match in colon-separated list         *
958 *************************************************/
959
960 /* This function is used for domain lists and local part lists. It is not used
961 for host lists or address lists, which have additional interpretation of the
962 patterns. Some calls of it set sep > UCHAR_MAX in order to use its matching
963 facilities on single items. When this is done, it arranges to set the numerical
964 variables as a result of the match.
965
966 This function is now just a short interface to match_check_list(), which does
967 list scanning in a general way. A good compiler will optimize the tail
968 recursion.
969
970 Arguments:
971   s              string to search for
972   listptr        ptr to ptr to colon separated list of patterns, or NULL
973   sep            a separator value for the list (see string_nextinlist())
974                  or zero for auto
975   anchorptr      ptr to tree for named items, or NULL if no named items
976   cache_bits     ptr to cache_bits for ditto, or NULL if not caching
977   type           MCL_DOMAIN when matching a domain list
978                  MCL_LOCALPART when matching a local part list (address lists
979                    have their own function)
980                  MCL_STRING for others (e.g. list of ciphers)
981                  MCL_NOEXPAND (whose value is greater than any of them) may
982                    be added to any value to suppress expansion of the list
983   caseless       TRUE for (mostly) caseless matching - passed directly to
984                    match_check_string()
985   valueptr       pointer to where any lookup data is to be passed back,
986                  or NULL (just passed on to match_check_string)
987
988 Returns:         OK    if matched a non-negated item
989                  OK    if hit end of list after a negated item
990                  FAIL  if expansion force-failed
991                  FAIL  if matched a negated item
992                  FAIL  if hit end of list after a non-negated item
993                  DEFER if a lookup deferred
994 */
995
996 int
997 match_isinlist(const uschar *s, const uschar **listptr, int sep,
998    tree_node **anchorptr,
999   unsigned int *cache_bits, int type, BOOL caseless, const uschar **valueptr)
1000 {
1001 unsigned int *local_cache_bits = cache_bits;
1002 check_string_block cb;
1003 cb.origsubject = s;
1004 cb.subject = caseless ? string_copylc(s) : string_copy(s);
1005 cb.flags = caseless ? MCS_PARTIAL+MCS_CASELESS : MCS_PARTIAL;
1006 switch (type & ~MCL_NOEXPAND)
1007   {
1008   case MCL_DOMAIN:      cb.flags |= MCS_AT_SPECIAL;     /*FALLTHROUGH*/
1009   case MCL_LOCALPART:   cb.expand_setup = 0;                            break;
1010   default:              cb.expand_setup = sep > UCHAR_MAX ? 0 : -1;     break;
1011   }
1012 if (valueptr) *valueptr = NULL;
1013 return  match_check_list(listptr, sep, anchorptr, &local_cache_bits,
1014   check_string, &cb, type, s, valueptr);
1015 }
1016
1017
1018
1019 /*************************************************
1020 *    Match address to single address-list item   *
1021 *************************************************/
1022
1023 /* This function matches an address to an item from an address list. It is
1024 called from match_address_list() via match_check_list(). That is why most of
1025 its arguments are in an indirect block.
1026
1027 Arguments:
1028   arg            the argument block (see below)
1029   pattern        the pattern to match
1030   valueptr       where to return a value
1031   error          for error messages (not used in this function; it never
1032                    returns ERROR)
1033
1034 The argument block contains:
1035   address        the start of the subject address; when called from retry.c
1036                    it may be *@domain if the local part isn't relevant
1037   origaddress    the original, un-case-forced address (not used here, but used
1038                    in match_check_list() when +caseful is encountered)
1039   expand_setup   controls setting up of $n variables
1040   caseless       TRUE for caseless local part matching
1041
1042 Returns:         OK     for a match
1043                  FAIL   for no match
1044                  DEFER  if a lookup deferred
1045 */
1046
1047 static int
1048 check_address(void * arg, const uschar * pattern, const uschar ** valueptr,
1049   uschar ** error)
1050 {
1051 check_address_block * cb = (check_address_block *)arg;
1052 check_string_block csb;
1053 int rc;
1054 int expand_inc = 0;
1055 unsigned int * null = NULL;
1056 const uschar * listptr;
1057 uschar * subject = cb->address;
1058 const uschar * s;
1059 uschar * pdomain, * sdomain;
1060 uschar * value = NULL;
1061
1062 DEBUG(D_lists) debug_printf_indent("address match test: subject=%s pattern=%s\n",
1063   subject, pattern);
1064
1065 /* Find the subject's domain */
1066
1067 sdomain = Ustrrchr(subject, '@');
1068
1069 /* The only case where a subject may not have a domain is if the subject is
1070 empty. Otherwise, a subject with no domain is a serious configuration error. */
1071
1072 if (!sdomain && *subject)
1073   {
1074   log_write(0, LOG_MAIN|LOG_PANIC, "no @ found in the subject of an "
1075     "address list match: subject=\"%s\" pattern=\"%s\"", subject, pattern);
1076   return FAIL;
1077   }
1078
1079 /* Handle a regular expression, which must match the entire incoming address.
1080 This may be the empty address. */
1081
1082 if (*pattern == '^')
1083   return match_check_string(subject, pattern, cb->expand_setup,
1084             cb->flags | MCS_PARTIAL, NULL);
1085
1086 /* Handle a pattern that is just a lookup. Skip over possible lookup names
1087 (letters, digits, hyphens). Skip over a possible * or *@ at the end. Then we
1088 must have a semicolon for it to be a lookup. */
1089
1090 for (s = pattern; isalnum(*s) || *s == '-'; s++) ;
1091 if (*s == '*') s++;
1092 if (*s == '@') s++;
1093
1094 /* If it is a straight lookup, do a lookup for the whole address. This may be
1095 the empty address. Partial matching doesn't make sense here, so we ignore it,
1096 but write a panic log entry. However, *@ matching will be honoured. */
1097
1098 if (*s == ';')
1099   {
1100   if (Ustrncmp(pattern, "partial-", 8) == 0)
1101     log_write(0, LOG_MAIN|LOG_PANIC, "partial matching is not applicable to "
1102       "whole-address lookups: ignored \"partial-\" in \"%s\"", pattern);
1103   return match_check_string(subject, pattern, -1, cb->flags, valueptr);
1104   }
1105
1106 /* For the remaining cases, an empty subject matches only an empty pattern,
1107 because other patterns expect to have a local part and a domain to match
1108 against. */
1109
1110 if (!*subject) return *pattern ? FAIL : OK;
1111
1112 /* If the pattern starts with "@@" we have a split lookup, where the domain is
1113 looked up to obtain a list of local parts. If the subject's local part is just
1114 "*" (called from retry) the match always fails. */
1115
1116 if (pattern[0] == '@' && pattern[1] == '@')
1117   {
1118   int watchdog = 50;
1119   uschar *list, *ss;
1120
1121   if (sdomain == subject + 1 && *subject == '*') return FAIL;
1122
1123   /* Loop for handling chains. The last item in any list may be of the form
1124   ">name" in order to chain on to another list. */
1125
1126   for (const uschar * key = sdomain + 1; key && watchdog-- > 0; )
1127     {
1128     int sep = 0;
1129
1130     if ((rc = match_check_string(key, pattern + 2, -1, MCS_PARTIAL, CUSS &list))
1131         != OK)
1132       return rc;
1133
1134     /* Check for chaining from the last item; set up the next key if one
1135     is found. */
1136
1137     ss = Ustrrchr(list, ':');
1138     if (!ss) ss = list; else ss++;
1139     Uskip_whitespace(&ss);
1140     if (*ss == '>')
1141       {
1142       *ss++ = 0;
1143       Uskip_whitespace(&ss);
1144       key = string_copy(ss);
1145       }
1146     else key = NULL;
1147
1148     /* Look up the local parts provided by the list; negation is permitted.
1149     If a local part has to begin with !, a regex can be used. */
1150
1151     while ((ss = string_nextinlist(CUSS &list, &sep, NULL, 0)))
1152       {
1153       int local_yield;
1154
1155       if (*ss == '!')
1156         {
1157         local_yield = FAIL;
1158         while (isspace(*++ss)) ;
1159         }
1160       else local_yield = OK;
1161
1162       *sdomain = 0;
1163       rc = match_check_string(subject, ss, -1, cb->flags + MCS_PARTIAL, valueptr);
1164       *sdomain = '@';
1165
1166       switch(rc)
1167         {
1168         case OK:
1169         return local_yield;
1170
1171         case DEFER:
1172         return DEFER;
1173         }
1174       }
1175     }
1176
1177   /* End of chain loop; panic if too many times */
1178
1179   if (watchdog <= 0)
1180     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Loop detected in lookup of "
1181       "local part of %s in %s", subject, pattern);
1182
1183   /* Otherwise the local part check has failed, so the whole match
1184   fails. */
1185
1186   return FAIL;
1187   }
1188
1189
1190 /* We get here if the pattern is not a lookup or a regular expression. If it
1191 contains an @ there is both a local part and a domain. */
1192
1193 if ((pdomain = Ustrrchr(pattern, '@')))
1194   {
1195   int pllen, sllen;
1196
1197   /* If the domain in the pattern is empty or one of the special cases [] or
1198   mx_{any,primary,secondary}, and the local part in the pattern ends in "@",
1199   we have a pattern of the form <something>@@, <something>@@[], or
1200   <something>@@mx_{any,primary,secondary}. These magic "domains" are
1201   automatically interpreted in match_check_string. We just need to arrange that
1202   the leading @ is included in the domain. */
1203
1204   if (pdomain > pattern && pdomain[-1] == '@' &&
1205        (pdomain[1] == 0 ||
1206         Ustrcmp(pdomain+1, "[]") == 0 ||
1207         Ustrcmp(pdomain+1, "mx_any") == 0 ||
1208         Ustrcmp(pdomain+1, "mx_primary") == 0 ||
1209         Ustrcmp(pdomain+1, "mx_secondary") == 0))
1210     pdomain--;
1211
1212   pllen = pdomain - pattern;
1213   sllen = sdomain - subject;
1214
1215   /* Compare the local parts in the subject and the pattern */
1216
1217   if (*pattern == '*')
1218     {
1219     int cllen = pllen - 1;
1220     if (sllen < cllen) return FAIL;
1221     if (cb->flags & MCS_CASELESS
1222         ? strncmpic(subject+sllen-cllen, pattern + 1, cllen) != 0
1223         : Ustrncmp(subject+sllen-cllen, pattern + 1, cllen) != 0)
1224         return FAIL;
1225     if (cb->expand_setup > 0)
1226       {
1227       expand_nstring[cb->expand_setup] = subject;
1228       expand_nlength[cb->expand_setup] = sllen - cllen;
1229       expand_inc = 1;
1230       }
1231     value = string_copyn(pattern + 1, cllen);
1232     }
1233   else
1234     {
1235     if (sllen != pllen) return FAIL;
1236     if (cb->flags & MCS_CASELESS
1237         ? strncmpic(subject, pattern, sllen) != 0
1238         : Ustrncmp(subject, pattern, sllen) != 0) return FAIL;
1239     }
1240     value = string_copyn(pattern, sllen);
1241   }
1242
1243 /* If the local part matched, or was not being checked, check the domain using
1244 the generalized function, which supports file lookups (which may defer). The
1245 original code read as follows:
1246
1247   return match_check_string(sdomain + 1,
1248       pdomain ? pdomain + 1 : pattern,
1249       cb->expand_setup + expand_inc, cb->flags, NULL);
1250
1251 This supported only literal domains and *.x.y patterns. In order to allow for
1252 named domain lists (so that you can write, for example, "senders=+xxxx"), it
1253 was changed to use the list scanning function. */
1254
1255 csb.origsubject = sdomain + 1;
1256 csb.subject = cb->flags & MCS_CASELESS
1257   ? string_copylc(sdomain+1) : string_copy(sdomain+1);
1258 csb.expand_setup = cb->expand_setup + expand_inc;
1259 csb.flags = MCS_PARTIAL | MCS_AT_SPECIAL | cb->flags & MCS_CASELESS;
1260
1261 listptr = pdomain ? pdomain + 1 : pattern;
1262 if (valueptr) *valueptr = NULL;
1263
1264   {
1265   const uschar * dvalue = NULL;
1266   rc = match_check_list(
1267     &listptr,                  /* list of one item */
1268     UCHAR_MAX+1,               /* impossible separator; single item */
1269     &domainlist_anchor,        /* it's a domain list */
1270     &null,                     /* ptr to NULL means no caching */
1271     check_string,              /* the function to do one test */
1272     &csb,                      /* its data */
1273     MCL_DOMAIN + MCL_NOEXPAND, /* domain list; don't expand */
1274     csb.subject,               /* string for messages */
1275     &dvalue);                       /* where to pass back lookup data */
1276   if (valueptr && (value || dvalue))
1277     *valueptr = string_sprintf("%s@%s",
1278                   value ? value : US"", dvalue ? dvalue : US"");
1279   }
1280 return rc;
1281 }
1282
1283
1284
1285
1286 /*************************************************
1287 *    Test whether address matches address list   *
1288 *************************************************/
1289
1290 /* This function is given an address and a list of things to match it against.
1291 The list may contain individual addresses, regular expressions, lookup
1292 specifications, and indirection via bare files. Negation is supported. The
1293 address to check can consist of just a domain, which will then match only
1294 domain items or items specified as *@domain.
1295
1296 Domains are always lower cased before the match. Local parts are also lower
1297 cased unless "caseless" is false. The work of actually scanning the list is
1298 done by match_check_list(), with an appropriate block of arguments and a
1299 callback to check_address(). During caseless matching, it will recognize
1300 +caseful and revert to caseful matching.
1301
1302 Arguments:
1303   address         address to test
1304   caseless        TRUE to start in caseless state
1305   expand          TRUE to allow list expansion
1306   listptr         list to check against
1307   cache_bits      points to cache bits for named address lists, or NULL
1308   expand_setup    controls setting up of $n variables - passed through
1309                   to check_address (q.v.)
1310   sep             separator character for the list;
1311                   may be 0 to get separator from the list;
1312                   may be UCHAR_MAX+1 for one-item list
1313   valueptr        where to return a lookup value, or NULL
1314
1315 Returns:          OK    for a positive match, or end list after a negation;
1316                   FAIL  for a negative match, or end list after non-negation;
1317                   DEFER if a lookup deferred
1318 */
1319
1320 int
1321 match_address_list(const uschar *address, BOOL caseless, BOOL expand,
1322   const uschar **listptr, unsigned int *cache_bits, int expand_setup, int sep,
1323   const uschar **valueptr)
1324 {
1325 check_address_block ab;
1326 unsigned int *local_cache_bits = cache_bits;
1327 int len;
1328
1329 /* RFC 2505 recommends that for spam checking, local parts should be caselessly
1330 compared. Therefore, Exim now forces the entire address into lower case here,
1331 provided that "caseless" is set. (It is FALSE for calls for matching rewriting
1332 patterns.) Otherwise just the domain is lower cases. A magic item "+caseful" in
1333 the list can be used to restore a caseful copy of the local part from the
1334 original address.
1335 Limit the subject address size to avoid mem-exhaustion attacks.  The size chosen
1336 is historical (we used to use big_buffer here). */
1337
1338 if ((len = Ustrlen(address)) > BIG_BUFFER_SIZE) len = BIG_BUFFER_SIZE;
1339 ab.address = string_copyn(address, len);
1340
1341 for (uschar * p = ab.address + len - 1; p >= ab.address; p--)
1342   {
1343   if (!caseless && *p == '@') break;
1344   *p = tolower(*p);
1345   }
1346
1347 /* If expand_setup is zero, we need to set up $0 to the whole thing, in
1348 case there is a match. Can't use the built-in facilities of match_check_string
1349 (via check_address), as we may just be calling that for part of the address
1350 (the domain). */
1351
1352 if (expand_setup == 0)
1353   {
1354   expand_nstring[0] = string_copy(address);
1355   expand_nlength[0] = Ustrlen(address);
1356   expand_setup++;
1357   }
1358
1359 /* Set up the data to be passed ultimately to check_address. */
1360
1361 ab.origaddress = address;
1362 /* ab.address is above */
1363 ab.expand_setup = expand_setup;
1364 ab.flags = caseless ? MCS_CASELESS : 0;
1365
1366 return match_check_list(listptr, sep, &addresslist_anchor, &local_cache_bits,
1367   check_address, &ab, MCL_ADDRESS + (expand ? 0 : MCL_NOEXPAND), address,
1368     valueptr);
1369 }
1370
1371 /* Simpler version of match_address_list; always caseless, expanding,
1372 no cache bits, no value-return.
1373
1374 Arguments:
1375   address         address to test
1376   listptr         list to check against
1377   sep             separator character for the list;
1378                   may be 0 to get separator from the list;
1379                   may be UCHAR_MAX+1 for one-item list
1380
1381 Returns:          OK    for a positive match, or end list after a negation;
1382                   FAIL  for a negative match, or end list after non-negation;
1383                   DEFER if a lookup deferred
1384 */
1385
1386 int
1387 match_address_list_basic(const uschar *address, const uschar **listptr, int sep)
1388 {
1389 return match_address_list(address, TRUE, TRUE, listptr, NULL, -1, sep, NULL);
1390 }
1391
1392 /* End of match.c */
1393 /* vi: aw ai sw=2
1394 */