Using regular expressions in sendmail.cf: map-regex-2.8

Look for changes in the file CHANGES.

The map-regex is included in sendmail-8.9. New Rulesets are available at http://www.unix-ag.uni-hannover.de/soft/check_local/.

If you want to use regular expressions in sendmail.cf e.g. to avoid UBE, you can use this little map implementation. If you want to use it in your sendmail.cf, be sure you understand, what you are doing. If you want to use the check_* rulesets look at http://www.informatik.uni-kiel.de/%7Eca/email/check.html

Features

How to install

  1. Download map-regex-2.8.tar and 'tar xf' it.
  2. Apply the patch (conf.c.patch) to sendmail-8.8.?/src/conf.c.
  3. Copy map_regex.c to sendmail-8.8.?/src/.
  4. Edit your Makefile in sendmail-8.8.?/src/Makefiles/
    DBMDEF= -DMAP_REGEX ...
    
    # additional .o files needed
    OBJADD=map_regex.o
    
  5. ./makesendmail (if it does not work "rm -r src/obj*")
  6. Test: ./sendmail -d72 -bt -Ctest_sendmail.cf
  7. Send bug-reports to: Jan.Krueger+map@stud.uni-hannover.de
  8. If you want to know, how extended regular expressions work, please read regex.ps.gz taken from lib-regex from gnu.

Troubleshooting

Link fails: undefined reference to 'regcomp' or
pattern-compile-error: : Operation not applicable
Your libc does not include a running version of POSIX-regex. Use libregex from gnu. ftp://prep.ai.mit.edu/pub/gnu/ Filename: regex-?.?.tar.gz. Or lookup a ftp-mirror e.g. ftp://ftp.rrzn.uni-hannover.de/pub/mirror/gnu/.
You can also use the regex-lib by Henry Spencer. ftp://ftp.funet.fi/pub/languages/C/spencer/regex.shar.gz
Your can link the regex.o from gnu or put it in a libregex.a and install it in the same place as e.g. libdb.a. Then you can link '-lregex'. Make sure, your compiler reads regex.h from the distribution and not from /usr/include, otherwise sendmail will dump a core. Sometimes you must "ln -s regex-0.12/regex.h sendmail-8.?.?/src/".

pattern-compile-error: [ ] imbalance or syntax error
If this error occurs using [^[()] syntax, your regex-lib is not POSIX compliant. Exercise: Remove it from your libc and put in a better one. ;-)

What is the patch doing?

The conf.c.patch adds the definition of the map-type "regex" to the function setupmaps() in the file conf.c.
    MAPDEF("regex", NULL, 0,
	    regex_map_init, null_map_open, null_map_close,
	    regex_map_lookup, null_map_store);
If you use Kname regex in your sendmail.cf, regex_map_init() is called. For the lookup $(name $1 $) regex_map_lookup() is used.
This is not really a patch, its only an addition: If you don't use regex-maps in your sendmail.cf, the behaviour of sendmail is not changed.

How it works

It knows the following options: The FIELDS parameter can also be given in the lookup (overrides the -sFIELDS):
R$*	$: $(parse $1 $@ FIELDS $)
This is a simple test_sendmail.cf
# regex map valid?
Kvalid regex -a@MATCH ^[0-9]+<@

Kparse regex -d@@ -s (\[([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\]|from *([a-z.]+))+

Smatch_parse
R$*			$: $(parse $1 $)
R$* @@ $* @@ $*		$: $2 $| $3
R$+ $| $*		$: IP: $1 $| $2
R$* $| $+		$: $1 $| host: $2


Smatch_valid
R$*			$: $(valid $1 $)
In the following, the dialogue of the test is shown:
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>

> match_valid 123<@domain.com>
rewrite: ruleset 198   input: 123 < @ domain . com >
regex_map_lookup: key '123<@domain.com>'
rewrite: ruleset 198 returns: @ MATCH

> match_valid user75<@domain.com>
rewrite: ruleset 198   input: user75 < @ domain . com >
regex_map_lookup: key 'user75<@domain.com>'
rewrite: ruleset 198 returns: user75 < @ domain . com >

> match_parse received from hostname.domain.com [123.43.5.1]
rewrite: ruleset 199   input: received from hostname . domain . com [ 123 . 43 . 5 . 1 ]
regex_map_lookup: key 'received from hostname.domain.com[123.43.5.1]'
rewrite: ruleset 199 returns: IP : 123 . 43 . 5 . 1 $| host : hostname . domain . com

Use it with m4

Copy checkregex.m4 to sendmail-?.?.?/cf/hack. Use HACK(checkregex, `pattern') in your .mc-file. The parameter is optional, the default pattern is `^[0-9]+<@'.
After this you can add "checkregex-calls" to your check_*.m4 rulesets. E.g.:
ifdef(`_CHECKREGEX_',
# check address against checkregex
R$*             $: $(checkregex $1 $)
R@MATCH         $#error $@ 5.1.8 $: 551 spam address. go away.)
This hook is included in check_mail3.m4 by Claus Aßmann.
Jan Krüger, Jan.Krueger+map@stud.uni-hannover.de