Here are the patches to bind-4.9.5-P1 to support the 'noforward' directive, and instructions for building and using a modified bind. 1. You must '#define NOFORWARD' for the modifications to be enabled. The best way to do this is to add it to conf/options.h, but you have to do that yourself, by hand. You can also edit the main Makefile and add '-DNOFORWARD' to the CPPFLAGS for your platform. 2. Apply the patches to the files in the 'named' sub- directory. Assuming that your current directory is the 'named' subdirectory and the name of this file is noforward.patches, the syntax on Digital Unix might be: patch -p1 -i noforward.patches It will, of course, depend on your platform's version of the patch utility. The man pages are highly recommended. 3. Move to the top level directory and run make. After it builds correctly, do a 'make install' or whatever you need to do to get the modified 'named' executable put in the right place. 4. Add one or more 'noforward' directives to named.boot as required. For instance, if you wanted to prevent forwarding for domain 'nutsnbolts.com' (and everything under it), add the following line to named.boot: noforward nutsnbolts.com You might also want to exclude address->name maps. For example, if nutsnbolts.com corresponds to network 192.168.0.0, you might add the following: noforward 168.192.in-addr.arpa Note that you can list multiple domains in a single 'noforward' directive: noforward nutsnbolts.com 168.192.in-addr.arpa 5. Restart your server to load the new config. That's all there is to it (in a perfect world)! Todd.Aven@BankersTrust.Com 23 December 1996 The rest of this file is patches... ======================================================================== *** named/ns_defs.h 1996/12/23 16:11:25 --- named/ns_defs.h 1996/12/23 16:44:38 *************** *** 291,296 **** --- 291,304 ---- fwdaddr; }; + #ifdef NOFORWARD + struct nofwdinfo { + struct nofwdinfo *next; + char nofwdname[255]; + }; + + #endif /* NOFORWARD */ + enum nameserStats { nssRcvdR, /* sent us an answer */ nssRcvdNXD, /* sent us a negative response */ nssRcvdFwdR, /* sent us a response we had to fwd */ *** named/ns_forw.c 1996/12/23 16:11:25 --- named/ns_forw.c 1996/12/23 16:44:38 *************** *** 143,148 **** --- 143,158 ---- qp->q_stream = qsp; qp->q_curaddr = 0; qp->q_fwd = fwdtab; + #ifdef NOFORWARD + if(noforward(dname)) { + qp->q_fwd = NULL; + if (n == 0) { + dprintf(2, (ddt, "forw: no nameservers found\n")); + qfree(qp); + return (FW_NOSERVER); + } + } + #endif /* NOFORWARD */ qp->q_dfd = dfd; qp->q_id = id; qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2; *************** *** 1087,1089 **** --- 1097,1150 ---- } free((char*)qp); } + + #ifdef NOFORWARD + int + noforward(dname) + char *dname; + { + /* Each entry in the 'noforward' list of domains is right-align + * compared against the dname arg. If a match is found, then + * return 1. Otherwise, return 0. + * e.g. noforward(test.dom.x.y), list={x.y} returns 1 + * ^^^ ^^^ + */ + + register struct nofwdinfo *nofwdptr; + register int dlen, tlen; + register char *tname; + + /* Protect ourselves from lunacy */ + if(dname == (char *)NULL) return 0; + + /* Announce our presence */ + dprintf(1, (ddt, "noforward: dname=%s\n", dname)); + + /* Pre-calculate the length of dname */ + dlen = strlen(dname); + if(dlen == 0) return 0; /* More lunacy-protection */ + + /* Search the noforward list (if exists) for self or parent */ + for(nofwdptr = nofwdtab; nofwdptr; nofwdptr = nofwdptr->next) { + tname = nofwdptr->nofwdname; + dprintf(1, (ddt, "noforward: compare dname=%s, tname=%s\n", + dname, tname)); + /* Get the length of the test name */ + tlen = strlen(tname); + + /* Skip if the tname is longer than the dname */ + if (tlen > dlen) continue; + + /* Make sure the match is only on complete labels */ + if ((dlen != tlen) && (dname[dlen-tlen-1] != '.')) continue; + /* Compare the tname against the dname, right-aligned */ + if(strcasecmp(tname, (char *)(dname+dlen-tlen)) == 0) { + dprintf(1, (ddt, "noforward: %s matches %s\n", dname, tname)); + return 1; + } + } + + /* Nothing matched */ + return 0; + } + #endif /* NOFORWARD */ *** named/ns_glob.h 1996/12/23 16:11:25 --- named/ns_glob.h 1996/12/23 16:44:38 *************** *** 82,87 **** --- 82,92 ---- /* list of forwarding hosts */ DECL struct fwdinfo *fwdtab INIT(NULL); + #ifdef NOFORWARD + /* list of zones for which we ignore forwarders */ + DECL struct nofwdinfo *nofwdtab INIT(NULL); + #endif /* NOFORWARD */ + /* datagram socket */ DECL int ds INIT(-1); *** named/ns_init.c 1996/12/23 16:11:25 --- named/ns_init.c 1996/12/23 16:44:38 *************** *** 83,88 **** --- 83,92 ---- #ifdef DEBUG content_zone __P((int)), #endif + #ifdef NOFORWARD + get_noforward __P((FILE *)), + free_noforward __P((void)), + #endif /* NOFORWARD */ do_reload __P((char *, int, int)), free_forwarders __P((void)), ns_limit __P((const char *name, int value)), *************** *** 169,174 **** --- 173,181 ---- } #endif free_forwarders(); + #ifdef NOFORWARD + free_noforward(); + #endif /* NOFORWARD */ free_netlist(enettab); #ifdef XFRNETS free_netlist(&xfrnets); *************** *** 294,299 **** --- 301,311 ---- } else if (strcasecmp(buf, "forwarders") == 0) { get_forwarders(fp); continue; + #ifdef NOFORWARD + } else if (strcasecmp(buf, "noforward") == 0) { + get_noforward(fp); + continue; + #endif /* NOFORWARD */ } else if (strcasecmp(buf, "slave") == 0) { forward_only++; continue; *************** *** 775,780 **** --- 787,854 ---- fwdtab = NULL; } + #ifdef NOFORWARD + static void + get_noforward(fp) + FILE *fp; + { + char buf[BUFSIZ]; + register struct nofwdinfo *fip = NULL, *ftp = NULL; + + dprintf(1, (ddt, "noforward ")); + + /* on mulitple noforward lines, move to end of the list */ + if (nofwdtab != NULL) { + for (fip = nofwdtab; fip->next != NULL; fip = fip->next) { + ; + } + } + + while (getword(buf, sizeof(buf), fp, 0)) { + if (strlen(buf) == 0) + break; + dprintf(1, (ddt," %s",buf)); + if (ftp == NULL) + ftp = (struct nofwdinfo *)malloc(sizeof(struct nofwdinfo)); + /*TSA- Should check size of buf before copying */ + strcpy(ftp->nofwdname, buf); + ftp->next = NULL; + if (nofwdtab == NULL) + nofwdtab = ftp; /* First time only */ + else + fip->next = ftp; + fip = ftp; + ftp = NULL; + } + if (ftp) + free((char *)ftp); + + dprintf(1, (ddt, "\n")); + #ifdef DEBUG + if (debug > 2) { + for (ftp = nofwdtab; ftp != NULL; ftp = ftp->next) { + fprintf(ddt,"ftp x%x [%s] next x%x\n", + ftp, + ftp->nofwdname, + ftp->next); + } + } + #endif + } + + static void + free_noforward() + { + register struct nofwdinfo *ftp, *fnext; + + for (ftp = nofwdtab; ftp != NULL; ftp = fnext) { + fnext = ftp->next; + free((char *)ftp); + } + nofwdtab = NULL; + } + #endif /* NOFORWARD */ + static struct zoneinfo * find_zone(name, type, class) char *name; *** named/ns_resp.c 1996/12/23 16:11:25 --- named/ns_resp.c 1996/12/23 16:44:38 *************** *** 1098,1103 **** --- 1098,1106 ---- qp->q_naddr = 0; qp->q_curaddr = 0; qp->q_fwd = fwdtab; + #ifdef NOFORWARD + if(noforward(dname)) qp->q_fwd = NULL; + #endif /* NOFORWARD */ getname(np, tmpdomain, sizeof tmpdomain); qp->q_domain = strdup(tmpdomain); *************** *** 2015,2020 **** --- 2018,2026 ---- qp->q_fwd = NULL; else qp->q_fwd = fwdtab; + #ifdef NOFORWARD + if(noforward(dname)) qp->q_fwd = NULL; + #endif /* NOFORWARD */ qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2; qp->q_flags |= Q_SYSTEM;