An attempt to set this control for any recipient but the first
for a mail will be quietly ignored.
If a recipient-verify callout
-(with use_sender)
+(with use_sender or use_tpt_sender)
connection is subsequently
requested in the same ACL it is held open and used for
any subsequent recipients and the data,
in the inbound (originating) connection.
A value of &"transport"& permits the transport used for the outbound
connection to modify the envelope-from, via its &*return_path*& option.
+If the control is used on combination with a verify (as described above)
+then the envelope-from options must match for the same connection to be used.
.wen
the sender address when verifying a recipient. Using the same address means
that a single cache entry can be used for each recipient. Some sites, however,
do make use of the sender address when verifying. These are catered for by the
-&%use_sender%& and &%use_postmaster%& options, described in the next section.
+&%use_sender%&,
+.new
+&%use_tptsender%&
+.wen
+and &%use_postmaster%& options, described in the next section.
If the response to the RCPT command is a 2&'xx'& code, the verification
succeeds. If it is 5&'xx'&, the verification fails. For any other condition,
sender when checking recipients. If used indiscriminately, it reduces the
usefulness of callout caching.
+.vitem &*use_tptsender*&
+This option is similar to &*use_sender*& above,
+but additionally permits the replacement of the sender address
+by the &*return_path*& option of the transport.
+
.vitem &*hold*&
This option applies to recipient callouts only. For example:
.code
enum { CALLOUT_DEFER_OK, CALLOUT_NOCACHE, CALLOUT_RANDOM, CALLOUT_USE_SENDER,
- CALLOUT_USE_POSTMASTER, CALLOUT_POSTMASTER, CALLOUT_FULLPOSTMASTER,
- CALLOUT_MAILFROM, CALLOUT_POSTMASTER_MAILFROM, CALLOUT_MAXWAIT, CALLOUT_CONNECT,
- CALLOUT_HOLD, CALLOUT_TIME /* TIME must be last */
+ CALLOUT_USE_TPTSENDER, CALLOUT_USE_POSTMASTER, CALLOUT_POSTMASTER,
+ CALLOUT_FULLPOSTMASTER, CALLOUT_MAILFROM, CALLOUT_POSTMASTER_MAILFROM,
+ CALLOUT_MAXWAIT, CALLOUT_CONNECT, CALLOUT_HOLD,
+ CALLOUT_TIME /* TIME must be last */
};
typedef struct {
uschar * name;
{ US"no_cache", CALLOUT_NOCACHE, vopt_callout_no_cache, FALSE, FALSE },
{ US"random", CALLOUT_RANDOM, vopt_callout_random, FALSE, FALSE },
{ US"use_sender", CALLOUT_USE_SENDER, vopt_callout_recipsender, FALSE, FALSE },
- { US"use_postmaster", CALLOUT_USE_POSTMASTER,vopt_callout_recippmaster, FALSE, FALSE },
+ { US"use_tptsender", CALLOUT_USE_TPTSENDER, vopt_callout_r_tptsender, FALSE, FALSE },
+ { US"use_postmaster", CALLOUT_USE_POSTMASTER,vopt_callout_r_pmaster, FALSE, FALSE },
{ US"postmaster_mailfrom",CALLOUT_POSTMASTER_MAILFROM,0, TRUE, FALSE },
{ US"postmaster", CALLOUT_POSTMASTER, 0, FALSE, FALSE },
{ US"fullpostmaster", CALLOUT_FULLPOSTMASTER,vopt_callout_fullpm, FALSE, FALSE },
acl_verify(int where, address_item *addr, const uschar *arg,
uschar **user_msgptr, uschar **log_msgptr, int *basic_errno)
{
-int sep = '/';
-int callout = -1;
-int callout_overall = -1;
-int callout_connect = -1;
-int verify_options = 0;
-int rc;
-BOOL verify_header_sender = FALSE;
-BOOL defer_ok = FALSE;
-BOOL callout_defer_ok = FALSE;
-BOOL no_details = FALSE;
-BOOL success_on_redirect = FALSE;
-BOOL quota = FALSE;
+int sep = '/', callout = -1, callout_overall = -1, callout_connect = -1;
+int verify_options = 0, rc;
+BOOL verify_header_sender = FALSE, defer_ok = FALSE, callout_defer_ok = FALSE;
+BOOL no_details = FALSE, success_on_redirect = FALSE, quota = FALSE;
int quota_pos_cache = QUOTA_POS_DEFAULT, quota_neg_cache = QUOTA_NEG_DEFAULT;
address_item * sender_vaddr = NULL;
const uschar * verify_sender_address = NULL;
-uschar * pm_mailfrom = NULL;
-uschar * se_mailfrom = NULL;
+uschar * pm_mailfrom = NULL, * se_mailfrom = NULL;
/* Some of the verify items have slash-separated options; some do not. Diagnose
an error if options are given for items that don't expect them.
*/
-uschar *slash = Ustrchr(arg, '/');
-const uschar *list = arg;
-uschar *ss = string_nextinlist(&list, &sep, NULL, 0);
+uschar * slash = Ustrchr(arg, '/');
+const uschar * list = arg;
+uschar * ss = string_nextinlist(&list, &sep, NULL, 0);
verify_type_t * vp;
if (!ss) goto BAD_VERIFY;
}
}
-if ((verify_options & (vopt_callout_recipsender|vopt_callout_recippmaster)) ==
- (vopt_callout_recipsender|vopt_callout_recippmaster))
- {
- *log_msgptr = US"only one of use_sender and use_postmaster can be set "
- "for a recipient callout";
- return ERROR;
- }
+ {
+ int ropts = verify_options &
+ (vopt_callout_recipsender|vopt_callout_r_tptsender|vopt_callout_r_pmaster);
+ if (ropts && verify_sender_address)
+ {
+ *log_msgptr = US"use_sender, use_tptsender or use_postmaster cannot be used"
+ "for a sender verify callout";
+ return ERROR;
+ }
+ if ((ropts-1) & -ropts) /* more than one bit set */
+ {
+ *log_msgptr = US"only one of use_sender, use_tptsender and use_postmaster"
+ " can be set for a recipient callout";
+ return ERROR;
+ }
+ }
/* Handle quota verification */
if (quota)
else if (verify_sender_address)
{
- if ((verify_options & (vopt_callout_recipsender|vopt_callout_recippmaster)))
- {
- *log_msgptr = US"use_sender or use_postmaster cannot be used for a "
- "sender verify callout";
- return ERROR;
- }
-
sender_vaddr = verify_checked_sender(verify_sender_address);
if ( sender_vaddr /* Previously checked */
&& callout <= 0) /* No callout needed this time */
}
else if (Ustrncmp(pp, "sender=", 7) == 0)
{
-/*XXX rather raises the Q: should r-verify have a similar option?
-Esp. given the callout hold options and upgrade to cutthrough... */
pp += 7;
if (Ustrncmp(pp, "transport", 9) == 0)
cutthrough.tpt_sender = TRUE;
}
break; /* host_list */
}
-if (!done)
- cancel_cutthrough_connection(TRUE, US"incompatible connection");
return done;
}
vopt_callout_fullpm => if postmaster check, do full one
vopt_callout_random => do the "random" thing
vopt_callout_recipsender => use original sender addres
- vopt_callout_recippmaster => use postmaster as sender
-vopt_callout_r_tptsender => use sender as defined by transport
- vopt_callout_hold => lazy close connection
+ vopt_callout_r_pmaster => use postmaster as sender
+ vopt_callout_r_tptsender => use sender defined by tpt
+ vopt_callout_hold => lazy close connection
se_mailfrom MAIL FROM address for sender verify; NULL => ""
pm_mailfrom if non-NULL, do the postmaster check with this sender
if (options & vopt_is_recipient)
if (options & ( vopt_callout_recipsender
| vopt_callout_r_tptsender
- | vopt_callout_recippmaster)
+ | vopt_callout_r_pmaster)
)
{
if (options & vopt_callout_recipsender)
from_address = string_sprintf("postmaster@%s", qualify_domain_sender);
address_key = string_sprintf("%s/<%s>", addr->address, from_address);
+ addr->return_path = from_address; /* for cutthrough logging */
if (cutthrough.delivery) /* cutthrough previously req. */
- {
options |= vopt_callout_no_cache; /* in case called by verify= */
- addr->return_path = from_address; /* for cutthrough logging */
- }
}
else
{
coding means skipping this whole loop and doing the append separately. */
/* Can we re-use an open cutthrough connection? */
- if ( cutthrough.cctx.sock >= 0
- && (options & ( vopt_callout_recipsender
- | vopt_callout_r_tptsender | vopt_callout_recippmaster))
- == vopt_callout_recipsender
- && !random_local_part
- && !pm_mailfrom
- )
- done = cutthrough_multi(addr, host_list, tf, &yield);
+
+ if (cutthrough.cctx.sock >= 0)
+ {
+ if ( !(options & vopt_callout_r_pmaster)
+ && !random_local_part
+ && !pm_mailfrom
+ && Ustrcmp(addr->return_path, cutthrough.addr.return_path) == 0
+ )
+ done = cutthrough_multi(addr, host_list, tf, &yield);
+
+ if (!done)
+ cancel_cutthrough_connection(TRUE, US"incompatible connection");
+ }
/* If we did not use a cached connection, make connections to the hosts
and do real callouts. The list of hosts is passed in as an argument. */
&& rcpt_count == 1
&& done
&& yield == OK
- && !(options & (vopt_callout_recippmaster | vopt_success_on_redirect))
+ && !(options & (vopt_callout_r_pmaster| vopt_success_on_redirect))
&& !random_local_part
&& !pm_mailfrom
&& cutthrough.cctx.sock < 0
vopt_callout_fullpm => if postmaster check, do full one
vopt_callout_no_cache => don't use callout cache
- vopt_callout_random => do the "random" thing
- vopt_callout_recipsender => use real sender for recipient
+ vopt_callout_random => do the "random" thing
+ vopt_callout_recipsender => use real sender for recipient
vopt_callout_recippmaster => use postmaster for recipient
-vopt_callout_r_tptsender => use sender as defined by transport
+ vopt_callout_r_tptsender => use sender as defined by tpt
callout if > 0, specifies that callout is required, and gives timeout
for individual commands