Further tidies to the ${dlfunc code (thanks, Tony): redirect options are
[exim.git] / src / src / routers / redirect.c
CommitLineData
4754440d 1/* $Cambridge: exim/src/src/routers/redirect.c,v 1.8 2005/03/22 15:02:34 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 { "forbid_filter_dlfunc", opt_bit | (RDON_DLFUNC << 16),
49 (void *)offsetof(redirect_router_options_block, bit_options) },
0756eb3c
PH
50 { "forbid_filter_existstest", opt_bit | (RDON_EXISTS << 16),
51 (void *)offsetof(redirect_router_options_block, bit_options) },
52 { "forbid_filter_logwrite",opt_bit | (RDON_LOG << 16),
53 (void *)offsetof(redirect_router_options_block, bit_options) },
54 { "forbid_filter_lookup", opt_bit | (RDON_LOOKUP << 16),
55 (void *)offsetof(redirect_router_options_block, bit_options) },
0756eb3c
PH
56 { "forbid_filter_perl", opt_bit | (RDON_PERL << 16),
57 (void *)offsetof(redirect_router_options_block, bit_options) },
0756eb3c
PH
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) },
23c7ff99
PH
70 { "forbid_sieve_filter",opt_bit | (RDON_SIEVE_FILTER << 16),
71 (void *)offsetof(redirect_router_options_block, bit_options) },
0756eb3c
PH
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) },
8523533c
TK
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) },
113#endif
0756eb3c
PH
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) }
118};
119
120/* Size of the options list. An extern variable has to be used so that its
121address can appear in the tables drtables.c. */
122
123int redirect_router_options_count =
124 sizeof(redirect_router_options)/sizeof(optionlist);
125
126/* Default private options block for the redirect router. */
127
128redirect_router_options_block redirect_router_option_defaults = {
129 NULL, /* directory_transport */
130 NULL, /* file_transport */
131 NULL, /* pipe_transport */
132 NULL, /* reply_transport */
133 NULL, /* data */
134 NULL, /* directory_transport_name */
135 NULL, /* file */
136 NULL, /* file_dir */
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 */
145 NULL, /* owners */
146 NULL, /* owngroups */
8523533c
TK
147#ifdef EXPERIMENTAL_SRS
148 NULL, /* srs */
149 NULL, /* srs_condition */
150 NULL, /* srs_db */
151 NULL, /* srs_alias */
152#endif
0756eb3c
PH
153 022, /* modemask */
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 */
165};
166
167
168
169/*************************************************
170* Initialization entry point *
171*************************************************/
172
173/* Called for each instance, after its options have been read, to enable
174consistency checks to be done, or anything else that needs to be set up. */
175
176void redirect_router_init(router_instance *rblock)
177{
178redirect_router_options_block *ob =
179 (redirect_router_options_block *)(rblock->options_block);
180
181/* Either file or data must be set, but not both */
182
183if ((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 ");
187
7f45268c
PH
188/* Onetime aliases can only be real addresses. Headers can't be manipulated.
189The combination of one_time and unseen is not allowed. We can't check the
190expansion of "unseen" here, but we assume that if it is set to anything other
191than false, there is likely to be a problem. */
0756eb3c
PH
192
193if (ob->one_time)
194 {
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);
7f45268c
PH
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);
0756eb3c
PH
203 }
204
205/* The defaults for check_owner and check_group depend on other settings. The
206defaults are: Check the owner if check_local_user or owners is set; check the
207group if check_local_user is set without a restriction on the group write bit,
208or if owngroups is set. */
209
210if (ob->check_owner == TRUE_UNSET)
211 ob->check_owner = rblock->check_local_user ||
212 (ob->owners != NULL && ob->owners[0] != 0);
213
214if (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);
217
218/* If explicit qualify domain set, the preserve option is locked out */
219
220if (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",
223 rblock->name);
224
225/* If allow_filter is set, either user or check_local_user must be set. */
226
227if (!rblock->check_local_user &&
228 !rblock->uid_set &&
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\"",
233 rblock->name);
234}
235
236
237
238/*************************************************
239* Get errors address and header mods *
240*************************************************/
241
242/* This function is called when new addresses are generated, in order to
243sort out errors address and header modifications. We put the errors address
244into the parent address (even though it is never used from there because that
245address is never transported) so that it can be retrieved if any of the
246children gets routed by an "unseen" router. The clone of the child that is
247passed on must have the original errors_address value.
248
249Arguments:
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
255
256Returns: the result of rf_get_errors_address() or rf_get_munge_headers(),
257 which is either OK or DEFER
258*/
259
260static int
261sort_errors_and_headers(router_instance *rblock, address_item *addr,
262 BOOL verify, address_item_propagated *addr_prop)
263{
264int frc = rf_get_errors_address(addr, rblock, verify,
265 &(addr_prop->errors_address));
266if (frc != OK) return frc;
267addr->p.errors_address = addr_prop->errors_address;
268return rf_get_munge_headers(addr, rblock, &(addr_prop->extra_headers),
269 &(addr_prop->remove_headers));
270}
271
272
273
274/*************************************************
275* Process a set of generated new addresses *
276*************************************************/
277
278/* This function sets up a set of newly generated child addresses and puts them
279on the new address chain. Copy in the uid, gid and permission flags for use by
280pipes and files, set the parent, and "or" its af_ignore_error flag. Also record
281the setting for any starting router.
282
283If the generated address is the same as one of its ancestors, and the
284check_ancestor flag is set, do not use this generated address, but replace it
285with a copy of the input address. This is to cope with cases where A is aliased
286to B and B has a .forward file pointing to A, though it is usually set on the
287forwardfile rather than the aliasfile. We can't just pass on the old
288address by returning FAIL, because it must act as a general parent for
289generated addresses, and only get marked "done" when all its children are
290delivered.
291
292Arguments:
293 rblock router block
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
301
302Returns: nothing
303*/
304
305static void
306add_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)
309{
310redirect_router_options_block *ob =
311 (redirect_router_options_block *)(rblock->options_block);
312
313while (generated != NULL)
314 {
315 address_item *parent;
316 address_item *next = generated;
317 uschar *errors_address = next->p.errors_address;
318
319 generated = next->next;
320 next->parent = addr;
321 orflag(next, addr, af_ignore_error);
322 next->start_router = rblock->redirect_router;
323 addr->child_count++;
324
325 next->next = *addr_new;
326 *addr_new = next;
327
328 /* Don't do the "one_time" thing for the first pass of a 2-stage queue run. */
329
330 if (ob->one_time && !queue_2stage)
331 {
332 for (parent = addr; parent->parent != NULL; parent = parent->parent);
333 next->onetime_parent = parent->address;
334 }
335
336 if (ob->hide_child_in_errmsg) setflag(next, af_hide_child);
337
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. */
341
342 if (ob->check_ancestor)
343 {
344 for (parent = addr; parent != NULL; parent = parent->parent)
345 {
346 if (((parent->router != NULL && parent->router->caseful_local_part)?
347 Ustrcmp(next->address, parent->address)
348 :
349 strcmpic(next->address, parent->address)
350 ) == 0)
351 {
352 DEBUG(D_route) debug_printf("generated parent replaced by child\n");
353 next->address = string_copy(addr->address);
354 break;
355 }
356 }
357 }
358
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. */
362
363 next->p = *addr_prop;
364 if (errors_address != NULL) next->p.errors_address = errors_address;
365
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. */
369
370 if (testflag(next, af_pfr))
371 {
372 next->router = rblock;
373 rf_set_ugid(next, ugidptr); /* Will contain pw values if not overridden */
374
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. */
378
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))
385 {
386 next->home_dir = deliver_home;
387 setflag(next, af_home_expanded);
388 }
389
390 next->current_dir = rblock->current_directory;
391
392 /* Permission options */
393
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);
397
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. */
400
401 if (next->address[0] == '|')
402 {
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;
407 address_pipe = NULL;
408 }
409 else if (next->address[0] == '>')
410 {
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;
414 }
415 else /* must be file or directory */
416 {
417 int len = Ustrlen(next->address);
418 address_file = next->address;
419 if (next->address[len-1] == '/')
420 {
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;
425 }
426 else
427 {
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;
431 }
432 address_file = NULL;
433 }
434 }
435
436 DEBUG(D_route)
437 {
438 debug_printf("%s router generated %s\n %serrors_to=%s transport=%s\n",
439 rblock->name,
440 next->address,
441 testflag(next, af_pfr)? "pipe, file, or autoreply\n " : "",
442 next->p.errors_address,
443 (next->transport == NULL)? US"NULL" : next->transport->name);
444
445 if (testflag(next, af_uid_set))
446 debug_printf(" uid=%ld ", (long int)(next->uid));
447 else
448 debug_printf(" uid=unset ");
449
450 if (testflag(next, af_gid_set))
451 debug_printf("gid=%ld ", (long int)(next->gid));
452 else
453 debug_printf("gid=unset ");
454
455 debug_printf("home=%s\n", next->home_dir);
456 }
457 }
458}
459
460
461/*************************************************
462* Main entry point *
463*************************************************/
464
465/* See local README for interface description. This router returns:
466
467DECLINE
468 . empty address list, or filter did nothing significant
469
470DEFER
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
478
479DISCARD
480 . address was :blackhole:d or "seen finish"ed
481
482FAIL
483 . :fail:
484
485OK
486 . new addresses added to addr_new
487*/
488
489int 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 */
498{
499redirect_router_options_block *ob =
500 (redirect_router_options_block *)(rblock->options_block);
501address_item *generated = NULL;
502uschar *save_qualify_domain_recipient = qualify_domain_recipient;
503uschar *discarded = US"discarded";
504address_item_propagated addr_prop;
505error_block *eblock = NULL;
506ugid_block ugid;
507redirect_block redirect;
508int filtertype = FILTER_UNSET;
509int yield = OK;
510int options = ob->bit_options;
511int frc = 0;
512int xrc = 0;
513
514addr_local = addr_local; /* Keep picky compilers happy */
515addr_remote = addr_remote;
516
517/* Initialize the data to be propagated to the children */
518
519addr_prop.address_data = deliver_address_data;
520addr_prop.domain_data = deliver_domain_data;
521addr_prop.localpart_data = deliver_localpart_data;
522addr_prop.errors_address = NULL;
523addr_prop.extra_headers = NULL;
524addr_prop.remove_headers = NULL;
525
526/* When verifying and testing addresses, the "logwrite" command in filters
527must be bypassed. */
528
529if (!verify && !address_test_mode) options |= RDO_REALLOG;
530
531/* Sort out the fixed or dynamic uid/gid. This uid is used (a) for reading the
532file (and interpreting a filter) and (b) for running the transports for
533generated file and pipe addresses. It is not (necessarily) the same as the uids
534that may own the file. Exim panics if an expanded string is not a number and
535can't be found in the password file. Other errors set the freezing bit. */
536
537if (!rf_get_ugid(rblock, addr, &ugid)) return DEFER;
538
539if (!ugid.uid_set && pw != NULL)
540 {
541 ugid.uid = pw->pw_uid;
542 ugid.uid_set = TRUE;
543 }
544
545if (!ugid.gid_set && pw != NULL)
546 {
547 ugid.gid = pw->pw_gid;
548 ugid.gid_set = TRUE;
549 }
550
8523533c
TK
551#ifdef EXPERIMENTAL_SRS
552 /* For reverse SRS, fill the srs_recipient expandsion variable,
553 on failure, return decline/fail as relevant */
554 if(ob->srs != NULL)
555 {
556 BOOL usesrs = TRUE;
8e669ac1 557
8523533c
TK
558 if(ob->srs_condition != NULL)
559 usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
8e669ac1 560
8523533c
TK
561 if(usesrs)
562 if(Ustrcmp(ob->srs, "reverse") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0)
563 {
564 uschar *res;
565 int n_srs;
8e669ac1 566
8523533c
TK
567 srs_orig_recipient = addr->address;
568 eximsrs_init();
569 if(ob->srs_db)
570 eximsrs_db_set(TRUE, ob->srs_db);
571 if((n_srs = eximsrs_reverse(&res, addr->address)) != OK)
572 return n_srs;
573 srs_recipient = res;
574 eximsrs_done();
575 DEBUG(D_any)
c988f1f4 576 debug_printf("SRS: Recipient '%s' rewritten to '%s'\n", srs_orig_recipient, srs_recipient);
8523533c
TK
577 }
578 }
579#endif
580
0756eb3c
PH
581/* Call the function that interprets redirection data, either inline or from a
582file. This is a separate function so that the system filter can use it. It will
583run the function in a subprocess if necessary. If qualify_preserve_domain is
584set, temporarily reset qualify_domain_recipient to the current domain so that
585any unqualified addresses get qualified with the same domain as the incoming
586address. Otherwise, if a local qualify_domain is provided, set that up. */
587
588if (ob->qualify_preserve_domain)
589 qualify_domain_recipient = addr->domain;
590else if (ob->qualify_domain != NULL)
591 {
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;
595 }
596
597redirect.owners = ob->owners;
598redirect.owngroups = ob->owngroups;
599redirect.modemask = ob->modemask;
600redirect.check_owner = ob->check_owner;
601redirect.check_group = ob->check_group;
602redirect.pw = pw;
603
604if (ob->file != NULL)
605 {
606 redirect.string = ob->file;
607 redirect.isfile = TRUE;
608 }
609else
610 {
611 redirect.string = ob->data;
612 redirect.isfile = FALSE;
613 }
614
615frc = 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));
619
620qualify_domain_recipient = save_qualify_domain_recipient;
621
622/* Handle exceptional returns from filtering or processing an address list.
623For FAIL and FREEZE we honour any previously set up deliveries by a filter. */
624
625switch (frc)
626 {
627 case FF_NONEXIST:
628 addr->message = addr->user_message = NULL;
629 return DECLINE;
630
631 case FF_BLACKHOLE:
632 DEBUG(D_route) debug_printf("address :blackhole:d\n");
633 generated = NULL;
634 discarded = US":blackhole:";
635 frc = FF_DELIVERED;
636 break;
637
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. */
641
642 case FF_DEFER:
643 if (addr->message == NULL) addr->message = US"forced defer";
644 else addr->user_message = addr->message;
645 return DEFER;
646
647 case FF_FAIL:
648 if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
649 return xrc;
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;
653 return FAIL;
654
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. */
658
659 case FF_FREEZE:
660 if (!deliver_manual_thaw)
661 {
662 if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop))
663 != OK) return xrc;
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;
668 return DEFER;
669 }
670 frc = FF_NOTDELIVERED;
671 break;
672
673 /* Handle syntax errors and :include: failures and lookup defers */
674
675 case FF_ERROR:
676 case FF_INCLUDEFAIL:
677
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
681 sufficient. */
682
683 if (filtertype == FILTER_UNSET) return DEFER;
684
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. */
687
688 if (filtertype != FILTER_FORWARD && ob->skip_syntax_errors)
689 {
690 eblock = store_get(sizeof(error_block));
691 eblock->next = NULL;
692 eblock->text1 = addr->message;
693 eblock->text2 = NULL;
694 addr->message = addr->user_message = NULL;
695 }
696
697 /* Otherwise set up the error for the address and defer. */
698
699 else
700 {
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",
705 addr->message);
706 return DEFER;
707 }
708 }
709
710
711/* Yield is either FF_DELIVERED (significant action) or FF_NOTDELIVERED (no
712significant action). Before dealing with these, however, we must handle the
713effect of skip_syntax_errors.
714
715If skip_syntax_errors was set and there were syntax errors in an address list,
716error messages will be present in eblock. Log them and send a message if so
717configured. We cannot do this earlier, because the error message must not be
718sent as the local user. If there were no valid addresses, generated will be
719NULL. In this case, the router declines.
720
721For a filter file, the error message has been fudged into an eblock. After
722dealing with it, the router declines. */
723
724if (eblock != NULL)
725 {
726 if (!moan_skipped_syntax_errors(
727 rblock->name, /* For message content */
728 eblock, /* Ditto */
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 */
733 return DEFER;
734
735 if (filtertype != FILTER_FORWARD || generated == NULL)
736 {
737 addr->message = US"syntax error in redirection data";
738 return DECLINE;
739 }
740 }
741
742/* Sort out the errors address and any header modifications, and handle the
743generated addresses, if any. If there are no generated addresses, we must avoid
744calling sort_errors_and_headers() in case this router declines - that function
745may modify the errors_address field in the current address, and we don't want
746to do that for a decline. */
747
748if (generated != NULL)
749 {
750 if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
751 return xrc;
752 add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
753 }
754
755/* FF_DELIVERED with no generated addresses is what we get when an address list
756contains :blackhole: or a filter contains "seen finish" without having
757generated anything. Log what happened to this address, and return DISCARD. */
758
759if (frc == FF_DELIVERED)
760 {
761 if (generated == NULL && !verify && !address_test_mode)
762 {
763 log_write(0, LOG_MAIN, "=> %s <%s> R=%s", discarded, addr->address,
764 rblock->name);
765 yield = DISCARD;
766 }
767 }
768
769/* For an address list, FF_NOTDELIVERED always means that no addresses were
770generated. For a filter, addresses may or may not have been generated. If none
771were, it's the same as an empty address list, and the router declines. However,
772if addresses were generated, we can't just decline because successful delivery
773of the base address gets it marked "done", so deferred generated addresses
774never get tried again. We have to generate a new version of the base address,
775as if there were a "deliver" command in the filter file, with the original
776address as parent. */
777
778else
779 {
780 address_item *next;
781
782 if (generated == NULL) return DECLINE;
783
784 next = deliver_make_addr(addr->address, FALSE);
785 next->parent = addr;
786 addr->child_count++;
787 next->next = *addr_new;
788 *addr_new = next;
789
790 /* Copy relevant flags (af_propagate is a name for the set), and set the
791 data that propagates. */
792
793 copyflag(next, addr, af_propagate);
794 next->p = addr_prop;
795
796 DEBUG(D_route) debug_printf("%s router autogenerated %s\n%s%s%s",
797 rblock->name,
798 next->address,
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" : "");
802 }
803
8523533c
TK
804#ifdef EXPERIMENTAL_SRS
805 /* On successful redirection, check for SRS forwarding and adjust sender */
806 if(ob->srs != NULL)
807 {
808 BOOL usesrs = TRUE;
8e669ac1 809
8523533c
TK
810 if(ob->srs_condition != NULL)
811 usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
8e669ac1 812
8523533c
TK
813 if(usesrs)
814 if((Ustrcmp(ob->srs, "forward") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0) && !verify)
815 {
816 uschar *res;
817 uschar *usedomain;
818 int n_srs;
8e669ac1 819
8523533c
TK
820 srs_orig_sender = sender_address;
821 eximsrs_init();
822 if(ob->srs_db)
823 eximsrs_db_set(FALSE, ob->srs_db);
824
825 if(ob->srs_alias != NULL ? (usedomain = expand_string(ob->srs_alias)) == NULL : 1)
826 usedomain = deliver_domain;
8e669ac1 827
8523533c
TK
828 if((n_srs = eximsrs_forward(&res, sender_address, usedomain)) != OK)
829 return n_srs;
830 sender_address = res;
831 DEBUG(D_any)
832 debug_printf("SRS: Sender '%s' rewritten to '%s'\n", srs_orig_sender, sender_address);
833 }
834 }
835#endif
836
0756eb3c
PH
837/* Control gets here only when the address has been completely handled. Put the
838original address onto the succeed queue so that any retry items that get
839attached to it get processed. */
840
841addr->next = *addr_succeed;
842*addr_succeed = addr;
843
844return yield;
845}
846
847/* End of routers/redirect.c */