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