build: use pkg-config for i18n
[exim.git] / src / src / routers / redirect.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
11 #include "../exim.h"
12
13 #ifdef ROUTER_REDIRECT  /* Remainder of file */
14 #include "rf_functions.h"
15 #include "redirect.h"
16
17
18
19 /* Options specific to the redirect router. */
20 #define LOFF(field) OPT_OFF(redirect_router_options_block, field)
21
22 optionlist redirect_router_options[] = {
23   { "allow_defer",        opt_bit | (RDON_DEFER << 16),
24       LOFF(bit_options) },
25   { "allow_fail",         opt_bit | (RDON_FAIL << 16),
26       LOFF(bit_options) },
27   { "allow_filter",       opt_bit | (RDON_FILTER << 16),
28       LOFF(bit_options) },
29   { "allow_freeze",       opt_bit | (RDON_FREEZE << 16),
30       LOFF(bit_options) },
31   { "check_ancestor",     opt_bool,             LOFF(check_ancestor) },
32   { "check_group",        opt_bool,             LOFF(check_group) },
33   { "check_owner",        opt_bool,             LOFF(check_owner) },
34   { "data",               opt_stringptr,        LOFF(data) },
35   { "directory_transport",opt_stringptr,        LOFF(directory_transport_name) },
36   { "file",               opt_stringptr,        LOFF(file) },
37   { "file_transport",     opt_stringptr,        LOFF(file_transport_name) },
38
39   { "filter_prepend_home",opt_bit | (RDON_PREPEND_HOME << 16),
40       LOFF(bit_options) },
41   { "forbid_blackhole",   opt_bit | (RDON_BLACKHOLE << 16),
42       LOFF(bit_options) },
43   { "forbid_exim_filter", opt_bit | (RDON_EXIM_FILTER << 16),
44       LOFF(bit_options) },
45   { "forbid_file",        opt_bool,
46       LOFF(forbid_file) },
47   { "forbid_filter_dlfunc", opt_bit | (RDON_DLFUNC << 16),
48       LOFF(bit_options) },
49   { "forbid_filter_existstest",  opt_bit | (RDON_EXISTS << 16),
50       LOFF(bit_options) },
51   { "forbid_filter_logwrite",opt_bit | (RDON_LOG << 16),
52       LOFF(bit_options) },
53   { "forbid_filter_lookup", opt_bit | (RDON_LOOKUP << 16),
54       LOFF(bit_options) },
55   { "forbid_filter_perl", opt_bit | (RDON_PERL << 16),
56       LOFF(bit_options) },
57   { "forbid_filter_readfile", opt_bit | (RDON_READFILE << 16),
58       LOFF(bit_options) },
59   { "forbid_filter_readsocket", opt_bit | (RDON_READSOCK << 16),
60       LOFF(bit_options) },
61   { "forbid_filter_reply",opt_bool,
62       LOFF(forbid_filter_reply) },
63   { "forbid_filter_run",  opt_bit | (RDON_RUN << 16),
64       LOFF(bit_options) },
65   { "forbid_include",     opt_bit | (RDON_INCLUDE << 16),
66       LOFF(bit_options) },
67   { "forbid_pipe",        opt_bool,
68       LOFF(forbid_pipe) },
69   { "forbid_sieve_filter",opt_bit | (RDON_SIEVE_FILTER << 16),
70       LOFF(bit_options) },
71   { "forbid_smtp_code",     opt_bool,
72       LOFF(forbid_smtp_code) },
73   { "hide_child_in_errmsg", opt_bool,
74       LOFF( hide_child_in_errmsg) },
75   { "ignore_eacces",      opt_bit | (RDON_EACCES << 16),
76       LOFF(bit_options) },
77   { "ignore_enotdir",     opt_bit | (RDON_ENOTDIR << 16),
78       LOFF(bit_options) },
79
80   { "include_directory",  opt_stringptr,        LOFF( include_directory) },
81   { "modemask",           opt_octint,           LOFF(modemask) },
82   { "one_time",           opt_bool,             LOFF(one_time) },
83   { "owners",             opt_uidlist,          LOFF(owners) },
84   { "owngroups",          opt_gidlist,          LOFF(owngroups) },
85   { "pipe_transport",     opt_stringptr,        LOFF(pipe_transport_name) },
86   { "qualify_domain",     opt_stringptr,        LOFF(qualify_domain) },
87   { "qualify_preserve_domain", opt_bool,        LOFF(qualify_preserve_domain) },
88   { "repeat_use",         opt_bool | opt_public, OPT_OFF(router_instance, repeat_use) },
89   { "reply_transport",    opt_stringptr,        LOFF(reply_transport_name) },
90
91   { "rewrite",            opt_bit | (RDON_REWRITE << 16),
92       LOFF(bit_options) },
93
94   { "sieve_enotify_mailto_owner", opt_stringptr, LOFF(sieve_enotify_mailto_owner) },
95   { "sieve_inbox",        opt_stringptr,        LOFF(sieve_inbox) },
96   { "sieve_subaddress",   opt_stringptr,        LOFF(sieve_subaddress) },
97   { "sieve_useraddress",  opt_stringptr,        LOFF(sieve_useraddress) },
98   { "sieve_vacation_directory", opt_stringptr,  LOFF(sieve_vacation_directory) },
99   { "skip_syntax_errors", opt_bool,             LOFF(skip_syntax_errors) },
100   { "syntax_errors_text", opt_stringptr,        LOFF(syntax_errors_text) },
101   { "syntax_errors_to",   opt_stringptr,        LOFF(syntax_errors_to) }
102 };
103
104 /* Size of the options list. An extern variable has to be used so that its
105 address can appear in the tables drtables.c. */
106
107 int redirect_router_options_count =
108   sizeof(redirect_router_options)/sizeof(optionlist);
109
110
111 #ifdef MACRO_PREDEF
112
113 /* Dummy entries */
114 redirect_router_options_block redirect_router_option_defaults = {0};
115 void redirect_router_init(driver_instance *rblock) {}
116 int redirect_router_entry(router_instance *rblock, address_item *addr,
117   struct passwd *pw, int verify, address_item **addr_local,
118   address_item **addr_remote, address_item **addr_new,
119   address_item **addr_succeed) {return 0;}
120
121 #else   /*!MACRO_PREDEF*/
122
123
124
125 /* Default private options block for the redirect router.
126 Unlisted elements are 0/NULL/FALSE */
127
128 redirect_router_options_block redirect_router_option_defaults = {
129   .modemask = 022,
130   .bit_options = RDO_REWRITE | RDO_PREPEND_HOME,
131   .check_owner = TRUE_UNSET,
132   .check_group = TRUE_UNSET,
133 };
134
135
136
137 /*************************************************
138 *          Initialization entry point            *
139 *************************************************/
140
141 /* Called for each instance, after its options have been read, to enable
142 consistency checks to be done, or anything else that needs to be set up. */
143
144 void
145 redirect_router_init(driver_instance * r)
146 {
147 router_instance * rblock = (router_instance *)r;
148 redirect_router_options_block * ob =
149   (redirect_router_options_block *)(r->options_block);
150
151 /* Either file or data must be set, but not both */
152
153 if ((ob->file == NULL) == (ob->data == NULL))
154   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
155     "%sone of \"file\" or \"data\" must be specified",
156     r->name, ob->file ? "only " : "");
157
158 /* Onetime aliases can only be real addresses. Headers can't be manipulated.
159 The combination of one_time and unseen is not allowed. We can't check the
160 expansion of "unseen" here, but we assume that if it is set to anything other
161 than false, there is likely to be a problem. */
162
163 if (ob->one_time)
164   {
165   ob->forbid_pipe = ob->forbid_file = ob->forbid_filter_reply = TRUE;
166   if (rblock->extra_headers || rblock->remove_headers)
167     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
168       "\"headers_add\" and \"headers_remove\" are not permitted with "
169       "\"one_time\"", r->name);
170   if (rblock->unseen || rblock->expand_unseen)
171     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
172       "\"unseen\" may not be used with \"one_time\"", r->name);
173   }
174
175 /* The defaults for check_owner and check_group depend on other settings. The
176 defaults are: Check the owner if check_local_user or owners is set; check the
177 group if check_local_user is set without a restriction on the group write bit,
178 or if owngroups is set. */
179
180 if (ob->check_owner == TRUE_UNSET)
181   ob->check_owner = rblock->check_local_user ||
182                     (ob->owners && ob->owners[0] != 0);
183
184 if (ob->check_group == TRUE_UNSET)
185   ob->check_group = (rblock->check_local_user && (ob->modemask & 020) == 0) ||
186                     (ob->owngroups != NULL && ob->owngroups[0] != 0);
187
188 /* If explicit qualify domain set, the preserve option is locked out */
189
190 if (ob->qualify_domain && ob->qualify_preserve_domain)
191   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
192     "only one of \"qualify_domain\" or \"qualify_preserve_domain\" must be set",
193     r->name);
194
195 /* If allow_filter is set, either user or check_local_user must be set. */
196
197 if (!rblock->check_local_user &&
198     !rblock->uid_set &&
199     rblock->expand_uid == NULL &&
200     (ob->bit_options & RDO_FILTER) != 0)
201   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n  "
202     "\"user\" or \"check_local_user\" must be set with \"allow_filter\"",
203     r->name);
204 }
205
206
207
208 /*************************************************
209 *       Get errors address and header mods       *
210 *************************************************/
211
212 /* This function is called when new addresses are generated, in order to
213 sort out errors address and header modifications. We put the errors address
214 into the parent address (even though it is never used from there because that
215 address is never transported) so that it can be retrieved if any of the
216 children gets routed by an "unseen" router. The clone of the child that is
217 passed on must have the original errors_address value.
218
219 Arguments:
220   rblock               the router control block
221   addr                 the address being routed
222   verify               v_none/v_recipient/v_sender/v_expn
223   addr_prop            point to the propagated block, which is where the
224                          new values are to be placed
225
226 Returns:    the result of rf_get_errors_address() or rf_get_munge_headers(),
227             which is either OK or DEFER
228 */
229
230 static int
231 sort_errors_and_headers(router_instance *rblock, address_item *addr,
232   int verify, address_item_propagated *addr_prop)
233 {
234 int frc = rf_get_errors_address(addr, rblock, verify,
235   &addr_prop->errors_address);
236 if (frc != OK) return frc;
237 addr->prop.errors_address = addr_prop->errors_address;
238 return rf_get_munge_headers(addr, rblock, &addr_prop->extra_headers,
239   &addr_prop->remove_headers);
240 }
241
242
243
244 /*************************************************
245 *    Process a set of generated new addresses    *
246 *************************************************/
247
248 /* This function sets up a set of newly generated child addresses and puts them
249 on the new address chain. Copy in the uid, gid and permission flags for use by
250 pipes and files, set the parent, and "or" its af_ignore_error flag. Also record
251 the setting for any starting router.
252
253 If the generated address is the same as one of its ancestors, and the
254 check_ancestor flag is set, do not use this generated address, but replace it
255 with a copy of the input address. This is to cope with cases where A is aliased
256 to B and B has a .forward file pointing to A, though it is usually set on the
257 forwardfile rather than the aliasfile. We can't just pass on the old
258 address by returning FAIL, because it must act as a general parent for
259 generated addresses, and only get marked "done" when all its children are
260 delivered.
261
262 Arguments:
263   rblock                  router block
264   addr_new                new address chain
265   addr                    original address
266   generated               list of generated addresses
267   addr_prop               the propagated block, containing the errors_address,
268                             header modification stuff, and address_data
269   ugidptr                 points to uid/gid data for files, pipes, autoreplies
270   pw                      password entry, set if ob->check_local_user is TRUE
271
272 Returns:         nothing
273 */
274
275 static void
276 add_generated(router_instance *rblock, address_item **addr_new,
277   address_item *addr, address_item *generated,
278   address_item_propagated *addr_prop, ugid_block *ugidptr, struct passwd *pw)
279 {
280 redirect_router_options_block * ob =
281   (redirect_router_options_block *)(rblock->drinst.options_block);
282
283 while (generated)
284   {
285   address_item * next = generated, * parent;
286   const uschar * errors_address = next->prop.errors_address;
287
288   generated = next->next;
289   next->parent = addr;
290   next->start_router = rblock->redirect_router;
291   if (addr->child_count == USHRT_MAX)
292     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router generated more than %d "
293       "child addresses for <%s>", rblock->drinst.name, USHRT_MAX, addr->address);
294   addr->child_count++;
295
296   next->next = *addr_new;
297   *addr_new = next;
298
299   /* Don't do the "one_time" thing for the first pass of a 2-stage queue run. */
300
301   if (ob->one_time && !f.queue_2stage)
302     {
303     for (parent = addr; parent->parent; parent = parent->parent) ;
304     next->onetime_parent = parent->address;
305     }
306
307   if (ob->hide_child_in_errmsg) setflag(next, af_hide_child);
308
309   /* If check_ancestor is set, we want to know if any ancestor of this address
310   is the address we are about to generate. The check must be done caselessly
311   unless the ancestor was routed by a case-sensitive router. */
312
313   if (ob->check_ancestor)
314     for (parent = addr; parent; parent = parent->parent)
315       if ((parent->router && parent->router->caseful_local_part
316            ? Ustrcmp(next->address, parent->address)
317            : strcmpic(next->address, parent->address)
318           ) == 0)
319         {
320         DEBUG(D_route) debug_printf("generated parent replaced by child\n");
321         next->address = string_copy(addr->address);
322         break;
323         }
324
325   /* A user filter may, under some circumstances, set up an errors address.
326   If so, we must take care to re-instate it when we copy in the propagated
327   data so that it overrides any errors_to setting on the router. */
328
329     {
330     BOOL ignore_error = next->prop.ignore_error;
331     next->prop = *addr_prop;
332     next->prop.ignore_error = ignore_error || addr->prop.ignore_error;
333     }
334   if (errors_address) next->prop.errors_address = errors_address;
335
336   /* For pipes, files, and autoreplies, record this router as handling them,
337   because they don't go through the routing process again. Then set up uid,
338   gid, home and current directories for transporting. */
339
340   if (testflag(next, af_pfr))
341     {
342     next->router = rblock;
343     rf_set_ugid(next, ugidptr);   /* Will contain pw values if not overridden */
344
345     /* When getting the home directory out of the password information, wrap it
346     in \N...\N to avoid expansion later. In Cygwin, home directories can
347     contain $ characters. */
348
349     if (rblock->home_directory)
350       next->home_dir = rblock->home_directory;
351     else if (rblock->check_local_user)
352       next->home_dir = string_sprintf("\\N%s\\N", pw->pw_dir);
353     else if (rblock->router_home_directory && testflag(addr, af_home_expanded))
354       {
355       next->home_dir = deliver_home;
356       setflag(next, af_home_expanded);
357       }
358
359     next->current_dir = rblock->current_directory;
360
361     /* Permission options */
362
363     if (!ob->forbid_pipe) setflag(next, af_allow_pipe);
364     if (!ob->forbid_file) setflag(next, af_allow_file);
365     if (!ob->forbid_filter_reply) setflag(next, af_allow_reply);
366
367     /* If the transport setting fails, the error gets picked up at the outer
368     level from the setting of basic_errno in the address. */
369
370     if (next->address[0] == '|')
371       {
372       address_pipe = next->address;
373       GET_OPTION("pipe_transport");
374       if (rf_get_transport(ob->pipe_transport_name, &ob->pipe_transport,
375           next, rblock->drinst.name, US"pipe_transport"))
376         next->transport = ob->pipe_transport;
377       address_pipe = NULL;
378       }
379     else if (next->address[0] == '>')
380       {
381       GET_OPTION("reply_transport");
382       if (rf_get_transport(ob->reply_transport_name, &ob->reply_transport,
383           next, rblock->drinst.name, US"reply_transport"))
384         next->transport = ob->reply_transport;
385       }
386     else  /* must be file or directory */
387       {
388       int len = Ustrlen(next->address);
389       address_file = next->address;
390       if (next->address[len-1] == '/')
391         {
392         GET_OPTION("directory_transport");
393         if (rf_get_transport(ob->directory_transport_name,
394             &ob->directory_transport, next, rblock->drinst.name,
395             US"directory_transport"))
396           next->transport = ob->directory_transport;
397         }
398       else
399         {
400         GET_OPTION("file_transport");
401         if (rf_get_transport(ob->file_transport_name, &ob->file_transport,
402             next, rblock->drinst.name, US"file_transport"))
403           next->transport = ob->file_transport;
404         }
405
406       address_file = NULL;
407       }
408     }
409
410 #ifdef SUPPORT_I18N
411     if (!next->prop.utf8_msg)
412       next->prop.utf8_msg = string_is_utf8(next->address)
413         || (sender_address && string_is_utf8(sender_address));
414 #endif
415
416   DEBUG(D_route)
417     {
418     debug_printf("%s router generated %s\n  %serrors_to=%s transport=%s\n",
419       rblock->drinst.name,
420       next->address,
421       testflag(next, af_pfr)? "pipe, file, or autoreply\n  " : "",
422       next->prop.errors_address,
423       next->transport ? next->transport->drinst.name : US"NULL");
424
425     if (testflag(next, af_uid_set))
426       debug_printf("  uid=%ld ", (long int)(next->uid));
427     else
428       debug_printf("  uid=unset ");
429
430     if (testflag(next, af_gid_set))
431       debug_printf("gid=%ld ", (long int)(next->gid));
432     else
433       debug_printf("gid=unset ");
434
435 #ifdef SUPPORT_I18N
436     if (next->prop.utf8_msg) debug_printf("utf8 ");
437 #endif
438
439     debug_printf("home=%s\n", next->home_dir);
440     }
441   }
442 }
443
444
445 /*************************************************
446 *              Main entry point                  *
447 *************************************************/
448
449 /* See local README for interface description. This router returns:
450
451 DECLINE
452   . empty address list, or filter did nothing significant
453
454 DEFER
455   . verifying the errors address caused a deferment or a big disaster such
456       as an expansion failure (rf_get_errors_address)
457   . expanding a headers_{add,remove} string caused a deferment or another
458       expansion error (rf_get_munge_headers)
459   . :defer: or "freeze" in a filter
460   . error in address list or filter
461   . skipped syntax errors, but failed to send the message
462
463 DISCARD
464   . address was :blackhole:d or "seen finish"ed
465
466 FAIL
467   . :fail:
468
469 OK
470   . new addresses added to addr_new
471 */
472
473 int redirect_router_entry(
474   router_instance *rblock,        /* data for this instantiation */
475   address_item *addr,             /* address we are working on */
476   struct passwd *pw,              /* passwd entry after check_local_user */
477   int verify,                     /* v_none/v_recipient/v_sender/v_expn */
478   address_item **addr_local,      /* add it to this if it's local */
479   address_item **addr_remote,     /* add it to this if it's remote */
480   address_item **addr_new,        /* put new addresses on here */
481   address_item **addr_succeed)    /* put old address here on success */
482 {
483 redirect_router_options_block * ob =
484   (redirect_router_options_block *)(rblock->drinst.options_block);
485 address_item *generated = NULL;
486 const uschar *save_qualify_domain_recipient = qualify_domain_recipient;
487 uschar *discarded = US"discarded";
488 address_item_propagated addr_prop;
489 error_block *eblock = NULL;
490 ugid_block ugid;
491 redirect_block redirect;
492 sieve_block sieve;
493 int filtertype = FILTER_UNSET;
494 int yield = OK;
495 int options = ob->bit_options;
496 int frc = 0;
497 int xrc = 0;
498
499 /* Initialize the data to be propagated to the children */
500
501 addr_prop.address_data = deliver_address_data;
502 addr_prop.domain_data = deliver_domain_data;
503 addr_prop.localpart_data = deliver_localpart_data;
504 addr_prop.errors_address = NULL;
505 addr_prop.extra_headers = NULL;
506 addr_prop.remove_headers = NULL;
507 addr_prop.variables = NULL;
508 tree_dup((tree_node **)&addr_prop.variables, addr->prop.variables);
509
510 #ifdef SUPPORT_I18N
511 addr_prop.utf8_msg = addr->prop.utf8_msg;
512 addr_prop.utf8_downcvt = addr->prop.utf8_downcvt;
513 addr_prop.utf8_downcvt_maybe = addr->prop.utf8_downcvt_maybe;
514 #endif
515
516
517 /* When verifying and testing addresses, the "logwrite" command in filters
518 must be bypassed. */
519
520 if (verify == v_none && !f.address_test_mode) options |= RDO_REALLOG;
521
522 /* Sort out the fixed or dynamic uid/gid. This uid is used (a) for reading the
523 file (and interpreting a filter) and (b) for running the transports for
524 generated file and pipe addresses. It is not (necessarily) the same as the uids
525 that may own the file. Exim panics if an expanded string is not a number and
526 can't be found in the password file. Other errors set the freezing bit. */
527
528 if (!rf_get_ugid(rblock, addr, &ugid)) return DEFER;
529
530 if (!ugid.uid_set && pw)
531   {
532   ugid.uid = pw->pw_uid;
533   ugid.uid_set = TRUE;
534   }
535
536 if (!ugid.gid_set && pw)
537   {
538   ugid.gid = pw->pw_gid;
539   ugid.gid_set = TRUE;
540   }
541
542 /* Call the function that interprets redirection data, either inline or from a
543 file. This is a separate function so that the system filter can use it. It will
544 run the function in a subprocess if necessary. If qualify_preserve_domain is
545 set, temporarily reset qualify_domain_recipient to the current domain so that
546 any unqualified addresses get qualified with the same domain as the incoming
547 address. Otherwise, if a local qualify_domain is provided, set that up. */
548
549 if (ob->qualify_preserve_domain)
550   qualify_domain_recipient = addr->domain;
551 else
552   {
553   GET_OPTION("qualify_domain");
554   if (ob->qualify_domain)
555     {
556     uschar *new_qdr = rf_expand_data(addr, ob->qualify_domain, &xrc);
557     if (!new_qdr) return xrc;
558     qualify_domain_recipient = new_qdr;
559     }
560   }
561
562 redirect.owners = ob->owners;
563 redirect.owngroups = ob->owngroups;
564 redirect.modemask = ob->modemask;
565 redirect.check_owner = ob->check_owner;
566 redirect.check_group = ob->check_group;
567 redirect.pw = pw;
568
569 redirect.string = (redirect.isfile = (ob->file != NULL))
570   ? ob->file : ob->data;
571
572 sieve.inbox = ob->sieve_inbox;
573 sieve.subaddress = ob->sieve_subaddress;
574 sieve.vacation_dir = ob->sieve_vacation_directory;
575 sieve.useraddress = ob->sieve_useraddress;
576 sieve.enotify_mailto_owner = ob->sieve_enotify_mailto_owner;
577
578 frc = rda_interpret(&redirect, options, ob->include_directory, &sieve, &ugid,
579   &generated, &addr->message, ob->skip_syntax_errors ? &eblock : NULL,
580   &filtertype, string_sprintf("%s router (recipient is %s)",
581   rblock->drinst.name, addr->address));
582
583 qualify_domain_recipient = save_qualify_domain_recipient;
584
585 /* Handle exceptional returns from filtering or processing an address list.
586 For FAIL and FREEZE we honour any previously set up deliveries by a filter. */
587
588 switch (frc)
589   {
590   case FF_NONEXIST:
591     addr->message = addr->user_message = NULL;
592     return DECLINE;
593
594   case FF_BLACKHOLE:
595     DEBUG(D_route) debug_printf("address :blackhole:d\n");
596     generated = NULL;
597     discarded = US":blackhole:";
598     frc = FF_DELIVERED;
599     break;
600
601     /* FF_DEFER and FF_FAIL can arise only as a result of explicit commands
602     (:defer: or :fail: in an alias file or "fail" in a filter). If a configured
603     message was supplied, allow it to be included in an SMTP response after
604     verifying. Remove any SMTP code if it is not allowed. */
605
606   case FF_DEFER:
607     yield = DEFER;
608     goto SORT_MESSAGE;
609
610   case FF_FAIL:
611     if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
612       return xrc;
613     add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
614     yield = FAIL;
615
616     SORT_MESSAGE:
617     if (!addr->message)
618       addr->message = yield == FAIL ? US"forced rejection" : US"forced defer";
619     else
620       {
621       uschar * matched;
622       if (  ob->forbid_smtp_code
623          && regex_match(regex_smtp_code, addr->message, -1, &matched))
624         {
625         DEBUG(D_route) debug_printf("SMTP code at start of error message "
626           "is ignored because forbid_smtp_code is set\n");
627         addr->message += Ustrlen(matched);
628         }
629       addr->user_message = addr->message;
630       setflag(addr, af_pass_message);
631       }
632     return yield;
633
634     /* As in the case of a system filter, a freeze does not happen after a manual
635     thaw. In case deliveries were set up by the filter, we set the child count
636     high so that their completion does not mark the original address done. */
637
638   case FF_FREEZE:
639     if (!f.deliver_manual_thaw)
640       {
641       if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop))
642         != OK) return xrc;
643       add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
644       if (addr->message == NULL) addr->message = US"frozen by filter";
645       addr->special_action = SPECIAL_FREEZE;
646       addr->child_count = 9999;
647       return DEFER;
648       }
649     frc = FF_NOTDELIVERED;
650     break;
651
652     /* Handle syntax errors and :include: failures and lookup defers */
653
654   case FF_ERROR:
655   case FF_INCLUDEFAIL:
656
657     /* If filtertype is still FILTER_UNSET, it means that the redirection data
658     was never inspected, so the error was an expansion failure or failure to open
659     the file, or whatever. In these cases, the existing error message is probably
660     sufficient. */
661
662     if (filtertype == FILTER_UNSET) return DEFER;
663
664     /* If it was a filter and skip_syntax_errors is set, we want to set up
665     the error message so that it can be logged and mailed to somebody. */
666
667     if (filtertype != FILTER_FORWARD && ob->skip_syntax_errors)
668       {
669       eblock = store_get(sizeof(error_block), GET_UNTAINTED);
670       eblock->next = NULL;
671       eblock->text1 = addr->message;
672       eblock->text2 = NULL;
673       addr->message = addr->user_message = NULL;
674       }
675
676     /* Otherwise set up the error for the address and defer. */
677
678     else
679       {
680       addr->basic_errno = ERRNO_BADREDIRECT;
681       addr->message = string_sprintf("error in %s %s: %s",
682         filtertype == FILTER_FORWARD ? "redirect" : "filter",
683         ob->data ? "data" : "file",
684         addr->message);
685       return DEFER;
686       }
687   }
688
689
690 /* Yield is either FF_DELIVERED (significant action) or FF_NOTDELIVERED (no
691 significant action). Before dealing with these, however, we must handle the
692 effect of skip_syntax_errors.
693
694 If skip_syntax_errors was set and there were syntax errors in an address list,
695 error messages will be present in eblock. Log them and send a message if so
696 configured. We cannot do this earlier, because the error message must not be
697 sent as the local user. If there were no valid addresses, generated will be
698 NULL. In this case, the router declines.
699
700 For a filter file, the error message has been fudged into an eblock. After
701 dealing with it, the router declines. */
702
703 if (eblock != NULL)
704   {
705   if (!moan_skipped_syntax_errors(
706         rblock->drinst.name,                     /* For message content */
707         eblock,                                  /* Ditto */
708         (verify != v_none || f.address_test_mode)?
709           NULL : ob->syntax_errors_to,           /* Who to mail */
710         generated != NULL,                       /* True if not all failed */
711         ob->syntax_errors_text))                 /* Custom message */
712     return DEFER;
713
714   if (filtertype != FILTER_FORWARD || !generated)
715     {
716     addr->message = US"syntax error in redirection data";
717     return DECLINE;
718     }
719   }
720
721 /* Sort out the errors address and any header modifications, and handle the
722 generated addresses, if any. If there are no generated addresses, we must avoid
723 calling sort_errors_and_headers() in case this router declines - that function
724 may modify the errors_address field in the current address, and we don't want
725 to do that for a decline. */
726
727 if (generated)
728   {
729   if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
730     return xrc;
731   add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
732   }
733
734 /* FF_DELIVERED with no generated addresses is what we get when an address list
735 contains :blackhole: or a filter contains "seen finish" without having
736 generated anything. Log what happened to this address, and return DISCARD. */
737
738 if (frc == FF_DELIVERED)
739   {
740   if (generated == NULL && verify == v_none && !f.address_test_mode)
741     {
742     log_write(0, LOG_MAIN, "=> %s <%s> R=%s", discarded, addr->address,
743       rblock->drinst.name);
744     yield = DISCARD;
745     }
746   }
747
748 /* For an address list, FF_NOTDELIVERED always means that no addresses were
749 generated. For a filter, addresses may or may not have been generated. If none
750 were, it's the same as an empty address list, and the router declines. However,
751 if addresses were generated, we can't just decline because successful delivery
752 of the base address gets it marked "done", so deferred generated addresses
753 never get tried again. We have to generate a new version of the base address,
754 as if there were a "deliver" command in the filter file, with the original
755 address as parent. */
756
757 else
758   {
759   address_item *next;
760
761   if (generated == NULL) return DECLINE;
762
763   next = deliver_make_addr(addr->address, FALSE);
764   next->parent = addr;
765   addr->child_count++;
766   next->next = *addr_new;
767   *addr_new = next;
768
769   /* Set the data that propagates. */
770
771   next->prop = addr_prop;
772
773   DEBUG(D_route) debug_printf("%s router autogenerated %s\n%s%s%s",
774     rblock->drinst.name,
775     next->address,
776     (addr_prop.errors_address != NULL)? "  errors to " : "",
777     (addr_prop.errors_address != NULL)? addr_prop.errors_address : US"",
778     (addr_prop.errors_address != NULL)? "\n" : "");
779   }
780
781 /* Control gets here only when the address has been completely handled. Put the
782 original address onto the succeed queue so that any retry items that get
783 attached to it get processed. */
784
785 addr->next = *addr_succeed;
786 *addr_succeed = addr;
787
788 return yield;
789 }
790
791
792
793 # ifdef DYNLOOKUP
794 #  define redirect_router_info _router_info
795 # endif
796
797 router_info redirect_router_info =
798 {
799 .drinfo = {
800   .driver_name =        US"redirect",
801   .options =            redirect_router_options,
802   .options_count =      &redirect_router_options_count,
803   .options_block =      &redirect_router_option_defaults,
804   .options_len =        sizeof(redirect_router_options_block),
805   .init =               redirect_router_init,
806 # ifdef DYNLOOKUP
807   .dyn_magic =          ROUTER_MAGIC,
808 # endif
809   },
810 .code =                 redirect_router_entry,
811 .tidyup =               NULL,     /* no tidyup entry */
812 .ri_flags =             ri_notransport
813 };
814
815 #endif   /*!MACRO_PREDEF*/
816 #endif  /*ROUTER_REDIRECT*/
817 /* End of routers/redirect.c */