Next: , Previous: , Up: Tutorial   [Contents][Index]

3.8 Avoiding Verification Loops

An envfrom program consisting only of the on poll statement will work smoothly for incoming mails, but will create infinite loops for outgoing mails. This is because upon sending an outgoing message mailfromd will start the verification procedure, which will initiate an SMTP transaction with the same mail server that runs it. This transaction will in turn trigger execution of on poll statement, etc. ad infinitum. To avoid this, any properly written filter script should not run the verification procedure on the email addresses in those domains that are relayed by the server it runs on. This can be achieved using relayed function. The function returns true if its argument is contained in one of the predefined domain list files. These files correspond to Sendmail plain text files used in F class definition forms (see Sendmail Installation and Operation Guide, chapter 5.3), i.e. they contain one domain name per line, with empty lines and lines started with ‘#’ being ignored. The domain files consulted by relayed function are defined in the relayed-domain-file configuration file statement (see relayed-domain-file):

relayed-domain-file (/etc/mail/local-host-names,


relayed-domain-file /etc/mail/local-host-names;
relayed-domain-file /etc/mail/relay-domains;

The above example declares two domain list files, most commonly used in Sendmail installations to keep hostnames of the server 6 and names of the domains, relayed by this server7.

Given all this, we can improve our filter program:

require 'dns'

prog envfrom
  if $f == ""
  elif relayed(hostname(${client_addr}))
    on poll $f do
    when success:
    when not_found or failure:
      reject 550 5.1.0 "Sender validity not confirmed"
    when temp_failure:
      tempfail 450 4.1.0 "Try again later"

If you feel that your Sendmail’s relayed domains are not restrictive enough for mailfromd filters (for example you are relaying mails from some third-party servers), you can use a database of trusted mail server addresses. If the number of such servers is small enough, a single ‘or’ statement can be used, e.g.:

  elif ${client_addr} = ""
       or ${client_addr} = ""

otherwise, if the servers’ IP addresses fall within one or several CIDRs, you can use the match_cidr function (see Internet address manipulation functions), e.g.:

  elif match_cidr (${client_addr}, "")

or combine both methods. Finally, you can keep a DBM database of relayed addresses and use dbmap or dbget function for checking (see Database functions).

  elif dbmap("%__statedir__/relay.db", ${client_addr})



class ‘w’, see Sendmail Installation and Operation Guide, chapter 5.2.


class ‘R

Next: , Previous: , Up: Tutorial   [Contents][Index]