diff options
Diffstat (limited to 'contrib/bind/named/ns_init.c')
-rw-r--r-- | contrib/bind/named/ns_init.c | 237 |
1 files changed, 130 insertions, 107 deletions
diff --git a/contrib/bind/named/ns_init.c b/contrib/bind/named/ns_init.c index 3ca8180..8a6fd92 100644 --- a/contrib/bind/named/ns_init.c +++ b/contrib/bind/named/ns_init.c @@ -1,6 +1,6 @@ #if !defined(lint) && !defined(SABER) static char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91"; -static char rcsid[] = "$Id: ns_init.c,v 8.17 1996/08/05 08:31:30 vixie Exp $"; +static char rcsid[] = "$Id: ns_init.c,v 8.24 1996/12/02 09:17:21 vixie Exp $"; #endif /* not lint */ /* @@ -75,7 +75,7 @@ static char rcsid[] = "$Id: ns_init.c,v 8.17 1996/08/05 08:31:30 vixie Exp $"; #undef nsaddr -enum limit { Datasize }; +enum limit { Datasize , Files }; static void zoneinit __P((struct zoneinfo *)), get_forwarders __P((FILE *)), @@ -83,6 +83,7 @@ static void zoneinit __P((struct zoneinfo *)), #ifdef DEBUG content_zone __P((int)), #endif + do_reload __P((char *, int, int)), free_forwarders __P((void)), ns_limit __P((const char *name, int value)), ns_checknames __P((const char *names, @@ -197,6 +198,7 @@ ns_init(bootfile) #ifdef SECURE_ZONES free_netlist(&zp->secure_nets); #endif + do_reload(zp->z_origin, zp->z_type, zp->z_class); syslog(LOG_NOTICE, "Zone \"%s\" was removed", zp->z_origin); free(zp->z_origin); free(zp->z_source); @@ -240,9 +242,6 @@ boot_read(filename, includefile) #endif struct stat f_time; static int tmpnum = 0; /* unique number for tmp zone files */ -#ifdef ALLOW_UPDATES - char *flag; -#endif int slineno; /* Saved global line number. */ int i; @@ -497,29 +496,7 @@ boot_read(filename, includefile) case Z_PRIMARY: source = savestr(buf); -#ifdef ALLOW_UPDATES - if (getword(buf, sizeof(buf), fp, 0)) { - endline(fp); - flag = buf; - while (flag) { - char *cp = strchr(flag, ','); - if (cp) - *cp++ = 0; - if (strcasecmp(flag, "dynamic") == 0) - zp->z_flags |= Z_DYNAMIC; - else if (strcasecmp(flag, "addonly") == 0) - zp->z_flags |= Z_DYNADDONLY; - else { - syslog(LOG_NOTICE, - "%s: line %d: bad flag '%s'\n", - filename, lineno, flag); - } - flag = cp; - } - } -#else /*ALLOW_UPDATES*/ endline(fp); -#endif dprintf(1, (ddt, ", source = %s\n", source)); /* @@ -552,13 +529,8 @@ boot_read(filename, includefile) dprintf(1, (ddt, "reloading zone\n")); if (!db_load(zp->z_source, zp->z_origin, zp, NULL)) zp->z_flags |= Z_AUTH; -#ifdef ALLOW_UPDATES - /* Guarantee calls to ns_maint() */ - zp->z_refresh = maint_interval; -#else zp->z_refresh = 0; /* no maintenance needed */ zp->z_time = 0; -#endif break; case Z_SECONDARY: @@ -603,7 +575,7 @@ boot_read(filename, includefile) if (zp->z_source && (strcmp(source, zp->z_source) || (stat(zp->z_source, &f_time) == -1 || - (zp->z_ftime != f_time.st_mtime)))) { + (zp->z_ftime != f_time.st_mtime)))) { dprintf(1, (ddt, "backup file changed\n")); free(zp->z_source); zp->z_source = NULL; @@ -614,6 +586,11 @@ boot_read(filename, includefile) #else remove_zone(hashtab, zp - zones); #endif + /* + * reload parent so that NS records are + * present during the zone transfer. + */ + do_reload(zp->z_origin, zp->z_type, zp->z_class); } if (zp->z_source) free(source); @@ -693,71 +670,6 @@ zoneinit(zp) } } -#ifdef ALLOW_UPDATES -/* - * Look for the authoritative zone with the longest matching RHS of dname - * and return its zone # or zero if not found. - */ -int -findzone(dname, class) - char *dname; - int class; -{ - char *dZoneName, *zoneName; - int dZoneNameLen, zoneNameLen; - int maxMatchLen = 0; - int maxMatchZoneNum = 0; - int zoneNum; - - dprintf(4, (ddt, "findzone(dname=%s, class=%d)\n", dname, class)); -#ifdef DEBUG - if (debug >= 5) { - fprintf(ddt, "zone dump:\n"); - for (zoneNum = 1; zoneNum < nzones; zoneNum++) - printzoneinfo(zoneNum); - } -#endif - - dZoneName = strchr(dname, '.'); - if (dZoneName == NULL) - dZoneName = ""; /* root */ - else - dZoneName++; /* There is a '.' in dname, so use remainder of - string as the zone name */ - dZoneNameLen = strlen(dZoneName); - for (zoneNum = 1; zoneNum < nzones; zoneNum++) { - if (zones[zoneNum].z_type == Z_NIL) - continue; - zoneName = (zones[zoneNum]).z_origin; - zoneNameLen = strlen(zoneName); - /* The zone name may or may not end with a '.' */ - if (zoneName[zoneNameLen - 1] == '.') - zoneNameLen--; - if (dZoneNameLen != zoneNameLen) - continue; - dprintf(5, (ddt, "about to strncasecmp('%s', '%s', %d)\n", - dZoneName, zoneName, dZoneNameLen)); - if (strncasecmp(dZoneName, zoneName, dZoneNameLen) == 0) { - dprintf(5, (ddt, "match\n")); - /* - * See if this is as long a match as any so far. - * Check if "<=" instead of just "<" so that if - * root domain (whose name length is 0) matches, - * we use it's zone number instead of just 0 - */ - if (maxMatchLen <= zoneNameLen) { - maxMatchZoneNum = zoneNum; - maxMatchLen = zoneNameLen; - } - } else { - dprintf(5, (ddt, "no match\n")); - } - } - dprintf(4, (ddt, "findzone: returning %d\n", maxMatchZoneNum)); - return (maxMatchZoneNum); -} -#endif /* ALLOW_UPDATES */ - static void get_forwarders(fp) FILE *fp; @@ -881,6 +793,75 @@ find_zone(name, type, class) return NULL; } +static void +do_reload(domain, type, class) + char *domain; + int type; + int class; +{ + char *s; + struct zoneinfo *zp; + + dprintf(1, (ddt, "do_reload: %s %d %d\n", + *domain ? domain : ".", type, class)); + + /* the zone has changed type? */ + /* NOTE: we still exist so don't match agains ourselves */ + /* If we are a STUB or SECONDARY check that we have loaded */ + if (((type != Z_STUB) && (zp = find_zone(domain, Z_STUB, class)) && + zp->z_serial) || + ((type != Z_CACHE) && find_zone(domain, Z_CACHE, class)) || + ((type != Z_PRIMARY) && find_zone(domain, Z_PRIMARY, class)) || + ((type != Z_SECONDARY) + && (zp = find_zone(domain, Z_SECONDARY, class)) && zp->z_serial) + ) { + return; + } + + while ((s = strchr(domain, '.')) || *domain) { + if (s) + domain = s + 1; /* skip dot */ + else + domain = ""; /* root zone */ + + if ((zp = find_zone(domain, Z_STUB, class)) || + (zp = find_zone(domain, Z_CACHE, class)) || + (zp = find_zone(domain, Z_PRIMARY, class)) || + (zp = find_zone(domain, Z_SECONDARY, class))) { + + dprintf(1, (ddt, "do_reload: matched %s\n", + *domain ? domain : ".")); + +#ifdef CLEANCACHE + if (zp->z_type == Z_CACHE) + remove_zone(fcachetab, 0, 1); + else + remove_zone(hashtab, zp - zones, 1); +#else + if (zp->z_type == Z_CACHE) + remove_zone(fcachetab, 0); + else + remove_zone(hashtab, zp - zones); +#endif + zp->z_flags &= ~Z_AUTH; + + switch (zp->z_type) { + case Z_SECONDARY: + case Z_STUB: + zoneinit(zp); + break; + case Z_PRIMARY: + case Z_CACHE: + if (db_load(zp->z_source, zp->z_origin, zp, 0) + == 0) + zp->z_flags |= Z_AUTH; + break; + } + break; + } + } +} + #ifdef DEBUG /* prints out the content of zones */ static void @@ -906,6 +887,8 @@ ns_limit(name, value) max_xfers_per_ns = value; } else if (!strcasecmp(name, "datasize")) { ns_rlimit("datasize", Datasize, value); + } else if (!strcasecmp(name, "files")) { + ns_rlimit("files", Files, value); } else { syslog(LOG_ERR, "error: unrecognized limit in bootfile: \"%s\"", @@ -985,7 +968,7 @@ ns_ownercontext(type, transport) context = hostname_ctx; break; default: - abort(); + panic(-1, "impossible condition in ns_ownercontext()"); } break; case T_MB: @@ -999,14 +982,16 @@ ns_ownercontext(type, transport) } int -ns_nameok(name, class, transport, context) +ns_nameok(name, class, transport, context, owner, source) const char *name; int class; enum transport transport; enum context context; + struct in_addr source; + const char *owner; { - int ok = 1; enum severity severity = checkname_severity[transport]; + int ok; if (severity == ignore) return (1); @@ -1024,17 +1009,44 @@ ns_nameok(name, class, transport, context) ok = res_hnok(name); break; default: - abort(); + panic(-1, "impossible condition in ns_nameok()"); } if (!ok) { + char *s, *o; + + if (source.s_addr == INADDR_ANY) + s = strdup(transport_strings[transport]); + else { + s = malloc(strlen(transport_strings[transport]) + + sizeof " from [000.000.000.000]"); + if (s) + sprintf(s, "%s from [%s]", + transport_strings[transport], + inet_ntoa(source)); + } + if (strcasecmp(owner, name) == 0) + o = strdup(""); + else { + const char *t = (*owner == '\0') ? "." : owner; + + o = malloc(strlen(t) + sizeof " (owner \"\")"); + if (o) + sprintf(o, " (owner \"%s\")", t); + } +#ifndef ultrix syslog((transport == response_trans) ? LOG_INFO : LOG_NOTICE, - "%s name \"%s %s\" (%s) is invalid - %s", + "%s name \"%s\"%s %s (%s) is invalid - %s", context_strings[context], - name, p_class(class), - transport_strings[transport], + name, o != NULL ? o : "[malloc failed]", p_class(class), + s != NULL ? s : "[malloc failed]", (severity == fail) ? "rejecting" : "proceeding anyway"); +#endif if (severity == warn) ok = 1; + if (s) + free(s); + if (o) + free(o); } return (ok); } @@ -1062,14 +1074,25 @@ ns_rlimit(name, limit, value) name); #else struct rlimit limits; - int rlimit; + int rlimit = -1; switch (limit) { case Datasize: rlimit = RLIMIT_DATA; break; + case Files: +#ifdef RLIMIT_NOFILE + rlimit = RLIMIT_NOFILE; +#endif + break; default: - abort(); + panic(-1, "impossible condition in ns_rlimit()"); + } + if (rlimit == -1) { + syslog(LOG_WARNING, + "limit \"%s\" not supported on this system - ignored", + name); + return; } if (getrlimit(rlimit, &limits) < 0) { syslog(LOG_WARNING, "getrlimit(%s): %m", name); |