diff options
Diffstat (limited to 'contrib/bind/named/ns_req.c')
-rw-r--r-- | contrib/bind/named/ns_req.c | 559 |
1 files changed, 218 insertions, 341 deletions
diff --git a/contrib/bind/named/ns_req.c b/contrib/bind/named/ns_req.c index c485f59..1d7e39e 100644 --- a/contrib/bind/named/ns_req.c +++ b/contrib/bind/named/ns_req.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static char sccsid[] = "@(#)ns_req.c 4.47 (Berkeley) 7/1/91"; -static char rcsid[] = "$Id: ns_req.c,v 8.20 1996/08/05 08:31:30 vixie Exp $"; +static char rcsid[] = "$Id: ns_req.c,v 8.27 1996/10/08 04:51:03 vixie Exp $"; #endif /* not lint */ /* @@ -55,6 +55,28 @@ static char rcsid[] = "$Id: ns_req.c,v 8.20 1996/08/05 08:31:30 vixie Exp $"; * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. * --Copyright-- */ @@ -99,27 +121,15 @@ static enum req_action req_notify __P((HEADER *hp, u_char **cpp, u_char *eom, #endif static void fwritemsg __P((FILE *, u_char *, int)), -#ifdef DEBUG - printSOAdata __P((struct databuf)), -#endif doaxfr __P((struct namebuf *, FILE *, struct namebuf *, int)), startxfr __P((struct qstream *, struct namebuf *, u_char *, int, int, const char *)); -#ifdef ALLOW_UPDATES -static int InitDynUpdate __P((register HEADER *hp, - char *msg, - int msglen, - u_char *startcp, - struct sockaddr_in *from, - struct qstream *qsp, - int dfd)); -#endif - static struct addinfo addinfo[NADDRECS]; static void addname __P((const char *, const char *, u_int16_t, u_int16_t)); +static void copyCharString __P((u_char **, const char *)); /* * Process request using database; assemble and send response. @@ -192,41 +202,6 @@ ns_req(msg, msglen, buflen, qsp, from, dfd) break; #endif -#ifdef ALLOW_UPDATES -#define FORWARDED 1000 -/* - * In a sense the following constant should be defined in <arpa/nameser.h>, - * since it is returned here in place of a response code if the update was - * forwarded, and the response codes are defined in nameser.h. On the other - * hand, though, this constant is only seen in this file. The assumption - * here is that none of the other return codes equals this one (a good - * assumption, since they only occupy 4 bits over-the-wire) - */ - /* Call InitDynUpdate for all dynamic update requests */ - case UPDATEM: - case UPDATEMA: - case UPDATED: - case UPDATEDA: - case UPDATEA: - n = InitDynUpdate(hp, msg, msglen, cp, from, qsp, dfd); - if (n == FORWARDED) { - /* Return directly because InitDynUpdate - * forwarded the query to the primary, so we - * will send response later - */ - action = Return; - } else { - /* Either sucessful primary update or failure; - * return response code to client - */ - action = Finish; - } - - case ZONEREF: - dprintf(1, (ddt, "Refresh Zone\n")); - /*FALLTHROUGH*/ -#endif /* ALLOW_UPDATES */ - default: dprintf(1, (ddt, "ns_req: Opcode %d not implemented\n", hp->opcode)); @@ -453,10 +428,7 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from) nameserIncr(from->sin_addr, nssRcvdQ); #endif -#ifdef DATUMREFCNT nsp[0] = NULL; -#endif - dpp = dnptrs; *dpp++ = msg; *dpp = NULL; @@ -504,6 +476,33 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from) qtypeIncr(type); /* + * Yow! + */ + if (!strcasecmp(dnbuf, "VERSION.BIND") && + class == C_CHAOS && type == T_TXT) { + u_char *tp; + + hp->ancount = htons(1); + hp->nscount = htons(0); + hp->arcount = htons(0); + hp->rcode = NOERROR; + hp->aa = 1; + hp->ra = 0; + copyCharString(cpp, "VERSION"); /* Name */ + copyCharString(cpp, "BIND"); + *(*cpp)++ = 0x00; + PUTSHORT(T_TXT, *cpp); /* Type */ + PUTSHORT(C_CHAOS, *cpp); /* Class */ + PUTLONG(0, *cpp); /* TTL */ + tp = *cpp; /* Temp RdLength */ + PUTSHORT(0, *cpp); + copyCharString(cpp, Version); + PUTSHORT((*cpp) - (tp + INT16SZ), tp); /* Real RdLength */ + *msglenp = *cpp - msg; /* Total message length */ + return (Finish); + } + + /* * Process query. */ if (type == T_AXFR) { @@ -551,7 +550,7 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from) } #endif /*QRYLOG*/ -try_again: + try_again: dprintf(1, (ddt, "req: nlookup(%s) id %d type=%d class=%d\n", dname, ntohs(hp->id), type, class)); htp = hashtab; /* lookup relative to root */ @@ -645,15 +644,17 @@ try_again: n = finddata(np, class, T_SOA, hp, &dname, buflenp, &count); if (n != 0 ) { + if (count) { + *cpp += n; + *buflenp -= n; + *msglenp += n; + hp->nscount = htons((u_int16_t)count); + } if (hp->rcode == NOERROR_NODATA) { /* this should not occur */ hp->rcode = NOERROR; return (Finish); } - *cpp += n; - *buflenp -= n; - *msglenp += n; - hp->nscount = htons((u_int16_t)count); } #endif hp->rcode = NXDOMAIN; @@ -683,6 +684,14 @@ try_again: #ifdef NCACHE if (hp->rcode == NOERROR_NODATA) { hp->rcode = NOERROR; +#ifdef RETURNSOA + if (count) { + *cpp += n; + *buflenp -= n; + *msglenp += n; + hp->nscount = htons(count); + } +#endif founddata = 1; return (Finish); } @@ -746,7 +755,7 @@ try_again: return (Finish); #endif -fetchns: + fetchns: /* * If we're already out of room in the response, we're done. */ @@ -758,9 +767,7 @@ fetchns: * section or record the address for forwarding the query * (recursion desired). */ -#ifdef DATUMREFCNT free_nsp(nsp); -#endif nsp[0] = NULL; count = 0; switch (findns(&np, class, nsp, &count, 0)) { @@ -772,11 +779,7 @@ fetchns: dname, hp->rcode)); if (class != C_ANY) { hp->aa = 1; - /* XXX: should return SOA if founddata == 0, - * but old named's are confused by an SOA - * in the auth. section if there's no error. - */ - if (foundname == 0 && np) { + if (np && (!foundname || !founddata)) { n = doaddauth(hp, *cpp, *buflenp, np, nsp[0]); *cpp += n; *buflenp -= n; @@ -784,9 +787,7 @@ fetchns: } else if (ntohs(hp->ancount) != 0) { /* don't add NS records for NOERROR NODATA as some servers can get confused */ -#ifdef DATUMREFCNT free_nsp(nsp); -#endif switch (findns(&np, class, nsp, &count, 1)) { case NXDOMAIN: case SERVFAIL: @@ -811,18 +812,14 @@ fetchns: #endif /*ADDAUTH*/ } } -#ifdef DATUMREFCNT free_nsp(nsp); -#endif return (Finish); case SERVFAIL: /* We're authoritative but the zone isn't loaded. */ if (!founddata && !(forward_only && fwdtab)) { hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT free_nsp(nsp); -#endif return (Finish); } } @@ -850,9 +847,7 @@ fetchns: *buflenp -= n; hp->nscount = htons((u_int16_t)count); } -#ifdef DATUMREFCNT free_nsp(nsp); -#endif /* Our caller will handle the Additional section. */ return (Finish); } @@ -869,9 +864,7 @@ fetchns: if (omsg == (u_char *)NULL) { syslog(LOG_INFO, "ns_req: Out Of Memory"); hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT free_nsp(nsp); -#endif return (Finish); } id = hp->id; @@ -883,14 +876,13 @@ fetchns: if (n < 0) { syslog(LOG_INFO, "res_mkquery(%s) failed", dname); hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT free_nsp(nsp); -#endif return (Finish); } *msglenp = n; } - n = ns_forw(nsp, msg, *msglenp, from, qsp, dfd, &qp, dname, np); + n = ns_forw(nsp, msg, *msglenp, from, qsp, dfd, &qp, + dname, class, type, np); if (n != FW_OK && cname) free(omsg); switch (n) { @@ -906,22 +898,20 @@ fetchns: break; /* Duplicate request dropped */ case FW_NOSERVER: /* - ** Don't go into an infinite loop if - ** the admin gave root NS records in the cache - ** file without giving address records - ** for the root servers. - */ + * Don't go into an infinite loop if + * the admin gave root NS records in the cache + * file without giving address records + * for the root servers. + */ if (np) { if (NAME(*np)[0] == '\0') { syslog(LOG_NOTICE, "ns_req: no address for root server"); hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT free_nsp(nsp); -#endif return (Finish); } -#ifdef VALIDATE +#ifdef VALIDATE /* * we need to kill all the NS records here as * validate will fail as we are talking to the parent @@ -956,14 +946,10 @@ fetchns: case FW_SERVFAIL: do_servfail: hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT free_nsp(nsp); -#endif return (Finish); } -#ifdef DATUMREFCNT free_nsp(nsp); -#endif return (Return); } @@ -1179,6 +1165,7 @@ stale(dp) zp->z_origin); } zp->z_flags &= ~Z_AUTH; + needmaint = 1; return (1); } if (zp->z_lastupdate > tt.tv_sec) { @@ -1188,6 +1175,7 @@ stale(dp) zp->z_origin); } zp->z_flags &= ~Z_AUTH; + needmaint = 1; return (1); } return (0); @@ -1223,6 +1211,7 @@ make_rr(name, dp, buf, buflen, doadd) u_char *cp1, *sp; struct zoneinfo *zp; register int32_t n; + register int16_t type = dp->d_type; register u_int32_t ttl; u_char **edp = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; @@ -1233,7 +1222,7 @@ make_rr(name, dp, buf, buflen, doadd) #ifdef NCACHE if (dp->d_rcode #ifdef RETURNSOA - && dp->d_rcode != NXDOMAIN + && dp->d_size == 0 #endif ) { panic(-1, "make_rr: impossible d_rcode value"); @@ -1268,23 +1257,24 @@ make_rr(name, dp, buf, buflen, doadd) buflen -= RRFIXEDSZ; #if defined(RETURNSOA) && defined(NCACHE) - if (dp->d_rcode == NXDOMAIN) { + if (dp->d_rcode) { name = (char *)dp->d_data; name += strlen(name) +1; name += strlen(name) +1; name += 5 * INT32SZ; + type = T_SOA; } #endif if ((n = dn_comp(name, buf, buflen, dnptrs, edp)) < 0) return (-1); cp = buf + n; buflen -= n; - PUTSHORT((u_int16_t)dp->d_type, cp); + PUTSHORT((u_int16_t)type, cp); PUTSHORT((u_int16_t)dp->d_class, cp); PUTLONG(ttl, cp); sp = cp; cp += INT16SZ; - switch (dp->d_type) { + switch (type) { case T_CNAME: case T_MG: case T_MR: @@ -1306,7 +1296,7 @@ make_rr(name, dp, buf, buflen, doadd) cp += n; if (doadd) addname((char*)dp->d_data, name, - dp->d_type, dp->d_class); + type, dp->d_class); break; case T_SOA: @@ -1317,13 +1307,13 @@ make_rr(name, dp, buf, buflen, doadd) if (n < 0) return (-1); cp += n; - buflen -= dp->d_type == T_SOA ? n + 5 * INT32SZ : n; + buflen -= type == T_SOA ? n + 5 * INT32SZ : n; cp1 += strlen((char *)cp1) + 1; n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp); if (n < 0) return (-1); cp += n; - if (dp->d_type == T_SOA) { + if (type == T_SOA) { cp1 += strlen((char *)cp1) + 1; bcopy(cp1, cp, (n = 5 * INT32SZ)); cp += n; @@ -1332,9 +1322,74 @@ make_rr(name, dp, buf, buflen, doadd) PUTSHORT((u_int16_t)n, sp); break; + case T_NAPTR: + /* cp1 == our data/ cp == data of RR */ + cp1 = dp->d_data; + + if ((buflen -= INT16SZ) < 0) + return (-1); + + /* copy order */ + bcopy(cp1, cp, INT16SZ); + cp += INT16SZ; + cp1 += INT16SZ; + n = (u_int16_t)((cp - sp) - INT16SZ); + dprintf(1, (ddt, "current size n = %u\n", n)); + + /* copy preference */ + bcopy(cp1, cp, INT16SZ); + cp += INT16SZ; + cp1 += INT16SZ; + n = (u_int16_t)((cp - sp) - INT16SZ); + dprintf(1, (ddt, "current size n = %u\n", n)); + + /* Flags */ + n = *cp1++; + dprintf(1, (ddt, "size of n at flags = %d\n", n)); + *cp++ = n; + bcopy(cp1,cp,n); + cp += n; + cp1 += n; + n = (u_int16_t)((cp - sp) - INT16SZ); + dprintf(1, (ddt, "current size n = %u\n", n)); + + /* Service */ + n = *cp1++; + *cp++ = n; + bcopy(cp1,cp,n); + cp += n; + cp1 += n; + n = (u_int16_t)((cp - sp) - INT16SZ); + dprintf(1, (ddt, "current size n = %u\n", n)); + + /* Regexp */ + n = *cp1++; + *cp++ = n; + bcopy(cp1,cp,n); + cp += n; + cp1 += n; + n = (u_int16_t)((cp - sp) - INT16SZ); + dprintf(1, (ddt, "current size n = %u\n", n)); + + /* Replacement */ + dprintf(1, (ddt, "Replacement = %s\n", cp1)); + n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp); + dprintf(1, (ddt, "dn_comp's n = %u\n", n)); + if (n < 0) + return (-1); + cp += n; + + /* save data length */ + n = (u_int16_t)((cp - sp) - INT16SZ); + dprintf(1, (ddt, "saved size n = %u\n", n)); + PUTSHORT((u_int16_t)n, sp); + + break; + case T_MX: case T_AFSDB: case T_RT: + case T_SRV: /* cp1 == our data/ cp == data of RR */ cp1 = dp->d_data; @@ -1346,6 +1401,12 @@ make_rr(name, dp, buf, buflen, doadd) cp += INT16SZ; cp1 += INT16SZ; + if (type == T_SRV) { + bcopy(cp1, cp, INT16SZ*2); + cp += INT16SZ*2; + cp1 += INT16SZ*2; + } + n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp); if (n < 0) return (-1); @@ -1355,7 +1416,7 @@ make_rr(name, dp, buf, buflen, doadd) n = (u_int16_t)((cp - sp) - INT16SZ); PUTSHORT((u_int16_t)n, sp); if (doadd) - addname((char*)cp1, name, dp->d_type, dp->d_class); + addname((char*)cp1, name, type, dp->d_class); break; case T_PX: @@ -1385,6 +1446,39 @@ make_rr(name, dp, buf, buflen, doadd) PUTSHORT((u_int16_t)n, sp); break; + case T_SIG: + /* cp1 == our data; cp == data of target RR */ + cp1 = dp->d_data; + + /* first just copy over the type_covered, algorithm, */ + /* labels, orig ttl, two timestamps, and the footprint */ + if ((dp->d_size - 18) > buflen) + return (-1); /* out of room! */ + bcopy( cp1, cp, 18 ); + cp += 18; + cp1 += 18; + buflen -= 18; + + /* then the signer's name */ + n = dn_comp((char *)cp1, cp, buflen, NULL, NULL); + if (n < 0) + return (-1); + cp += n; + buflen -= n; + cp1 += strlen((char*)cp1)+1; + + /* finally, we copy over the variable-length signature */ + n = dp->d_size - (u_int16_t)((cp1 - dp->d_data)); + if (n > buflen) + return (-1); /* out of room! */ + bcopy(cp1, cp, n); + cp += n; + + /* save data length & return */ + n = (u_int16_t)((cp - sp) - INT16SZ); + PUTSHORT((u_int16_t)n, sp); + break; + default: if (dp->d_size > buflen) return (-1); @@ -1458,8 +1552,7 @@ doaddinfo(hp, msg, msglen) count = 0; cp = msg; for (ap = addinfo; --addcount >= 0; ap++) { - int foundstale = 0, - foundany = 0, + int foundany = 0, foundcname = 0, save_count = count, save_msglen = msglen; @@ -1473,6 +1566,7 @@ doaddinfo(hp, msg, msglen) goto next_rr; dprintf(3, (ddt, "found it\n")); /* look for the data */ + delete_stale(np); for (dp = np->n_data; dp != NULL; dp = dp->d_next) { #ifdef NCACHE if (dp->d_rcode) @@ -1490,17 +1584,6 @@ doaddinfo(hp, msg, msglen) continue; } foundany++; - if (stale(dp)) { - foundstale++; - dprintf(1, (ddt, - "doaddinfo: stale entry '%s'%s\n", - NAME(*np), - (dp->d_flags&DB_F_HINT) - ? " hint" - : "" - )); - continue; - } /* * Should be smart and eliminate duplicate * data here. XXX @@ -1532,11 +1615,7 @@ doaddinfo(hp, msg, msglen) count++; } next_rr: - if (foundstale) { - /* Cache invalidate the address RR's */ - delete_all(np, (int)ap->a_class, T_A); - } - if (!NoFetchGlue && !foundcname && (foundstale || !foundany)) { + if (!NoFetchGlue && !foundcname && !foundany) { /* ask a real server for this info */ (void) sysquery(ap->a_dname, (int)ap->a_class, T_A, NULL, 0, QUERY); @@ -1730,6 +1809,16 @@ doaxfr(np, rfp, top, class) */ if (dp->d_type == T_SOA || dp->d_type == T_NS) continue; + +#if 0 /* Not yet implemented. Only a SHOULD in the I-D. -gnu@toad.com */ + /* skip the SIG AXFR record because we did it first too. */ + if (dp->d_type == T_SIG) { + int sig_rrtype = GETSHORT (dp->d_data); + if (sig_rrtype == T_AXFR) + continue; + } +#endif /* 0 */ + if (dp->d_zone == 0 || stale(dp)) continue; #ifdef NCACHE @@ -1791,228 +1880,6 @@ doaxfr(np, rfp, top, class) dprintf(1, (ddt, "exit doaxfr()\n")); } -#ifdef ALLOW_UPDATES -/* - * Called by UPDATE{A,D,DA,M,MA} to initiate a dynamic update. If this is the - * primary server for the zone being updated, we update the zone's serial - * number and then call doupdate directly. If this is a secondary, we just - * forward the update; this way, if the primary update fails (e.g., if the - * primary is unavailable), we don't update the secondary; if the primary - * update suceeds, ns_resp will get called with the response (when it comes - * in), and then update the secondary's copy. - */ -static int -InitDynUpdate(hp, msg, msglen, startcp, from, qsp, dfd) - register HEADER *hp; - char *msg; - int msglen; - u_char *startcp; - struct sockaddr_in *from; - struct qstream *qsp; - int dfd; -{ - struct databuf *nsp[NSMAX]; - struct zoneinfo *zp; - char dnbuf[MAXDNAME]; - struct hashbuf *htp = hashtab; /* lookup relative to root */ - struct namebuf *np; - struct databuf *olddp, *newdp, *dp; - struct databuf **nspp; - char *fname; - register u_char *cp = startcp; - u_int16_t class, type; - int n, size, zonenum; - char ZoneName[MAXDNAME], *znp; - -#ifdef DATUMREFCNT - nsp[0] = NULL; -#endif - if ((n = dn_expand(msg, msg + msglen, cp, dnbuf, sizeof(dnbuf))) < 0) { - dprintf(1, (ddt,"FORMERR InitDynUpdate expand name failed\n")); - hp->rcode = FORMERR; - return (FORMERR); - } - cp += n; - GETSHORT(type, cp); - if (type == T_SOA) { /* T_SOA updates not allowed */ - hp->rcode = REFUSED; - dprintf(1, (ddt, "InitDynUpdate: REFUSED - SOA update\n")); - return (REFUSED); - } - GETSHORT(class, cp); - cp += INT32SZ; - GETSHORT(size, cp); -/****XXX - need bounds checking here ****/ - cp += size; - - if ((zonenum = findzone(dnbuf, class)) == 0) { /* zone not found */ - hp->rcode = NXDOMAIN; - return (NXDOMAIN); - } - zp = &zones[zonenum]; - - /* Disallow updates for which we aren't authoratative. Note: the - following test doesn't work right: If it's for a non-local zone, - we will think it's a primary but be unable to lookup the namebuf, - thus returning 'NXDOMAIN' */ - if (zp->z_type != Z_PRIMARY && zp->z_type != Z_SECONDARY) { - hp->rcode = REFUSED; - dprintf(1, (ddt, - "InitDynUpdate: REFUSED - non-{primary,secondary} update\n")); - return (REFUSED); - } - if (!(zp->z_flags & Z_DYNAMIC)) { - hp->rcode = REFUSED; - dprintf(1, (ddt, - "InitDynUpdate: REFUSED - dynamic flag not set for zone\n")); - return (REFUSED); - } - - /* - * Lookup the zone namebuf. Lookup "xyz" not "xyz.", since - * otherwise the lookup fails, because '.' may have a nil n_hash - * associated with it. - */ - strcpy(ZoneName, zp->z_origin); - znp = &ZoneName[strlen(ZoneName) - 1]; - if (*znp == '.') - *znp = NULL; - np = nlookup(ZoneName, &htp, &fname, 0); - if ((np == NULL) || (fname != ZoneName)) { - syslog(LOG_ERR, "InitDynUpdate: lookup failed on zone (%s)\n", - ZoneName); - hp->rcode = NXDOMAIN; - return (NXDOMAIN); - } - - /* - * If this is the primary copy increment the serial number. Don't - * increment the serial number if this is a secondary; this way, if 2 - * different secondaries both update the primary, they will both have - * lower serial numbers than the primary has, and hence eventually - * refresh and get all updates and become consistent. - * - * Note that the serial number must be incremented in both the zone - * data structure and the zone's namebuf. - */ - switch (zp->z_type) { - case Z_SECONDARY: /* forward update to primary */ - nspp = nsp; - dp = np->n_data; - while (dp != NULL) { - if (match(dp, class, T_NS)) { - if (nspp < &nsp[NSMAX-1]) { - *nspp++ = dp; -#ifdef DATUMREFCNT - dp->d_rcnt++; -#endif - } else - break; - } - dp = dp->d_next; - } - *nspp = NULL; /* Delimiter */ - if (ns_forw(nsp, msg, msglen, from, qsp, dfd, NULL, dnbuf, np) - < - 0) { - hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (SERVFAIL); - } -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (FORWARDED); - - case Z_PRIMARY: - zp->z_serial++; - /* Find the SOA record */ - for (olddp = np->n_data; olddp != NULL; olddp = olddp->d_next) - if (match(olddp, class, T_SOA)) - break; - if (olddp == NULL) { - syslog(LOG_NOTICE, - "InitDynUpdate: Couldn't find SOA RR for '%s'\n", - ZoneName); - hp->rcode = NXDOMAIN; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (NXDOMAIN); - } - newdp = savedata(olddp->d_class, olddp->d_type, olddp->d_ttl, - olddp->d_data, olddp->d_size); - newdp->d_zone = olddp->d_zone; - newdp->d_cred = DB_C_AUTH; /* XXX - it may not be so */ - newdp->d_clev = db_getclev(zp->z_origin); - cp = (u_char *)newdp->d_data; - cp += strlen(cp) + 1; /* skip origin string */ - cp += strlen(cp) + 1; /* skip in-charge string */ - putlong((u_int32_t)(zp->z_serial), cp); - dprintf(4, (ddt, "after stuffing data into newdp:\n")); -#ifdef DEBUG - if (debug >= 4) - printSOAdata(newdp); -#endif - - if ((n = db_update(ZoneName, olddp, newdp, DB_DELETE, - hashtab)) != NOERROR) { /* XXX */ - dprintf(1, (ddt, - "InitDynUpdate: SOA update failed\n")); - hp->rcode = NOCHANGE; - free((char*) dp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (NOCHANGE); - } - - /* Now update the RR itself */ - /* XXX - DB_C_AUTH may be wrong */ - if (doupdate(msg, msglen, msg + HFIXEDSZ, zonenum, - (struct databuf *)0, DB_NODATA, DB_C_AUTH) < 0) { - dprintf(1, (ddt, "InitDynUpdate: doupdate failed\n")); - /* doupdate fills in rcode */ -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (hp->rcode); - } - zp->z_flags |= Z_CHANGED; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (NOERROR); - } -} - -#ifdef DEBUG -/* - * Print the contents of the data in databuf pointed to by dp for an SOA record - */ -static void -printSOAdata(dp) - struct databuf *dp; -{ - register u_char *cp; - - if (!debug) - return; /* Otherwise fprintf to ddt will bomb */ - cp = (u_char *)dp->d_data; - fprintf(ddt, "printSOAdata(%#lx): origin(%#lx)='%s'\n", - (u_long)dp, (u_long)cp, cp); - cp += strlen(cp) + 1; /* skip origin string */ - fprintf(ddt, "printSOAdata: in-charge(%#lx)='%s'\n", - (u_long)cp, cp); - cp += strlen(cp) + 1; /* skip in-charge string */ - fprintf(ddt, "printSOAdata: serial(%lx)=%lu\n", - (u_long)cp, (u_long)_getlong(cp)); -} -#endif -#endif - static void startxfr(qsp, np, soa, soalen, class, dname) struct qstream *qsp; @@ -2159,7 +2026,6 @@ free_addinfo() { addcount = 0; } -#ifdef DATUMREFCNT void free_nsp(nsp) struct databuf **nsp; @@ -2171,9 +2037,20 @@ free_nsp(nsp) } else { dprintf(3, (ddt, "free_nsp: %s rcnt %d delayed\n", (*nsp)->d_data, (*nsp)->d_rcnt)); - free(*nsp); /* delayed free */ + db_free(*nsp); /* delayed free */ } *nsp++ = NULL; } } -#endif + +static void +copyCharString(dst, src) + u_char **dst; + const char *src; +{ + size_t len = strlen(src) & 0xff; + + *(*dst)++ = (u_char) len; + memcpy(*dst, src, len); + *dst += len; +} |