-/* $Cambridge: exim/src/src/acl.c,v 1.41 2005/06/27 14:29:43 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.45 2005/09/06 13:17:36 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
BOOL defer_ok = FALSE;
BOOL callout_defer_ok = FALSE;
BOOL no_details = FALSE;
+BOOL success_on_redirect = FALSE;
address_item *sender_vaddr = NULL;
uschar *verify_sender_address = NULL;
uschar *pm_mailfrom = NULL;
return FAIL;
}
-/* We can test the result of optional HELO verification */
+/* We can test the result of optional HELO verification that might have
+occurred earlier. If not, we can attempt the verification now. */
if (strcmpic(ss, US"helo") == 0)
{
if (slash != NULL) goto NO_OPTIONS;
- return helo_verified? OK : FAIL;
+ if (helo_verified) return OK;
+ if (helo_verify_failed) return FAIL;
+ if (smtp_verify_helo()) return helo_verified? OK : FAIL;
+ return DEFER;
}
/* Do Client SMTP Authorization checks in a separate function, and turn the
if (strcmpic(ss, US"header_syntax") == 0)
{
if (slash != NULL) goto NO_OPTIONS;
- if (where != ACL_WHERE_DATA && where != ACL_WHERE_NOTSMTP)
- {
- *log_msgptr = string_sprintf("cannot check header contents in ACL for %s "
- "(only possible in ACL for DATA)", acl_wherenames[where]);
- return ERROR;
- }
+ if (where != ACL_WHERE_DATA && where != ACL_WHERE_NOTSMTP) goto WRONG_ACL;
rc = verify_check_headers(log_msgptr);
if (rc != OK && smtp_return_error_details && *log_msgptr != NULL)
*user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr);
return rc;
}
+/* Check that no recipient of this message is "blind", that is, every envelope
+recipient must be mentioned in either To: or Cc:. */
+
+if (strcmpic(ss, US"not_blind") == 0)
+ {
+ if (slash != NULL) goto NO_OPTIONS;
+ if (where != ACL_WHERE_DATA && where != ACL_WHERE_NOTSMTP) goto WRONG_ACL;
+ rc = verify_check_notblind();
+ if (rc != OK)
+ {
+ *log_msgptr = string_sprintf("bcc recipient detected");
+ if (smtp_return_error_details)
+ *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr);
+ }
+ return rc;
+ }
/* The remaining verification tests check recipient and sender addresses,
either from the envelope or from the header. There are a number of
if (strcmpic(ss, US"header_sender") == 0)
{
- if (where != ACL_WHERE_DATA && where != ACL_WHERE_NOTSMTP)
- {
- *log_msgptr = string_sprintf("cannot check header contents in ACL for %s "
- "(only possible in ACL for DATA)", acl_wherenames[where]);
- return ERROR;
- }
+ if (where != ACL_WHERE_DATA && where != ACL_WHERE_NOTSMTP) goto WRONG_ACL;
verify_header_sender = TRUE;
}
{
if (strcmpic(ss, US"defer_ok") == 0) defer_ok = TRUE;
else if (strcmpic(ss, US"no_details") == 0) no_details = TRUE;
+ else if (strcmpic(ss, US"success_on_redirect") == 0) success_on_redirect = TRUE;
/* These two old options are left for backwards compatibility */
else
verify_options |= vopt_fake_sender;
+ if (success_on_redirect)
+ verify_options |= vopt_success_on_redirect;
+
/* The recipient, qualify, and expn options are never set in
verify_options. */
{
address_item addr2;
+ if (success_on_redirect)
+ verify_options |= vopt_success_on_redirect;
+
/* We must use a copy of the address for verification, because it might
get rewritten. */
*log_msgptr = string_sprintf("unexpected '/' found in \"%s\" "
"(this verify item has no options)", arg);
return ERROR;
+
+/* Calls in the wrong ACL come here */
+
+WRONG_ACL:
+*log_msgptr = string_sprintf("cannot check header contents in ACL for %s "
+ "(only possible in ACL for DATA)", acl_wherenames[where]);
+return ERROR;
}
Arguments:
where ACL_WHERE_xxxx indicating where called from
- data_string RCPT address, or SMTP command argument, or NULL
+ recipient RCPT address for RCPT check, else NULL
s the input string; NULL is the same as an empty ACL => DENY
user_msgptr where to put a user error (for SMTP response)
log_msgptr where to put a logging message (not for SMTP response)
*/
int
-acl_check(int where, uschar *data_string, uschar *s, uschar **user_msgptr,
+acl_check(int where, uschar *recipient, uschar *s, uschar **user_msgptr,
uschar **log_msgptr)
{
int rc;
address_item adb;
-address_item *addr;
+address_item *addr = NULL;
*user_msgptr = *log_msgptr = NULL;
sender_verified_failed = NULL;
{
adb = address_defaults;
addr = &adb;
- addr->address = data_string;
+ addr->address = recipient;
if (deliver_split_address(addr) == DEFER)
{
*log_msgptr = US"defer in percent_hack_domains check";
deliver_domain = addr->domain;
deliver_localpart = addr->local_part;
}
-else
- {
- addr = NULL;
- smtp_command_argument = data_string;
- }
rc = acl_check_internal(where, addr, s, 0, user_msgptr, log_msgptr);
-smtp_command_argument = deliver_domain =
- deliver_localpart = deliver_address_data = sender_address_data = NULL;
+deliver_domain = deliver_localpart = deliver_address_data =
+ sender_address_data = NULL;
/* A DISCARD response is permitted only for message ACLs, excluding the PREDATA
ACL, which is really in the middle of an SMTP command. */