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