Dan Bernstein's qmail package is mirrored here.
All qmail/mess822-related patches and scripts here are in the public domain.
patch copies logic from
qmail-qmtpd, so that if a local delivery (i.e., one for a domain
would eventually bounce due to a missing
.qmail file, then that
recipient address is rejected during the SMTP or QMTP protocol conversation.
There are other qmail patches around that do similar jobs (badrcptto, etc.);
the focus of this patch is to get this functionality with no additional
administrative effort, rather than
qmail-smtpd's running speed.
You just set up your
.qmail files, as you would have to do
anyway, and the rest is automatic, though slower than a CDB lookup.
Addresses which use the default delivery instructions are never rejected by
this patch, because they would never be bounced due to the lack of a
.qmail file. If you're not sure whether this patch will reject
mail for certain addresses on your system, you can check using the qtraceaddr script below. If it reports
bounce message due to lack of a .qmail file”, then
qmail-realrcptto will reject mail for that address; otherwise mail will be
This makes less work for the qmail machine, since these undeliverable addresses are rejected before ever entering the qmail queue (but it makes more work - to perform the check itself - in cases that would not bounce). Joe-job double bounces are also eliminated.
Note that with this patch,
qmail-qmtpd will always use the latest versions of the control
qmail-send will use its cached copy in memory until it receives
SIGHUP or is restarted. (Even after
qmail-send still uses the old
percenthack.) So after control files are changed, and before
qmail-send is notified, it is possible that a message recipient
might be accepted through the network even though it would bounce later, or a
message recipient might be rejected through the network even though the
delivery would succeed.
QMAILRRTDENYALL=1 is set in the environment for
qmail-qmtpd, then each individual
recipient address will be accepted, but the whole message will be rejected,
to stop attackers from probing for valid addresses. It's still possible to
probe by sending empty, single-recipient messages, and then sending the real
message with all the recipients that weren't rejected.
This patch is less effective when there are
files, or when
qmaild does not have sufficient filesystem
.qmail files, since in
qmail-smtpd cannot know that the delivery would
later bounce due to the lack of a
.qmail file. For example, I'm
told that this patch is not useful for virtual domains managed with vpopmail,
since an applicable
.qmail-default file always exists. (I'm not
familiar with vpopmail myself.) The patch may still be useful for other
local or virtual domains on the same server, if they are not managed by
The qmail-branch patch
.qmail delivery instruction language, narrowing the
procmail. If you have
a sequence of lines like:
?label command arg ... ... :label
qmail-local will deliver the message to the command just as it
does for a
|command line, and if the command exits with status
qmail-local will skip down to the
delivery instructions in the intervening lines are ignored. If the
command exits with status other than 99, the result is the same as
:label lines are
otherwise ignored, just like
A label is a (possibly empty) sequence of non-space, non-tab, nonzero
bytes. Text following a label on a "
:" line is
ignored. If there is no command on a
?label line, it's
an unconditional jump. If a command exits 99 and the corresponding
label is not found, all following delivery instructions are skipped
|command). There are no backward jumps.
This makes the
.qmail language a little more useful, IMO,
but not enough to cause trouble. :) (You get if-then-else, but no
loops.) The syntax is a little ugly, but it gets the job done. The
same functionality is already available with
lines, but then you need multiple
.qmail files, which
exposes extra addresses to outside senders, so it gets a little more
.qmail file using this feature might look like:
# Sort out mail from Sue. ?test [ "$SENDER" = email@example.com ] || exit 99 /home/b1ff/mail/sue/ # Skip all further processing. ?done :test # Is this a copy of a mailing list message? ?test iftocc `cat lists` || exit 99 # Bounce this copy. |cat duplicate; exit 100 :test # Deliver to the default mailbox. /home/b1ff/mail/main/
Another way of tackling this problem is to do all deliveries for a given
address from a single shell script, and then to deliver to just that shell
script in the
.qmail file. This requires manually rewinding the
standard input between deliveries; you can do this with
seek0. This is more error-prone, but faster,
since a shell is spawned only once per message. I might write a wrapper for
qmail-local that checks for such a delivery script called
.qmailx adjacent to
.qmail, executes it without
forking if it exists, and executes
qmail-local without forking
The qtraceaddr Perl script illustrates how qmail
decides how to deliver messages for any addresses given on the command line.
If your qmail installation used non-default values for
conf-break, or the
user, you can specify them in the
$QMAILALIAS environment variables.
# env QMAILBREAK=+ /path/to/qtraceaddr firstname.lastname@example.org
Dan Bernstein's mess822 package is mirrored here.
patch prevents mess822 from installing its own
/etc. This is useful for installing mess822 as a
non-root user or when the existing
/etc/leapsecs.dat file is
more up-to-date than the one in mess822.