Path: utzoo!utgpu!watserv1!watmath!att!linac!uwm.edu!wuarchive!sdd.hp.com!caen!uflorida!mlb.semi.harris.com!algol.mlb.semi.harris.com!del From: del@algol.mlb.semi.harris.com (Don Lewis) Newsgroups: comp.protocols.tcp-ip.domains Subject: Re: Removing unneeded glue records Message-ID: <1991Feb5.064846.5711@mlb.semi.harris.com> Date: 5 Feb 91 06:48:46 GMT References: <1991Feb3.225247.14168@ugle.unit.no> Sender: news@mlb.semi.harris.com Organization: Harris Semiconductor, Melbourne FL Lines: 237 Nntp-Posting-Host: algol.mlb.semi.harris.com In article <1991Feb3.225247.14168@ugle.unit.no> he@idt.unit.no (Havard Eidnes) writes: >We have had some problems with "undesired information leakage" in >BIND.4.8.3. Let me illustrate with the following situation: > >Two name servers: A and B, registered in unrelated domains >Two domains: dom.A and dom.B > >dom.A authoritative copy on A, secondary on B >dom.B authoritative copy on B, secondary on A > >You decide to change the IP address of name server A. You will probably >have a hard time stomping out the RR for the old A information. The >reason is that during a zone transfer, BIND insists on sending glue >records (containing A information) even though the glue record is for a >name outside of the domain the zone contains. It may fetch this old A >record from anywhere, including from cached-up information (making the >need for a secondary-NS-loop like the above unneccessary for this >misfeature to bite). In order to get rid of this stale record in the >domain name servers you will have to simultaneously do this on both name >servers: > >stop name server >remove secondary zone data (to force a reload) >start name server > Another way is to: stop name server A update A's address in dom.A (and update serial number). remove glue record for A from dom.B's secondary zone file on A (leaving serial number alone) restart name server on A The next zone transfer of dom.A from A -> B will update A's address on B, and subsequent B -> A transfers of dom.B will include the correct address. >For various reasons this may be hard to do. Instead, I have developed a >fix to BIND version 4.8.3 so that BIND will only supply glue records >that are truly needed (eg. the NS in question is located in a subdomain >of the "current" domain name) when doing a zone transfer. The fix >follows below, possibly with tabs converted to spaces. I made a similar change a while ago. My patch is a bit fancier (and much more complicated). It has the advantage that it only includes the extra A records if they reside below an NS RR delegating authority to a subzone. *** ORIG/ns_req.c Wed Jun 27 18:39:46 1990 --- ns_req.c Fri Feb 1 23:01:23 1991 *************** *** 975,984 **** /* * Do a zone transfer. SOA record already sent. */ ! doaxfr(np, rfp, isroot) register struct namebuf *np; FILE *rfp; int isroot; { register struct databuf *dp; register int n; --- 976,986 ---- /* * Do a zone transfer. SOA record already sent. */ ! doaxfr(np, rfp, isroot, top) register struct namebuf *np; FILE *rfp; int isroot; + struct namebuf *top; { register struct databuf *dp; register int n; *************** *** 985,990 **** --- 987,994 ---- struct hashbuf *htp; struct databuf *gdp; /* glue databuf */ struct namebuf *gnp; /* glue namebuf */ + struct namebuf *tnp; + struct databuf *tdp; struct namebuf **npp, **nppend; char msg[PACKETSZ]; char *cp; *************** *** 1010,1060 **** cp = msg + sizeof(HEADER); getname(np, dname, sizeof(dname)); ! /* first do data records */ for (dp = np->n_data; dp != NULL; dp = dp->d_next) { /* * Skip the root SOA record (marks end of data); * don't send SOA for subdomains, as we're not sending them. */ ! if (dp->d_type == T_SOA) continue; - if (dp->d_type == T_NS) - fndns = 1; if (dp->d_zone == 0 || stale(dp)) continue; if ((n = make_rr(dname, dp, cp, sizeof(msg)-sizeof(HEADER), 0)) < 0) continue; fwritemsg(rfp, msg, n + sizeof(HEADER)); - - if (dp->d_type == T_NS) { - /* Glue the sub domains together by sending - * the address records for the sub domain - * name servers along. - */ - htp = hashtab; - cp = msg + sizeof(HEADER); - gnp = nlookup(dp->d_data, &htp, &fname, 0); - if (gnp == NULL || fname != dp->d_data) - continue; - for(gdp=gnp->n_data; gdp != NULL; gdp=gdp->d_next) { - if (gdp->d_type != T_A || stale(gdp)) - continue; - if ((n = make_rr(fname, gdp, cp, - sizeof(msg)-sizeof(HEADER), 0)) < 0) - continue; - fwritemsg(rfp, msg, n + sizeof(HEADER)); - } - } } ! /* next do subdomains, unless delegated */ ! if ((isroot == 0 && fndns) || np->n_hash == NULL) return; npp = np->n_hash->h_tab; nppend = npp + np->n_hash->h_size; while (npp < nppend) { for (np = *npp++; np != NULL; np = np->n_next) { ! doaxfr(np, rfp, 0); } } #ifdef DEBUG --- 1014,1090 ---- cp = msg + sizeof(HEADER); getname(np, dname, sizeof(dname)); ! /* first do the NS records */ for (dp = np->n_data; dp != NULL; dp = dp->d_next) { + if (dp->d_type == T_NS) { + fndns = 1; + if ((n = make_rr(dname, dp, cp, sizeof(msg)-sizeof(HEADER), 0)) < 0) + continue; + fwritemsg(rfp, msg, n + sizeof(HEADER)); + if (!isroot) { + /* Glue the sub domains together by sending + * the address records for the sub domain + * name servers along if they belong at + * or below the subdomain + */ + htp = hashtab; + cp = msg + sizeof(HEADER); + gnp = nlookup(dp->d_data, &htp, &fname, 0); + if (gnp == NULL || fname != dp->d_data) + continue; + for (tnp = gnp; tnp != NULL; tnp = tnp->n_parent) + if ( tnp == top ) + break; + if ( tnp == NULL ) + continue; /* name server is not in a (sub)domain */ + for (tnp = gnp; tnp != top; tnp = tnp->n_parent) { + for (tdp = tnp->n_data; tdp != NULL; tdp = tdp->d_next) + if (tdp->d_type == T_NS) + break; + if (tdp != NULL) + break; + } + if (tnp == top) + continue; /* name server is not in a subdomain */ + for(gdp=gnp->n_data; gdp != NULL; gdp=gdp->d_next) { + if (gdp->d_type != T_A || stale(gdp)) + continue; + if ((n = make_rr(fname, gdp, cp, + sizeof(msg)-sizeof(HEADER), 0)) < 0) + continue; + fwritemsg(rfp, msg, n + sizeof(HEADER)); + } + } + } + } + /* no need to send anything else because of delegation */ + if (!isroot && fndns) + return; + + /* do the rest of the data records */ + for (dp = np->n_data; dp != NULL; dp = dp->d_next) { /* * Skip the root SOA record (marks end of data); * don't send SOA for subdomains, as we're not sending them. + * Skip the NS record because we did it first */ ! if (dp->d_type == T_SOA || dp->d_type == T_NS) continue; if (dp->d_zone == 0 || stale(dp)) continue; if ((n = make_rr(dname, dp, cp, sizeof(msg)-sizeof(HEADER), 0)) < 0) continue; fwritemsg(rfp, msg, n + sizeof(HEADER)); } ! /* finally do subdomains */ ! if (np->n_hash == NULL) return; npp = np->n_hash->h_tab; nppend = npp + np->n_hash->h_size; while (npp < nppend) { for (np = *npp++; np != NULL; np = np->n_next) { ! doaxfr(np, rfp, 0, top); } } #ifdef DEBUG *************** *** 1327,1333 **** if (fdstat != -1) (void) fcntl(qsp->s_rfd, F_SETFL, fdstat & ~FNDELAY); fwritemsg(rfp, msg, msglen); ! doaxfr(np, rfp, 1); fwritemsg(rfp, msg, msglen); (void) fflush(rfp); exit(0); --- 1357,1363 ---- if (fdstat != -1) (void) fcntl(qsp->s_rfd, F_SETFL, fdstat & ~FNDELAY); fwritemsg(rfp, msg, msglen); ! doaxfr(np, rfp, 1, np); fwritemsg(rfp, msg, msglen); (void) fflush(rfp); exit(0); -- Don "Truck" Lewis Harris Semiconductor Internet: del@mlb.semi.harris.com PO Box 883 MS 62A-028 Phone: (407) 729-5205 Melbourne, FL 32901