add log message
[mirror/dsa-puppet.git] / modules / exim / templates / eximconf.erb
index f6cc8b7..f156a03 100644 (file)
@@ -35,6 +35,7 @@
 #           us. This is primarily only usefull for emergancy 'queue
 #           flushing' operations, but should be populated with a list
 #           of trusted machines. Wildcards are not permitted
+#  bsmtp_domains - Domains that we deliver locally via bsmtp
 <%=
 out = ""
 if nodeinfo['mailrelay']
@@ -78,7 +79,7 @@ out
 # will trigger things like rcpt to rate limiting or possibly a reject if
 # enough hits are triggered.
 #
-# value is stored in acl_c1
+# value is stored in acl_c_scr
 
 ######################################################################
 #                    MAIN CONFIGURATION SETTINGS                     #
@@ -108,6 +109,7 @@ if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty?
 end
 out
 %>
+acl_smtp_predata = acl_check_predata
 
 # accept domain literal syntax in e-mail addresses. To actually make use of
 # this a router is also required
@@ -130,10 +132,14 @@ domainlist virtual_domains = partial-lsearch;/etc/exim4/virtualdomains
 
 domainlist submission_domains = ${if exists {/etc/exim4/submission-domains}{/etc/exim4/submission-domains}{}}
 
-domainlist handled_domains = +local_domains : +virtual_domains
+domainlist bsmtp_domains = ${if exists {/etc/exim4/bsmtp}{partial-lsearch;/etc/exim4/bsmtp}{}}
+
+domainlist handled_domains = +local_domains : +virtual_domains : +bsmtp_domains
 
 localpartlist local_only_users = lsearch;/etc/exim4/localusers
 
+localpartlist postmasterish = postmaster : abuse : hostmaster : root
+
 # Domains we relay for; that is domains that aren't considered local but we 
 # accept mail for them.
 domainlist rcpthosts = partial-lsearch;/etc/exim4/rcpthosts
@@ -192,10 +198,16 @@ timeout_frozen_after=14d
 
 message_size_limit = 100M
 message_logs = false
-smtp_accept_max = 300
 smtp_accept_max_per_host = ${if match_ip {$sender_host_address}{+debianhosts}{0}{7}}
+<% if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty? %>
+smtp_accept_max = 300
 smtp_accept_queue = 200
 smtp_accept_queue_per_connection = 50
+<% else %>
+smtp_accept_max = 30
+smtp_accept_queue = 20
+smtp_accept_queue_per_connection = 10
+<% end %>
 smtp_accept_reserve = 25
 smtp_reserve_hosts = +debianhosts
 
@@ -205,9 +217,15 @@ check_spool_space  = 20M
 
 delay_warning =
 
+<% if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty? %>
 queue_run_max = 50
 deliver_queue_load_max = 50
 queue_only_load = 15
+<% else %>
+queue_run_max = 5
+deliver_queue_load_max = 10
+queue_only_load = 5
+<% end %>
 queue_list_requires_admin = false
 
 <%= out  = ""
@@ -280,9 +298,108 @@ RT_QUEUE_MAP = /srv/rt.debian.org/mail/rt_queue_map
 ######################################################################
 begin acl
 
+acl_getprofile:
+  # This is a bad hack to reset the variable, by defining it be something
+  # never referenced.
+
+  warn    set acl_m_rprf = $acl_m_undefined
+
+  warn    recipients     = survey@popcon.debian.org
+          set acl_m_rprf = PopconMail
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    local_parts    = +local_only_users
+          domains        = +local_domains
+          hosts          = !+debianhosts
+          set acl_m_rprf = localonly
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+<%=
+out=''
+if nodeinfo['rtmaster']
+  out='
+  warn    domains        = rt.debian.org
+          set acl_m_rprf = RTMail
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+'
+end
+out
+%>
+<%=
+out = ''
+if nodeinfo['packagesmaster']
+  out = '
+  warn    domains        = packages.debian.org
+          set acl_m_rprf = PackagesMail
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+'
+end
+out
+%>
+<%=
+out = ''
+if nodeinfo['packagesqamaster']
+  out='
+  warn    recipients     = owner@packages.qa.debian.org : postmaster@packages.qa.debian.org
+          set acl_m_rprf = PTSOwner
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    senders        = :
+          domains        = packages.qa.debian.org
+          condition      = ${if match{$local_part}{\N^bounces+\N}}
+          set acl_m_rprf = PTSListBounce
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    domains        = packages.qa.debian.org
+          set acl_m_rprf = PTSMail
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+'
+end
+out
+%>
+  warn    recipients     = change@db.debian.org : changes@db.debian.org : chpasswd@db.debian.org : ping@db.debian.org : recommend@nm.debian.org
+          set acl_m_rprf = DBSignedMail
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    domains        = +virtual_domains
+          condition      = ${if exists {${extract{directory}{VDOMAINDATA}{${value}/contentinspectionaction}}}}
+          condition      = ${if eq{${lookup{$local_part}lsearch*{${extract{directory}{VDOMAINDATA}{${value}/contentinspectionaction}}}{$value}{}}}{markup}}
+          set acl_m_rprf = markup
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    condition      = ${if eq{${lookup{$local_part}cdb{/var/lib/misc/${primary_hostname}/mail-contentinspectionaction.cdb}{$value}{}}}{markup}}
+          set acl_m_rprf = markup
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    condition      = ${if eq{${lookup{$local_part}cdb{/var/lib/misc/${primary_hostname}/mail-contentinspectionaction.cdb}{$value}{}}}{blackhole}}
+          set acl_m_rprf = blackhole
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    domains        = +virtual_domains
+          condition      = ${if exists {${extract{directory}{VDOMAINDATA}{${value}/contentinspectionaction}}}}
+          condition      = ${if eq{${lookup{$local_part}lsearch*{${extract{directory}{VDOMAINDATA}{${value}/contentinspectionaction}}}{$value}{}}}{blackhole}}
+          set acl_m_rprf = blackhole
+
+  accept  condition      = ${if eq {$acl_m_rprf}{}{no}{yes}}
+
+  warn    set acl_m_rprf = normal
+
+  accept
+
 check_helo:
 
-  warn    set acl_c1    = 0
+  warn    set acl_c_scr    = 0
 
 <%= 
 out = ""
@@ -297,36 +414,36 @@ out
 
   warn    dnslists       = list.dnswl.org&0.0.0.3
           log_message    = Hit on list.dnswl.org for $sender_host_address
-          set acl_c1     = ${eval:$acl_c1-30}
+          set acl_c_scr  = ${eval:$acl_c_scr-30}
 
   warn    dnslists       = list.dnswl.org&0.0.0.2
           log_message    = Hit on list.dnswl.org for $sender_host_address
-          set acl_c1     = ${eval:$acl_c1-20}
+          set acl_c_scr  = ${eval:$acl_c_scr-20}
 
   warn    dnslists       = list.dnswl.org
           log_message    = Hit on list.dnswl.org for $sender_host_address
-          set acl_c1     = ${eval:$acl_c1-10}
+          set acl_c_scr  = ${eval:$acl_c_scr-10}
 
   warn    condition      = ${if isip {$sender_helo_name}{true}{false}}
           log_message    = remote host used IP address in HELO/EHLO greeting
-          set acl_c1     = ${eval:$acl_c1+20}
+          set acl_c_scr  = ${eval:$acl_c_scr+20}
 
   warn    !hosts         = +debianhosts
           condition      = ${if eq{$host_lookup_failed}{1}}
-          set acl_c1     = ${eval:$acl_c1+20}
+          set acl_c_scr  = ${eval:$acl_c_scr+20}
 
   warn    !hosts         = +debianhosts
           condition      = ${if eq{$host_lookup_failed}{0}}
           condition      = ${if match{$sender_host_name}{\N(^[^\.]*[0-9]\-+[0-9]|^[^\.]*[0-9]{5,}[^\.]|^([^\.]+\.)?[0-9][^ \.]*\.[^\.]+\..+\.[a-z]|^[^\.]*[0-9]\.[^\.]*[0-9]-[0-9]|^(dyn|cable|dhcp|dialup|ppp|adsl)[^\.]*[0-9])\N}}
-          set acl_c1     = ${eval:$acl_c1+20}
+          set acl_c_scr  = ${eval:$acl_c_scr+20}
 
   warn    !hosts         = +debianhosts
           condition      = ${if match{$sender_helo_name}{\N(^[^\.]*[0-9]\-+[0-9]|^[^\.]*[0-9]{5,}[^\.]|^([^\.]+\.)?[0-9][^ \.]*\.[^\.]+\..+\.[a-z]|^[^\.]*[0-9]\.[^\.]*[0-9]-[0-9]|^(dyn|cable|dhcp|dialup|ppp|adsl)[^\.]*[0-9])\N}}
-          set acl_c1     = ${eval:$acl_c1+20}
+          set acl_c_scr  = ${eval:$acl_c_scr+20}
 
   warn    !hosts         = +debianhosts
           dnslists       = dul.dnsbl.sorbs.net
-          set acl_c1     = ${eval:$acl_c1+15}
+          set acl_c_scr  = ${eval:$acl_c_scr+15}
 
   # If the sender's helo name is empty, the message will be rejected later
   # because the helo is empty.  If the rDNS lookup failed, we are already
@@ -338,7 +455,7 @@ out
           condition      = ${if def:sender_helo_name {yes}{no}}
           condition      = ${if eq {${lc:$sender_helo_name}}{${lc:$sender_host_name}}{no}{yes}}
           log_message    = HELO doesn't match rDNS
-          set acl_c1     = ${eval:$acl_c1+8}
+          set acl_c_scr  = ${eval:$acl_c_scr+8}
 
   # Regexes of doom
   # matches 098325879 - looks fishy
@@ -349,13 +466,13 @@ out
                                     } \
                             }
        log_message      = non-FQDN HELO
-       set acl_c1       = ${eval:$acl_c1+12}
+       set acl_c_scr    = ${eval:$acl_c_scr+12}
 
   # Matches DOMAIN99.com - looks bad
 
   warn condition       = ${if match {$sender_helo_name}{\N^[A-Z]+[A-Z0-9\-]+\.[A-Za-z0-9]+$\N}}
        log_message     = SHOUTING HELO
-       set acl_c1      = ${eval:$acl_c1+7}
+       set acl_c_scr   = ${eval:$acl_c_scr+7}
 
   # Random HELO (run of 7 consonants) (constructed by viruses).  We purposefully
   # skip matching on machines named .*smtp.*, since that's 4 already.  This is a fairly
@@ -365,7 +482,7 @@ out
        condition       = ${if match {${lc:$sender_helo_name}}{\N^[a-z0-9]+\.[a-z]+$\N}}
        condition       = ${if match {${lc:$sender_helo_name}}{\N.*[bcdfghjklmnpqrstvwxz]{7,}.*\.[a-z]+$\N}}
        log_message     = random HELO
-       set acl_c1      = ${eval:$acl_c1+5}
+       set acl_c_scr   = ${eval:$acl_c_scr+5}
 
   # Implicit, but simpler to just say it
   accept
@@ -457,7 +574,7 @@ out
 
   # This logic gives you a list of commonly forged domains in helo to reject against
 
-  warn set acl_m2      = ${lookup{$sender_helo_name} \
+  warn set acl_m_frg   = ${lookup{$sender_helo_name} \
                            nwildlsearch{/etc/exim4/helo-check} \
                           {${if eq{$value}{}{$sender_helo_name}{$value}}}{}}
 
@@ -465,15 +582,15 @@ out
   # say helo as a name in the list but we can't look them up
 
   defer !hosts         = +debianhosts
-        condition      = ${if eq{$acl_m2}{}{no}{yes}}
+        condition      = ${if eq{$acl_m_frg}{}{no}{yes}}
         condition      = ${if eq{$sender_host_name}{}{yes}{no}}
         condition      = ${if eq{$host_lookup_failed}{1}{no}{yes}}
         message        = Access temporarily denied. Resolve failed PTR for $sender_host_address
 
   # If DNS works, go ahead and reject them
 
-  drop !hosts          = +debianhosts
-       condition       = ${if and { {!eq{$acl_m2}{}}{!match{$sender_host_name}{${rxquote:$acl_m2}\N$\N}}}{yes}{no}}
+  drop  !hosts         = +debianhosts
+        condition      = ${if and { {!eq{$acl_m_frg}{}}{!match{$sender_host_name}{${rxquote:$acl_m_frg}\N$\N}}}{yes}{no}}
         message        = HELO mismatch Forged HELO for ($sender_helo_name)
 
   # disabled accounts don't even get local mail.
@@ -513,10 +630,15 @@ out
           condition     = ${if match_local_part {$sender_address_local_part}{${extract{directory}{VDOMAINDATA}{${value}/neversenders}}}{1}{0}}
          message       = no mail should ever come from <$sender_address>
 
-  deny    local_parts   = +local_only_users
-         domains       = +local_domains
-          hosts         = !+debianhosts
-         message       = mail for $local_part is only accepted internally
+  warn    acl           = acl_getprofile
+          condition     = ${if eq{$acl_m_prf}{}}
+          set acl_m_prf = $acl_m_rprf
+
+  defer   condition     = ${if eq{$acl_m_prf}{$acl_m_rprf}{no}{yes}}
+          log_message   = Only one profile at a time, please
+
+  warn    condition     = ${if eq{$acl_m_prf}{localonly}}
+          set acl_m_lrc = ${if eq{$acl_m_lrc}{}{$local_part@$domain}{$acl_m_lrc, $local_part@$domain}}
 
 <%=
 out=''
@@ -529,12 +651,22 @@ out='
 end
 out
 %>
-
-  deny    !recipients = survey@popcon.debian.org
-          !verify = sender
+<%=
+out=''
+if nodeinfo['packagesmaster']
+  out='
+  warn    condition      = ${if eq {$acl_m_prf}{PackagesMail}}
+          condition      = ${if eq {$sender_address}{$local_part@$domain}}
+          message        = X-Packages-FromTo-Same: yes
+'
+end
+out
+%>
+  deny    condition      = ${if eq {$acl_m_prf}{PopconMail}{no}{yes}}
+          !verify        = sender
 
   defer   !hosts         = +debianhosts
-          condition      = ${if >{${eval:$acl_c1}}{0}}
+          condition      = ${if >{${eval:$acl_c_scr+0}}{0}}
           ratelimit      = 10 / 60m / per_rcpt / $sender_host_address
           message        = slow down (no reverse dns, mismatched ehlo, dialup, or in blacklists)
 <%=
@@ -550,7 +682,7 @@ out = '
   # closure, but I\'m fairly sure it\'s now worth it, since the backport of
   # policyd-weight is trivial.
   warn  !hosts         = +debianhosts
-        set acl_m9     = ${readsocket{inet:127.0.0.1:12525}\
+        set acl_m_pw   = ${readsocket{inet:127.0.0.1:12525}\
                           {request=smtpd_access_policy\n\
                            protocol_state=RCPT\n\
                            protocol_name=${uc:$received_protocol}\n\
@@ -567,72 +699,47 @@ out = '
 
   # Defer on socket error
   defer !hosts         = +debianhosts
-        condition      = ${if eq{$acl_m9}{socket failure}{yes}{no}}
+        condition      = ${if eq{$acl_m_pw}{socket failure}{yes}{no}}
         message        = Cannot connect to policyd-weight. Please try again later.
 
-  # Set proposed action to $acl_m8 and message to $acl_m7
+  # Set proposed action to $acl_m_act and message to $acl_m_mes
   warn  !hosts         = +debianhosts
-        set acl_m8     = ${extract{action}{$acl_m9}}
-        set acl_m7     = ${sg{$acl_m9}{\Naction=[^ ]+ (.*)\n\n\N}{\$1}}
+        set acl_m_mes  = ${extract{action}{$acl_m_pw}}
+        set acl_m_act  = ${sg{$acl_m_pw}{\Naction=[^ ]+ (.*)\n\n\N}{\$1}}
 
   # Add X-policyd-weight header line to message
   warn  !hosts         = +debianhosts
-        message        = $acl_m7
-        condition      = ${if eq{$acl_m8}{PREPEND}{yes}{no}}
+        message        = $acl_m_mes
+        condition      = ${if eq{$acl_m_act}{PREPEND}{yes}{no}}
 
   # Write log message, if policyd-weight can\'t run checks
   warn  !hosts         = +debianhosts
-        log_message    = policyd-weight message: $acl_m7
-        condition      = ${if eq{$acl_m8}{DUNNO}{yes}{no}}
+        log_message    = policyd-weight message: $acl_m_mes
+        condition      = ${if eq{$acl_m_act}{DUNNO}{yes}{no}}
 
   # Deny mails which policyd-weight thinks are spam
   deny  !hosts         = +debianhosts
-        message        = policyd-weight said: $acl_m7
-        condition      = ${if eq{$acl_m8}{550}{yes}{no}}
+        message        = policyd-weight said: $acl_m_mes
+        condition      = ${if eq{$acl_m_act}{550}{yes}{no}}
 
   # Defer messages when policyd-weight suggests so.
   defer  !hosts         = +debianhosts
-         message        = policyd-weight said: $acl_m7
-         condition      = ${if eq{$acl_m8}{450}{yes}{no}}
+         message        = policyd-weight said: $acl_m_mes
+         condition      = ${if eq{$acl_m_act}{450}{yes}{no}}
 '
 end
 out
 %>
-  warn    recipients = survey@popcon.debian.org
-          set acl_m1 = PopconMail
-
 <%=
 out=''
 if nodeinfo['rtmaster']
   out='
-  warn    domains  = rt.debian.org
-          set acl_m1 = RTMail
-          set acl_m12 = ${if def:acl_m12 {$acl_m12} {${if or{{match{$local_part}{[^+]+\\+\\d+}}{match{$local_part}{[^+]+\\+new}}} {RTMailRecipientHasSubaddress}}}}
+  warn    condition     = ${if eq{$acl_m_prf}{RTMail}}
+          set acl_m12   = ${if def:acl_m12 {$acl_m12} {${if or{{match{$local_part}{\N[^+]+\+\d+\N}}{match{$local_part}{\N[^+]+\+new\N}}} {RTMailRecipientHasSubaddress}}}}
 '
 end
 out
 %>
-<%=
-out=''
-if nodeinfo['packagesmaster']
-  out='
-  warn    domains  = packages.qa.debian.org
-          set acl_m1 = PTSMail
-
-  warn    recipients = owner@packages.qa.debian.org : postmaster@packages.qa.debian.org
-          set acl_m1 = PTSOwner
-
-  warn    senders  = :
-          domains  = packages.qa.debian.org
-          condition = ${if match{$local_part}{\N^bounces+\N}}
-          set acl_m1 = PTSListBounce
-'
-end
-out
-%>
-  warn    recipients = change@db.debian.org : changes@db.debian.org : chpasswd@db.debian.org : ping@db.debian.org : recommend@nm.debian.org
-          set acl_m1 = DBSignedMail
-
 <%=
 out = ""
 if has_variable?("greylistd") && greylistd == "true"
@@ -663,12 +770,12 @@ if has_variable?("greylistd") && greylistd == "true"
 elsif has_variable?("postgrey") && postgrey == "true"
   out = '
   # next three are greylisting, inspired by http://www.bebt.de/blog/debian/archives/2006/07/30/T06_12_27/index.html
-  # this adds acl_m4 if there isn\'t one (so unique per message)
+  # this adds acl_m_grey if there isn\'t one (so unique per message)
   warn
     !senders       = :
     !hosts         = : +debianhosts : WHITELIST
-    condition      = ${if def:acl_m4 {no}{yes}}
-    set acl_m4     = $pid.$tod_epoch.$sender_host_port
+    condition      = ${if def:acl_m_grey {no}{yes}}
+    set acl_m_grey = $pid.$tod_epoch.$sender_host_port
 
   # and defers the message if postgrey thinks it should be defered ...
   defer
@@ -677,22 +784,22 @@ elsif has_variable?("postgrey") && postgrey == "true"
     !authenticated = *
     domains        = +handled_domains : +rcpthosts
     local_parts    = GREYLIST_LOCAL_PARTS
-    set acl_m3     = request=smtpd_access_policy\n\
+    set acl_m_pgr  = request=smtpd_access_policy\n\
                      protocol_state=RCPT\n\
                      protocol_name=${uc:$received_protocol}\n\
-                     instance=${acl_m4}\n\
+                     instance=${acl_m_grey}\n\
                      helo_name=${sender_helo_name}\n\
                      client_address=${substr_-3:${mask:$sender_host_address/24}}\n\
                      client_name=${sender_host_name}\n\
                      sender=${sender_address}\n\
                      recipient=$local_part@$domain\n\n
-    set acl_m3     = ${sg{\
-                         ${readsocket{/var/run/postgrey/socket}{$acl_m3}\
+    set acl_m_pgr  = ${sg{\
+                         ${readsocket{/var/run/postgrey/socket}{$acl_m_pgr}\
                                {5s}{}{action=DUNNO}}\
                      }{action=}{}}
-    message        = ${sg{$acl_m3}{^\\\\w+\\\\s*}{}}
+    message        = ${sg{$acl_m_pgr}{^\\\\w+\\\\s*}{}}
     log_message    = greylisted.
-    condition      = ${if eq{${uc:${substr{0}{5}{$acl_m3}}}}{DEFER}}
+    condition      = ${if eq{${uc:${substr{0}{5}{$acl_m_pgr}}}}{DEFER}}
 
  # ... or adds a header with information about how long the delay was
  warn
@@ -701,16 +808,20 @@ elsif has_variable?("postgrey") && postgrey == "true"
     !authenticated = *
     domains        = +handled_domains : +rcpthosts
     local_parts    = GREYLIST_LOCAL_PARTS
-    condition      = ${if eq{${uc:${substr_0_7:$acl_m3}}}{PREPEND}}
-    message        = ${sg{$acl_m3}{^\\\\w+\\\\s*}{}}
+    condition      = ${if eq{${uc:${substr_0_7:$acl_m_pgr}}}{PREPEND}}
+    message        = ${sg{$acl_m_pgr}{^\\\\w+\\\\s*}{}}
 '
 end
 out
 %>
 
-  accept  local_parts   = postmaster
+  accept  local_parts   = +postmasterish
           domains       = +handled_domains : +rcpthosts
 
+  deny    hosts        = ${if exists{/etc/exim4/host_blacklist}{/etc/exim4/host_blacklist}{}}
+          message      = I'm terribly sorry, but it seems you have been blacklisted
+          log_message  = blacklisted IP
+
   deny   log_message   = <$sender_address> is blacklisted
          senders       = ${if exists{/etc/exim4/blacklist}{/etc/exim4/blacklist}{}}
          message       = We have blacklisted <$sender_address>.  Please stop mailing us
@@ -776,11 +887,25 @@ if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty?
 out='
 acl_check_mime:
 
+ discard condition     = ${if <{$message_size}{256000}}
+         condition     = ${if eq {$acl_m_prf}{blackhole}}
+         set acl_m_srb = ${perl{surblspamcheck}}
+         condition     = ${if eq{$acl_m_srb}{false}{no}{yes}}
+         log_message   = discarded surbl message for $recipients
+
+  warn   condition     = ${if <{$message_size}{256000}}
+         condition     = ${if eq {$acl_m_prf}{markup}}
+         set acl_m_srb = ${perl{surblspamcheck}}
+         condition     = ${if eq{$acl_m_srb}{false}{no}{yes}}
+         message       = X-Surbl-Hit: $primary_hostname: $acl_m_srb
+
+  accept condition     = ${if eq {$acl_m_prf}{markup}}
+
   deny   condition     = ${if <{$message_size}{256000}}
-         set acl_m5    = ${perl{surblspamcheck}}
-         condition     = ${if eq{$acl_m5}{false}{no}{yes}}
-         log_message   = $acl_m5
-         message       = $acl_m5
+         set acl_m_srb = ${perl{surblspamcheck}}
+         condition     = ${if eq{$acl_m_srb}{false}{no}{yes}}
+         log_message   = $acl_m_srb
+         message       = $acl_m_srb
 
   accept
 '
@@ -788,6 +913,13 @@ end
 out
 %>
 
+acl_check_predata:
+  deny   condition     = ${if eq{$acl_m_lcl}{localonly}}
+         message       = mail for $acl_m_lrc is only accepted internally
+
+  accept
+
+
 #!!# ACL that is used after the DATA command
 check_message:
   require verify = header_syntax
@@ -797,9 +929,9 @@ check_message:
 out=''
 if nodeinfo['rtmaster']
   out='
-  deny    condition = ${if eq {$acl_m1}{RTMail}}
+  deny    condition = ${if eq {$acl_m_prf}{RTMail}}
           condition = ${if and{{!match {${lc:$rh_Subject:}} {debian rt}} \
-                               {!match {${lc:$rh_Subject:]}} {\\[rt.debian.org }} \
+                               {!match {${lc:$rh_Subject:]}} {\N\[rt.debian.org \N}} \
                                {!match {$acl_m12}{RTMailRecipientHasSubaddress}}}}
           message  = messages to the Request Tracker system require a subject tag or a subaddress
 '
@@ -808,20 +940,17 @@ out
 %>
 <%=
 out=''
-if nodeinfo['packagesmaster']
+if nodeinfo['packagesqamaster']
   out='
   deny    !hosts  = +debianhosts : 217.196.43.134
-          condition = ${if eq {$acl_m1}{PTSMail}}
+          condition = ${if eq {$acl_m_prf}{PTSMail}}
           condition = ${if def:h_X-PTS-Approved:{false}{true}}
           message   = messages to the PTS require an X-PTS-Approved header
 '
 end
 out
 %>
-  deny    condition      = ${if match {$message_body}{\Nhttp:\/\/[a-z\.-]+\/video1?.exe\N}}
-          message        = Blackisted URI found in body
-
-  deny    condition      = ${if eq {$acl_m1}{DBSignedMail}}
+  deny    condition      = ${if eq {$acl_m_prf}{DBSignedMail}}
           condition      = ${if and {{!match {$message_body}{PGP MESSAGE}}              \
                                      {!match {$message_body}{PGP SIGNED MESSAGE}}       \
                                      {!match {$message_body}{PGP SIGNATURE}}            \
@@ -849,40 +978,73 @@ out
 out = ""
 if has_variable?("clamd") && clamd == "true"
 out = '
-  deny    
+  discard condition       = ${if eq {$acl_m_prf}{blackhole}{no}{yes}}
+          demime          = *
+          malware         = */defer_ok
+          log_message     = discarded malware message for $recipients
+
+  deny    condition       = ${if eq {$acl_m_prf}{markup}{no}{yes}}
          demime          = *
           malware         = */defer_ok
           message         = malware detected: $malware_name: message rejected
+
+  warn    condition       = ${if eq {$acl_m_prf}{markup}}
+         demime          = *
+          malware         = */defer_ok
+          message         = X-malware detected: $malware_name
 '
 end
 out
 %>
-
-  deny    spam            = $value/defer_ok
-          domains         = +handled_domains : +rcpthosts
-          message         = message got a spam score of $spam_score
-          local_parts     = ${if exists {/etc/exim4/sa_users}\
-                            {${if match_domain{$domain}{+virtual_domains}\
-                            {${lookup{$local_part@$domain}nwildlsearch{/etc/exim4/sa_users}{$local_part}{}}}\
-                            {${lookup{$local_part}lsearch{/etc/exim4/sa_users}{$local_part}{}}}}}}
-
 <%=
 out=''
 if nodeinfo.has_key?('heavy_exim') and not nodeinfo['heavy_exim'].empty?
 out='
+ discard condition     = ${if <{$message_size}{256000}}
+         condition     = ${if eq {$acl_m_prf}{blackhole}}
+         set acl_m_srb = ${perl{surblspamcheck}}
+         condition     = ${if eq{$acl_m_srb}{false}{no}{yes}}
+         log_message   = discarded surbl message for $recipients
+
+  warn   condition     = ${if <{$message_size}{256000}}
+         condition     = ${if eq {$acl_m_prf}{markup}}
+         set acl_m_srb = ${perl{surblspamcheck}}
+         condition     = ${if eq{$acl_m_srb}{false}{no}{yes}}
+         message       = X-Surbl-Hit: $primary_hostname: $acl_m_srb
+
+  accept condition     = ${if eq {$acl_m_prf}{markup}}
+
   deny   condition     = ${if <{$message_size}{256000}}
-         set acl_m5    = ${perl{surblspamcheck}}
-         condition     = ${if eq{$acl_m5}{false}{no}{yes}}
-         log_message   = $acl_m5
+         set acl_m_srb = ${perl{surblspamcheck}}
+         condition     = ${if eq{$acl_m_srb}{false}{no}{yes}}
+         log_message   = $acl_m_srb
+         message       = $acl_m_srb
 '
 end
 out
 %>
   # Check header_sender except for survey@popcon.d.o
-  deny    condition = ${if eq{$acl_m1}{PopconMail}{false}{true}}
-          !verify = header_sender
-          message = No valid sender found in the From:, Sender: and Reply-to: headers
+  deny    condition    = ${if eq{$acl_m_prf}{PopconMail}{false}{true}}
+          !verify      = header_sender
+          message      = No valid sender found in the From:, Sender: and Reply-to: headers
 
+<%=
+out = ""
+if nodeinfo['packagesmaster']
+  out = '
+  deny  message        = Congratulations, you scored $spam_score points.
+        log_message    = spam: $spam_score points.
+        condition      = ${if eq {$acl_m_prf}{PackagesMail}}
+        !authenticated = *
+        !verify        = certificate
+        !hosts         = +debianhosts
+        condition      = ${if <{$message_size}{256000}}
+        spam           = pkg_user : true
+        condition      = ${if >{$spam_score_int}{59}}
+'
+end
+out
+%>
   accept
 
 
@@ -938,7 +1100,7 @@ out
 bsmtp:
   debug_print = "R: bsmtp for $local_part@$domain"
   driver = manualroute
-  domains = !+local_domains
+  domains = +bsmtp_domains
   require_files = /etc/exim4/bsmtp
   route_list = * ${extract{file}{\
                    ${lookup{$domain}partial-lsearch{/etc/exim4/bsmtp}\
@@ -983,6 +1145,17 @@ dnslookup:
   ignore_target_hosts = +reservedaddrs
   no_more
 
+postmasterish:
+  debug_print = "R: postmasterish for $local_part@$domain"
+  driver = redirect
+  verify = false
+  unseen = true
+  expn = true
+  local_parts = +postmasterish
+  domains = +handled_domains
+  data = debian-admin@debian.org
+  headers_add = "Delivered-To: ${local_part}${local_part_suffix}@${domain}"
+
 # This router handles aliasing using a traditional /etc/aliases file.
 # If any of your aliases expand to pipes or files, you will need to set
 # up a user and a group for these deliveries to run under. You can do
@@ -1395,6 +1568,7 @@ address_reply:
 remote_smtp:
   driver = smtp
   connect_timeout = 1m
+  delay_after_cutoff = false
 <%=
 out = ""
 if has_variable?("exim_ssl_certs") && exim_ssl_certs == "true"
@@ -1411,6 +1585,7 @@ out = '
 remote_smtp_smarthost:
   debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
   driver = smtp
+  delay_after_cutoff = false
   port = '
   out += nodeinfo['smarthost_port'].to_s + "\n"
   if has_variable?("exim_ssl_certs") && exim_ssl_certs == "true"
@@ -1494,7 +1669,6 @@ out
 begin retry
 
 debian.org            *           F,2h,10m; G,16h,2h,1.5; F,14d,8h
-*                      * senders=: F,2h,10m
 *                      rcpt_4xx    F,2h,5m;  F,4h,10m; F,4d,15m
 *                      *           F,2h,15m; G,16h,2h,1.5; F,4d,8h