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