Apparent dnsbl bug in Sendmail or m4

John Nielsen lists at jnielsen.net
Sun Aug 22 07:10:46 UTC 2010


I'm migrating a sendmail server from FreeBSD 4.x to FreeBSD 8.x. After 
turning on the new server and feeding it some "live" e-mail, I noticed 
that the DNS blacklist lookups weren't actually rejecting e-mail like 
they did on the old server. (Actually the presence of blacklist 
information in the SpamAssassin report on an unwanted message that was 
delivered and a total lack of them in the sendmail logs (versus a 
steady stream on the old server).)

I double-checked the syntax of my .mc file, re-ran "cd /etc/mail; 
make", and examined the resulting .cf file. While I saw lines 
referencing each dnsbl I included in the .mc, all of the error clauses 
were missing.

My .mc file includes this line on both servers:

FEATURE(dnsbl, `bl.spamcop.net', `"550 Mail from " $&{client_addr} " 
rejected, see http://spamcop.net/bl.shtml?" $&{client_addr}')

On the FreeBSD 4.x server, this is the corresponding section in the .cf file:

# DNS based IP address spam list bl.spamcop.net
R$*                     $: $&{client_addr}
R$-.$-.$-.$-            $: <?> $(dnsbl $4.$3.$2.$1.bl.spamcop.net. $: OK $)
R<?>OK                  $: OKSOFAR
R<?>$+<TMP>             $: TMPOK
R<?>$+                  $#error $@ 5.7.1 $: "550 Mail from " 
$&{client_addr} " rejected, s
ee http://spamcop.net/bl.shtml?" $&{client_addr}

On the FreeBSD 8.x server, this is the corresponding section:

# DNS based IP address spam list bl.spamcop.net
R$*                     $: $&{client_addr}
R$-.$-.$-.$-            $: <?> $(dnsbl $4.$3.$2.$1.bl.spamcop.net. $: OK $)
R<?>OK                  $: OKSOFAR
R<?>$+<TMP>             $: TMPOK

Note that the last line (containing the "error" clause and custom 550 
message) is absent from the new server's file.

I know next to nothing about m4, but I compared the cf/feature/dnsbl.m4 
files on the two machines and noticed that the newer version has an 
"ifelse" statement to handle 'quarantine' or 'discard' keywords that is 
not present in the older version. I counted the arguments and compared 
them to the documented behavior of "ifelse" and didn't see any glaring 
problems, but the correct output string from the statement simply does 
not appear in the .cf file.

Apparently this is the only case that causes the ifelse statement to 
not produce any output. Omitting the custom error message, specifying 
'discard' or specifying 'quarantine' all produce a suitable action line 
in the output (error with default message, discard or quarantine, 
respectively). So just specifying e.g. "FEATURE(dnsbl, 
`bl.spamcop.net')" is one workaround.

Since I don't use the 'quarantine' or 'discard' keywords I doctored the 
dnsbl.m4 file to remove the final "ifelse" statement and always output 
the error clause. That allowed me to produce a .cf file which included 
the appropriate error clauses and customized 550 error messages.

This is an issue on FreeBSD 7.2 and 8.1 (and probably -CURRENT, but I 
don't have a test machine handy), but not on 4.9 (I know, old). For 
kicks I tried substituting gm4 from ports for m4 in the base but got 
the same results. I also verified that a simple macro containing an 
"ifelse" statement with seven arguments works as expected, including 
printing the seventh argument if both comparisons (1&2 and 4&5) are 
false.

So--I'm stumped. I do have the workarounds I mentioned but now that 
I've encountered this mystery I would like to see it solved. Can anyone 
help unravel it?

Thanks,

JN


More information about the freebsd-stable mailing list