-/* $Cambridge: exim/src/src/verify.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */
+/* $Cambridge: exim/src/src/verify.c,v 1.3 2004/11/05 16:53:28 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
portstring "port" option from transport, or NULL
protocolstring "protocol" option from transport, or NULL
callout the per-command callout timeout
- callout_overall the overall callout timeout (if < 0; use 4*callout)
+ callout_overall the overall callout timeout (if < 0 use 4*callout)
+ callout_connect the callout connection timeout (if < 0 use callout)
options the verification options - these bits are used:
vopt_is_recipient => this is a recipient address
vopt_callout_no_cache => don't use callout cache
static int
do_callout(address_item *addr, host_item *host_list, transport_feedback *tf,
- int callout, int callout_overall, int options, uschar *se_mailfrom,
- uschar *pm_mailfrom)
+ int callout, int callout_overall, int callout_connect, int options,
+ uschar *se_mailfrom, uschar *pm_mailfrom)
{
BOOL is_recipient = (options & vopt_is_recipient) != 0;
BOOL callout_no_cache = (options & vopt_callout_no_cache) != 0;
uschar *address_key;
uschar *from_address;
uschar *random_local_part = NULL;
+uschar **failure_ptr = is_recipient?
+ &recipient_verify_failure : &sender_verify_failure;
open_db dbblock;
open_db *dbm_file = NULL;
dbdata_callout_cache new_domain_record;
setflag(addr, af_verify_nsfail);
addr->user_message = US"(result of an earlier callout reused).";
yield = FAIL;
+ *failure_ptr = US"mail";
goto END_CALLOUT;
}
debug_printf("callout cache: domain does not accept "
"RCPT TO:<postmaster@domain>\n");
yield = FAIL;
+ *failure_ptr = US"postmaster";
setflag(addr, af_verify_pmfail);
addr->user_message = US"(result of earlier verification reused).";
goto END_CALLOUT;
HDEBUG(D_verify)
debug_printf("callout cache: address record is negative\n");
addr->user_message = US"Previous (cached) callout verification failure";
+ *failure_ptr = US"recipient";
yield = FAIL;
}
goto END_CALLOUT;
"callout_random_local_part: %s", expand_string_message);
}
-/* Default the overall callout timeout if not set, and record the time we are
-starting so that we can enforce it. */
+/* Default the connect and overall callout timeouts if not set, and record the
+time we are starting so that we can enforce it. */
if (callout_overall < 0) callout_overall = 4 * callout;
+if (callout_connect < 0) callout_connect = callout;
callout_start_time = time(NULL);
/* Now make connections to the hosts and do real callouts. The list of hosts
outblock.authenticating = FALSE;
/* Connect to the host; on failure, just loop for the next one, but we
- set the error for the last one. */
+ set the error for the last one. Use the callout_connect timeout. */
inblock.sock = outblock.sock =
- smtp_connect(host, host_af, port, interface, callout, TRUE);
+ smtp_connect(host, host_af, port, interface, callout_connect, TRUE);
if (inblock.sock < 0)
{
addr->message = string_sprintf("could not connect to %s [%s]: %s",
if (!done)
{
+ *failure_ptr = US"mail";
if (errno == 0 && responsebuffer[0] == '5')
{
setflag(addr, af_verify_nsfail);
if (done)
new_address_record.result = ccache_accept;
else if (errno == 0 && responsebuffer[0] == '5')
+ {
+ *failure_ptr = US"recipient";
new_address_record.result = ccache_reject;
+ }
/* Do postmaster check if requested */
new_domain_record.postmaster_result = ccache_accept;
else if (errno == 0 && responsebuffer[0] == '5')
{
+ *failure_ptr = US"postmaster";
setflag(addr, af_verify_pmfail);
new_domain_record.postmaster_result = ccache_reject;
}
vopt_callout_recippmaster => use postmaster for recipient
callout if > 0, specifies that callout is required, and gives timeout
- for individual connections and commands
+ for individual commands
callout_overall if > 0, gives overall timeout for the callout function;
if < 0, a default is used (see do_callout())
+ callout_connect the connection timeout for callouts
se_mailfrom when callout is requested to verify a sender, use this
in MAIL FROM; NULL => ""
pm_mailfrom when callout is requested, if non-NULL, do the postmaster
int
verify_address(address_item *vaddr, FILE *f, int options, int callout,
- int callout_overall, uschar *se_mailfrom, uschar *pm_mailfrom, BOOL *routed)
+ int callout_overall, int callout_connect, uschar *se_mailfrom,
+ uschar *pm_mailfrom, BOOL *routed)
{
BOOL allok = TRUE;
BOOL full_info = (f == NULL)? FALSE : (debug_selector != 0);
BOOL is_recipient = (options & vopt_is_recipient) != 0;
BOOL expn = (options & vopt_expn) != 0;
-
int i;
int yield = OK;
int verify_type = expn? v_expn :
address_item *addr_remote = NULL;
address_item *addr_local = NULL;
address_item *addr_succeed = NULL;
+uschar **failure_ptr = is_recipient?
+ &recipient_verify_failure : &sender_verify_failure;
uschar *ko_prefix, *cr;
uschar *address = vaddr->address;
uschar *save_sender;
uschar null_sender[] = { 0 }; /* Ensure writeable memory */
+/* Clear, just in case */
+
+*failure_ptr = NULL;
+
/* Set up a prefix and suffix for error message which allow us to use the same
output statements both in EXPN mode (where an SMTP response is needed) and when
debugging with an output file. */
if (f != NULL)
fprintf(f, "%sA domain is required for \"%s\"%s\n", ko_prefix, address,
cr);
+ *failure_ptr = US"qualify";
return FAIL;
}
address = rewrite_address_qualify(address, is_recipient);
}
}
- /* Can only do a callout if we have at least one host! */
+ /* Can only do a callout if we have at least one host! If the callout
+ fails, it will have set ${sender,recipient}_verify_failure. */
if (host_list != NULL)
{
else
{
rc = do_callout(addr, host_list, &tf, callout, callout_overall,
- options, se_mailfrom, pm_mailfrom);
+ callout_connect, options, se_mailfrom, pm_mailfrom);
}
}
else
}
}
}
+
+ /* Otherwise, any failure is a routing failure */
+
+ else *failure_ptr = US"route";
/* A router may return REROUTED if it has set up a child address as a result
of a change of domain name (typically from widening). In this case we always
}
}
-return yield; /* Will be DEFER or FAIL if any one address has */
+/* Will be DEFER or FAIL if any one address has, only for full_info (which is
+the -bv or -bt case). */
+
+return yield;
}
log_msgptr points to where to put a log error message
callout timeout for callout check (passed to verify_address())
callout_overall overall callout timeout (ditto)
+ callout_connect connect callout timeout (ditto)
se_mailfrom mailfrom for verify; NULL => ""
pm_mailfrom sender for pm callout check (passed to verify_address())
options callout options (passed to verify_address())
int
verify_check_header_address(uschar **user_msgptr, uschar **log_msgptr,
- int callout, int callout_overall, uschar *se_mailfrom, uschar *pm_mailfrom,
- int options)
+ int callout, int callout_overall, int callout_connect, uschar *se_mailfrom,
+ uschar *pm_mailfrom, int options)
{
static int header_types[] = { htype_sender, htype_reply_to, htype_from };
int yield = FAIL;
{
vaddr = deliver_make_addr(address, FALSE);
new_ok = verify_address(vaddr, NULL, options | vopt_fake_sender,
- callout, callout_overall, se_mailfrom, pm_mailfrom, NULL);
+ callout, callout_overall, callout_connect, se_mailfrom,
+ pm_mailfrom, NULL);
}
}