error |
Perform a policy-based rejection | All versions |
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 three-part numeric expression (so as to be easily parsed by machines). This expression is included in the "machine-readable" part of bounced messages:
success.category.detail
Each part is separated from the others with dot characters. There can be no space around the dots. The parts are numeric, and the meanings are as follows:
Was the overall delivery attempt a success? This part can be one of three digits. A 2 means the message was successfully delivered. A 4 means delivery has failed so far but might succeed in the future. A 5 means delivery failed (permanently).
Success or failure can be attributed to several reasons. For example, if this category is a 1, it means the reason refers to an address. If it is a 4, it means the reason refers to the network. Other categories are described in RFC1893.
The detail further illuminates the category. For example, a category 1 address (problem) can additionally be specified as 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 20-4 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 might be present (that is, 2.anything.anything marks successful delivery, and 4.anything.anything marks a temporary failure). If $@ lists a code that is not in the table, the default exit value is EX_CONFIG. To illustrate, observe that 5.7.1 (see RFC1893) will exit with EX_DATAERR because it corresponds to the *.7.* in the table.
DSN |
exit(2) |
String |
Meaning |
---|---|---|---|
2.*.* |
EX_OK |
Successful delivery |
|
4.*.* |
EX_TEMPFAIL |
tempfail |
Temporary failure, will keep trying |
*.0.* |
EX_UNAVAILABLE |
unavailable |
Other address status |
*.1.0 |
EX_DATAERR |
Other address status |
|
*.1.1 |
EX_NOUSER |
nouser |
Address is that of a bad mailbox |
*.1.2 |
EX_NOHOST |
nohost |
Address of recipient is bad |
*.1.3 |
EX_USAGE |
usage |
Address of recipient has bad syntax |
*.1.4 |
EX_UNAVAILABLE |
unavailable |
Address is ambiguous |
*.1.5 |
EX_CONFIG |
Address of destination is valid |
|
*.1.6 |
EX_NOUSER |
nouser |
Address has moved, no forwarding |
*.1.7 |
EX_USAGE |
usage |
Address of sender has bad syntax |
*.1.8 |
EX_NOHOST |
nohost |
Address of sender is bad |
*.2.0 |
EX_UNAVAILABLE |
unavailable |
Mailbox status is undefined |
*.2.1 |
EX_UNAVAILABLE |
unavailable |
Mailbox disabled |
*.2.2 |
EX_UNAVAILABLE |
unavailable |
Mailbox full |
*.2.3 |
EX_DATAERR |
Mailbox is too small or message is too large |
|
*.2.4 |
EX_UNAVAILABLE |
unavailable |
Mailbox led to mail list expansion problems |
*.3.* |
EX_OSERR |
Operating system error |
|
*.4.0 |
EX_IOERR |
Network error is undefined |
|
*.4.1 |
EX_TEMPFAIL |
tempfail |
Network: no answer from host |
*.4.2 |
EX_IOERR |
Network bad connection |
|
*.4.3 |
EX_TEMPFAIL |
tempfail |
Network routing failure |
*.4.4 |
EX_PROTOCOL |
protocol |
Network unable to route |
*.4.5 |
EX_TEMPFAIL |
tempfail |
Network congestion |
*.4.6 |
EX_CONFIG |
config |
Network routing loop detected |
*.4.7 |
EX_UNAVAILABLE |
unavailable |
Network delivery time expired |
*.5.* |
EX_PROTOCOL |
protocol |
Protocol failure |
*.6.* |
EX_UNAVAILABLE |
unavailable |
Message contents bad, or media failure |
*.7.* |
EX_DATAERR |
Security: general security rejection |
|
5.*.* |
EX_UNAVAILABLE |
unavailable |
Any unrecognized 5.y.z code |
*.*.* |
EX_CONFIG |
config |
Any other unrecognized code |
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 such as 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. causes sendmail to set its exit value to EX_DATAERR. 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 following code results in the same exit(2) value as the preceding code but gives a less informative DSN status line in the bounce message:
R$* < @ evilhost.domain > $* $#error $@ 65 $: You are bad, go awaythe value of EX_DATAERR from <sysexits.h >
If the expression following the $@ is nonnumeric, sendmail looks up the string and translates any string it recognizes into the appropriate exit(2) value. The recognized strings are listed in the third column of Table 20-4. 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.
Recall that the text of the error message following the $: is used as a literal error message. That is, this $: part:
R... $#error $@ 5.0.0 $: george doesn't sleep here anymore
produces this error for the address george@wash.dc.gov:
553 5.0.0 <george@wash.dc.gov>... george doesn't sleep here anymore
Here the 553 is an SMTP code (see RFC821). If you want a different SMTP code issued, you can do so by prefixing the $: part with it, as shown:
R... $#error $: 450 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 20-5. The complete list of all SMTP codes can be found in RFC2821.
Code |
Meaning |
---|---|
421 |
Service not available (queue the message), and close the connection |
450 |
Service not available (queue the message) |
550 |
General permanent failure (bounce the message)[4] |
553 |
Requested action not taken (bounce the message) |
[4] All the 5xy codes generally mean permanent failure for the address.
Note that you should restrict yourself to the small set of codes that can legally be returned to the RCPT SMTP command. Also note that any DSN status expression 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. In general, the first digit of the SMTP code should match the first digit of the DSN status expression.