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