Part II in an apparently ongoing series, “Nifty and Minimally Invasive qmail Tricks.”

qmail notoriously doesn't try to reject invalid local recipients during SMTP. Instead, it accepts all mail for its domains, attempts delivery, and sends back bounce messages for recipients that prove invalid. This follows all the rules for proper email behavior, but is impractical with today's evolved spammers, as the queue tends to fill up with gobs of undeliverable bounces. I imagine most people running actual mail servers apply one of the many patches to make qmail verify recipients during SMTP.

I certainly do: my patch of choice is Paul Jarc's realrcptto. (He explains the benefits and drawbacks well.) It works brilliantly for me and several of my system's users, but another of them runs pretty squarely into the drawbacks. badrcptto would help him a lot, but it doesn't apply cleanly over realrcptto, let alone the rest of my patchset of choice. So I solved the problem another way.

Among other things, netqmail — which is the de facto community-provided standard patchset — modifies qmail in a way that lets the savvy sysadmin set arbitrary SMTP policies. Adding qmail-qfilter lays an easy, Unixy API on top. My qmail installation already included netqmail and qmail-qfilter, so I decided to reimplement badrcptto as a shell script. Here it is:

#!/bin/sh

relayclient_isset()
{
        /usr/bin/env | /usr/bin/grep -q '^RELAYCLIENT=' >/dev/null 2>&1
}

recipient_isbad()
{
        /usr/bin/grep -qFx -- "$1" control/badrcptto >/dev/null 2>&1
}

reject_mail()
{
        echo >&2 "badrcptto: $1 at ${TCPREMOTEIP}"
        exit 31
}

main()
{
        local recipient
        if ! relayclient_isset; then
                for recipient in ${QMAILRCPTS}; do
                        if recipient_isbad "${recipient}"; then
                                reject_mail "${recipient}"
                        fi
                done
        fi
        /bin/cat
}

main "$@"
exit $?