tidying
[exim.git] / src / src / rewrite.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2021 - 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 concerned with rewriting headers */
11
12
13 #include "exim.h"
14
15 /* Names for testing rewriting */
16
17 static const char *rrname[] = {
18   "  sender",
19   "    from",
20   "      to",
21   "      cc",
22   "     bcc",
23   "reply-to",
24   "env-from",
25   "  env-to"
26 };
27
28 /* Structure and table for finding source of address for debug printing */
29
30 typedef struct where_list_block {
31   int bit;
32   const uschar *string;
33 } where_list_block;
34
35 static where_list_block where_list[] = {
36   { rewrite_sender,  CUS"sender:" },
37   { rewrite_from,    CUS"from:" },
38   { rewrite_to,      CUS"to:" },
39   { rewrite_cc,      CUS"cc:" },
40   { rewrite_bcc,     CUS"bcc:" },
41   { rewrite_replyto, CUS"reply-to:" },
42   { rewrite_envfrom, CUS"env-from" },
43   { rewrite_envto,   CUS"env-to" },
44   { rewrite_smtp,    CUS"smtp recipient" },
45   { rewrite_smtp|rewrite_smtp_sender, CUS"smtp sender" }
46 };
47
48 static int where_list_size = sizeof(where_list)/sizeof(where_list_block);
49
50
51
52 /*************************************************
53 *            Ensure an address is qualified      *
54 *************************************************/
55
56 /*
57 Arguments:
58   s              address to check
59   is_recipient   TRUE if a recipient address; FALSE if a sender address
60
61 Returns:         fully-qualified address
62 */
63
64 const uschar *
65 rewrite_address_qualify(const uschar *s, BOOL is_recipient)
66 {
67 return parse_find_at(s)
68   ? s : string_sprintf("%s@%s", s,
69           is_recipient ? qualify_domain_recipient : qualify_domain_sender);
70 }
71
72
73
74 /*************************************************
75 *               Rewrite a single address         *
76 *************************************************/
77
78 /* The yield is the input address if there is no rewriting to be done. Assume
79 the input is a valid address, except in the case of SMTP-time rewriting, which
80 is handled specially. When this function is called while processing filter and
81 forward files, the uid may be that of the user. Ensure it is reset while
82 expanding a replacement, in case that involves file lookups.
83
84 Arguments:
85   s              address to rewrite
86   flag           indicates where this address comes from; it must match the
87                    flags in the rewriting rule
88   whole          if not NULL, set TRUE if any rewriting rule contained the
89                    "whole" bit and it is a header that is being rewritten
90   add_header     if TRUE and rewriting occurs, add an "X-rewrote-xxx" header
91                    if headers are in existence; this should be TRUE only when
92                    a message is being received, not during delivery
93   name           name of header, for use when adding X-rewrote-xxxx
94   rewrite_rules  chain of rewriting rules
95
96 Returns:         new address if rewritten; the input address if no change;
97                  for a header rewrite, if the "whole" bit is set, the entire
98                  rewritten address is returned, not just the active bit.
99 */
100
101 const uschar *
102 rewrite_one(const uschar *s, int flag, BOOL *whole, BOOL add_header, uschar *name,
103   rewrite_rule *rewrite_rules)
104 {
105 const uschar *yield = s;
106 const uschar *subject = s;
107 const uschar *domain = NULL;
108 BOOL done = FALSE;
109 int rule_number = 1;
110 int yield_start = 0, yield_end = 0;
111
112 if (whole) *whole = FALSE;
113
114 /* Scan the rewriting rules, ignoring any without matching flag */
115
116 for (rewrite_rule * rule = rewrite_rules;
117      rule && !done;
118      rule_number++, rule = rule->next) if (rule->flags & flag)
119   {
120   int start, end, pdomain;
121   int count = 0;
122   const uschar * save_localpart;
123   const uschar * save_domain;
124   uschar * error, * new;
125   const uschar * newparsed;
126
127   /* Come back here for a repeat after a successful rewrite. We do this
128   only so many times. */
129
130   REPEAT_RULE:
131
132   /* If this is an SMTP-time rewrite, the pattern must be a regex and
133   the subject may have any structure. No local part or domain variables
134   can be set for the expansion. We expand the pattern in order to be consistent
135   with the other kinds of rewrite, where expansion happens inside
136   match_address_list(). */
137
138   if (flag & rewrite_smtp)
139     {
140     BOOL textonly_re;
141     const uschar * key = expand_string_2(rule->key, &textonly_re);
142     if (!key)
143       {
144       if (!f.expand_string_forcedfail)
145         log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand \"%s\" while "
146           "checking for SMTP rewriting: %s", rule->key, expand_string_message);
147       continue;
148       }
149     if (match_check_string(subject, key, 0,
150       textonly_re ? MCS_CACHEABLE | MCS_PARTIAL : MCS_PARTIAL, NULL) != OK)
151       continue;
152     new = expand_string(rule->replacement);
153     }
154
155   /* All other rewrites expect the input to be a valid address, so local part
156   and domain variables can be set for expansion. For the first rule, to be
157   applied to this address, domain will be NULL and needs to be set. */
158
159   else
160     {
161     if (!domain) domain = CUstrrchr(subject, '@') + 1;
162
163     /* Use the general function for matching an address against a list (here
164     just one item, so use the "impossible value" separator UCHAR_MAX+1). */
165
166     if (match_address_list(subject, FALSE, TRUE, CUSS &(rule->key), NULL, 0,
167         UCHAR_MAX + 1, NULL) != OK)
168       continue;
169
170     /* The source address matches, and numerical variables have been
171     set up. If the replacement string consists of precisely "*" then no
172     rewriting is required for this address - the behaviour is as for "fail"
173     in the replacement expansion, but assuming the quit flag. */
174
175     if (Ustrcmp(rule->replacement, "*") == 0) break;
176
177     /* Otherwise, expand the replacement string. Set $local_part and $domain to
178     the appropriate values, restoring whatever value they previously had
179     afterwards. */
180
181     save_localpart = deliver_localpart;
182     save_domain = deliver_domain;
183
184     /* We have subject pointing to "localpart@domain" and domain pointing to
185     the domain. Split into local part and domain so that it can be set up as 
186     an expansion variable */
187
188     deliver_localpart = US string_copyn(subject, domain-subject-1);
189     deliver_domain = domain;
190
191     new = expand_string(rule->replacement);
192
193     deliver_localpart = save_localpart;
194     deliver_domain = save_domain;
195     }
196
197   /* If the expansion failed with the "forcedfail" flag, don't generate
198   an error - just give up on this rewriting rule. If the "q" flag is set,
199   give up altogether. For other expansion failures we have a configuration
200   error. */
201
202   if (!new)
203     {
204     if (f.expand_string_forcedfail)
205       { if (rule->flags & rewrite_quit) break; else continue; }
206
207     expand_string_message = expand_hide_passwords(expand_string_message);
208
209     log_write(0, LOG_MAIN|LOG_PANIC, "Expansion of %s failed while rewriting: "
210       "%s", rule->replacement, expand_string_message);
211     break;
212     }
213
214   /* Check the what has been generated is a valid RFC 2822 address. Only
215   envelope from or SMTP sender is permitted to be rewritten as <>.*/
216
217   newparsed = parse_extract_address(new, &error, &start, &end, &pdomain,
218     flag == rewrite_envfrom || flag == (rewrite_smtp|rewrite_smtp_sender));
219
220   if (!newparsed)
221     {
222     log_write(0, LOG_MAIN|LOG_PANIC, "Rewrite of %s yielded unparseable "
223       "address: %s in address %s", subject, error, new);
224     break;   /* Give up on this address */
225     }
226
227   /* A non-null unqualified address can be qualified if requested. Otherwise,
228   this is an error unless it's the empty address in circumstances where that is
229   permitted. */
230
231   if (pdomain == 0 && (*newparsed != 0 ||
232       (flag != rewrite_envfrom && flag != (rewrite_smtp|rewrite_smtp_sender))))
233     {
234     if (rule->flags & rewrite_qualify)
235       {
236       newparsed = rewrite_address_qualify(newparsed, TRUE);
237       new = string_sprintf("%.*s%s%.*s", start, new, newparsed,
238         Ustrlen(new) - end, new + end);
239       end = start + Ustrlen(newparsed);
240       }
241     else
242       {
243       log_write(0, LOG_MAIN|LOG_PANIC, "Rewrite of %s yielded unqualified "
244         "address \"%s\"", subject, new);
245       break;   /* Give up on this address */
246       }
247     }
248
249   /* We have a validly rewritten address */
250
251   if (LOGGING(address_rewrite) || (debug_selector & D_rewrite) != 0)
252     {
253     const uschar *where = CUS"?";
254
255     for (int i = 0; i < where_list_size; i++)
256       if (flag == where_list[i].bit)
257         {
258         where = where_list[i].string;
259         break;
260         }
261     log_write(L_address_rewrite,
262            LOG_MAIN, "\"%s\" from %s rewritten as \"%s\" by rule %d",
263            yield, where, new, rule_number);
264     }
265
266   /* A header will only actually be added if header_last is non-NULL,
267   i.e. during message reception or delivery, but add_header should not
268   be set TRUE during delivery, as otherwise multiple instances of the header
269   can fill up the -H file and make it embarrassingly large. We don't need
270   to set header_rewritten because the -H file always gets written at the end
271   of message reception. */
272
273   if (add_header)
274     header_add(htype_old, "X-rewrote-%s: %s\n", name, subject);
275
276   /* Handle the case when replacement of the whole address is possible.
277   This happens only when whole is not NULL and we are rewriting a header.
278   If *whole is already TRUE it means that a previous rule had the w
279   flag set and so we must preserve the non-active portion of the current
280   subject unless the current rule also has the w flag set. */
281
282   if (whole && (flag & rewrite_all_headers))
283     {
284     /* Current rule has the w flag set. We must ensure the phrase parts
285     are syntactically valid if they are present. */
286
287     if (rule->flags & rewrite_whole)
288       {
289       if (start > 0 && new[start-1] == '<')
290         {
291         uschar *p1 = new + start - 1;
292         uschar *p2 = new + end + 1;
293         const uschar *pf1, *pf2;
294
295         while (p1 > new && p1[-1] == ' ') p1--;
296         pf1 = parse_fix_phrase(new, p1 - new);
297         while (*p2 == ' ') p2++;
298         pf2 = parse_fix_phrase(p2, Ustrlen(p2));
299
300         start = Ustrlen(pf1) + start + new - p1;
301         end = start + Ustrlen(newparsed);
302         new = string_sprintf("%s%.*s%s", pf1, (int)(p2 - p1), p1, pf2);
303         }
304
305       /* Now accept the whole thing */
306
307       yield = new;
308       yield_start = start;
309       yield_end = end;
310       subject = newparsed;
311       *whole = TRUE;
312       }
313
314     /* Current rule does not have the w flag set; if not previously
315     done any whole rewriting, behave in non-whole manner. */
316
317     else if (!*whole) goto NEVER_WHOLE;
318
319     /* Current rule does not have the w flag set, but a previous
320     rule did rewrite the whole address. Thus yield and subject will be
321     different. Preserve the previous non-active part of the address. */
322
323     else
324       {
325       subject = newparsed;
326       new = string_sprintf("%.*s%s%n%s",
327          yield_start, yield, subject, &end, yield + yield_end);
328       yield_end = end;
329       yield = new;
330       }
331     }
332
333   /* Rule just rewrites active part, or handling an envelope. This
334   code is obeyed only when all rules so far have not done "whole"
335   replacement. */
336
337   else
338     {
339     NEVER_WHOLE:
340     subject = yield = newparsed;
341     }
342
343   domain = NULL;    /* Reset for next rule */
344
345   /* If no further rewrites are to be done, set the done flag. This allows
346   repeats of the current rule if configured before breaking the loop. */
347
348   if (rule->flags & rewrite_quit) done = TRUE;
349
350   /* Allow the current rule to be applied up to 10 times if
351   requested. */
352
353   if (rule->flags & rewrite_repeat)
354     {
355     if (count++ < 10) goto REPEAT_RULE;
356     log_write(0, LOG_MAIN|LOG_PANIC, "rewrite rule repeat ignored after 10 "
357       "times");
358     }
359   }
360
361 /* Unset expansion numeric variables, and that's it. */
362
363 expand_nmax = -1;
364 return yield;
365 }
366
367
368
369 /*************************************************
370 *         Ensure qualification and rewrite       *
371 *************************************************/
372
373 /* This function is called for envelope addresses, the boolean specifying
374 whether a recipient or a sender. It must first of all ensure the address is
375 fully qualified, and then apply any relevant re-writing rules. The add-header
376 flag causes a header to be added, recording the old address. This is marked
377 "old", so that it is never transported anywhere; it exists for local checking
378 and debugging purposes.
379
380 Arguments:
381   s              the address to be considered
382   is_recipient   TRUE for recipient addresses; FALSE otherwise
383   add_header     add "X-rewrote-xxx" header when rewriting; this is
384                    set TRUE only for calls from the reception functions
385   rewrite_rules  points to chain of rewrite rules
386   existflags     bits indicating which headers there are rewrites for
387                  (just an optimisation)
388
389 Returns:         possibly rewritten address
390 */
391
392 const uschar *
393 rewrite_address(const uschar *s, BOOL is_recipient, BOOL add_header,
394   rewrite_rule *rewrite_rules, int existflags)
395 {
396 int flag = is_recipient ? rewrite_envto : rewrite_envfrom;
397
398 s = rewrite_address_qualify(s, is_recipient);
399 if (existflags & flag)
400   {
401   const uschar *new = rewrite_one(s, flag, NULL, add_header, is_recipient?
402     US"original-recipient" : US"sender", rewrite_rules);
403   if (new != s) s = new;
404   }
405 return s;
406 }
407
408
409
410 /*************************************************
411 *    Qualify and possibly rewrite one header     *
412 *************************************************/
413
414 /* This is called only from rewrite_header() below, either when reading a
415 message. or when routing, in order to rewrite addresses that get changed by a
416 router. This is normally the addition of full qualification to a partial
417 domain. The first rewriting rule in this case is "change routed_old into
418 routed_new", and it applies to all header lines that contain addresses. Then
419 header-specific rewriting rules are applied.
420
421 Before rewriting can be done, addresses without domains have to be qualified.
422 This should only be done for messages from "local" senders. This is a difficult
423 concept to pin down, what with the use of SMTP both as a submission and as a
424 transmission protocol. Exim normally requires incoming SMTP to contain fully-
425 qualified addresses, but there are options to permit unqualified ones from
426 certain hosts. For those hosts only, addresses in headers can also be
427 qualified. For other hosts, unqualified addresses in headers do not get touched
428 in any way. For locally sourced messages, unqualified addresses always get
429 qualified, except when -bnq is used to explicitly suppress this.
430
431 Arguments:
432   h              pointer to header line block
433   flag           indicates which header this is
434   routed_old     if not NULL, this is a rewrite caused by a router, changing
435                    this domain into routed_new
436   routed_new     new routed domain if routed_old is not NULL
437   rewrite_rules  points to chain of rewriting rules
438   existflags     bits indicating which rewrites exist
439   replace        if TRUE, insert the new header in the chain after the old
440                    one, and mark the old one "replaced"
441
442 Returns:         NULL if header unchanged; otherwise the rewritten header
443 */
444
445 static header_line *
446 rewrite_one_header(header_line *h, int flag,
447   const uschar *routed_old, const uschar *routed_new,
448   rewrite_rule *rewrite_rules, int existflags, BOOL replace)
449 {
450 int lastnewline = 0;
451 header_line * newh = NULL;
452 rmark function_reset_point = store_mark();
453 uschar * s = Ustrchr(h->text, ':') + 1;
454
455 Uskip_whitespace(&s);
456
457 DEBUG(D_rewrite)        /* The header text includes the trailing newline */
458   debug_printf_indent("rewrite_one_header: type=%c:\n  %s", h->type, h->text);
459
460 f.parse_allow_group = TRUE;     /* Allow group syntax */
461
462 /* Loop for multiple addresses in the header. We have to go through them all
463 in case any need qualifying, even if there's no rewriting. Pathological headers
464 may have thousands of addresses in them, so cause the store to be reset for
465 any that don't actually get rewritten. We also play silly games for those that
466 _are_ rewritten so as to avoid runaway store usage for these kinds of header.
467 We want to avoid keeping store for any intermediate versions. */
468
469 while (*s)
470   {
471   uschar * sprev = s;
472   uschar * ss = parse_find_address_end(s, FALSE), * ss1 = ss;
473   uschar * recipient, * new;
474   rmark loop_reset_point = store_mark();
475   uschar * errmess = NULL;
476   BOOL changed = FALSE;
477   uschar terminator = *ss;
478   int start, end, domain;
479
480   /* If we hit the end of the header, trim trailing newline and whitespace */
481
482   if (!terminator)
483     {
484     while (ss1 > s && isspace(ss1[-1])) ss1--;
485     terminator = *ss1;
486     }
487
488   /* Temporarily terminate the string at this point, and extract the
489   operative address within. Then put back the terminator and prepare for
490   the next address, saving the start of the old one. */
491
492   *ss1 = '\0';
493   recipient = parse_extract_address(s, &errmess, &start, &end, &domain, FALSE);
494   *ss1 = terminator;
495   s = ss + (*ss ? 1 : 0);
496   Uskip_whitespace(&s);
497
498   /* There isn't much we can do for syntactic disasters at this stage.
499   Pro tem (possibly for ever) ignore them.
500   If we got nothing, then there was any sort of error: non-parsable address,
501   empty address, overlong addres. Sometimes the result matters, sometimes not.
502   It seems this function is called for *any* header we see. */
503
504   if (!recipient)
505     {
506     /* Log unparesable addresses in the header. Slightly ugly because a
507     null output from the extract can also result from a header without an
508     address, "To: undisclosed recpients:;" being the classic case. Ignore
509     this one and carry on. */
510
511     if (Ustrcmp(errmess, "empty address") != 0)
512       log_write(0, LOG_MAIN, "qualify/rewrite: %s", errmess);
513
514     loop_reset_point = store_reset(loop_reset_point);
515     continue;
516     }
517
518   /* If routed_old is not NULL, this is a rewrite caused by a router,
519   consisting of changing routed_old into routed_new, and applying to all
520   headers. If the header address has no domain, it is excluded, since a router
521   rewrite affects domains only. The new value should always be fully qualified,
522   but it may be something that has an explicit re-write rule set, so we need to
523   check the configured rules subsequently as well. (Example: there's an
524   explicit rewrite turning *.foo.com into foo.com, and an address is supplied
525   as abc@xyz, which the DNS lookup turns into abc@xyz.foo.com). However, if no
526   change is made here, don't bother carrying on. */
527
528   if (routed_old)
529     {
530     if (domain <= 0 || strcmpic(recipient+domain, routed_old) != 0) continue;
531     recipient[domain-1] = 0;
532     new = string_sprintf("%s@%s", recipient, routed_new);
533     DEBUG(D_rewrite)
534       {
535       recipient[domain-1] = '@';
536       debug_printf("%s rewritten by router as %s\n", recipient, new);
537       }
538     recipient = new;
539     changed = TRUE;
540     }
541
542   /* This is not a router-inspired rewrite. Ensure the address is fully
543   qualified if that is permitted. If an unqualified address was received
544   from a host that isn't listed, do not continue rewriting this address.
545   Sender, From or Reply-To headers are treated as senders, the rest as
546   recipients. This matters only when there are different qualify strings. */
547
548   else
549     {
550     BOOL is_recipient =
551       (flag & (rewrite_sender | rewrite_from | rewrite_replyto)) == 0;
552     /* deconst ok as recipient was notconst */
553     new = US rewrite_address_qualify(recipient, is_recipient);
554     changed = (new != recipient);
555     recipient = new;
556
557     /* Can only qualify if permitted; if not, no rewrite. */
558
559     if (changed && ((is_recipient && !f.allow_unqualified_recipient) ||
560                     (!is_recipient && !f.allow_unqualified_sender)))
561       {
562       loop_reset_point = store_reset(loop_reset_point);
563       continue;
564       }
565     }
566
567   /* If there are rewrite rules for this type of header, apply
568   them. This test is just for efficiency, to save scanning the rules
569   in cases when nothing is going to change. If any rewrite rule had the
570   "whole" flag set, adjust the pointers so that the whole address gets
571   replaced, except possibly a final \n. */
572
573   if (existflags & flag)
574     {
575     BOOL whole;
576     /* deconst ok as recipient was notconst */
577     new = US rewrite_one(recipient, flag, &whole, FALSE, NULL, rewrite_rules);
578     if (new != recipient)
579       {
580       changed = TRUE;
581       if (whole)
582         {
583         start = 0;
584         end = ss - sprev;
585         if (sprev[end-1] == '\n') end--;
586         }
587       }
588     }
589
590   /* If nothing has changed, lose all dynamic store obtained in this loop, and
591   move on to the next address. We can't reset to the function start store
592   point, because we may have a rewritten line from a previous time round the
593   loop. */
594
595   if (!changed)
596     loop_reset_point = store_reset(loop_reset_point);
597
598   /* If the address has changed, create a new header containing the
599   rewritten address. We do not need to set the chain pointers at this
600   stage. We want to avoid using more and more memory if the header is very long
601   and contains lots and lots of rewritten addresses. Therefore, we build the
602   new text string in malloc store, then at the end we reset dynamic store
603   before copying the new header to a new block (and then freeing the malloc
604   block). The header must end up in dynamic store so that it's freed at the end
605   of receiving a message. */
606
607   else
608     {
609     int remlen;
610     int newlen = Ustrlen(new);
611     int oldlen = end - start;
612
613     header_line * prev = newh ? newh : h;
614     uschar * newt = store_get_perm(prev->slen - oldlen + newlen + 4, GET_TAINTED);
615     uschar * newtstart = newt;
616
617     int type = prev->type;
618     int slen = prev->slen - oldlen + newlen;
619
620     /* Build the new header text by copying the old and putting in the
621     replacement. This process may make the header substantially longer
622     than it was before - qualification of a list of bare addresses can
623     often do this - so we stick in a newline after the re-written address
624     if it has increased in length and ends more than 40 characters in. In
625     fact, the code is not perfect, since it does not scan for existing
626     newlines in the header, but it doesn't seem worth going to that
627     amount of trouble. */
628
629     Ustrncpy(newt, prev->text, sprev - prev->text + start);
630     newt += sprev - prev->text + start;
631     *newt = 0;
632     Ustrcat(newt, new);
633     newt += newlen;
634     remlen = s - (sprev + end);
635     if (remlen > 0)
636       {
637       Ustrncpy(newt, sprev + end, remlen);
638       newt += remlen;
639       *newt = 0;
640       }
641
642     /* Must check that there isn't a newline here anyway; in particular, there
643     will be one at the very end of the header, where we DON'T want to insert
644     another one! The pointer s has been skipped over white space, so just
645     look back to see if the last non-space-or-tab was a newline. */
646
647     if (newlen > oldlen && newt - newtstart - lastnewline > 40)
648       {
649       uschar *p = s - 1;
650       while (p >= prev->text && (*p == ' ' || *p == '\t')) p--;
651       if (*p != '\n')
652         {
653         lastnewline = newt - newtstart;
654         Ustrcat(newt, US"\n\t");
655         slen += 2;
656         }
657       }
658
659     /* Finally, the remaining unprocessed addresses, if any. */
660
661     Ustrcat(newt, s);
662
663     DEBUG(D_rewrite) debug_printf("newlen=%d newtype=%c newtext:\n%s",
664       slen, type, newtstart);
665
666     /* Compute the length of the rest of the header line before we possibly
667     flatten a previously rewritten copy. */
668
669     remlen = (s - prev->text) - oldlen + newlen;
670
671     /* We have the new text in a malloc block. That enables us to release all
672     the memory that has been used, back to the point at which the function was
673     entered. Then set up a new header in dynamic store. This will override a
674     rewritten copy from a previous time round this loop. */
675
676     store_reset(function_reset_point);
677     function_reset_point = store_mark();
678     newh = store_get(sizeof(header_line), GET_UNTAINTED);
679     newh->type = type;
680     newh->slen = slen;
681     newh->text = string_copyn(newtstart, slen);
682
683     /* Set up for scanning the rest of the header */
684
685     s = newh->text + remlen;
686     DEBUG(D_rewrite) debug_printf("remainder: %s", *s ? s : US"\n");
687     }
688   }
689
690 f.parse_allow_group = FALSE;  /* Reset group flags */
691 f.parse_found_group = FALSE;
692
693 /* If a rewrite happened and "replace" is true, put the new header into the
694 chain following the old one, and mark the old one as replaced. */
695
696 if (newh && replace)
697   {
698   newh->next = h->next;
699   if (!newh->next) header_last = newh;
700   h->type = htype_old;
701   h->next = newh;
702   }
703
704 return newh;
705 }
706
707
708
709
710 /*************************************************
711 *              Rewrite a header line             *
712 *************************************************/
713
714 /* This function may be passed any old header line. It must detect those which
715 contain addresses, then then apply any rewriting rules that apply. If
716 routed_old is NULL, only the configured rewriting rules are consulted.
717 Otherwise, the rewriting rule is "change routed_old into routed_new", and it
718 applies to all header lines that contain addresses. Then header-specific
719 rewriting rules are applied.
720
721 The old header line is flagged as "old". Old headers are saved on the spool for
722 debugging but are never sent to any recipients.
723
724 Arguments:
725   h              header line to rewrite
726   routed_old     if not NULL, this is a rewrite caused by a router, changing
727                    this domain into routed_new
728   routed_new     new routed domain if routed_old is not NULL
729   rewrite_rules  points to chain of rewrite rules
730   existflags     bits indicating which rewrites exist
731   replace        if TRUE, the new header is inserted into the header chain
732                     after the old one, and the old one is marked replaced
733
734 Returns:         NULL if header unchanged; otherwise the rewritten header
735 */
736
737 header_line *
738 rewrite_header(header_line *h,
739   const uschar *routed_old, const uschar *routed_new,
740   rewrite_rule *rewrite_rules, int existflags, BOOL replace)
741 {
742 int flag;
743 switch (h->type)
744   {
745   case htype_sender:    flag = rewrite_sender;  break;
746   case htype_from:      flag = rewrite_from;    break;
747   case htype_to:        flag = rewrite_to;      break;
748   case htype_cc:        flag = rewrite_cc;      break;
749   case htype_bcc:       flag = rewrite_bcc;     break;
750   case htype_reply_to:  flag = rewrite_replyto; break;
751   default:              return NULL;
752   }
753 return rewrite_one_header(h, flag, routed_old, routed_new,
754   rewrite_rules, existflags, replace);
755 }
756
757
758
759 /************************************************
760 *            Test rewriting rules               *
761 ************************************************/
762
763 /* Called from the mainline as a result of the -brw option. Test the
764 address for all possible cases.
765
766 Argument: the address to test
767 Returns:  nothing
768 */
769
770 void
771 rewrite_test(const uschar *s)
772 {
773 uschar *recipient, *error;
774 int start, end, domain;
775 BOOL done_smtp = FALSE;
776
777 if (rewrite_existflags == 0)
778   {
779   printf("No rewrite rules are defined\n");
780   return;
781   }
782
783 /* Do SMTP rewrite only if a rule with the S flag exists. Allow <> by
784 pretending it is a sender. */
785
786 if ((rewrite_existflags & rewrite_smtp) != 0)
787   {
788   const uschar * new = rewrite_one(s, rewrite_smtp|rewrite_smtp_sender, NULL,
789     FALSE, US"", global_rewrite_rules);
790   if (new != s)
791     {
792     if (*new == 0)
793       printf("    SMTP: <>\n");
794     else
795       printf("    SMTP: %s\n", new);
796     done_smtp = TRUE;
797     }
798   }
799
800 /* Do the other rewrites only if a rule without the S flag exists */
801
802 if ((rewrite_existflags & ~rewrite_smtp) == 0) return;
803
804 /* Qualify if necessary before extracting the address */
805
806 if (parse_find_at(s) == NULL)
807   s = string_sprintf("%s@%s", s, qualify_domain_recipient);
808
809 recipient = parse_extract_address(s, &error, &start, &end, &domain, FALSE);
810
811 if (!recipient)
812   {
813   if (!done_smtp)
814     printf("Syntax error in %s\n%c%s\n", s, toupper(error[0]), error+1);
815   return;
816   }
817
818 for (int i = 0; i < 8; i++)
819   {
820   BOOL whole = FALSE;
821   int flag = 1 << i;
822   const uschar * new = rewrite_one(recipient, flag, &whole, FALSE, US"",
823     global_rewrite_rules);
824   printf("%s: ", rrname[i]);
825   if (*new == 0)
826     printf("<>\n");
827   else if (whole || (flag & rewrite_all_headers) == 0)
828     printf("%s\n", CS new);
829   else printf("%.*s%s%s\n", start, s, new, s+end);
830   }
831 }
832
833 /* End of rewrite.c */