From: nigelm@ohm.york.ac.uk (Nigel Metheringham)
Newsgroups: comp.mail.sendmail
Subject: Dbm lookup bug in sendmail-5.65c+IDA-1.4.4.1 (with patch)
Summary: Description of bug in sendmail along with patch to fix
Keywords: sendmail bug dbm ida patch
Date: 8 Apr 92 15:07:55 GMT
Organization: Electronics Department, University of York, UK

I have discovered a fairly serious bug in the handling of dbm map
matching in sendmail-5.65c+IDA-1.4.4.1.

A quick description of the bug is that although the basic pattern
matching code was included in the rewrite code to handle dbm map
matches (ie a $% in the LHS of a rule), there was no code added into
the backup part of rewrite, so if the pattern match initially fails,
the matcher is unable to backtrack and try again.

The way this bug shows up is shown by the following rule from my
config file:-
  R$+@$+$%G	$@<$1@$2$3>$2$3.ether

In this case the dbm map G contains a list of top level domains that
we can use SMTP to - things like edu com se lu

We found that putting the address "fred@xx.lu.se" to this rule gave
a match on the lu part of the address to the detriment of the
trailing se part of the address, so the rule returned
"<fred@xx.lu>xx.lu.ether" instead of the correct
"<fred@xx.lu.se>xx.lu.se.ether".

When you finally work out how the rewrite code works it is obvious
that when the MATCHMAP code was put in (well it was actually
directly copied from the MATCHCLASS code above it) there should also
have been a matching piece added to the backup code a bit further
down - and it just isn't there.

The enclosed patch has been tested, but not worked to death.  I have
not really tested the one line I changed to handle MATCHNMAP since I
don't use that construction, but it looks OK to me.

Is it really the case that no one is using DBM lookups within
sendmail - I can't imagine how this could have stayed underground
for any length of time if the code is actually being used!

Here's the patch to parseaddr.c file:-

Index: parseaddr.c
*** /tmp/,RCSt1002047	Wed Apr  8 15:49:29 1992
--- parseaddr.c	Wed Apr  8 15:49:15 1992
***************
*** 813,818 ****
--- 813,848 ----
  					rvp++;
  					break;
  				}
+ 				if (*rp == MATCHMAP)
+ 				{
+ 					char **oldavp;
+ 
+ 					/* attempt to extend binding */
+ 					/* slow, concat version by lel@ida.liu.se */
+ 
+ 					oldavp = avp;
+ 					*tokbuf = (char) NULL;
+ 					for (avp = mlp[-1].first;
+ 					    avp <= mlp[-1].last; avp++)
+ 						(void) strcat(tokbuf, *avp);
+ 
+ 					do {
+ 						if (*avp == NULL)
+ 						{
+ 							/* back out binding */
+ 							avp = oldavp;
+ 							mlp--;
+ 							goto cantextend;
+ 						}
+ 						(void) strcat(tokbuf, *avp++);
+ 					} while (mapkey(rp[1], tokbuf, sizeof(tokbuf)-1,
+ 							NULL) == NULL);
+ 
+ 					/* found an extension */
+ 					mlp[-1].last = avp-1;
+ 					rvp++;
+ 					break;
+ 				}
  cantextend:
  				if (*rp == MATCHANY || *rp == MATCHZANY)
  				{
***************
*** 823,829 ****
  					break;
  				}
  				avp--;
! 				if (*rp == MATCHONE || *rp == MATCHNCLASS)
  				{
  					/* back out binding */
  					mlp--;
--- 853,859 ----
  					break;
  				}
  				avp--;
! 				if (*rp == MATCHONE || *rp == MATCHNCLASS || *rp == MATCHNCLASS)
  				{
  					/* back out binding */
  					mlp--;

--------------------------------------------------------------------------

	Nigel.

-- 
# Nigel Metheringham   # (NeXT) EMail: nigelm@ohm.york.ac.uk #
# System Administrator #######  Phone: +44 904 432374        #
# Department of Electronics  #  Fax:   +44 904 432335        #
#     University of York, Heslington, York, UK, YO1 5DD      #