Logging: ensure that an error for a mistyped IPv6 address in a search
[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)
441   {
442   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. Skip the debugging output for
447 an unnamed list. */
448
449 if (!*listptr)
450   {
451   HDEBUG(D_lists) if (ot) debug_printf_indent("%s no (option unset)\n", ot);
452   return FAIL;
453   }
454
455 /* Expand the list before we scan it. A forced expansion gives the answer
456 "not in list"; other expansion errors cause DEFER to be returned. However,
457 if the type value is greater than or equal to than MCL_NOEXPAND, do not expand
458 the list. */
459
460 if (type >= MCL_NOEXPAND)
461   {
462   list = *listptr;
463   type -= MCL_NOEXPAND;       /* Remove the "no expand" flag */
464   textonly_re = TRUE;
465   }
466 else
467   {
468   /* If we are searching a domain list, and $domain is not set, set it to the
469   subject that is being sought for the duration of the expansion. */
470
471   if (type == MCL_DOMAIN && !deliver_domain)
472     {
473     check_string_block *cb = (check_string_block *)arg;
474     deliver_domain = string_copy(cb->subject);
475     list = expand_string_2(*listptr, &textonly_re);
476     deliver_domain = NULL;
477     }
478   else
479     list = expand_string_2(*listptr, &textonly_re);
480
481   if (!list)
482     {
483     if (f.expand_string_forcedfail)
484       {
485       HDEBUG(D_lists) debug_printf_indent("expansion of \"%s\" forced failure: "
486         "assume not in this list\n", *listptr);
487       return FAIL;
488       }
489     log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand \"%s\" while checking "
490       "a list: %s", *listptr, expand_string_message);
491     return DEFER;
492     }
493   }
494
495 if (textonly_re) switch (type)
496   {
497   case MCL_STRING:
498   case MCL_DOMAIN:
499   case MCL_LOCALPART: ((check_string_block *)arg)->flags |= MCS_CACHEABLE; break;
500   case MCL_HOST:     ((check_host_block *)arg)->flags |= MCS_CACHEABLE; break;
501   case MCL_ADDRESS: ((check_address_block *)arg)->flags |= MCS_CACHEABLE; break;
502   }
503
504 /* For an unnamed list, use the expanded version in comments */
505 #define LIST_LIMIT_PR 2048
506
507 HDEBUG(D_any) if (!ot)
508   {
509   int n, m;
510   gstring * g = string_fmt_append(NULL, "%s in \"%n%.*s%n\"",
511     name, &n, LIST_LIMIT_PR, list, &m);
512   if (m - n >= LIST_LIMIT_PR) g = string_catn(g, US"...", 3);
513   g = string_catn(g, US"?", 1);
514   gstring_release_unused(g);
515   ot = string_from_gstring(g);
516   }
517 HDEBUG(D_lists)
518   {
519   debug_printf_indent("%s\n", ot);
520   expand_level++;
521   }
522
523 /* Now scan the list and process each item in turn, until one of them matches,
524 or we hit an error. */
525
526 while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
527   {
528   uschar * ss = sss;
529
530   HDEBUG(D_lists) debug_printf_indent("list element: %s\n", ss);
531
532   /* Address lists may contain +caseful, to restore caseful matching of the
533   local part. We have to know the layout of the control block, unfortunately.
534   The lower cased address is in a temporary buffer, so we just copy the local
535   part back to the start of it (if a local part exists). */
536
537   if (type == MCL_ADDRESS)
538     {
539     if (Ustrcmp(ss, "+caseful") == 0)
540       {
541       check_address_block *cb = (check_address_block *)arg;
542       uschar *at = Ustrrchr(cb->origaddress, '@');
543
544       if (at)
545         Ustrncpy(cb->address, cb->origaddress, at - cb->origaddress);
546       cb->flags &= ~MCS_CASELESS;
547       continue;
548       }
549     }
550
551   /* Similar processing for local parts */
552
553   else if (type == MCL_LOCALPART)
554     {
555     if (Ustrcmp(ss, "+caseful") == 0)
556       {
557       check_string_block *cb = (check_string_block *)arg;
558       Ustrcpy(US cb->subject, cb->origsubject);
559       cb->flags &= ~MCS_CASELESS;
560       continue;
561       }
562     }
563
564   /* If the host item is "+include_unknown" or "+ignore_unknown", remember it
565   in case there's a subsequent failed reverse lookup. There is similar
566   processing for "defer". */
567
568   else if (type == MCL_HOST && *ss == '+')
569     {
570     if (Ustrcmp(ss, "+include_unknown") == 0)
571       {
572       include_unknown = TRUE;
573       ignore_unknown = FALSE;
574       continue;
575       }
576     if (Ustrcmp(ss, "+ignore_unknown") == 0)
577       {
578       ignore_unknown = TRUE;
579       include_unknown = FALSE;
580       continue;
581       }
582     if (Ustrcmp(ss, "+include_defer") == 0)
583       {
584       include_defer = TRUE;
585       ignore_defer = FALSE;
586       continue;
587       }
588     if (Ustrcmp(ss, "+ignore_defer") == 0)
589       {
590       ignore_defer = TRUE;
591       include_defer = FALSE;
592       continue;
593       }
594     }
595
596   /* Starting with ! specifies a negative item. It is theoretically possible
597   for a local part to start with !. In that case, a regex has to be used. */
598
599   if (*ss == '!')
600     {
601     yield = FAIL;
602     while (isspace((*(++ss))));
603     }
604   else
605     yield = OK;
606
607   /* If the item does not begin with '/', it might be a + item for a named
608   list. Otherwise, it is just a single list entry that has to be matched.
609   We recognize '+' only when supplied with a tree of named lists. */
610
611   if (*ss != '/')
612     {
613     if (*ss == '+' && anchorptr)
614       {
615       int bits = 0, offset = 0, shift = 0;
616       unsigned int * use_cache_bits = original_cache_bits;
617       uschar * cached = US"";
618       namedlist_block * nb;
619       tree_node * t;
620
621       DEBUG(D_lists)
622         { debug_printf_indent(" start sublist %s\n", ss+1); expand_level += 2; }
623
624       if (!(t = tree_search(*anchorptr, ss+1)))
625         {
626         log_write(0, LOG_MAIN|LOG_PANIC, "unknown named%s list \"%s\"",
627           type == MCL_DOMAIN ?    " domain" :
628           type == MCL_HOST ?      " host" :
629           type == MCL_ADDRESS ?   " address" :
630           type == MCL_LOCALPART ? " local part" : "",
631           ss);
632         goto DEFER_RETURN;
633         }
634       nb = t->data.ptr;
635
636       /* If the list number is negative, it means that this list is not
637       cacheable because it contains expansion items. */
638
639       if (nb->number < 0) use_cache_bits = NULL;
640
641       /* If we have got a cache pointer, get the bits. This is not an "else"
642       because the pointer may be NULL from the start if caching is not
643       required. */
644
645       if (use_cache_bits)
646         {
647         offset = (nb->number)/16;
648         shift = ((nb->number)%16)*2;
649         bits = use_cache_bits[offset] & (3 << shift);
650         }
651
652       /* Not previously tested or no cache - run the full test */
653
654       if (bits == 0)
655         {
656         int res = match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits,
657                 func, arg, type, name, valueptr);
658         DEBUG(D_lists)
659           { expand_level -= 2; debug_printf_indent(" end sublist %s\n", ss+1); }
660
661         switch (res)
662           {
663           case OK:   bits = 1; break;
664           case FAIL: bits = 3; break;
665           case DEFER: goto DEFER_RETURN;
666           }
667
668         /* If this list was uncacheable, or a sublist turned out to be
669         uncacheable, the value of use_cache_bits will now be NULL, even if it
670         wasn't before. Ensure that this is passed up to the next level.
671         Otherwise, remember the result of the search in the cache. */
672
673         if (!use_cache_bits)
674           *cache_ptr = NULL;
675         else
676           {
677           use_cache_bits[offset] |= bits << shift;
678
679           if (valueptr)
680             {
681             int old_pool = store_pool;
682             namedlist_cacheblock *p;
683
684             /* Cached data for hosts persists over more than one message,
685             so we use the permanent store pool */
686
687             store_pool = POOL_PERM;
688             p = store_get(sizeof(namedlist_cacheblock), GET_UNTAINTED);
689             p->key = string_copy(get_check_key(arg, type));
690
691
692             p->data = *valueptr ? string_copy(*valueptr) : NULL;
693             store_pool = old_pool;
694
695             p->next = nb->cache_data;
696             nb->cache_data = p;
697             if (*valueptr)
698               DEBUG(D_lists) debug_printf_indent("data from lookup saved for "
699                 "cache for %s: key '%s' value '%s'\n", ss, p->key, *valueptr);
700             }
701           }
702         }
703
704        /* Previously cached; to find a lookup value, search a chain of values
705        and compare keys. Typically, there is only one such, but it is possible
706        for different keys to have matched the same named list. */
707
708       else
709         {
710         DEBUG(D_lists)
711           {
712           expand_level -= 2;
713           debug_printf_indent("cached %s match for %s\n",
714             (bits & (-bits)) == bits ? "yes" : "no", ss);
715           }
716
717         cached = US" - cached";
718         if (valueptr)
719           {
720           const uschar *key = get_check_key(arg, type);
721
722           for (namedlist_cacheblock * p = nb->cache_data; p; p = p->next)
723             if (Ustrcmp(key, p->key) == 0)
724               {
725               *valueptr = p->data;
726               break;
727               }
728           DEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
729           }
730         }
731
732       /* Result of test is indicated by value in bits. For each test, we
733       have 00 => untested, 01 => tested yes, 11 => tested no. */
734
735       if ((bits & (-bits)) == bits)    /* Only one of the two bits is set */
736         {
737         HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\"%s)\n", ot,
738           yield == OK ? "yes" : "no", sss, cached);
739         goto YIELD_RETURN;
740         }
741       }
742
743     /* Run the provided function to do the individual test. */
744
745     else
746       {
747       uschar * error = NULL;
748       switch ((func)(arg, ss, valueptr, &error))
749         {
750         case OK:
751           HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\")\n", ot,
752             (yield == OK)? "yes" : "no", sss);
753           goto YIELD_RETURN;
754
755         case DEFER:
756           if (!error)
757             error = string_sprintf("DNS lookup of \"%s\" deferred", ss);
758           if (ignore_defer)
759             {
760             HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_defer\n",
761               error);
762             break;
763             }
764           if (include_defer)
765             {
766             log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
767             return OK;
768             }
769           if (!search_error_message) search_error_message = error;
770           goto DEFER_RETURN;
771
772         /* The ERROR return occurs when checking hosts, when either a forward
773         or reverse lookup has failed. It can also occur in a match_ip list if a
774         non-IP address item is encountered. The error string gives details of
775         which it was. */
776
777         case ERROR:
778           if (ignore_unknown)
779             {
780             HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
781               error);
782             }
783           else
784             {
785             HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
786               include_unknown? "yes":"no", error);
787             if (!include_unknown)
788               {
789               if (LOGGING(unknown_in_list))
790                 log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
791               return FAIL;
792               }
793             log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
794             return OK;
795             }
796         }
797       }
798     }
799
800   /* If the item is a file name, we read the file and do a match attempt
801   on each line in the file, including possibly more negation processing. */
802
803   else
804     {
805     int file_yield = yield;       /* In case empty file */
806     uschar * filename = ss;
807     FILE * f = Ufopen(filename, "rb");
808     uschar filebuffer[1024];
809
810     /* ot will be null in non-debugging cases, and anyway, we get better
811     wording by reworking it. */
812
813     if (!f)
814       {
815       uschar * listname = readconf_find_option(listptr);
816       if (listname[0] == 0)
817         listname = string_sprintf("\"%s\"", *listptr);
818       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
819         string_open_failed("%s when checking %s", sss, listname));
820       }
821
822     /* Trailing comments are introduced by #, but in an address list or local
823     part list, the # must be preceded by white space or the start of the line,
824     because the # character is a legal character in local parts. */
825
826     while (Ufgets(filebuffer, sizeof(filebuffer), f) != NULL)
827       {
828       uschar *error;
829       uschar *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       while (isspace(*ss)) ss++;                        /* leading space */
848
849       if (!*ss) continue;                               /* ignore empty */
850
851       file_yield = yield;                               /* positive yield */
852       sss = ss;                                         /* for debugging */
853
854       if (*ss == '!')                                   /* negation */
855         {
856         file_yield = (file_yield == OK)? FAIL : OK;
857         while (isspace((*(++ss))));
858         }
859
860       switch ((func)(arg, ss, valueptr, &error))
861         {
862         case OK:
863           (void)fclose(f);
864           HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\" in %s)\n", ot,
865             yield == OK ? "yes" : "no", sss, filename);
866
867           /* The "pattern" being matched came from the file; we use a stack-local.
868           Copy it to allocated memory now we know it matched. */
869
870           if (valueptr) *valueptr = string_copy(ss);
871           yield = file_yield;
872           goto YIELD_RETURN;
873
874         case DEFER:
875           if (!error)
876             error = string_sprintf("DNS lookup of %s deferred", ss);
877           if (ignore_defer)
878             {
879             HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_defer\n",
880               error);
881             break;
882             }
883           (void)fclose(f);
884           if (!include_defer)
885             goto DEFER_RETURN;
886           log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
887           goto OK_RETURN;
888
889         /* The ERROR return occurs when checking hosts, when either a forward
890         or reverse lookup has failed. It can also occur in a match_ip list if a
891         non-IP address item is encountered. The error string gives details of
892         which it was. */
893
894         case ERROR:
895           if (ignore_unknown)
896             {
897             HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
898               error);
899             }
900           else
901             {
902             HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
903               include_unknown? "yes":"no", error);
904             (void)fclose(f);
905             if (!include_unknown)
906               {
907               if (LOGGING(unknown_in_list))
908                 log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
909               goto FAIL_RETURN;
910               }
911             log_write(0, LOG_MAIN, "%s: accepted by +include_unknown", error);
912             goto OK_RETURN;
913             }
914         }
915       }
916
917     /* At the end of the file, leave the yield setting at the final setting
918     for the file, in case this is the last item in the list. */
919
920     yield = file_yield;
921     (void)fclose(f);
922     }
923   }    /* Loop for the next item on the top-level list */
924
925 /* End of list reached: if the last item was negated yield OK, else FAIL. */
926
927 HDEBUG(D_lists)
928   HDEBUG(D_lists)
929     {
930     expand_level--;
931     debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes");
932     }
933   return yield == OK ? FAIL : OK;
934
935 /* Something deferred */
936
937 DEFER_RETURN:
938   HDEBUG(D_lists)
939     {
940     expand_level--;
941     debug_printf_indent("%s list match deferred for %s\n", ot, sss);
942     }
943   return DEFER;
944
945 FAIL_RETURN:
946   yield = FAIL;
947   goto YIELD_RETURN;
948
949 OK_RETURN:
950   yield = OK;
951
952 YIELD_RETURN:
953   HDEBUG(D_lists) expand_level--;
954   return yield;
955 }
956
957
958 /*************************************************
959 *          Match in colon-separated list         *
960 *************************************************/
961
962 /* This function is used for domain lists and local part lists. It is not used
963 for host lists or address lists, which have additional interpretation of the
964 patterns. Some calls of it set sep > UCHAR_MAX in order to use its matching
965 facilities on single items. When this is done, it arranges to set the numerical
966 variables as a result of the match.
967
968 This function is now just a short interface to match_check_list(), which does
969 list scanning in a general way. A good compiler will optimize the tail
970 recursion.
971
972 Arguments:
973   s              string to search for
974   listptr        ptr to ptr to colon separated list of patterns, or NULL
975   sep            a separator value for the list (see string_nextinlist())
976                  or zero for auto
977   anchorptr      ptr to tree for named items, or NULL if no named items
978   cache_bits     ptr to cache_bits for ditto, or NULL if not caching
979   type           MCL_DOMAIN when matching a domain list
980                  MCL_LOCALPART when matching a local part list (address lists
981                    have their own function)
982                  MCL_STRING for others (e.g. list of ciphers)
983                  MCL_NOEXPAND (whose value is greater than any of them) may
984                    be added to any value to suppress expansion of the list
985   caseless       TRUE for (mostly) caseless matching - passed directly to
986                    match_check_string()
987   valueptr       pointer to where any lookup data is to be passed back,
988                  or NULL (just passed on to match_check_string)
989
990 Returns:         OK    if matched a non-negated item
991                  OK    if hit end of list after a negated item
992                  FAIL  if expansion force-failed
993                  FAIL  if matched a negated item
994                  FAIL  if hit end of list after a non-negated item
995                  DEFER if a lookup deferred
996 */
997
998 int
999 match_isinlist(const uschar *s, const uschar **listptr, int sep,
1000    tree_node **anchorptr,
1001   unsigned int *cache_bits, int type, BOOL caseless, const uschar **valueptr)
1002 {
1003 unsigned int *local_cache_bits = cache_bits;
1004 check_string_block cb;
1005 cb.origsubject = s;
1006 cb.subject = caseless ? string_copylc(s) : string_copy(s);
1007 cb.flags = caseless ? MCS_PARTIAL+MCS_CASELESS : MCS_PARTIAL;
1008 switch (type & ~MCL_NOEXPAND)
1009   {
1010   case MCL_DOMAIN:      cb.flags |= MCS_AT_SPECIAL;     /*FALLTHROUGH*/
1011   case MCL_LOCALPART:   cb.expand_setup = 0;                            break;
1012   default:              cb.expand_setup = sep > UCHAR_MAX ? 0 : -1;     break;
1013   }
1014 if (valueptr) *valueptr = NULL;
1015 return  match_check_list(listptr, sep, anchorptr, &local_cache_bits,
1016   check_string, &cb, type, s, valueptr);
1017 }
1018
1019
1020
1021 /*************************************************
1022 *    Match address to single address-list item   *
1023 *************************************************/
1024
1025 /* This function matches an address to an item from an address list. It is
1026 called from match_address_list() via match_check_list(). That is why most of
1027 its arguments are in an indirect block.
1028
1029 Arguments:
1030   arg            the argument block (see below)
1031   pattern        the pattern to match
1032   valueptr       where to return a value
1033   error          for error messages (not used in this function; it never
1034                    returns ERROR)
1035
1036 The argument block contains:
1037   address        the start of the subject address; when called from retry.c
1038                    it may be *@domain if the local part isn't relevant
1039   origaddress    the original, un-case-forced address (not used here, but used
1040                    in match_check_list() when +caseful is encountered)
1041   expand_setup   controls setting up of $n variables
1042   caseless       TRUE for caseless local part matching
1043
1044 Returns:         OK     for a match
1045                  FAIL   for no match
1046                  DEFER  if a lookup deferred
1047 */
1048
1049 static int
1050 check_address(void * arg, const uschar * pattern, const uschar ** valueptr,
1051   uschar ** error)
1052 {
1053 check_address_block * cb = (check_address_block *)arg;
1054 check_string_block csb;
1055 int rc;
1056 int expand_inc = 0;
1057 unsigned int * null = NULL;
1058 const uschar * listptr;
1059 uschar * subject = cb->address;
1060 const uschar * s;
1061 uschar * pdomain, * sdomain;
1062 uschar * value = NULL;
1063
1064 DEBUG(D_lists) debug_printf_indent("address match test: subject=%s pattern=%s\n",
1065   subject, pattern);
1066
1067 /* Find the subject's domain */
1068
1069 sdomain = Ustrrchr(subject, '@');
1070
1071 /* The only case where a subject may not have a domain is if the subject is
1072 empty. Otherwise, a subject with no domain is a serious configuration error. */
1073
1074 if (!sdomain && *subject)
1075   {
1076   log_write(0, LOG_MAIN|LOG_PANIC, "no @ found in the subject of an "
1077     "address list match: subject=\"%s\" pattern=\"%s\"", subject, pattern);
1078   return FAIL;
1079   }
1080
1081 /* Handle a regular expression, which must match the entire incoming address.
1082 This may be the empty address. */
1083
1084 if (*pattern == '^')
1085   return match_check_string(subject, pattern, cb->expand_setup,
1086             cb->flags | MCS_PARTIAL, NULL);
1087
1088 /* Handle a pattern that is just a lookup. Skip over possible lookup names
1089 (letters, digits, hyphens). Skip over a possible * or *@ at the end. Then we
1090 must have a semicolon for it to be a lookup. */
1091
1092 for (s = pattern; isalnum(*s) || *s == '-'; s++) ;
1093 if (*s == '*') s++;
1094 if (*s == '@') s++;
1095
1096 /* If it is a straight lookup, do a lookup for the whole address. This may be
1097 the empty address. Partial matching doesn't make sense here, so we ignore it,
1098 but write a panic log entry. However, *@ matching will be honoured. */
1099
1100 if (*s == ';')
1101   {
1102   if (Ustrncmp(pattern, "partial-", 8) == 0)
1103     log_write(0, LOG_MAIN|LOG_PANIC, "partial matching is not applicable to "
1104       "whole-address lookups: ignored \"partial-\" in \"%s\"", pattern);
1105   return match_check_string(subject, pattern, -1, cb->flags, valueptr);
1106   }
1107
1108 /* For the remaining cases, an empty subject matches only an empty pattern,
1109 because other patterns expect to have a local part and a domain to match
1110 against. */
1111
1112 if (!*subject) return *pattern ? FAIL : OK;
1113
1114 /* If the pattern starts with "@@" we have a split lookup, where the domain is
1115 looked up to obtain a list of local parts. If the subject's local part is just
1116 "*" (called from retry) the match always fails. */
1117
1118 if (pattern[0] == '@' && pattern[1] == '@')
1119   {
1120   int watchdog = 50;
1121   uschar *list, *ss;
1122
1123   if (sdomain == subject + 1 && *subject == '*') return FAIL;
1124
1125   /* Loop for handling chains. The last item in any list may be of the form
1126   ">name" in order to chain on to another list. */
1127
1128   for (const uschar * key = sdomain + 1; key && watchdog-- > 0; )
1129     {
1130     int sep = 0;
1131
1132     if ((rc = match_check_string(key, pattern + 2, -1, MCS_PARTIAL, CUSS &list))
1133         != OK)
1134       return rc;
1135
1136     /* Check for chaining from the last item; set up the next key if one
1137     is found. */
1138
1139     ss = Ustrrchr(list, ':');
1140     if (!ss) ss = list; else ss++;
1141     Uskip_whitespace(&ss);
1142     if (*ss == '>')
1143       {
1144       *ss++ = 0;
1145       Uskip_whitespace(&ss);
1146       key = string_copy(ss);
1147       }
1148     else key = NULL;
1149
1150     /* Look up the local parts provided by the list; negation is permitted.
1151     If a local part has to begin with !, a regex can be used. */
1152
1153     while ((ss = string_nextinlist(CUSS &list, &sep, NULL, 0)))
1154       {
1155       int local_yield;
1156
1157       if (*ss == '!')
1158         {
1159         local_yield = FAIL;
1160         while (isspace((*(++ss))));
1161         }
1162       else local_yield = OK;
1163
1164       *sdomain = 0;
1165       rc = match_check_string(subject, ss, -1, cb->flags + MCS_PARTIAL, valueptr);
1166       *sdomain = '@';
1167
1168       switch(rc)
1169         {
1170         case OK:
1171         return local_yield;
1172
1173         case DEFER:
1174         return DEFER;
1175         }
1176       }
1177     }
1178
1179   /* End of chain loop; panic if too many times */
1180
1181   if (watchdog <= 0)
1182     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Loop detected in lookup of "
1183       "local part of %s in %s", subject, pattern);
1184
1185   /* Otherwise the local part check has failed, so the whole match
1186   fails. */
1187
1188   return FAIL;
1189   }
1190
1191
1192 /* We get here if the pattern is not a lookup or a regular expression. If it
1193 contains an @ there is both a local part and a domain. */
1194
1195 if ((pdomain = Ustrrchr(pattern, '@')))
1196   {
1197   int pllen, sllen;
1198
1199   /* If the domain in the pattern is empty or one of the special cases [] or
1200   mx_{any,primary,secondary}, and the local part in the pattern ends in "@",
1201   we have a pattern of the form <something>@@, <something>@@[], or
1202   <something>@@mx_{any,primary,secondary}. These magic "domains" are
1203   automatically interpreted in match_check_string. We just need to arrange that
1204   the leading @ is included in the domain. */
1205
1206   if (pdomain > pattern && pdomain[-1] == '@' &&
1207        (pdomain[1] == 0 ||
1208         Ustrcmp(pdomain+1, "[]") == 0 ||
1209         Ustrcmp(pdomain+1, "mx_any") == 0 ||
1210         Ustrcmp(pdomain+1, "mx_primary") == 0 ||
1211         Ustrcmp(pdomain+1, "mx_secondary") == 0))
1212     pdomain--;
1213
1214   pllen = pdomain - pattern;
1215   sllen = sdomain - subject;
1216
1217   /* Compare the local parts in the subject and the pattern */
1218
1219   if (*pattern == '*')
1220     {
1221     int cllen = pllen - 1;
1222     if (sllen < cllen) return FAIL;
1223     if (cb->flags & MCS_CASELESS
1224         ? strncmpic(subject+sllen-cllen, pattern + 1, cllen) != 0
1225         : Ustrncmp(subject+sllen-cllen, pattern + 1, cllen) != 0)
1226         return FAIL;
1227     if (cb->expand_setup > 0)
1228       {
1229       expand_nstring[cb->expand_setup] = subject;
1230       expand_nlength[cb->expand_setup] = sllen - cllen;
1231       expand_inc = 1;
1232       }
1233     value = string_copyn(pattern + 1, cllen);
1234     }
1235   else
1236     {
1237     if (sllen != pllen) return FAIL;
1238     if (cb->flags & MCS_CASELESS
1239         ? strncmpic(subject, pattern, sllen) != 0
1240         : Ustrncmp(subject, pattern, sllen) != 0) return FAIL;
1241     }
1242     value = string_copyn(pattern, sllen);
1243   }
1244
1245 /* If the local part matched, or was not being checked, check the domain using
1246 the generalized function, which supports file lookups (which may defer). The
1247 original code read as follows:
1248
1249   return match_check_string(sdomain + 1,
1250       pdomain ? pdomain + 1 : pattern,
1251       cb->expand_setup + expand_inc, cb->flags, NULL);
1252
1253 This supported only literal domains and *.x.y patterns. In order to allow for
1254 named domain lists (so that you can write, for example, "senders=+xxxx"), it
1255 was changed to use the list scanning function. */
1256
1257 csb.origsubject = sdomain + 1;
1258 csb.subject = cb->flags & MCS_CASELESS
1259   ? string_copylc(sdomain+1) : string_copy(sdomain+1);
1260 csb.expand_setup = cb->expand_setup + expand_inc;
1261 csb.flags = MCS_PARTIAL | MCS_AT_SPECIAL | cb->flags & MCS_CASELESS;
1262
1263 listptr = pdomain ? pdomain + 1 : pattern;
1264 if (valueptr) *valueptr = NULL;
1265
1266   {
1267   const uschar * dvalue = NULL;
1268   rc = match_check_list(
1269     &listptr,                  /* list of one item */
1270     UCHAR_MAX+1,               /* impossible separator; single item */
1271     &domainlist_anchor,        /* it's a domain list */
1272     &null,                     /* ptr to NULL means no caching */
1273     check_string,              /* the function to do one test */
1274     &csb,                      /* its data */
1275     MCL_DOMAIN + MCL_NOEXPAND, /* domain list; don't expand */
1276     csb.subject,               /* string for messages */
1277     &dvalue);                       /* where to pass back lookup data */
1278   if (valueptr && (value || dvalue))
1279     *valueptr = string_sprintf("%s@%s",
1280                   value ? value : US"", dvalue ? dvalue : US"");
1281   }
1282 return rc;
1283 }
1284
1285
1286
1287
1288 /*************************************************
1289 *    Test whether address matches address list   *
1290 *************************************************/
1291
1292 /* This function is given an address and a list of things to match it against.
1293 The list may contain individual addresses, regular expressions, lookup
1294 specifications, and indirection via bare files. Negation is supported. The
1295 address to check can consist of just a domain, which will then match only
1296 domain items or items specified as *@domain.
1297
1298 Domains are always lower cased before the match. Local parts are also lower
1299 cased unless "caseless" is false. The work of actually scanning the list is
1300 done by match_check_list(), with an appropriate block of arguments and a
1301 callback to check_address(). During caseless matching, it will recognize
1302 +caseful and revert to caseful matching.
1303
1304 Arguments:
1305   address         address to test
1306   caseless        TRUE to start in caseless state
1307   expand          TRUE to allow list expansion
1308   listptr         list to check against
1309   cache_bits      points to cache bits for named address lists, or NULL
1310   expand_setup    controls setting up of $n variables - passed through
1311                   to check_address (q.v.)
1312   sep             separator character for the list;
1313                   may be 0 to get separator from the list;
1314                   may be UCHAR_MAX+1 for one-item list
1315   valueptr        where to return a lookup value, or NULL
1316
1317 Returns:          OK    for a positive match, or end list after a negation;
1318                   FAIL  for a negative match, or end list after non-negation;
1319                   DEFER if a lookup deferred
1320 */
1321
1322 int
1323 match_address_list(const uschar *address, BOOL caseless, BOOL expand,
1324   const uschar **listptr, unsigned int *cache_bits, int expand_setup, int sep,
1325   const uschar **valueptr)
1326 {
1327 check_address_block ab;
1328 unsigned int *local_cache_bits = cache_bits;
1329 int len;
1330
1331 /* RFC 2505 recommends that for spam checking, local parts should be caselessly
1332 compared. Therefore, Exim now forces the entire address into lower case here,
1333 provided that "caseless" is set. (It is FALSE for calls for matching rewriting
1334 patterns.) Otherwise just the domain is lower cases. A magic item "+caseful" in
1335 the list can be used to restore a caseful copy of the local part from the
1336 original address.
1337 Limit the subject address size to avoid mem-exhaustion attacks.  The size chosen
1338 is historical (we used to use big_buffer here). */
1339
1340 if ((len = Ustrlen(address)) > BIG_BUFFER_SIZE) len = BIG_BUFFER_SIZE;
1341 ab.address = string_copyn(address, len);
1342
1343 for (uschar * p = ab.address + len - 1; p >= ab.address; p--)
1344   {
1345   if (!caseless && *p == '@') break;
1346   *p = tolower(*p);
1347   }
1348
1349 /* If expand_setup is zero, we need to set up $0 to the whole thing, in
1350 case there is a match. Can't use the built-in facilities of match_check_string
1351 (via check_address), as we may just be calling that for part of the address
1352 (the domain). */
1353
1354 if (expand_setup == 0)
1355   {
1356   expand_nstring[0] = string_copy(address);
1357   expand_nlength[0] = Ustrlen(address);
1358   expand_setup++;
1359   }
1360
1361 /* Set up the data to be passed ultimately to check_address. */
1362
1363 ab.origaddress = address;
1364 /* ab.address is above */
1365 ab.expand_setup = expand_setup;
1366 ab.flags = caseless ? MCS_CASELESS : 0;
1367
1368 return match_check_list(listptr, sep, &addresslist_anchor, &local_cache_bits,
1369   check_address, &ab, MCL_ADDRESS + (expand ? 0 : MCL_NOEXPAND), address,
1370     valueptr);
1371 }
1372
1373 /* Simpler version of match_address_list; always caseless, expanding,
1374 no cache bits, no value-return.
1375
1376 Arguments:
1377   address         address to test
1378   listptr         list to check against
1379   sep             separator character for the list;
1380                   may be 0 to get separator from the list;
1381                   may be UCHAR_MAX+1 for one-item list
1382
1383 Returns:          OK    for a positive match, or end list after a negation;
1384                   FAIL  for a negative match, or end list after non-negation;
1385                   DEFER if a lookup deferred
1386 */
1387
1388 int
1389 match_address_list_basic(const uschar *address, const uschar **listptr, int sep)
1390 {
1391 return match_address_list(address, TRUE, TRUE, listptr, NULL, -1, sep, NULL);
1392 }
1393
1394 /* End of match.c */