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
).
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
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
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.
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_OK | 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 | |
else | EX_CONFIG | config | Internal 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.
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 george@wash.dc.gov:
553 <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 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.
Code | Meaning |
---|---|
421 | Service not available (drop the message) |
553 | Requested 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.