tidying
[exim.git] / src / src / routers / redirect.c
CommitLineData
0756eb3c
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
80fea873 5/* Copyright (c) University of Cambridge 1995 - 2016 */
0756eb3c
PH
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) },
4608d683
PH
40 { "filter_prepend_home",opt_bit | (RDON_PREPEND_HOME << 16),
41 (void *)offsetof(redirect_router_options_block, bit_options) },
0756eb3c
PH
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) },
a5bd321b
PH
72 { "forbid_smtp_code", opt_bool,
73 (void *)offsetof(redirect_router_options_block, forbid_smtp_code) },
0756eb3c
PH
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) },
9683a68f
MH
102 { "sieve_enotify_mailto_owner", opt_stringptr,
103 (void *)offsetof(redirect_router_options_block, sieve_enotify_mailto_owner) },
e4a89c47
PH
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) },
0756eb3c
PH
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) },
8523533c
TK
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) },
384152a6
TK
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) },
8523533c 123#endif
0756eb3c
PH
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
d185889f
JH
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) {}
146
147#else /*!MACRO_PREDEF*/
148
149
150
0756eb3c
PH
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 */
e4a89c47
PH
166 NULL, /* sieve_subaddress */
167 NULL, /* sieve_useraddress */
0756eb3c 168 NULL, /* sieve_vacation_directory */
efd9a422 169 NULL, /* sieve_enotify_mailto_owner */
0756eb3c
PH
170 NULL, /* syntax_errors_text */
171 NULL, /* syntax_errors_to */
172 NULL, /* qualify_domain */
173 NULL, /* owners */
174 NULL, /* owngroups */
8523533c
TK
175#ifdef EXPERIMENTAL_SRS
176 NULL, /* srs */
8523533c 177 NULL, /* srs_alias */
384152a6
TK
178 NULL, /* srs_condition */
179 NULL, /* srs_dbinsert */
180 NULL, /* srs_dbselect */
8523533c 181#endif
0756eb3c 182 022, /* modemask */
4608d683 183 RDO_REWRITE | RDO_PREPEND_HOME, /* bit_options */
0756eb3c
PH
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 */
a5bd321b 190 FALSE, /* forbid_smtp_code */
0756eb3c
PH
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
7f45268c
PH
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. */
0756eb3c
PH
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);
7f45268c
PH
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);
0756eb3c
PH
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
fd6de02e 282 verify v_none/v_recipient/v_sender/v_expn
0756eb3c
PH
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,
fd6de02e 292 int verify, address_item_propagated *addr_prop)
0756eb3c
PH
293{
294int frc = rf_get_errors_address(addr, rblock, verify,
d43cbe25 295 &addr_prop->errors_address);
0756eb3c 296if (frc != OK) return frc;
d43cbe25
JH
297addr->prop.errors_address = addr_prop->errors_address;
298return rf_get_munge_headers(addr, rblock, &addr_prop->extra_headers,
299 &addr_prop->remove_headers);
0756eb3c
PH
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
d1f9fb42 343while (generated)
0756eb3c
PH
344 {
345 address_item *parent;
346 address_item *next = generated;
d43cbe25 347 uschar *errors_address = next->prop.errors_address;
0756eb3c
PH
348
349 generated = next->next;
350 next->parent = addr;
351 orflag(next, addr, af_ignore_error);
352 next->start_router = rblock->redirect_router;
82f90600 353 if (addr->child_count == USHRT_MAX)
4362ff0d 354 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router generated more than %d "
82f90600 355 "child addresses for <%s>", rblock->name, USHRT_MAX, addr->address);
0756eb3c
PH
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 {
d1f9fb42 365 for (parent = addr; parent->parent; parent = parent->parent) ;
0756eb3c
PH
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)
d1f9fb42
JH
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)
0756eb3c
PH
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 }
0756eb3c
PH
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
d43cbe25
JH
391 next->prop = *addr_prop;
392 if (errors_address != NULL) next->prop.errors_address = errors_address;
0756eb3c
PH
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
8c5d388a 464#ifdef SUPPORT_I18N
3c8b3577 465 next->prop.utf8_msg = string_is_utf8(next->address)
f923454a
JH
466 || (sender_address && string_is_utf8(sender_address));
467#endif
468
0756eb3c
PH
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 " : "",
d43cbe25 475 next->prop.errors_address,
0756eb3c
PH
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
8c5d388a 488#ifdef SUPPORT_I18N
3c8b3577 489 if (next->prop.utf8_msg) debug_printf("utf8 ");
f923454a
JH
490#endif
491
0756eb3c
PH
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 */
fd6de02e 530 int verify, /* v_none/v_recipient/v_sender/v_expn */
0756eb3c
PH
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;
55414b25 539const uschar *save_qualify_domain_recipient = qualify_domain_recipient;
0756eb3c
PH
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
384152a6
TK
563#ifdef EXPERIMENTAL_SRS
564addr_prop.srs_sender = NULL;
565#endif
cb570b5e
JH
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
384152a6 572
0756eb3c
PH
573/* When verifying and testing addresses, the "logwrite" command in filters
574must be bypassed. */
575
fd6de02e 576if (verify == v_none && !address_test_mode) options |= RDO_REALLOG;
0756eb3c
PH
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
8523533c 598#ifdef EXPERIMENTAL_SRS
384152a6
TK
599 /* Perform SRS on recipient/return-path as required */
600
8523533c
TK
601 if(ob->srs != NULL)
602 {
603 BOOL usesrs = TRUE;
8e669ac1 604
8523533c
TK
605 if(ob->srs_condition != NULL)
606 usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
8e669ac1 607
8523533c 608 if(usesrs)
384152a6 609 {
5614ee86 610 int srs_action = 0, n_srs;
384152a6
TK
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)
8523533c 618 {
384152a6 619 srs_action = 3;
8e669ac1 620
384152a6
TK
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 {
8523533c 630 srs_orig_recipient = addr->address;
384152a6 631
8523533c 632 eximsrs_init();
384152a6
TK
633 if(ob->srs_dbselect)
634 eximsrs_db_set(TRUE, ob->srs_dbselect);
130e9641 635/* Comment this out for now...
384152a6
TK
636// else
637// eximsrs_db_set(TRUE, NULL);
130e9641 638*/
384152a6
TK
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)
8523533c 650 return n_srs;
384152a6
TK
651 }
652
653 /* Forward SRS */
654 /* No point in actually performing SRS if we are just verifying a recipient */
fd6de02e
PH
655 if((srs_action & 1) && verify == v_none &&
656 (sender_address ? sender_address[0] != 0 : FALSE))
384152a6
TK
657 {
658
659 srs_orig_sender = sender_address;
660 eximsrs_init();
661 if(ob->srs_dbinsert)
662 eximsrs_db_set(FALSE, ob->srs_dbinsert);
130e9641 663/* Comment this out for now...
384152a6
TK
664// else
665// eximsrs_db_set(FALSE, NULL);
130e9641 666*/
384152a6 667
dc8091e7
JH
668 if (!(usedomain = ob->srs_alias ? expand_string(ob->srs_alias) : NULL))
669 usedomain = string_copy(deliver_domain);
384152a6
TK
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
8523533c 678 eximsrs_done();
384152a6
TK
679
680 if(n_srs != OK)
681 return n_srs;
8523533c 682 }
384152a6 683 }
8523533c
TK
684 }
685#endif
686
0756eb3c
PH
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,
efd9a422
MH
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));
0756eb3c
PH
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
a5bd321b
PH
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. */
0756eb3c
PH
749
750 case FF_DEFER:
a5bd321b
PH
751 yield = DEFER;
752 goto SORT_MESSAGE;
0756eb3c
PH
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);
a5bd321b
PH
758 yield = FAIL;
759
760 SORT_MESSAGE:
447d236c 761 if (addr->message == NULL)
a5bd321b 762 addr->message = (yield == FAIL)? US"forced rejection" : US"forced defer";
447d236c
PH
763 else
764 {
a5bd321b
PH
765 int ovector[3];
766 if (ob->forbid_smtp_code &&
767 pcre_exec(regex_smtp_code, NULL, CS addr->message,
d6a96edc
PH
768 Ustrlen(addr->message), 0, PCRE_EOPT,
769 ovector, sizeof(ovector)/sizeof(int)) >= 0)
a5bd321b
PH
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 }
447d236c
PH
775 addr->user_message = addr->message;
776 setflag(addr, af_pass_message);
777 }
a5bd321b 778 return yield;
0756eb3c
PH
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(
fd6de02e
PH
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 */
0756eb3c
PH
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 {
fd6de02e 886 if (generated == NULL && verify == v_none && !address_test_mode)
0756eb3c
PH
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);
d43cbe25 919 next->prop = addr_prop;
0756eb3c
PH
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
d185889f 939#endif /*!MACRO_PREDEF*/
0756eb3c 940/* End of routers/redirect.c */