-/* $Cambridge: exim/src/src/routers/redirect.c,v 1.7 2005/03/22 14:11:55 ph10 Exp $ */
+/* $Cambridge: exim/src/src/routers/redirect.c,v 1.14 2005/09/12 15:09:55 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
(void *)offsetof(redirect_router_options_block, bit_options) },
{ "forbid_file", opt_bool,
(void *)offsetof(redirect_router_options_block, forbid_file) },
- #ifdef EXPAND_DLFUNC
{ "forbid_filter_dlfunc", opt_bit | (RDON_DLFUNC << 16),
(void *)offsetof(redirect_router_options_block, bit_options) },
- #endif
{ "forbid_filter_existstest", opt_bit | (RDON_EXISTS << 16),
(void *)offsetof(redirect_router_options_block, bit_options) },
{ "forbid_filter_logwrite",opt_bit | (RDON_LOG << 16),
(void *)offsetof(redirect_router_options_block, bit_options) },
{ "forbid_filter_lookup", opt_bit | (RDON_LOOKUP << 16),
(void *)offsetof(redirect_router_options_block, bit_options) },
- #ifdef EXIM_PERL
{ "forbid_filter_perl", opt_bit | (RDON_PERL << 16),
(void *)offsetof(redirect_router_options_block, bit_options) },
- #endif
{ "forbid_filter_readfile", opt_bit | (RDON_READFILE << 16),
(void *)offsetof(redirect_router_options_block, bit_options) },
{ "forbid_filter_readsocket", opt_bit | (RDON_READSOCK << 16),
(void *)offsetof(redirect_router_options_block, reply_transport_name) },
{ "rewrite", opt_bit | (RDON_REWRITE << 16),
(void *)offsetof(redirect_router_options_block, bit_options) },
+ { "sieve_subaddress", opt_stringptr,
+ (void *)offsetof(redirect_router_options_block, sieve_subaddress) },
+ { "sieve_useraddress", opt_stringptr,
+ (void *)offsetof(redirect_router_options_block, sieve_useraddress) },
{ "sieve_vacation_directory", opt_stringptr,
(void *)offsetof(redirect_router_options_block, sieve_vacation_directory) },
{ "skip_syntax_errors", opt_bool,
(void *)offsetof(redirect_router_options_block, srs_alias) },
{ "srs_condition", opt_stringptr,
(void *)offsetof(redirect_router_options_block, srs_condition) },
- { "srs_db", opt_stringptr,
- (void *)offsetof(redirect_router_options_block, srs_db) },
+ { "srs_dbinsert", opt_stringptr,
+ (void *)offsetof(redirect_router_options_block, srs_dbinsert) },
+ { "srs_dbselect", opt_stringptr,
+ (void *)offsetof(redirect_router_options_block, srs_dbselect) },
#endif
{ "syntax_errors_text", opt_stringptr,
(void *)offsetof(redirect_router_options_block, syntax_errors_text) },
NULL, /* include_directory */
NULL, /* pipe_transport_name */
NULL, /* reply_transport_name */
+ NULL, /* sieve_subaddress */
+ NULL, /* sieve_useraddress */
NULL, /* sieve_vacation_directory */
NULL, /* syntax_errors_text */
NULL, /* syntax_errors_to */
NULL, /* owngroups */
#ifdef EXPERIMENTAL_SRS
NULL, /* srs */
- NULL, /* srs_condition */
- NULL, /* srs_db */
NULL, /* srs_alias */
+ NULL, /* srs_condition */
+ NULL, /* srs_dbinsert */
+ NULL, /* srs_dbselect */
#endif
022, /* modemask */
RDO_REWRITE, /* bit_options */
Arguments:
rblock the router control block
addr the address being routed
- verify true if verifying
+ verify v_none/v_recipient/v_sender/v_expn
addr_prop point to the propagated block, which is where the
new values are to be placed
static int
sort_errors_and_headers(router_instance *rblock, address_item *addr,
- BOOL verify, address_item_propagated *addr_prop)
+ int verify, address_item_propagated *addr_prop)
{
int frc = rf_get_errors_address(addr, rblock, verify,
&(addr_prop->errors_address));
router_instance *rblock, /* data for this instantiation */
address_item *addr, /* address we are working on */
struct passwd *pw, /* passwd entry after check_local_user */
- BOOL verify, /* TRUE when verifying */
+ int verify, /* v_none/v_recipient/v_sender/v_expn */
address_item **addr_local, /* add it to this if it's local */
address_item **addr_remote, /* add it to this if it's remote */
address_item **addr_new, /* put new addresses on here */
addr_prop.extra_headers = NULL;
addr_prop.remove_headers = NULL;
+#ifdef EXPERIMENTAL_SRS
+addr_prop.srs_sender = NULL;
+#endif
+
/* When verifying and testing addresses, the "logwrite" command in filters
must be bypassed. */
-if (!verify && !address_test_mode) options |= RDO_REALLOG;
+if (verify == v_none && !address_test_mode) options |= RDO_REALLOG;
/* Sort out the fixed or dynamic uid/gid. This uid is used (a) for reading the
file (and interpreting a filter) and (b) for running the transports for
}
#ifdef EXPERIMENTAL_SRS
- /* For reverse SRS, fill the srs_recipient expandsion variable,
- on failure, return decline/fail as relevant */
+ /* Perform SRS on recipient/return-path as required */
+
if(ob->srs != NULL)
{
BOOL usesrs = TRUE;
usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
if(usesrs)
- if(Ustrcmp(ob->srs, "reverse") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0)
+ {
+ int srs_action = 0, n_srs;
+ uschar *res;
+ uschar *usedomain;
+
+ /* What are we doing? */
+ if(Ustrcmp(ob->srs, "forward") == 0)
+ srs_action = 1;
+ else if(Ustrcmp(ob->srs, "reverseandforward") == 0)
{
- uschar *res;
- int n_srs;
+ srs_action = 3;
+
+ if((ob->srs_dbinsert == NULL) ^ (ob->srs_dbselect == NULL))
+ return DEFER;
+ }
+ else if(Ustrcmp(ob->srs, "reverse") == 0)
+ srs_action = 2;
+ /* Reverse SRS */
+ if(srs_action & 2)
+ {
srs_orig_recipient = addr->address;
+
eximsrs_init();
- if(ob->srs_db)
- eximsrs_db_set(TRUE, ob->srs_db);
- if((n_srs = eximsrs_reverse(&res, addr->address)) != OK)
+ if(ob->srs_dbselect)
+ eximsrs_db_set(TRUE, ob->srs_dbselect);
+/* Comment this out for now...
+// else
+// eximsrs_db_set(TRUE, NULL);
+*/
+
+ if((n_srs = eximsrs_reverse(&res, addr->address)) == OK)
+ {
+ srs_recipient = res;
+ DEBUG(D_any)
+ debug_printf("SRS (reverse): Recipient '%s' rewritten to '%s'\n", srs_orig_recipient, srs_recipient);
+ }
+
+ eximsrs_done();
+
+ if(n_srs != OK)
return n_srs;
- srs_recipient = res;
+ }
+
+ /* Forward SRS */
+ /* No point in actually performing SRS if we are just verifying a recipient */
+ if((srs_action & 1) && verify == v_none &&
+ (sender_address ? sender_address[0] != 0 : FALSE))
+ {
+
+ srs_orig_sender = sender_address;
+ eximsrs_init();
+ if(ob->srs_dbinsert)
+ eximsrs_db_set(FALSE, ob->srs_dbinsert);
+/* Comment this out for now...
+// else
+// eximsrs_db_set(FALSE, NULL);
+*/
+
+ if(ob->srs_alias != NULL ? (usedomain = expand_string(ob->srs_alias)) == NULL : 1)
+ usedomain = deliver_domain;
+
+ if((n_srs = eximsrs_forward(&res, sender_address, usedomain)) == OK)
+ {
+ addr_prop.srs_sender = res;
+ DEBUG(D_any)
+ debug_printf("SRS (forward): Sender '%s' rewritten to '%s'\n", srs_orig_sender, res);
+ }
+
eximsrs_done();
- DEBUG(D_any)
- debug_printf("SRS: Recipient '%s' rewritten to '%s'\n", srs_orig_recipient, srs_recipient);
+
+ if(n_srs != OK)
+ return n_srs;
}
+ }
}
#endif
}
frc = rda_interpret(&redirect, options, ob->include_directory,
- ob->sieve_vacation_directory, &ugid, &generated, &(addr->message),
- ob->skip_syntax_errors? &eblock : NULL, &filtertype,
- string_sprintf("%s router (recipient is %s)", rblock->name, addr->address));
+ ob->sieve_vacation_directory, ob->sieve_useraddress, ob->sieve_subaddress,
+ &ugid, &generated, &(addr->message), ob->skip_syntax_errors? &eblock : NULL,
+ &filtertype, string_sprintf("%s router (recipient is %s)", rblock->name,
+ addr->address));
qualify_domain_recipient = save_qualify_domain_recipient;
if ((xrc = sort_errors_and_headers(rblock, addr, verify, &addr_prop)) != OK)
return xrc;
add_generated(rblock, addr_new, addr, generated, &addr_prop, &ugid, pw);
- if (addr->message == NULL) addr->message = US"forced rejection";
- else addr->user_message = addr->message;
+ if (addr->message == NULL)
+ addr->message = US"forced rejection";
+ else
+ {
+ addr->user_message = addr->message;
+ setflag(addr, af_pass_message);
+ }
return FAIL;
/* As in the case of a system filter, a freeze does not happen after a manual
if (eblock != NULL)
{
if (!moan_skipped_syntax_errors(
- rblock->name, /* For message content */
- eblock, /* Ditto */
- (verify || address_test_mode)?
- NULL : ob->syntax_errors_to, /* Who to mail */
- generated != NULL, /* True if not all failed */
- ob->syntax_errors_text)) /* Custom message */
+ rblock->name, /* For message content */
+ eblock, /* Ditto */
+ (verify != v_none || address_test_mode)?
+ NULL : ob->syntax_errors_to, /* Who to mail */
+ generated != NULL, /* True if not all failed */
+ ob->syntax_errors_text)) /* Custom message */
return DEFER;
if (filtertype != FILTER_FORWARD || generated == NULL)
if (frc == FF_DELIVERED)
{
- if (generated == NULL && !verify && !address_test_mode)
+ if (generated == NULL && verify == v_none && !address_test_mode)
{
log_write(0, LOG_MAIN, "=> %s <%s> R=%s", discarded, addr->address,
rblock->name);
(addr_prop.errors_address != NULL)? "\n" : "");
}
-#ifdef EXPERIMENTAL_SRS
- /* On successful redirection, check for SRS forwarding and adjust sender */
- if(ob->srs != NULL)
- {
- BOOL usesrs = TRUE;
-
- if(ob->srs_condition != NULL)
- usesrs = expand_check_condition(ob->srs_condition, "srs_condition expansion failed", NULL);
-
- if(usesrs)
- if((Ustrcmp(ob->srs, "forward") == 0 || Ustrcmp(ob->srs, "reverseandforward") == 0) && !verify)
- {
- uschar *res;
- uschar *usedomain;
- int n_srs;
-
- srs_orig_sender = sender_address;
- eximsrs_init();
- if(ob->srs_db)
- eximsrs_db_set(FALSE, ob->srs_db);
-
- if(ob->srs_alias != NULL ? (usedomain = expand_string(ob->srs_alias)) == NULL : 1)
- usedomain = deliver_domain;
-
- if((n_srs = eximsrs_forward(&res, sender_address, usedomain)) != OK)
- return n_srs;
- sender_address = res;
- DEBUG(D_any)
- debug_printf("SRS: Sender '%s' rewritten to '%s'\n", srs_orig_sender, sender_address);
- }
- }
-#endif
-
/* Control gets here only when the address has been completely handled. Put the
original address onto the succeed queue so that any retry items that get
attached to it get processed. */