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