[comp.mail.sendmail] How to recognize domain literals

moore@betelgeuse.cs.utk.edu (Keith Moore) (12/01/89)

In article <wZRL3aK00VsLA11Y1Z@andrew.cmu.edu>,
	cfe+@andrew.cmu.edu (Craig F. Everhart) writes:
(lamenting the fact that most sendmail sites don't recognize domain literals)
>There's no cure but for the target administrator to fix the 
>sendmail.cf file to recognize explicit dotted-quads, alas, [...]
                               ^^^^^^^^ ^^^^^^^^^^^^

While it's true that many sites running sendmail don't recognize
domain literals, you don't have to hard-code the IP address into
every machine's sendmail.cf file.  The example below shows how.

(somewhere in ruleset zero before you start resolving to mailers)
[...]
#
# If sending to a domain literal, attempt to canonicalize it.
#
R$*<[$+.$+.$+.$+]>$*	$:$1<$[[$2.$3.$4.$5]$]:[$2.$3.$4.$5]>$6
#
# If canonicalization returned our domain name, substitute that
# for the domain literal.  Otherwise leave the domain literal in
# place.
#
R$*<$j:[$-.$-.$-.$-]>$*		$:$1<$j>$6
R$*<$*:[$-.$-.$-.$-]>$*		$:$1<[$3.$4.$5.$6]>$7
[...]
(somewhere below this, your ruleset zero should have a rule that
matches local addresses and sends them to your local mail program.)

This hack assumes that:

1.  $j is the official domain name of your machine.

2.  $[ and $] work properly.

3.  Ruleset 3 puts brackets around the domain to send mail to (before
ruleset 0 sees the address), without including the '@'.  Otherwise,
the above example should be modified to conform to the conventions
used in your existing sendmail.cf file.

(How to fix either (1) or (2) is beyond the scope of this article.)
--
Keith Moore			Internet: moore@cs.utk.edu
University of Tenn. CS Dept.	BITNET: moore@utkvx
107 Ayres Hall, UT Campus	UT Decnet: utkcs::moore
Knoxville Tennessee 37996-1301	Telephone: +1 615 974 0822

ecf_hap@jhunix.HCF.JHU.EDU (Andrew Poling) (12/02/89)

In article <1436@utkcs2.cs.utk.edu> moore@cs.utk.edu (Keith Moore) writes:
>In article <wZRL3aK00VsLA11Y1Z@andrew.cmu.edu>,
>	cfe+@andrew.cmu.edu (Craig F. Everhart) writes:
>(lamenting the fact that most sendmail sites don't recognize domain literals)
>>There's no cure but for the target administrator to fix the 
>>sendmail.cf file to recognize explicit dotted-quads, alas, [...]
>While it's true that many sites running sendmail don't recognize
>domain literals, you don't have to hard-code the IP address into
>every machine's sendmail.cf file.  The example below shows how.
[shows one method of recognizing domain literals using canonicalization]

Wail hail, it's even easier than that if you have functional $[ and $]
canonicalization.  In that case, attempting to canonicalize the address
should return the hosts domain name anyway.

I'm sure that most of the sites Craig was referring to don't yet have the
ability to canonicalize using $[ and $].  In that case, one DOES have to
hard-code their address in.  it need not be difficult.  in the generic
sendmail.cf files that I distribute, all such host specific info is assigned
to various macros at the beginning of the file.  So I do it this way:

near the top of /usr/lib/sendmail.cf
# change "255.255.255.255" below to YOUR IP-address
DA255.255.255.255

then in ruleset 0
# recognize my IP-address - make it my name
R$+<@[$A]>		$1<@$w>		w macro is our simple hostname


There... that didn't hurt too bad. :-)


-Andy

Andy Poling                              Internet: andy@gollum.hcf.jhu.edu
Network Services Group                   Bitnet: ANDY@JHUVMS
Homewood Academic Computing              Voice: (301)338-8096    
Johns Hopkins University                 UUCP: mimsy!aplcen!jhunix!gollum!andy

wcf@psuhcx.psu.edu (Bill Fenner) (12/02/89)

In article <3472@jhunix.HCF.JHU.EDU> ecf_hap@jhunix.UUCP (Andrew Poling) writes:
|sendmail.cf files that I distribute, all such host specific info is assigned
|to various macros at the beginning of the file.  So I do it this way:
|
|near the top of /usr/lib/sendmail.cf
|# change "255.255.255.255" below to YOUR IP-address
|DA255.255.255.255
|
|then in ruleset 0
|# recognize my IP-address - make it my name
|R$+<@[$A]>		$1<@$w>		w macro is our simple hostname
|
|
|There... that didn't hurt too bad. :-)

Unfortunately, I think many binary-only sendmail's will split dotted quads
into seperate tokens, and thus the single token "255.255.255.255" will not
match the 7 tokens "255" "." "255" "." "255" "." "255" .  I've had this
problem quite a bit with customizing psuhcx's sendmail.cf ...

  Bill
-- 
Bill Fenner                   wcf@hcx.psu.edu             ..!psuvax1!psuhcx!wcf
sysop@hogbbs.fidonet.org (1:129/87 - 814/238-9633)     ..!lll-winken!/

moore@betelgeuse.cs.utk.edu (Keith Moore) (12/02/89)

In article <3472@jhunix.HCF.JHU.EDU> ecf_hap@jhunix.UUCP (Andrew Poling) writes:
>In article <1436@utkcs2.cs.utk.edu> moore@cs.utk.edu (Keith Moore) writes:
>>In article <wZRL3aK00VsLA11Y1Z@andrew.cmu.edu>,
>>	cfe+@andrew.cmu.edu (Craig F. Everhart) writes:
>>(lamenting the fact that most sendmail sites don't recognize domain literals)
>>>There's no cure but for the target administrator to fix the 
>>>sendmail.cf file to recognize explicit dotted-quads, alas, [...]
>>While it's true that many sites running sendmail don't recognize
>>domain literals, you don't have to hard-code the IP address into
>>every machine's sendmail.cf file.  The example below shows how.
>[shows one method of recognizing domain literals using canonicalization]
>
>Wail hail, it's even easier than that if you have functional $[ and $]
>canonicalization.  In that case, attempting to canonicalize the address
>should return the hosts domain name anyway.

This can cause delivery failure for outgoing mail to domain literals,
given the following set of conditions:

1)  $[ IP-address $]  yields  "domain.address"
2a) DNS lookup of "domain.address" for record type MX yields a host with
    a different IP address, or
2b) DNS lookup of "domain.address" for ADDR record yields a different IP
    address than in the original domain literal.

The situation described in case 2a is normal for many sites that send all
incoming mail to a single host.  But you still want to be able to send
directly to any given IP address, if only for testing purposes.

I've actually been bitten by the situation described in 2b.  Furthermore,
even though I could identify the problem using nslookup, I had no way
of sending mail to the postmaster or system maintainer at that site.

The only reason to use domain literals at all is as a trapdoor for when
the name server / host tables are incorrect or insufficient.  So it's 
important that they work properly even if the name server database at some
particular site is bogus.

To be fair, even the method I posted earlier will fail if all of the
recipient's nameservers are down and there's no fallback to a local
/etc/hosts file.  (Sendmail really should pre-define a class that will 
match all local IP addresses as obtained from the SIOCGIFCONF ioctl;
then the matches would be foolproof.)

>I'm sure that most of the sites Craig was referring to don't yet have the
>ability to canonicalize using $[ and $].  

Well, support for $[ and $] (at least via the /etc/hosts file) has been
in sendmail since version 4.39, dated August 1984.  Any one on the Internet
that is using something older should certainly ftp the latest sources
from Berkeley and compile them :-).


Keith Moore			Internet: moore@cs.utk.edu
University of Tenn. CS Dept.	BITNET: moore@utkvx
107 Ayres Hall, UT Campus	UT Decnet: utkcs::moore
Knoxville Tennessee 37996-1301	Telephone: +1 615 974 0822

karl@cheops.cis.ohio-state.edu (Karl Kleinpaste) (12/03/89)

It seems to me that you can't expect the MX'd addresses to be the
same, because although you may want to be able to send mail to a host
via its IP address, the reason for the MX record's existence is that
the host in question doesn't run a mailer in the first place;
knowledge of the IP address is useless.

Ultimately, if one is trying in desperation to get in touch with a
postmaster or sysadmin, one can always use "whois" to find out who the
responsible people are, or alternatively, "telnet 11.22.33.44 smtp,"
and do it The Hard Way.  This is useful in any event, for the more
creative applications of VERB and VRFY, not to mention verification of
worm immunity.

User interface usage of email to IP addresses is strictly passe'.

Real postmasters send mail
via telnet to the SMTP port,
--karl

ecf_hap@jhunix.HCF.JHU.EDU (Andrew Poling) (12/05/89)

In article <1937@psuhcx.psu.edu> wcf@psuhcx.psu.edu (Bill Fenner) writes:
>In article <3472@jhunix.HCF.JHU.EDU> ecf_hap@jhunix.UUCP (Andrew Poling) writes:
[...]
>|near the top of /usr/lib/sendmail.cf
>|# change "255.255.255.255" below to YOUR IP-address
>|DA255.255.255.255
[...]
>Unfortunately, I think many binary-only sendmail's will split dotted quads
>into seperate tokens, and thus the single token "255.255.255.255" will not
>match the 7 tokens "255" "." "255" "." "255" "." "255" .  I've had this
>problem quite a bit with customizing psuhcx's sendmail.cf ...

I think you're confusing macros and classes.  While it' doesn't seem to be
documented anywhere, it's been my experience that a macro definition can
contain multiple tokens, but a class definition cannot.

Thus one could really view a macro as a class that ignores the special
characters defined by the "o" macro (while you're defining the class/macro
in question) - it can match only the exact same set of tokens later.

Jeez - that seemd alot simpler until I tried to articulate it.


-Andy

--
Andy Poling                              Internet: andy@gollum.hcf.jhu.edu
Network Services Group                   Bitnet: ANDY@JHUVMS
Homewood Academic Computing              Voice: (301)338-8096    
Johns Hopkins University                 UUCP: mimsy!aplcen!jhunix!gollum!andy

ecf_hap@jhunix.HCF.JHU.EDU (Andrew Poling) (12/05/89)

In article <1439@utkcs2.cs.utk.edu> moore@cs.utk.edu (Keith Moore) writes:
>In article <3472@jhunix.HCF.JHU.EDU> ecf_hap@jhunix.UUCP (Andrew Poling) writes:
>>Wail hail, it's even easier than that if you have functional $[ and $]
>>canonicalization.  In that case, attempting to canonicalize the address
>>should return the hosts domain name anyway.
>
>This can cause delivery failure for outgoing mail to domain literals,
>given the following set of conditions:
>
>1)  $[ IP-address $]  yields  "domain.address"
>2a) DNS lookup of "domain.address" for record type MX yields a host with
>    a different IP address, or

	This is not a concern when using $[ and $] - they simply return the
	full domain-name for the hostname or address contained within them.
	The MX lookup is done later when attempting to connect for delivery.

>2b) DNS lookup of "domain.address" for ADDR record yields a different IP
>    address than in the original domain literal.
>
>I've actually been bitten by the situation described in 2b.  Furthermore,
>even though I could identify the problem using nslookup, I had no way
>of sending mail to the postmaster or system maintainer at that site.

	This is out of your hands if it happens - they're screwed and
	they'll have to fix it.  You can always talk to their SMTP daemon
	and get them mail the hard way though.  I keep a specially
	configured old dumb sendmail around for just this purpose - I type
	too poorly to interact with the SMTP daemon directly.

>Well, support for $[ and $] (at least via the /etc/hosts file) has been
>in sendmail since version 4.39, dated August 1984.  Any one on the Internet
>that is using something older should certainly ftp the latest sources
>from Berkeley and compile them :-).

	Spoken like a man with a VAX and BSD.  Alot of people are trying to
	get what their vendor gave them to work.  I can name examples of
	vendor-released sendmail binaries where the host table based $[ and
	$] simply don't work.

-Andy

--
Andy Poling                              Internet: andy@gollum.hcf.jhu.edu
Network Services Group                   Bitnet: ANDY@JHUVMS
Homewood Academic Computing              Voice: (301)338-8096    
Johns Hopkins University                 UUCP: mimsy!aplcen!jhunix!gollum!andy

nowicki@legato (Bill Nowicki) (12/06/89)

In article <1439@utkcs2.cs.utk.edu> moore@cs.utk.edu (Keith Moore) writes:
>In article <3472@jhunix.HCF.JHU.EDU> ecf_hap@jhunix.UUCP (Andrew Poling) writes:
>>In article <1436@utkcs2.cs.utk.edu> moore@cs.utk.edu (Keith Moore) writes:
>>>In article <wZRL3aK00VsLA11Y1Z@andrew.cmu.edu>,
>>>	cfe+@andrew.cmu.edu (Craig F. Everhart) writes:
>>>(lamenting the fact that most sendmail sites don't recognize domain literals)
...
>The only reason to use domain literals at all is as a trapdoor for when
>the name server / host tables are incorrect or insufficient.  So it's 
>important that they work properly even if the name server database at some
>particular site is bogus.
>

Yes!  The only time I have ever had to send mail to an explicit IP
address was when the name server for that site was broken.  As you
note, that is exactly the same case in which $[ fails.  That is the
general problem with $[ -- there is no well-defined error behavior.
Sometimes you want it to quietly act as a no-op on any error, other
times you want to force a re-queue of the message, etc.

>(Sendmail really should pre-define a class that will match all local
>IP addresses as obtained from the SIOCGIFCONF ioctl; then the matches
>would be foolproof.)

This is actually simple to do.  I did this while working for "a
certain major Unix vendor" many months ago.  Since SunOS 4.x sendmail
had the ability to match multiple tokens in a class (see my last
message) from the IDA enhancements, all you need to do is add these to
the $=w class.  You might also want to shuffle a few lines in the
sendmail.cf file to match $=w before the IP dotted-quad.  This is the
way SunOS 4.1 was set up to work, so that you can use the exact same
sendmail.cf file on tens of thousands of systems instead of needing to
diddle each one manually.  You can get a sendmail with this feature
from uunet.uu.net:~ftp/sun-fixes.

For those of you who like source:

char **
myhostname(hostbuf, size)
	char hostbuf[];
	int size;
{
	extern struct hostent *gethostbyname();
	struct hostent *hp;
	static char *nicknames[MAXATOM];
	register char **avp, *thisname;
	int s, n;
        struct ifconf ifc;
        struct ifreq *ifr;
	char interfacebuf[1024];

	if (gethostname(hostbuf, size) < 0)
	{
		(void) strcpy(hostbuf, "localhost");
	}
	hp = gethostbyname(hostbuf);
	if (hp == NULL)
		return (NULL);

	(void) strncpy(hostbuf, hp->h_name, size-1);
	for (avp=nicknames;*hp->h_aliases;)
		*avp++ = *hp->h_aliases++;
	*avp = NULL;
	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s == -1)
		return (nicknames);
        ifc.ifc_len = sizeof(interfacebuf);
        ifc.ifc_buf = interfacebuf;
	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)
		return (nicknames);
        ifr = ifc.ifc_req;
        for (n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
		char thisbuf[256];
		
		if (ifr->ifr_addr.sa_family != AF_INET)
			continue;
		(void) sprintf(thisbuf, "[%s]", inet_ntoa(
	((struct sockaddr_in *)(&ifr->ifr_addr))->sin_addr));
		thisname = newstr(thisbuf);
		*avp++ = thisname;
	}
	*avp = NULL;
	return (nicknames);
}