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