[Chapter 30] 30.5 Internally Defined Names

sendmail

sendmailSearch this book
Previous: 30.4 The EquatesChapter 30
Delivery Agents
Next: 30.6 How Executed
 

30.5 Internally Defined Names

V8 sendmail internally predefines two delivery agents for the special handling of files (*file* and *include*) and one for the special handling of errors (error).

30.5.1 The *file* and *include* Agents

The *file* delivery agent (the * characters are part of the name) handles delivery to files. The *include* delivery agent handles delivery through :include: lists. Neither can be considered a real delivery agent, because actual delivery is still handled internally by sendmail. Instead, they provide a way to tune delivery-agent behavior for these two delivery needs.

The predefined defaults for these delivery agents can be viewed with the following command: [13]

[13] The output lines are unfortunately wrapped at the right margin of this book text.

% /usr/lib/sendmail -d0.15 -bt < /dev/null | egrep "file|include" 
mailer 1 (*file*): P=[FILE] S=0/0 R=0/0 M=0 U=0:0 F=9DEFMPloqsu L=0 E=\n T=DNS/RF
C822/X-Unix A=FILE $u
mailer 2 (*include*): P=/dev/null S=0/0 R=0/0 M=0 U=0:0 F=su L=0 E=\n T=<undefine
d>/<undefined>/<undefined> A=INCLUDE $u

The defaults may be overwritten by declaring these delivery agents in the configuration file. For example, the following configuration file declaration overrides the internal definition shown above, and limits the size of any mail message that is delivered to files to 1 megabyte:

M*file*, P=[FILE], M=1000000, F=9DEFMPloqsu, T=DNS/RFC822/X-Unix, A=FILE $u

Note that any equate that does not default to zero (such as the P=, F=, T=, and A= equates) needs to be copied to this configuration file declaration, or the original value will be lost.

A similar change in definition for the m4 configuration of V8 sendmail would look like this:

LOCAL_CONFIG
M*file*, P=[FILE], M=1000000, F=9DEFMPloqsu, T=DNS/RFC822/X-Unix, A=FILE $u

30.5.2 The error Delivery Agent

All versions of sendmail define a special internal delivery agent called error that is designed to aid in the issuance of error messages. It is always available for use in rule sets 0 and 5, and the check_... rule sets and cannot be defined with an M command.

Beginning with V8.7, the form for using the error agent in the RHS of a rule looks like this:

R...          $#error $@ dsn  $: text of error message here

In general terms, the text following the $: is the actual error message that will be included in bounced mail and sent back to a connecting SMTP host. For example, the following rule in rule set 0 would cause all mail to the local user George Washington to bounce:

RGeorge.Washington       $#error $: George Washington doesn't sleep here anymore

with an error message like this:

553 <george.washington>... George Washington doesn't sleep here anymore

30.5.2.1 The $@ dsn part

Delivery Status Notification (DSN, see RFC1893) provides a means for conveying the status of a message's delivery. That status is conveyed in the form of a numeric triple (so as to be easily parseable by machines). This triple is included in the "machine readable" part of bounced messages:

success.category.detail

Each part of the triple is separated from the others with dot characters. There may be no space around the dots. The parts are numeric, and the meanings are as follows: success Was the overall delivery attempt a success? This part can be one of three digits. A 2 means that the message was successfully delivered. A 4 means that delivery has failed so far but it may succeed in the future. A 5 means that delivery failed (permanently). category Failure can be caused by several categories of problem. For example, if this category is a 1, it means that there was a problem with the address. If it is a 4 it means that there was a problem with the network. detail The detail further illuminates the category. For example, a category of 1 (address problem) might be caused by a detail of 1 (no such mailbox), or 4 (ambiguous address).

The $@ part of the error delivery agent declaration specifies a DSN code that is appropriate for the error.

R...          $#error $@ success.category.detail  $: text of error message here

The sendmail program sets its exit(2) value according to the success.category.detail specified. Table 30.6 shows the relationship between those DSN codes on the left and UNIX exit(2) values on the right. Note that the exit values are defined in <sysexits.h>, and note that success codes of 2 and 4 completely ignore any category and detail that may be present (that is, 2.anything.anything marks successful delivery). If $@ lists a code that is not in the table, the default exit value is EX_CONFIG. To illustrate, observe that 8.7.1 (see RFC1893) will exit with EX_DATAERR because it corresponds to the *.7.* in the table.

Table 30.6: DSN Versus exit(2) Values with $@ of $#error
DSNexit(2)StringMeaning
2.*.*EX_OKSuccessful delivery
4.*.*EX_TEMPFAILtempfailTemporary failure, will keep trying
*.0.*EX_UNAVAILABLEunavailableOther address status
*.1.0EX_DATAERROther address status
*.1.1EX_NOUSERnouserAddress is that of a bad mailbox
*.1.2EX_NOHOSTnohostAddress of recipient is bad
*.1.3EX_USAGEusageAddress of recipient has bad syntax
*.1.4EX_UNAVAILABLEunavailableAddress is ambiguous
*.1.5EX_OKAddress of destination is valid
*.1.6EX_NOUSERnouserAddress has moved, no forwarding
*.1.7EX_USAGEusageAddress of sender has bad syntax
*.1.8EX_NOHOSTnohostAddress of sender is bad
*.2.0EX_UNAVAILABLEunavailableMailbox status is undefined
*.2.1EX_UNAVAILABLEunavailableMailbox disabled
*.2.2EX_UNAVAILABLEunavailableMailbox full
*.2.3EX_DATAERRMailbox is too small or message is too large
*.2.4EX_UNAVAILABLEunavailableMailbox led to mail list expansion problems
*.3.*EX_OSERROperating system error
*.4.0EX_IOERRNetwork error is undefined
*.4.1EX_TEMPFAILtempfailNetwork: no answer from host
*.4.2EX_IOERRNetwork bad connection
*.4.3EX_TEMPFAILtempfailNetwork routing failure
*.4.4EX_PROTOCOLprotocolNetwork unable to route
*.4.5EX_TEMPFAILtempfailNetwork congestion
*.4.6EX_CONFIGconfigNetwork routing loop detected
*.4.7EX_UNAVAILABLEunavailableNetwork delivery time expired
*.5.*EX_PROTOCOLprotocolProtocol failure
*.6.*EX_UNAVAILABLEunavailableMessage contents bad or media failure
*.7.*EX_DATAERRSecurity: general security rejection
elseEX_CONFIGconfigInternal configuration error

To illustrate, consider the need to reject all mail from a particular host (say evilhost.domain). We want to reject that host for security reasons, so we might set up a rule like this:

R$* < @ evilhost.domain > $*        $#error $@ 5.7.1 $: You are bad, go away

Here, the number following the $@ contains a dot, so it is interpreted as a DSN status expression. The .7. in it causes sendmail to set its exit valut to EX_DATAERR, and the 5.7.1 is defined in RFC1893 as meaning "Permanent failure, delivery not authorized, message refused."

If the number following the $@ does not contain a dot, sendmail sets its exit(2) value to that number. For example, the below results in the same exit(2) value as the above but gives a less informative DSN in the bounce message:

R$* < @ evilhost.domain > $*        $#error $@ 65 $: You are bad, go away
                                               -^
                                    the value of EX_DATAERR from <sysexits.h>

If the expression following the $@ is non-numeric, sendmail looks up the string and translates a known one into the appropriate exit(2) value. The recognized strings are listed in the third column of Table 30.6. For example, the following will cause sendmail to exit with an EX_UNAVAILABLE value:

R$* < @ evilhost.domain > $*        $#error $@ unavailable $: You are bad, go away

If the string following the $@ is not one of those listed in the table, the default exit(2) value becomes EX_UNAVAILABLE.

30.5.3 The $: Part

Recall that the text of the error message following the $: is used as a literal error message. That is, this $: part:

R...          $#error  $: george doesn't sleep here anymore

produces this error for the address [email protected]:

553 <[email protected]>... george doesn't sleep here anymore

Here the 553 is an SMTP code (see RFC821). If you want a different SMTP code issued, you may do so by prefixing the $: part with it:

R...          $#error  $: 421 george doesn't sleep here anymore

If three digits followed by a space are present as a prefix, those digits are used as the SMTP reply code when sendmail is speaking SMTP. If no digits and space prefix the text, the default SMTP reply code is 553.

A few SMTP codes that are useful with $: are listed in Table 30.7. The complete list of all SMTP codes can be found in RFC821.

Table 30.7: Useful SMTP Codes for Use with $:
CodeMeaning
421Service not available (drop the message)
553Requested action not taken (bounce the message)

Note that you should restrict yourself to the small set of codes that may legally be returned to the RCPT SMTP command. Also note that any DSN code that is specified in the $@ part must avoid conflicting with the meaning of the SMTP code. For example, the following construct is wrong and should be avoided:

R...          $#error $@ 2.1.1 $: 553 ...     <- avoid such conflicts

Here, the DSN 2.1.1 means that delivery was successful, whereas the SMTP 553 means that delivery failed and the message bounced.


Previous: 30.4 The EquatessendmailNext: 30.6 How Executed
30.4 The EquatesBook Index30.6 How Executed