diff options
Diffstat (limited to 'usr.sbin/sendmail/src/domain.c')
-rw-r--r-- | usr.sbin/sendmail/src/domain.c | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c index f446e741821da..ca2d8f8d86e9f 100644 --- a/usr.sbin/sendmail/src/domain.c +++ b/usr.sbin/sendmail/src/domain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1986, 1995 Eric P. Allman + * Copyright (c) 1986, 1995, 1996 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * @@ -36,9 +36,9 @@ #ifndef lint #if NAMED_BIND -static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (with name server)"; +static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)"; #else -static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (without name server)"; +static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)"; #endif #endif /* not lint */ @@ -46,21 +46,39 @@ static char sccsid[] = "@(#)domain.c 8.54.1.2 (Berkeley) 9/16/96 (without name s #include <errno.h> #include <resolv.h> +#include <arpa/inet.h> + +/* +** The standard udp packet size PACKETSZ (512) is not sufficient for some +** nameserver answers containing very many resource records. The resolver +** may switch to tcp and retry if it detects udp packet overflow. +** Also note that the resolver routines res_query and res_search return +** the size of the *un*truncated answer in case the supplied answer buffer +** it not big enough to accommodate the entire answer. +*/ + +#ifndef MAXPACKET +# define MAXPACKET 8192 /* max packet size used internally by BIND */ +#endif typedef union { HEADER qb1; - u_char qb2[PACKETSZ]; + u_char qb2[MAXPACKET]; } querybuf; -static char MXHostBuf[MAXMXHOSTS*PACKETSZ]; +#ifndef MXHOSTBUFSIZE +# define MXHOSTBUFSIZE (128 * MAXMXHOSTS) +#endif + +static char MXHostBuf[MXHOSTBUFSIZE]; #ifndef MAXDNSRCH -#define MAXDNSRCH 6 /* number of possible domains to search */ +# define MAXDNSRCH 6 /* number of possible domains to search */ #endif #ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) +# define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef NO_DATA @@ -114,32 +132,21 @@ getmxrr(host, mxhosts, droplocalhost, rcode) u_short pref, type; u_short localpref = 256; char *fallbackMX = FallBackMX; - static bool firsttime = TRUE; bool trycanon = FALSE; int (*resfunc)(); extern int res_query(), res_search(); u_short prefer[MAXMXHOSTS]; int weight[MAXMXHOSTS]; - extern bool getcanonname(); + extern int mxrand __P((char *)); if (tTd(8, 2)) printf("getmxrr(%s, droplocalhost=%d)\n", host, droplocalhost); - if (fallbackMX != NULL) + if (fallbackMX != NULL && droplocalhost && + wordinclass(fallbackMX, 'w')) { - if (firsttime && - res_query(FallBackMX, C_IN, T_A, - (u_char *) &answer, sizeof answer) < 0) - { - /* this entry is bogus */ - fallbackMX = FallBackMX = NULL; - } - else if (droplocalhost && wordinclass(fallbackMX, 'w')) - { - /* don't use fallback for this pass */ - fallbackMX = NULL; - } - firsttime = FALSE; + /* don't use fallback for this pass */ + fallbackMX = NULL; } *rcode = EX_OK; @@ -212,6 +219,10 @@ getmxrr(host, mxhosts, droplocalhost, rcode) return (-1); } + /* avoid problems after truncation in tcp packets */ + if (n > sizeof(answer)) + n = sizeof(answer); + /* find first satisfactory answer */ hp = (HEADER *)&answer; cp = (u_char *)&answer + HFIXEDSZ; @@ -356,8 +367,11 @@ punt: if (p != NULL) { *p = '\0'; - if (inet_addr(&MXHostBuf[1]) != -1) + if (inet_addr(&MXHostBuf[1]) != INADDR_NONE) + { + nmx++; *p = ']'; + } else { trycanon = TRUE; @@ -518,7 +532,7 @@ dns_getcanonname(host, hbsize, trymx, statp) int qtype; int loopcnt; char *xp; - char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)]; + char nbuf[MAX(MAXPACKET, MAXDNAME*2+2)]; char *searchlist[MAXDNSRCH+2]; extern char *gethostalias(); @@ -651,6 +665,10 @@ cnameloop: else if (tTd(8, 7)) printf("\tYES\n"); + /* avoid problems after truncation in tcp packets */ + if (ret > sizeof(answer)) + ret = sizeof(answer); + /* ** Appear to have a match. Confirm it by searching for A or ** CNAME records. If we don't have a local domain |