1 /* $Cambridge: exim/src/src/routers/redirect.c,v 1.6 2005/03/15 11:37:21 ph10 Exp $ */
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
7 /* Copyright (c) University of Cambridge 1995 - 2005 */
8 /* See the file NOTICE for conditions of use and distribution. */
12 #include "rf_functions.h"
17 /* Options specific to the redirect router. */
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) },
55 { "forbid_filter_perl", opt_bit | (RDON_PERL << 16),
56 (void *)offsetof(redirect_router_options_block, bit_options) },
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 #ifdef EXPERIMENTAL_SRS
105 { "srs", opt_stringptr,
106 (void *)offsetof(redirect_router_options_block, srs) },
107 { "srs_alias", opt_stringptr,
108 (void *)offsetof(redirect_router_options_block, srs_alias) },
109 { "srs_condition", opt_stringptr,
110 (void *)offsetof(redirect_router_options_block, srs_condition) },
111 { "srs_db", opt_stringptr,
112 (void *)offsetof(redirect_router_options_block, srs_db) },
114 { "syntax_errors_text", opt_stringptr,
115 (void *)offsetof(redirect_router_options_block, syntax_errors_text) },
116 { "syntax_errors_to", opt_stringptr,
117 (void *)offsetof(redirect_router_options_block, syntax_errors_to) }
120 /* Size of the options list. An extern variable has to be used so that its
121 address can appear in the tables drtables.c. */
123 int redirect_router_options_count =
124 sizeof(redirect_router_options)/sizeof(optionlist);
126 /* Default private options block for the redirect router. */
128 redirect_router_options_block redirect_router_option_defaults = {
129 NULL, /* directory_transport */
130 NULL, /* file_transport */
131 NULL, /* pipe_transport */
132 NULL, /* reply_transport */
134 NULL, /* directory_transport_name */
137 NULL, /* file_transport_name */
138 NULL, /* include_directory */
139 NULL, /* pipe_transport_name */
140 NULL, /* reply_transport_name */
141 NULL, /* sieve_vacation_directory */
142 NULL, /* syntax_errors_text */
143 NULL, /* syntax_errors_to */
144 NULL, /* qualify_domain */
146 NULL, /* owngroups */
147 #ifdef EXPERIMENTAL_SRS
149 NULL, /* srs_condition */
151 NULL, /* srs_alias */
154 RDO_REWRITE, /* bit_options */
155 FALSE, /* check_ancestor */
156 TRUE_UNSET, /* check_owner */
157 TRUE_UNSET, /* check_group */
158 FALSE, /* forbid_file */
159 FALSE, /* forbid_filter_reply */
160 FALSE, /* forbid_pipe */
161 FALSE, /* hide_child_in_errmsg */
162 FALSE, /* one_time */
163 FALSE, /* qualify_preserve_domain */
164 FALSE /* skip_syntax_errors */
169 /*************************************************
170 * Initialization entry point *
171 *************************************************/
173 /* Called for each instance, after its options have been read, to enable
174 consistency checks to be done, or anything else that needs to be set up. */
176 void redirect_router_init(router_instance *rblock)
178 redirect_router_options_block *ob =
179 (redirect_router_options_block *)(rblock->options_block);
181 /* Either file or data must be set, but not both */
183 if ((ob->file == NULL) == (ob->data == NULL))
184 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
185 "%sone of \"file\" or \"data\" must be specified",
186 rblock->name, (ob->file == NULL)? "" : "only ");
188 /* Onetime aliases can only be real addresses. Headers can't be manipulated.
189 The combination of one_time and unseen is not allowed. We can't check the
190 expansion of "unseen" here, but we assume that if it is set to anything other
191 than false, there is likely to be a problem. */
195 ob->forbid_pipe = ob->forbid_file = ob->forbid_filter_reply = TRUE;
196 if (rblock->extra_headers != NULL || rblock->remove_headers != NULL)
197 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
198 "\"headers_add\" and \"headers_remove\" are not permitted with "
199 "\"one_time\"", rblock->name);
200 if (rblock->unseen || rblock->expand_unseen != NULL)
201 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
202 "\"unseen\" may not be used with \"one_time\"", rblock->name);
205 /* The defaults for check_owner and check_group depend on other settings. The
206 defaults are: Check the owner if check_local_user or owners is set; check the
207 group if check_local_user is set without a restriction on the group write bit,
208 or if owngroups is set. */
210 if (ob->check_owner == TRUE_UNSET)
211 ob->check_owner = rblock->check_local_user ||
212 (ob->owners != NULL && ob->owners[0] != 0);
214 if (ob->check_group == TRUE_UNSET)
215 ob->check_group = (rblock->check_local_user && (ob->modemask & 020) == 0) ||
216 (ob->owngroups != NULL && ob->owngroups[0] != 0);
218 /* If explicit qualify domain set, the preserve option is locked out */
220 if (ob->qualify_domain != NULL && ob->qualify_preserve_domain)
221 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
222 "only one of \"qualify_domain\" or \"qualify_preserve_domain\" must be set",
225 /* If allow_filter is set, either user or check_local_user must be set. */
227 if (!rblock->check_local_user &&
229 rblock->expand_uid == NULL &&
230 (ob->bit_options & RDO_FILTER) != 0)
231 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s router:\n "
232 "\"user\" or \"check_local_user\" must be set with \"allow_filter\"",
238 /*************************************************
239 * Get errors address and header mods *
240 *************************************************/
242 /* This function is called when new addresses are generated, in order to
243 sort out errors address and header modifications. We put the errors address
244 into the parent address (even though it is never used from there because that
245 address is never transported) so that it can be retrieved if any of the
246 children gets routed by an "unseen" router. The clone of the child that is
247 passed on must have the original errors_address value.
250 rblock the router control block
251 addr the address being routed
252 verify true if verifying
253 addr_prop point to the propagated block, which is where the
254 new values are to be placed
256 Returns: the result of rf_get_errors_address() or rf_get_munge_headers(),
257 which is either OK or DEFER
261 sort_errors_and_headers(router_instance *rblock, address_item *addr,
262 BOOL verify, address_item_propagated *addr_prop)
264 int frc = rf_get_errors_address(addr, rblock, verify,
265 &(addr_prop->errors_address));
266 if (frc != OK) return frc;
267 addr->p.errors_address = addr_prop->errors_address;
268 return rf_get_munge_headers(addr, rblock, &(addr_prop->extra_headers),
269 &(addr_prop->remove_headers));
274 /*************************************************
275 * Process a set of generated new addresses *
276 *************************************************/
278 /* This function sets up a set of newly generated child addresses and puts them
279 on the new address chain. Copy in the uid, gid and permission flags for use by
280 pipes and files, set the parent, and "or" its af_ignore_error flag. Also record
281 the setting for any starting router.
283 If the generated address is the same as one of its ancestors, and the
284 check_ancestor flag is set, do not use this generated address, but replace it
285 with a copy of the input address. This is to cope with cases where A is aliased
286 to B and B has a .forward file pointing to A, though it is usually set on the
287 forwardfile rather than the aliasfile. We can't just pass on the old
288 address by returning FAIL, because it must act as a general parent for
289 generated addresses, and only get marked "done" when all its children are
294 addr_new new address chain
295 addr original address
296 generated list of generated addresses
297 addr_prop the propagated block, containing the errors_address,
298 header modification stuff, and address_data
299 ugidptr points to uid/gid data for files, pipes, autoreplies
300 pw password entry, set if ob->check_local_user is TRUE
306 add_generated(router_instance *rblock, address_item **addr_new,
307 address_item *addr, address_item *generated,
308 address_item_propagated *addr_prop, ugid_block *ugidptr, struct passwd *pw)
310 redirect_router_options_block *ob =
311 (redirect_router_options_block *)(rblock->options_block);
313 while (generated != NULL)
315 address_item *parent;
316 address_item *next = generated;
317 uschar *errors_address = next->p.errors_address;
319 generated = next->next;
321 orflag(next, addr, af_ignore_error);
322 next->start_router = rblock->redirect_router;
325 next->next = *addr_new;
328 /* Don't do the "one_time" thing for the first pass of a 2-stage queue run. */
330 if (ob->one_time && !queue_2stage)
332 for (parent = addr; parent->parent != NULL; parent = parent->parent);
333 next->onetime_parent = parent->address;
336 if (ob->hide_child_in_errmsg) setflag(next, af_hide_child);
338 /* If check_ancestor is set, we want to know if any ancestor of this address
339 is the address we are about to generate. The check must be done caselessly
340 unless the ancestor was routed by a case-sensitive router. */
342 if (ob->check_ancestor)
344 for (parent = addr; parent != NULL; parent = parent->parent)
346 if (((parent->router != NULL && parent->router->caseful_local_part)?
347 Ustrcmp(next->address, parent->address)
349 strcmpic(next->address, parent->address)
352 DEBUG(D_route) debug_printf("generated parent replaced by child\n");
353 next->address = string_copy(addr->address);
359 /* A user filter may, under some circumstances, set up an errors address.
360 If so, we must take care to re-instate it when we copy in the propagated
361 data so that it overrides any errors_to setting on the router. */
363 next->p = *addr_prop;
364 if (errors_address != NULL) next->p.errors_address = errors_address;
366 /* For pipes, files, and autoreplies, record this router as handling them,
367 because they don't go through the routing process again. Then set up uid,
368 gid, home and current directories for transporting. */
370 if (testflag(next, af_pfr))
372 next->router = rblock;
373 rf_set_ugid(next, ugidptr); /* Will contain pw values if not overridden */
375 /* When getting the home directory out of the password information, wrap it
376 in \N...\N to avoid expansion later. In Cygwin, home directories can
377 contain $ characters. */
379 if (rblock->home_directory != NULL)
380 next->home_dir = rblock->home_directory;
381 else if (rblock->check_local_user)
382 next->home_dir = string_sprintf("\\N%s\\N", pw->pw_dir);
383 else if (rblock->router_home_directory != NULL &&
384 testflag(addr, af_home_expanded))
386 next->home_dir = deliver_home;
387 setflag(next, af_home_expanded);
390 next->current_dir = rblock->current_directory;
392 /* Permission options */
394 if (!ob->forbid_pipe) setflag(next, af_allow_pipe);
395 if (!ob->forbid_file) setflag(next, af_allow_file);
396 if (!ob->forbid_filter_reply) setflag(next, af_allow_reply);
398 /* If the transport setting fails, the error gets picked up at the outer
399 level from the setting of basic_errno in the address. */
401 if (next->address[0] == '|')
403 address_pipe = next->address;
404 if (rf_get_transport(ob->pipe_transport_name, &(ob->pipe_transport),
405 next, rblock->name, US"pipe_transport"))
406 next->transport = ob->pipe_transport;
409 else if (next->address[0] == '>')
411 if (rf_get_transport(ob->reply_transport_name, &(ob->reply_transport),
412 next, rblock->name, US"reply_transport"))
413 next->transport = ob->reply_transport;
415 else /* must be file or directory */
417 int len = Ustrlen(next->address);
418 address_file = next->address;
419 if (next->address[len-1] == '/')
421 if (rf_get_transport(ob->directory_transport_name,
422 &(ob->directory_transport), next, rblock->name,
423 US"directory_transport"))
424 next->transport = ob->directory_transport;
428 if (rf_get_transport(ob->file_transport_name, &(ob->file_transport),
429 next, rblock->name, US"file_transport"))
430 next->transport = ob->file_transport;
438 debug_printf("%s router generated %s\n %serrors_to=%s transport=%s\n",
441 testflag(next, af_pfr)? "pipe, file, or autoreply\n " : "",
442 next->p.errors_address,
443 (next->transport == NULL)? US"NULL" : next->transport->name);
445 if (testflag(next, af_uid_set))
446 debug_printf(" uid=%ld ", (long int)(next->uid));
448 debug_printf(" uid=unset ");
450 if (testflag(next, af_gid_set))
451 debug_printf("gid=%ld ", (long int)(next->gid));
453 debug_printf("gid=unset ");
455 debug_printf("home=%s\n", next->home_dir);
461 /*************************************************
463 *************************************************/
465 /* See local README for interface description. This router returns:
468 . empty address list, or filter did nothing significant
471 . verifying the errors address caused a deferment or a big disaster such
472 as an expansion failure (rf_get_errors_address)
473 . expanding a headers_{add,remove} string caused a deferment or another
474 expansion error (rf_get_munge_headers)
475 . :defer: or "freeze" in a filter
476 . error in address list or filter
477 . skipped syntax errors, but failed to send the message
480 . address was :blackhole:d or "seen finish"ed
486 . new addresses added to addr_new
489 int redirect_router_entry(
490 router_instance *rblock, /* data for this instantiation */
491 address_item *addr, /* address we are working on */
492 struct passwd *pw, /* passwd entry after check_local_user */
493 BOOL verify, /* TRUE when verifying */
494 address_item **addr_local, /* add it to this if it's local */
495 address_item **addr_remote, /* add it to this if it's remote */
496 address_item **addr_new, /* put new addresses on here */
497 address_item **addr_succeed) /* put old address here on success */
499 redirect_router_options_block *ob =
500 (redirect_router_options_block *)(rblock->options_block);
501 address_item *generated = NULL;
502 uschar *save_qualify_domain_recipient = qualify_domain_recipient;
503 uschar *discarded = US"discarded";
504 address_item_propagated addr_prop;
505 error_block *eblock = NULL;
507 redirect_block redirect;
508 int filtertype = FILTER_UNSET;
510 int options = ob->bit_options;
514 addr_local = addr_local; /* Keep picky compilers happy */
515 addr_remote = addr_remote;
517 /* Initialize the data to be propagated to the children */
519 addr_prop.address_data = deliver_address_data;
520 addr_prop.domain_data = deliver_domain_data;
521 addr_prop.localpart_data = deliver_localpart_data;
522 addr_prop.errors_address = NULL;
523 addr_prop.extra_headers = NULL;
524 addr_prop.remove_headers = NULL;
526 /* When verifying and testing addresses, the "logwrite" command in filters
529 if (!verify && !address_test_mode) options |= RDO_REALLOG;
531 /* Sort out the fixed or dynamic uid/gid. This uid is used (a) for reading the
532 file (and interpreting a filter) and (b) for running the transports for
533 generated file and pipe addresses. It is not (necessarily) the same as the uids
534 that may own the file. Exim panics if an expanded string is not a number and
535 can't be found in the password file. Other errors set the freezing bit. */
537 if (!rf_get_ugid(rblock, addr, &ugid)) return DEFER;
539 if (!ugid.uid_set && pw != NULL)
541 ugid.uid = pw->pw_uid;
545 if (!ugid.gid_set && pw != NULL)
547 ugid.gid = pw->pw_gid;
551 #ifdef EXPERIMENTAL_SRS
552 /* For reverse SRS, fill the srs_recipient expandsion variable,
553 on failure, return decline/fail as relevant */
558 if(ob->srs_condition != NULL)
559 usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
562 if(Ustrcmp(ob->srs, "reverse") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0)
567 srs_orig_recipient = addr->address;
570 eximsrs_db_set(TRUE, ob->srs_db);
571 if((n_srs = eximsrs_reverse(&res, addr->address)) != OK)
576 debug_printf("SRS: Recipient '%s' rewritten to '%s'\n", srs_orig_recipient, srs_recipient);
581 /* Call the function that interprets redirection data, either inline or from a
582 file. This is a separate function so that the system filter can use it. It will
583 run the function in a subprocess if necessary. If qualify_preserve_domain is
584 set, temporarily reset qualify_domain_recipient to the current domain so that
585 any unqualified addresses get qualified with the same domain as the incoming
586 address. Otherwise, if a local qualify_domain is provided, set that up. */
588 if (ob->qualify_preserve_domain)
589 qualify_domain_recipient = addr->domain;
590 else if (ob->qualify_domain != NULL)
592 uschar *new_qdr = rf_expand_data(addr, ob->qualify_domain, &xrc);
593 if (new_qdr == NULL) return xrc;
594 qualify_domain_recipient = new_qdr;
597 redirect.owners = ob->owners;
598 redirect.owngroups = ob->owngroups;
599 redirect.modemask = ob->modemask;
600 redirect.check_owner = ob->check_owner;
601 redirect.check_group = ob->check_group;
604 if (ob->file != NULL)
606 redirect.string = ob->file;
607 redirect.isfile = TRUE;
611 redirect.string = ob->data;
612 redirect.isfile = FALSE;
615 frc = rda_interpret(&redirect, options, ob->include_directory,
616 ob->sieve_vacation_directory, &ugid, &generated, &(addr->message),
617 ob->skip_syntax_errors? &eblock : NULL, &filtertype,
618 string_sprintf("%s router (recipient is %s)", rblock->name, addr->address));
620 qualify_domain_recipient = save_qualify_domain_recipient;
622 /* Handle exceptional returns from filtering or processing an address list.
623 For FAIL and FREEZE we honour any previously set up deliveries by a filter. */
628 addr->message = addr->user_message = NULL;
632 DEBUG(D_route) debug_printf("address :blackhole:d\n");
634 discarded = US":blackhole:";
638 /* FF_DEFER and FF_FAIL can arise only as a result of explicit commands
639 (:fail: in an alias file or "fail" in a filter). If a configured message was
640 supplied, allow it to be included in an SMTP response after verifying. */
643 if (addr->message == NULL) addr->message = US"forced defer";
644 else addr->user_message = addr->message;
648 if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
650 add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
651 if (addr->message == NULL) addr->message = US"forced rejection";
652 else addr->user_message = addr->message;
655 /* As in the case of a system filter, a freeze does not happen after a manual
656 thaw. In case deliveries were set up by the filter, we set the child count
657 high so that their completion does not mark the original address done. */
660 if (!deliver_manual_thaw)
662 if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop))
664 add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
665 if (addr->message == NULL) addr->message = US"frozen by filter";
666 addr->special_action = SPECIAL_FREEZE;
667 addr->child_count = 9999;
670 frc = FF_NOTDELIVERED;
673 /* Handle syntax errors and :include: failures and lookup defers */
678 /* If filtertype is still FILTER_UNSET, it means that the redirection data
679 was never inspected, so the error was an expansion failure or failure to open
680 the file, or whatever. In these cases, the existing error message is probably
683 if (filtertype == FILTER_UNSET) return DEFER;
685 /* If it was a filter and skip_syntax_errors is set, we want to set up
686 the error message so that it can be logged and mailed to somebody. */
688 if (filtertype != FILTER_FORWARD && ob->skip_syntax_errors)
690 eblock = store_get(sizeof(error_block));
692 eblock->text1 = addr->message;
693 eblock->text2 = NULL;
694 addr->message = addr->user_message = NULL;
697 /* Otherwise set up the error for the address and defer. */
701 addr->basic_errno = ERRNO_BADREDIRECT;
702 addr->message = string_sprintf("error in %s %s: %s",
703 (filtertype != FILTER_FORWARD)? "filter" : "redirect",
704 (ob->data == NULL)? "file" : "data",
711 /* Yield is either FF_DELIVERED (significant action) or FF_NOTDELIVERED (no
712 significant action). Before dealing with these, however, we must handle the
713 effect of skip_syntax_errors.
715 If skip_syntax_errors was set and there were syntax errors in an address list,
716 error messages will be present in eblock. Log them and send a message if so
717 configured. We cannot do this earlier, because the error message must not be
718 sent as the local user. If there were no valid addresses, generated will be
719 NULL. In this case, the router declines.
721 For a filter file, the error message has been fudged into an eblock. After
722 dealing with it, the router declines. */
726 if (!moan_skipped_syntax_errors(
727 rblock->name, /* For message content */
729 (verify || address_test_mode)?
730 NULL : ob->syntax_errors_to, /* Who to mail */
731 generated != NULL, /* True if not all failed */
732 ob->syntax_errors_text)) /* Custom message */
735 if (filtertype != FILTER_FORWARD || generated == NULL)
737 addr->message = US"syntax error in redirection data";
742 /* Sort out the errors address and any header modifications, and handle the
743 generated addresses, if any. If there are no generated addresses, we must avoid
744 calling sort_errors_and_headers() in case this router declines - that function
745 may modify the errors_address field in the current address, and we don't want
746 to do that for a decline. */
748 if (generated != NULL)
750 if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
752 add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
755 /* FF_DELIVERED with no generated addresses is what we get when an address list
756 contains :blackhole: or a filter contains "seen finish" without having
757 generated anything. Log what happened to this address, and return DISCARD. */
759 if (frc == FF_DELIVERED)
761 if (generated == NULL && !verify && !address_test_mode)
763 log_write(0, LOG_MAIN, "=> %s <%s> R=%s", discarded, addr->address,
769 /* For an address list, FF_NOTDELIVERED always means that no addresses were
770 generated. For a filter, addresses may or may not have been generated. If none
771 were, it's the same as an empty address list, and the router declines. However,
772 if addresses were generated, we can't just decline because successful delivery
773 of the base address gets it marked "done", so deferred generated addresses
774 never get tried again. We have to generate a new version of the base address,
775 as if there were a "deliver" command in the filter file, with the original
776 address as parent. */
782 if (generated == NULL) return DECLINE;
784 next = deliver_make_addr(addr->address, FALSE);
787 next->next = *addr_new;
790 /* Copy relevant flags (af_propagate is a name for the set), and set the
791 data that propagates. */
793 copyflag(next, addr, af_propagate);
796 DEBUG(D_route) debug_printf("%s router autogenerated %s\n%s%s%s",
799 (addr_prop.errors_address != NULL)? " errors to " : "",
800 (addr_prop.errors_address != NULL)? addr_prop.errors_address : US"",
801 (addr_prop.errors_address != NULL)? "\n" : "");
804 #ifdef EXPERIMENTAL_SRS
805 /* On successful redirection, check for SRS forwarding and adjust sender */
810 if(ob->srs_condition != NULL)
811 usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
814 if((Ustrcmp(ob->srs, "forward") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0) && !verify)
820 srs_orig_sender = sender_address;
823 eximsrs_db_set(FALSE, ob->srs_db);
825 if(ob->srs_alias != NULL ? (usedomain = expand_string(ob->srs_alias)) == NULL : 1)
826 usedomain = deliver_domain;
828 if((n_srs = eximsrs_forward(&res, sender_address, usedomain)) != OK)
830 sender_address = res;
832 debug_printf("SRS: Sender '%s' rewritten to '%s'\n", srs_orig_sender, sender_address);
837 /* Control gets here only when the address has been completely handled. Put the
838 original address onto the succeed queue so that any retry items that get
839 attached to it get processed. */
841 addr->next = *addr_succeed;
842 *addr_succeed = addr;
847 /* End of routers/redirect.c */