Using a Database in the check_* Rulesets with an Error Message

Last Update 1997-10-03

Further Enhanced Version to use a Database in check_mail/check_relay

Using a map lookup has the advantage that you don't need to restart sendmail when you change the entries in the database. Moreover, if the file gets large (as it may happen since UCEs become nearly ubiquitous) the match should be faster. This enhanced version uses a common database for check_mail and check_relay . For the latter, you need a patch for sendmail 8.8.5 to make this work.

The new version of check_mail can also make more rigorous validations of the supplied FROM address. These rules can be activated by define(`_CHECK_FROM_',1) if you use check_mail3 from the check.tar file. At least the rule removes an extraneous dot at the end of the address since this would circumvent the check for valid domains.

The database (map) contains entries for well-known spammers in the form:

spammer@address.domain "Error-Code Error-Text"
and for junk domains in the form
junk.domain "Error-Code Error-Text"
and for IP numbers which are not allowed to connect to your mail server:
D.X.Y.Z "Error-Code Error-Text"
C.X.Y "Error-Code Error-Text"
B.X "Error-Code Error-Text"
A "Error-Code Error-Text"
where the lines refer to full IP addresses, class B, C, or A nets.

An example for entries in the map is:

natureplus.com "551 This domain is banned."
cyberpromo.com "551 Go away, Spamford."
honey@sweeties.com "551 Honey, you're a spammer, go away."
lamer@aol.com "551 You're a real lamer, go away."
205.199.212	"No access for you, Spamford."
The last entry has no error code, since check_relay refuses access always with 550 Access denied and logs the error string.

The map can be used in sendmail.cf as:

Kjunk dbm -a@JUNK /etc/mail/junk
(you may choose another database type and another location). This is now used in the ruleset as follows:
Scheck_mail
# don't check these
R<$*@$=w>	$@ ok			shortcut
# idea from Steven Schultz
R<>		$: <$n @ $(dequote "" $&{client_name} $) >
# mark address
#R$*		$:<@>$1
# is the syntax ok (uses <> and no dot at the end?)
#R<@><$*@$*$~.>	$:<$1@$2$3>
# mark still there: error...
#R<@>$*		$#error $@ 5.1.8 $: 551 illegal MAIL FROM $1,
# if we don't to the above: remove at least the dot...
R<$*@$*.>	<$1@$2>
R$*		$: $>3 $1			canonify
R$-		$@ ok				local host
# no host without a . in the FQHN ?
# if you get local e-mail from hosts without full domains,
# put a hash in front of the next rule
R$*<@$->$*	$#error $@ 5.1.8 $: 551 invalid host name $2, check your configuration.
# lookup IP address (reverse mapping available?)
# R$*<@[$-.$-.$-.$-]>$*	$: $1 < @ $[ [ $2.$3.$4.$5 ] $] > $6 
# copy the result of the lookup
R$*		$:$1 $| $1
# now remove the dot
R$* $| $*<@$*.>$*	$: $1 $| $2<@$3>$4
# and check the database
R$* $| $*<@$*>$*	$: $1 $| $>junk $2<@$3>
# match: return given error code (rhs of map)
R$* $| $*<@$*@JUNK>$*	$#error $@ 5.7.1 $: $3
# restore original value (after canonicalization by ruleset 3)
# this is only required if you want to enable the last rule
# R$* $| $*		$: $1
# this is dangerous! no real name
# R$*<@$*$~P>$*	$#error $@ 4.1.8 $: 451 unresolvable host name $2$3, check your setup.

# check for junk domain/spammers
Sjunk
# lookup domain in database
R$*<@$+>		$:$1<@$(junk $2$)>
# exists? return
R$*<@$*@JUNK>		$@$1<@$2@JUNK>
# lookup address in database
R$*<@$+>		$:$1<@$(junk $1@$2 $:$2$)>
# exists? return
R$*<@$*@JUNK>		$@$1<@$2@JUNK>
# remove one subdomain, try again
R$*<@$-.$-.$+>		$: $>junk $1<@$3.$4>
Scheck_relay
# check IP
R$+ $| $+	$: $1 $| $>junkIP $2
R$+ $| $*@JUNK	$#error $@ 5.7.1 $: $2
# check hostname
R$+ $| $+	$: $>junk <@$1>
R$*<@$*@JUNK>$*	$#error $@ 5.7.1 $: $2

SjunkIP
# lookup IP in database
# full IP address
R$-.$-.$-.$-	$: $(junk $1.$2.$3.$4 $)
# class C net
R$-.$-.$-.$-	$: $(junk $1.$2.$3 $: $1.$2.$3.$4 $)
# class B net
R$-.$-.$-.$-	$: $(junk $1.$2 $: $1.$2.$3.$4 $)
# class A net
R$-.$-.$-.$-	$: $(junk $1 $: $1.$2.$3.$4 $)
It is also available as HACK(check_mail3) and HACK(check_relay3) in the check.tar file for use in a .mc file.

Accept some Addresses without Checking

The check_mail2 and check_mail3 versions in the check.tar file have a "backdoor" to accept some addresses without checking them. This can be activated with:
define(`_ACCEPT_SOME_',1)
Default for the database is:
dbm -o /etc/mail/accept
Other values can be given as argument, e.g.,
define(`_ACCEPT_SOME_',`hash /etc/AcceptIt')
Entries must have the form:
user@address	OK
domain	OK

[(links)] [Hints] [Avoiding Spam] [FAQ] [cf/README] [New]
Copyright © Claus Aßmann Please send comments to: <ca@informatik.uni-kiel.de>