[exim] Recipient verification doesn't work at SMTP time

Top Page
Delete this message
Reply to this message
Author: Alexander Stintzing
Date:  
To: exim-users
Subject: [exim] Recipient verification doesn't work at SMTP time
Hello list,

I set up an exim with virtual users stored in a MySQL-Database. When I
send a message to existentuser@??? it is scanned and delivered
correctly. But when I send a message to nonexistent@??? which
should be rejected immediately, it will be accepted at first, then it's
spam-scanned and after that, Mail delivery failed: returning message to
sender.

Perhaps somebody will find the error:

begin routers

dnslookup:
driver = dnslookup
domains = ! +local_domains : !+smart_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
no_more

spampositive_local:
  condition = ${if and \
                { \
                  {match {$h_X-Spam-Flag:}{YES}} \
                  {> {${sg{$h_X-Spam-Score:}{\\.}{}}} \
                     {${lookup mysql{select users.sa_tag * 10 \
                      from users,domains \
                      where localpart = '${quote_mysql:$local_part}' \
                      and domain = '${quote_mysql:$domain}' \
                      and users.on_spamassassin = '1' \
                      and users.type = 'local' \
                      and users.domain_id=domains.domain_id } \
                    {$value}fail}} \
                  } \
                } \
                {yes}{no}}
  driver = accept
  transport = local_spam


spampositive_alias:
  condition = ${if and { {match {$h_X-Spam-Flag:}{YES}} \
                         {eq {${lookup mysql{select 
users.on_spamassassin from users,domains \
                                where localpart = 
'${quote_mysql:$local_part}' \
                                and domain = '${quote_mysql:$domain}' \
                                and users.on_spamassassin = '1' \
                                and users.type = 'alias' \
                                and 
users.domain_id=domains.domain_id}}}{1} }} {yes}{no} }
  driver = redirect
  allow_fail
  data = ${lookup mysql{select concat('${quote_mysql:$local_part}@', 
domain) \
                from domains,domainalias where domainalias.alias = 
'${quote_mysql:$domain}' \
                and domainalias.domain_id = domains.domain_id}}
  retry_use_local_part


spamcheck_local:
domains = +local_domains
condition = ${if eq {$received_protocol}{spam-scanned}{no}{yes}}
driver = accept
transport = spamcheck

spamcheck_smart:
  domains = +smart_domains                
  condition = ${if eq {$received_protocol}{spam-scanned}{no}{yes}}
  driver = accept
  transport = spamcheck


ditch_maxmsgsize:
  driver = redirect
  allow_fail
  condition = ${if >{$message_size}{${lookup mysql{select 
users.maxmsgsize from users,domains \
          where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and users.maxmsgsize > 0 \
        and users.domain_id=domains.domain_id }{${value}K}fail}} {yes}{no}}
  data = :fail:\n\Your message is too big.\n \
         Your message was rejected because the user $local_part@$domain\n \
        does not accept messages larger than \
        ${lookup mysql{select users.maxmsgsize from users,domains \
        where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and users.maxmsgsize > 0 \
        and users.domain_id=domains.domain_id}{${value}K}fail} Kb.
  local_part_suffix = -*
  local_part_suffix_optional
  retry_use_local_part


ditch_malware:
  driver = redirect
  allow_fail
  data = :blackhole:
  condition = ${if and { {match {$h_X-ACL-Warn:}{.*malware.*}} \
                         {eq {${lookup mysql{select users.on_avscan from 
users,domains \
                        where localpart = '${quote_mysql:$local_part}' \
                        and domain = '${quote_mysql:$domain}' \
                        and users.on_avscan = '1' \
                        and users.domain_id=domains.domain_id}}}{1} }} 
{yes}{no} }


ditch_hdrmailer:
  driver = redirect
  allow_fail
  data = :blackhole:
  condition = ${if eq {${lookup mysql{select count(*) from 
blocklists,users,domains \
              where blocklists.blockhdr = 'x-mailer' \
            and blocklists.blockval = '${quote_mysql:$h_x-mailer:}' \
            and users.localpart = '${quote_mysql:$local_part}' \
              and domains.domain = '${quote_mysql:$domain}' \
            and domains.domain_id=blocklists.domain_id \
            and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
  local_part_suffix = -*
  local_part_suffix_optional
  retry_use_local_part


ditch_hdrto:
  driver = redirect
  allow_fail
  data = :blackhole:
  condition = ${if eq {${lookup mysql{select count(*) from 
blocklists,users,domains \
              where blocklists.blockhdr = 'to' \
            and blocklists.blockval = '${quote_mysql:$h_to:}' \
            and users.localpart = '${quote_mysql:$local_part}' \
              and domains.domain = '${quote_mysql:$domain}' \
            and domains.domain_id=blocklists.domain_id \
            and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
  local_part_suffix = -*
  local_part_suffix_optional
  retry_use_local_part


ditch_hdrfrom:
  driver = redirect
  allow_fail
  data = :blackhole:
  condition = ${if eq {${lookup mysql{select count(*) from 
blocklists,users,domains \
              where blocklists.blockhdr = 'from' \
            and blocklists.blockval = '${quote_mysql:$h_from:}' \
            and users.localpart = '${quote_mysql:$local_part}' \
              and domains.domain = '${quote_mysql:$domain}' \
            and domains.domain_id=blocklists.domain_id \
            and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
  local_part_suffix = -*
  local_part_suffix_optional
  retry_use_local_part


ditch_hdrsubject:
  driver = redirect
  allow_fail
  data = :blackhole:
  condition = ${if eq {${lookup mysql{select count(*) from 
blocklists,users,domains \
              where blocklists.blockhdr = 'subject' \
            and blocklists.blockval = '${quote_mysql:$h_subject:}' \
            and users.localpart = '${quote_mysql:$local_part}' \
              and domains.domain = '${quote_mysql:$domain}' \
            and domains.domain_id=blocklists.domain_id \
            and users.user_id=blocklists.user_id}}}{1} {yes}{no}}
  local_part_suffix = -*
  local_part_suffix_optional
  retry_use_local_part


virtual_vacation:
  driver = accept
  condition = ${if and { {!match {$h_precedence:}{(?i)junk|bulk|list}} \
                         {eq {${lookup mysql{select users.on_vacation 
from users,domains \
                        where localpart = '${quote_mysql:$local_part}' \
                        and domain = '${quote_mysql:$domain}' \
                        and users.on_vacation = '1' \
                        and users.domain_id=domains.domain_id}}}{1} }} 
{yes}{no} }
  no_verify
  no_expn
  unseen
  transport = virtual_vacation_delivery


virtual_forward:
  driver = redirect
  check_ancestor
  unseen = ${if eq {${lookup mysql{select unseen from users,domains \
        where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and users.on_forward = '1' \
        and users.domain_id=domains.domain_id}}}{1} {yes}{no}}
  data = ${lookup mysql{select forward from users,domains \
    where localpart='${quote_mysql:$local_part}' \
    and domain='${quote_mysql:$domain}' \
    and users.domain_id=domains.domain_id \
    and on_forward = '1'}}
  # We explicitly make this condition NOT forward mailing list mail!
  condition = ${if and { {!match {$h_precedence:}{(?i)junk}} \
                         {eq {${lookup mysql{select users.on_forward 
from users,domains \
                        where localpart = '${quote_mysql:$local_part}' \
                        and domain = '${quote_mysql:$domain}' \
                        and users.on_forward = '1' \
                        and users.domain_id=domains.domain_id}}}{1} }} 
{yes}{no} }


virtual_domains:
  driver = redirect
  allow_fail
  data = ${lookup mysql{select smtp from users,domains \
          where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and domains.enabled = '1' \
        and users.enabled = '1' \
        and users.domain_id = domains.domain_id}}


local_part_suffix = -*
local_part_suffix_optional
retry_use_local_part
file_transport = virtual_delivery
reply_transport = address_reply
pipe_transport = address_pipe

.include /etc/exim4/vexim-group-router.conf

virtual_domains_catchall:
  driver = redirect
  allow_fail
  data = ${lookup mysql{select smtp from users,domains where localpart = 
'*' \
          and domain = '${quote_mysql:$domain}' \
        and users.domain_id = domains.domain_id}}
  retry_use_local_part
  file_transport = virtual_delivery
  reply_transport = address_reply
  pipe_transport = address_pipe_catchall


virtual_domain_alias:
  driver = redirect
  allow_fail
  data = ${lookup mysql{select concat('${quote_mysql:$local_part}@', 
domain) \
          from domains,domainalias where domainalias.alias = 
'${quote_mysql:$domain}' \
        and domainalias.domain_id = domains.domain_id}}
  retry_use_local_part


system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
user = mail
group = mail
file_transport = address_file
pipe_transport = address_pipe

userforward:
driver = redirect
check_local_user
file = $home/.forward
no_verify
no_expn
check_ancestor
# allow_filter
file_transport = address_file
pipe_transport = address_pipe_local
reply_transport = address_reply
condition = ${if exists{$home/.forward} {yes} {no} }
group = mail


hubbed_hosts:
        debug_print = "R: hubbed_hosts for $domain"
        driver = manualroute
        domains = +smart_domains
        route_data = ${lookup mysql{select destination from smarthosts 
where domain = '${quote_mysql:$domain}' \
                and enabled = 1}}


        transport = remote_smtp



localuser:
driver = accept
check_local_user
transport = local_delivery
cannot_route_message = Unknown user

begin acl
.include /etc/exim4/vexim-acl-check-spf.conf

acl_check_helo:
  accept hosts = :
  accept hosts = +relay_from_hosts
  drop condition = ${if match{$sender_helo_name}{MY_IP}{yes}{no} }
       message   = "Dropped spammer pretending to be us"
  drop condition = ${if 
match{$sender_helo_name}{^[0-9]\.[0-9]\.[0-9]\.[0-9]}{yes}{no} }
       message   = "Dropped IP-only or IP-starting helo"
  accept


acl_check_rcpt:
accept hosts = :

  deny    !authenticated = *
          message       = DNSBL listed at $dnslist_domain\n$dnslist_text
          dnslists      = zen.spamhaus.org:list.dsbl.org


  deny    local_parts   = ^.*[@%!/|] : ^\\.


  accept  local_parts   = postmaster
          domains       = +local_domains


#  require verify    = recipient


  accept  domains       = +local_domains
          endpass
          message       = Unknown user
          verify        = recipient


  accept domains        = +smart_domains
         endpass
         message        = Unknown user
         verify         = recipient/callout


  accept  domains       = +relay_to_domains
          endpass
          verify        = recipient


  accept  hosts         = +relay_from_hosts


  accept authenticated = *
       condition = ${if or \
                 { \
                 {eq{$sender_address}{$authenticated_id}} \
                 {eq{$sender_address}{test@???}} \
                 } \
                 {yes}{no}}


  deny    message       = relay not permitted




acl_check_content:

.include /etc/exim4/vexim-acl-check-content.conf

accept

begin transports

remote_smtp:
driver = smtp

local_delivery:
driver = appendfile
file = /var/mail/$local_part
delivery_date_add
envelope_to_add
return_path_add
group = mail
user = $local_part
mode = 0660
no_mode_fail_narrower

virtual_delivery:
  driver = appendfile
  envelope_to_add
  return_path_add
  mode = 0600
  maildir_format = true
  create_directory = true
  directory = ${lookup mysql{select smtp from users,domains \
        where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and users.domain_id = domains.domain_id}}
  user = ${lookup mysql{select users.uid  from users,domains \
        where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and users.domain_id = domains.domain_id}}
  group = ${lookup mysql{select users.gid from users,domains \
        where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and users.domain_id = domains.domain_id}}
  quota = ${lookup mysql{select users.quota from users,domains \
          where localpart = '${quote_mysql:$local_part}' \
        and domain = '${quote_mysql:$domain}' \
        and users.domain_id = domains.domain_id}{${value}M}}
  quota_is_inclusive = false
  #quota_size_regex = ,S=(\d+):
  quota_warn_threshold = 75%
  maildir_use_size_file = false
  quota_warn_message = "To: $local_part@$domain\n\
              Subject: Mailbox quota warning\n\n\
            This message was automatically generated by the mail 
delivery software.\n\n\
            You are now using over 75% of your allocated mail storage 
quota.\n\n\
            If your mailbox fills completely, further incoming messages 
will be automatically\n\
            returned to their senders.\n\n\
            Please take note of this and remove unwanted mail from your 
mailbox.\n"


spamcheck:
debug_print = "T: spamassassin_pipe for $local_part@$domain"
driver = pipe
command = /usr/sbin/exim -oMr spam-scanned -bS
use_bsmtp
transport_filter = /usr/bin/spamc -d localhost -u $domain
return_fail_output
message_prefix =
message_suffix =

local_spam:
  driver = appendfile
  envelope_to_add
  return_path_add
  mode = 0600
  maildir_format = true
  create_directory = true
  directory = ${lookup mysql{select smtp from users,domains \
                where localpart = '${quote_mysql:$local_part}' \
                and domain = '${quote_mysql:$domain}' \
                and users.domain_id = domains.domain_id}}/.Spam/
  user = ${lookup mysql{select users.uid  from users,domains \
                where localpart = '${quote_mysql:$local_part}' \
                and domain = '${quote_mysql:$domain}' \
                and users.domain_id = domains.domain_id}}
  group = ${lookup mysql{select users.gid from users,domains \
                where localpart = '${quote_mysql:$local_part}' \
                and domain = '${quote_mysql:$domain}' \
                and users.domain_id = domains.domain_id}}


virtual_vacation_delivery:
  driver   = autoreply
  from     = "${local_part}@${domain}"
  to       = ${sender_address}
  subject  = "Autoreply from ${local_part}@${domain}"
  text     = ${lookup mysql{select vacation from users,domains \
        where domain='${quote_mysql:$domain}' \
        and localpart='${quote_mysql:$local_part}' \
        and users.domain_id=domains.domain_id}}


address_pipe:
driver = pipe
return_output
user = ${lookup mysql{select users.uid from users,domains where
localpart = '${quote_mysql:$local_part}' and domain =
'${quote_mysql:$domain}' and users.domain_id = domains.domain_id}}
group = ${lookup mysql{select users.gid from users,domains where
localpart = '${quote_mysql:$local_part}' and domain =
'${quote_mysql:$domain}' and users.domain_id = domains.domain_id}}

address_pipe_catchall:
driver = pipe
return_output
user = ${lookup mysql{select users.uid from users,domains where
localpart = '*' and domain = '${quote_mysql:$domain}' and
users.domain_id = domains.domain_id}}
group = ${lookup mysql{select users.gid from users,domains where
localpart = '*' and domain = '${quote_mysql:$domain}' and
users.domain_id = domains.domain_id}}

address_pipe_local:
driver = pipe
return_output


# This transport is used for handling deliveries directly to files that are
# generated by aliasing or forwarding.

address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add


# This transport is used for handling autoreplies generated by the filtering
# option of the userforward router.

address_reply:
driver = autoreply