BSD 4_4_Lite2 release
[unix-history] / usr / src / usr.sbin / sendmail / src / domain.c
index 85ea835..61570ed 100644 (file)
@@ -3,16 +3,42 @@
  * Copyright (c) 1988, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
  * Copyright (c) 1988, 1993
  *     The Regents of the University of California.  All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #include "sendmail.h"
 
 #ifndef lint
 #if NAMED_BIND
  */
 
 #include "sendmail.h"
 
 #ifndef lint
 #if NAMED_BIND
-static char sccsid[] = "@(#)domain.c   8.44 (Berkeley) %G% (with name server)";
+static char sccsid[] = "@(#)domain.c   8.47 (Berkeley) 6/20/95 (with name server)";
 #else
 #else
-static char sccsid[] = "@(#)domain.c   8.44 (Berkeley) %G% (without name server)";
+static char sccsid[] = "@(#)domain.c   8.47 (Berkeley) 6/20/95 (without name server)";
 #endif
 #endif /* not lint */
 
 #endif
 #endif /* not lint */
 
@@ -77,7 +103,6 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
        bool droplocalhost;
        int *rcode;
 {
        bool droplocalhost;
        int *rcode;
 {
-       extern int h_errno;
        register u_char *eom, *cp;
        register int i, j, n;
        int nmx = 0;
        register u_char *eom, *cp;
        register int i, j, n;
        int nmx = 0;
@@ -91,6 +116,8 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
        char *fallbackMX = FallBackMX;
        static bool firsttime = TRUE;
        bool trycanon = FALSE;
        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();
        u_short prefer[MAXMXHOSTS];
        int weight[MAXMXHOSTS];
        extern bool getcanonname();
@@ -131,9 +158,13 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
 
        if (!UseNameServer)
                goto punt;
 
        if (!UseNameServer)
                goto punt;
+       if (HasWildcardMX && ConfigLevel >= 6)
+               resfunc = res_query;
+       else
+               resfunc = res_search;
 
        errno = 0;
 
        errno = 0;
-       n = res_search(host, C_IN, T_MX, (u_char *) &answer, sizeof(answer));
+       n = (*resfunc)(host, C_IN, T_MX, (u_char *) &answer, sizeof(answer));
        if (n < 0)
        {
                if (tTd(8, 1))
        if (n < 0)
        {
                if (tTd(8, 1))
@@ -216,8 +247,6 @@ getmxrr(host, mxhosts, droplocalhost, rcode)
                        seenlocal = TRUE;
                        continue;
                }
                        seenlocal = TRUE;
                        continue;
                }
-               if (fallbackMX != NULL && strcasecmp(bp, fallbackMX) == 0)
-                       fallbackMX = NULL;
                weight[nmx] = mxrand(bp);
                prefer[nmx] = pref;
                mxhosts[nmx++] = bp;
                weight[nmx] = mxrand(bp);
                prefer[nmx] = pref;
                mxhosts[nmx++] = bp;
@@ -304,35 +333,22 @@ punt:
                                }
                        }
                }
                                }
                        }
                }
-               n = strlen(MXHostBuf);
-               bp = &MXHostBuf[n];
-               buflen = sizeof MXHostBuf - n - 1;
                if (trycanon &&
                    getcanonname(mxhosts[0], sizeof MXHostBuf - 2, FALSE))
                {
                if (trycanon &&
                    getcanonname(mxhosts[0], sizeof MXHostBuf - 2, FALSE))
                {
+                       bp = &MXHostBuf[strlen(MXHostBuf)];
                        if (bp[-1] != '.')
                        {
                                *bp++ = '.';
                                *bp = '\0';
                        if (bp[-1] != '.')
                        {
                                *bp++ = '.';
                                *bp = '\0';
-                               buflen--;
                        }
                        nmx = 1;
                }
                        }
                        nmx = 1;
                }
-               bp++;
        }
 
        /* if we have a default lowest preference, include that */
        }
 
        /* if we have a default lowest preference, include that */
-       if (fallbackMX != NULL && !seenlocal && strlen(fallbackMX) < buflen)
-       {
-               strcpy(bp, fallbackMX);
-               mxhosts[nmx++] = bp;
-               bp += strlen(bp);
-               if (bp[-1] != '.')
-               {
-                       *bp++ = '.';
-                       *bp = '\0';
-               }
-       }
+       if (fallbackMX != NULL && !seenlocal)
+               mxhosts[nmx++] = fallbackMX;
 
        return (nmx);
 }
 
        return (nmx);
 }
@@ -388,6 +404,35 @@ mxrand(host)
        return hfunc;
 }
 \f/*
        return hfunc;
 }
 \f/*
+**  BESTMX -- find the best MX for a name
+**
+**     This is really a hack, but I don't see any obvious way
+**     to generalize it at the moment.
+*/
+
+char *
+bestmx_map_lookup(map, name, av, statp)
+       MAP *map;
+       char *name;
+       char **av;
+       int *statp;
+{
+       int nmx;
+       auto int rcode;
+       int saveopts = _res.options;
+       char *mxhosts[MAXMXHOSTS + 1];
+
+       _res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
+       nmx = getmxrr(name, mxhosts, FALSE, &rcode);
+       _res.options = saveopts;
+       if (nmx <= 0)
+               return NULL;
+       if (bitset(MF_MATCHONLY, map->map_mflags))
+               return map_rewrite(map, name, strlen(name), NULL);
+       else
+               return map_rewrite(map, mxhosts[0], strlen(mxhosts[0]), av);
+}
+\f/*
 **  DNS_GETCANONNAME -- get the canonical name for named host using DNS
 **
 **     This algorithm tries to be smart about wildcard MX records.
 **  DNS_GETCANONNAME -- get the canonical name for named host using DNS
 **
 **     This algorithm tries to be smart about wildcard MX records.
@@ -424,7 +469,6 @@ dns_getcanonname(host, hbsize, trymx, statp)
        bool trymx;
        int *statp;
 {
        bool trymx;
        int *statp;
 {
-       extern int h_errno;
        register u_char *eom, *ap;
        register char *cp;
        register int n; 
        register u_char *eom, *ap;
        register char *cp;
        register int n; 
@@ -719,7 +763,6 @@ gethostalias(host)
        if (fname == NULL ||
            (fp = safefopen(fname, O_RDONLY, 0, SFF_REGONLY)) == NULL)
                return NULL;
        if (fname == NULL ||
            (fp = safefopen(fname, O_RDONLY, 0, SFF_REGONLY)) == NULL)
                return NULL;
-       setbuf(fp, NULL);
        while (fgets(buf, sizeof buf, fp) != NULL)
        {
                for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++)
        while (fgets(buf, sizeof buf, fp) != NULL)
        {
                for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++)
@@ -753,128 +796,4 @@ gethostalias(host)
        return hbuf;
 }
 
        return hbuf;
 }
 
-\f/*
-**  MAILB_LOOKUP -- do DNS mailbox lookup
-*/
-
-#ifdef DNS_MAILB
-
-mailb_lookup(addr)
-       char *addr;
-{
-       /*
-       **  Convert addr to DNS form (user.host).
-       */
-
-       /* figure out how much space it needs */
-       atp = strchr(addr, '@');
-       if (atp == NULL)
-               atp = &addr(strlen(addr));
-       i = strlen(addr);
-       for (p = addr; (p = strchr(p, '.')) != NULL; p++)
-       {
-               if (p > atp)
-                       break;
-               i++;
-       }
-       if (i < sizeof abuf)
-               bufp = abuf;
-       else
-               bufp = xalloc(i + 1);
-
-       lhsmode = TRUE;
-       for (p = addr, q = bufp; (c = *p++) != '\0'; )
-       {
-               if (c == '.' && lhsmode)
-                       *q++ = '\\';
-               if (c == '@')
-                       lhsmode = FALSE;
-               *q++ = c;
-       }
-       *q = '\0';
-
-       /*
-       **  Now do a MAILB lookup.
-       */
-
-retry:
-       if (res_query(bufp, C_IN, T_MAILB, (char *) &answer, sizeof answer < 0)
-       {
-               /* no match -- just continue as usual */
-               return FALSE;
-       }
-
-       /* find first satisfactory answer */
-       hp = (HEADER *)&answer;
-       ap = (u_char *)&answer + sizeof(HEADER);
-       eom = (u_char *)&answer + n;
-       for (qdcount = ntohs(hp->qdcount); qdcount--; ap += n + QFIXEDSZ)
-               if ((n = dn_skipname(ap, eom)) < 0)
-                       return FALSE;
-       for (ancount = ntohs(hp->ancount); --ancount >= 0 && ap < eom; ap += n)
-       {
-               n = dn_expand((u_char *)&answer, eom, ap, (u_char *)bp, buflen);
-               if (n < 0)
-                       break;
-               ap += n;
-               GETSHORT(type, ap);
-               ap += SHORTSIZE + LONGSIZE;
-               GETSHORT(n, ap);
-               switch (type)
-               {
-                 case T_MR:
-                       /* rename: try again */
-                       i = dn_expand((u_char *) &answer, eom, ap,
-                                       (u_char) abuf, sizeof abuf);
-                       if (i < 0)
-                               break;
-                       if (bufp != abuf)
-                       {
-                               free(bufp);
-                               bufp = abuf;
-                       }
-                       goto retry;
-
-                 case T_MB:
-                       i = dn_expand((u_char *) &answer, eom, ap,
-                                       (u_char) hbuf, sizeof hbuf);
-                       if (i < 0)
-                               break;
-
-                       /* hbuf now has the host to deliver to */
-                       break;
-
-                 case T_MG:
-                       i = dn_expand((u_char *) &answer, eom, ap,
-                                       (u_char) gbuf, sizeof gbuf);
-                       if (i < 0)
-                               break;
-                       AliasLevel++;
-                       naddrs += sendtolist(ubuf, a, sendq, e);
-                       AliasLevel--;
-                       break;
-
-                 case T_MINFO:
-                       /* bleach */
-                       XXX;
-               }
-
-
-
-               if (type != T_MX)
-               {
-                       if (tTd(8, 8) || _res.options & RES_DEBUG)
-                               printf("unexpected answer type %d, size %d\n",
-                                   type, n);
-                       cp += n;
-                       continue;
-               }
-               GETSHORT(pref, cp);
-               if ((n = dn_expand((u_char *)&answer, eom, cp,
-                                  (u_char *)bp, buflen)) < 0)
-                       break;
-               cp += n;
-
-
-#endif /* DNS_MAILB */
 #endif /* NAMED_BIND */
 #endif /* NAMED_BIND */