1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms are permitted
   6:  * provided that this notice is preserved and that due credit is given
   7:  * to the University of California at Berkeley. The name of the University
   8:  * may not be used to endorse or promote products derived from this
   9:  * software without specific prior written permission. This software
  10:  * is provided ``as is'' without express or implied warranty.
  11:  */
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)ns_init.c	4.23 (Berkeley) 2/28/88";
  15: #endif /* not lint */
  16: 
  17: #include <sys/types.h>
  18: #include <sys/socket.h>
  19: #include <sys/time.h>
  20: #include <netinet/in.h>
  21: #include <stdio.h>
  22: #include <errno.h>
  23: #include <signal.h>
  24: #include <syslog.h>
  25: #include <ctype.h>
  26: #include <arpa/nameser.h>
  27: #include "ns.h"
  28: #include "db.h"
  29: 
  30: struct  zoneinfo zones[MAXZONES];   /* zone information */
  31: int nzones;             /* number of zones in use */
  32: int forward_only = 0;       /* run only as a slave */
  33: char    *cache_file;
  34: char    *localdomain;           /* "default" for non-dotted names */
  35: u_long  maint_interval = 300;       /* minimum ns_maint() interval */
  36: 
  37: extern  int lineno;
  38: 
  39: /*
  40:  * Read boot file for configuration info.
  41:  */
  42: 
  43: ns_init(bootfile)
  44:     char *bootfile;
  45: {
  46:     register struct zoneinfo *zp;
  47:     char buf[BUFSIZ];
  48:     FILE *fp;
  49:     int type;
  50:     time_t next_refresh = 0;
  51:     struct itimerval ival;
  52:     extern int needmaint;
  53: 
  54: #ifdef DEBUG
  55:     if (debug >= 3)
  56:         fprintf(ddt,"ns_init(%s)\n", bootfile);
  57: #endif
  58:     gettime(&tt);
  59: 
  60:     if ((fp = fopen(bootfile, "r")) == NULL) {
  61:         syslog(LOG_ERR, "%s: %m", bootfile);
  62:         exit(1);
  63:     }
  64:     lineno = 0;
  65: 
  66:     /* allocate cache hash table, formerly the root hash table. */
  67:     hashtab = savehash((struct hashbuf *)NULL);
  68: 
  69:     /* allocate root-hints/file-cache hash table */
  70:     fcachetab = savehash((struct hashbuf *)NULL);
  71: 
  72:     if (localdomain)
  73:         free(localdomain);
  74:     localdomain = NULL;
  75: 
  76:     /* init zone data */
  77:     cache_file = NULL;
  78:     nzones = 1;     /* zone zero is cache data */
  79:     zones[0].z_type = Z_CACHE;
  80:     while (!feof(fp) && !ferror(fp)) {
  81:         if (!getword(buf, sizeof(buf), fp))
  82:             continue;
  83:         /* read named.boot keyword and process args */
  84:         if (strcasecmp(buf, "cache") == 0) {
  85:             type = Z_CACHE;
  86:             zp = zones;
  87:         }
  88:         else if (strcasecmp(buf, "primary") == 0)
  89:             type = Z_PRIMARY;
  90:         else if (strcasecmp(buf, "secondary") == 0)
  91:             type = Z_SECONDARY;
  92:         else if (strcasecmp(buf, "directory") == 0) {
  93:             (void) getword(buf, sizeof(buf), fp);
  94:             if (chdir(buf) < 0) {
  95:                 syslog(LOG_CRIT, "directory %s: %m\n",
  96:                     buf);
  97:                 exit(1);
  98:             }
  99:             continue;
 100:         }
 101:         else if (strcasecmp(buf, "sortlist") == 0) {
 102:             get_sort_list(fp);
 103:             continue;
 104:         }
 105:         else if (strcasecmp(buf, "forwarders") == 0) {
 106:             get_forwarders(fp);
 107:             continue;
 108:         }
 109:         else if (strcasecmp(buf, "slave") == 0) {
 110:             forward_only++;
 111:             endline(fp);
 112:             continue;
 113:         }
 114:         else if (strcasecmp(buf, "domain") == 0) {
 115:             if (getword(buf, sizeof(buf), fp))
 116:                 localdomain = savestr(buf);
 117:             endline(fp);
 118:             continue;
 119:         } else {
 120:             syslog(LOG_ERR, "%s: line %d: unknown field '%s'\n",
 121:                 bootfile, lineno, buf);
 122:             endline(fp);
 123:             continue;
 124:         }
 125:         if (nzones >= MAXZONES) {
 126:             syslog(LOG_ERR, "too many zones (MAXZONES=%d)\n",
 127:                 MAXZONES);
 128:             endline(fp);
 129:             continue;
 130:         }
 131:         if (type != Z_CACHE)
 132:             zp = &zones[nzones++];
 133:         if (zp->z_origin) {
 134:             free(zp->z_origin);
 135:             zp->z_origin = 0;
 136:         }
 137:         if (zp->z_source) {
 138:             free(zp->z_source);
 139:             zp->z_source = 0;
 140:         }
 141:         zp->z_type = type;
 142:         zp->z_addrcnt = 0;
 143:         zp->z_auth = 0;
 144:         /*
 145: 		 * read zone origin
 146: 		 */
 147:         if (!getword(buf, sizeof(buf), fp)) {
 148:             syslog(LOG_ERR, "%s: line %d: missing origin\n",
 149:                         bootfile, lineno);
 150:             continue;
 151:         }
 152:         if (buf[0] == '.')
 153:             buf[0] = '\0';
 154:         zp->z_origin = savestr(buf);
 155:         /*
 156: 		 * read source file or host address
 157: 		 */
 158:         if (!getword(buf, sizeof(buf), fp)) {
 159:             syslog(LOG_ERR, "%s: line %d: missing origin\n",
 160:                         bootfile, lineno);
 161:             continue;
 162:         }
 163: #ifdef DEBUG
 164:         if (debug)
 165:             fprintf(ddt,"zone[%d] type %d: '%s'",
 166:                     zp-zones, zp->z_type,
 167:                 *(zp->z_origin) == '\0' ? "." : zp->z_origin);
 168: #endif
 169:         zp->z_time = 0;
 170:         zp->z_refresh = 0;  /* by default, no dumping */
 171:         switch (type) {
 172:         case Z_CACHE:
 173:             zp->z_source = savestr(buf);
 174: #ifdef DEBUG
 175:             if (debug)
 176:                 fprintf(ddt,", source = %s\n", zp->z_source);
 177: #endif
 178:             if (getword(buf, sizeof(buf), fp)) {
 179: #ifdef notyet
 180:                 zp->z_refresh = atoi(buf);
 181:                 if (zp->z_refresh <= 0) {
 182:                     syslog(LOG_ERR,
 183:                 "%s: line %d: bad refresh '%s', ignored\n",
 184:                         bootfile, lineno, buf);
 185:                     zp->z_refresh = 0;
 186:                 } else if (cache_file == NULL)
 187:                     cache_file = zp->z_source;
 188: #else
 189:                 syslog(LOG_WARNING,
 190:                 "%s: line %d: cache refresh ignored\n",
 191:                     bootfile, lineno);
 192: #endif
 193:                 endline(fp);
 194:             }
 195:             (void) db_load(zp->z_source, zp->z_origin, zp);
 196:             break;
 197: 
 198:         case Z_PRIMARY:
 199:             zp->z_source = savestr(buf);
 200: #ifdef DEBUG
 201:             if (debug)
 202:                 fprintf(ddt,", source = %s\n", zp->z_source);
 203: #endif
 204:             if (db_load(zp->z_source, zp->z_origin, zp) == 0)
 205:                 zp->z_auth = 1;
 206: #ifdef ALLOW_UPDATES
 207:             /* Guarantee calls to ns_maint() */
 208:             zp->z_refresh = maint_interval;
 209: #else
 210:             zp->z_refresh = 0;
 211:             zp->z_time = 0;
 212: #endif ALLOW_UPDATES
 213:             break;
 214: 
 215:         case Z_SECONDARY:
 216: #ifdef DEBUG
 217:             if (debug)
 218:                 fprintf(ddt,"\n\taddrs: %s, ", buf);
 219: #endif
 220:             zp->z_addr[zp->z_addrcnt].s_addr =
 221:                 inet_addr(buf);
 222:             /* Indicate no cache for this zone yet */
 223:             zp->z_source = (char *) NULL;
 224:             if (zp->z_addr[zp->z_addrcnt].s_addr != (unsigned)-1)
 225:                 zp->z_addrcnt++;
 226:             while (getword(buf, sizeof(buf), fp)) {
 227:                 zp->z_addr[zp->z_addrcnt].s_addr =
 228:                     inet_addr(buf);
 229:                 if (zp->z_addr[zp->z_addrcnt].s_addr ==
 230:                         (unsigned)-1) {
 231:                     zp->z_source = savestr(buf);
 232:                     break;
 233:                 }
 234: #ifdef DEBUG
 235:                 if (debug)
 236:                     fprintf(ddt,"%s, ",buf);
 237: #endif
 238:                 if (++zp->z_addrcnt >= NSMAX) {
 239:                     zp->z_addrcnt = NSMAX;
 240: #ifdef DEBUG
 241:                     if (debug)
 242:                         fprintf(ddt,
 243:                         "\nns.h NSMAX reached\n");
 244: #endif
 245:                     break;
 246:                 }
 247:             }
 248: #ifdef DEBUG
 249:             if (debug)
 250:                 fprintf(ddt,"addrcnt = %d\n", zp->z_addrcnt);
 251: #endif
 252:             zoneinit(zp);
 253:             break;
 254: 
 255:         }
 256:         if (zp->z_refresh && zp->z_time == 0)
 257:             zp->z_time = zp->z_refresh + tt.tv_sec;
 258: #ifdef DEBUG
 259:         if (debug)
 260:             fprintf(ddt, "z_time %ld, z_refresh %ld\n",
 261:                 zp->z_time, zp->z_refresh);
 262: #endif
 263:         if (zp->z_time != 0 &&
 264:             (next_refresh == 0 || next_refresh > zp->z_time))
 265:             next_refresh = zp->z_time;
 266:     }
 267:     (void) fclose(fp);
 268: 
 269:     /*
 270: 	 * Schedule calls to ns_maint().
 271: 	 */
 272:     bzero((char *)&ival, sizeof(ival));
 273:     if (next_refresh) {
 274:         gettime(&tt);
 275:         if (next_refresh <= tt.tv_sec)
 276:             needmaint = 1;
 277:         else {
 278:             ival.it_value.tv_sec = next_refresh - tt.tv_sec;
 279:             if (ival.it_value.tv_sec < maint_interval)
 280:                 ival.it_value.tv_sec = maint_interval;
 281:         }
 282:     }
 283:     (void) setitimer(ITIMER_REAL, &ival, (struct itimerval *)NULL);
 284: #ifdef DEBUG
 285:     if (debug) {
 286:         fprintf(ddt,"exit ns_init() ");
 287:         if (needmaint || ival.it_value.tv_sec)
 288:             fprintf(ddt,"Next interrupt in %ld sec\n",
 289:                 ival.it_value.tv_sec);
 290:         else
 291:             fprintf(ddt,"No maintenance scheduled\n");
 292:     }
 293: #endif
 294: }
 295: 
 296: zoneinit(zp)
 297:     register struct zoneinfo *zp;
 298: {
 299: 
 300: #ifdef DEBUG
 301:     if (debug)
 302:         fprintf(ddt,"zoneinit()\n");
 303: #endif
 304: 
 305:     /*
 306: 	 * Try to load zone from backup file,
 307: 	 * if one was specified and it exists.
 308: 	 * If not, or if the data are out of date,
 309: 	 * we will refresh the zone from a primary
 310: 	 * immediately.
 311: 	 */
 312:     if (zp->z_source == NULL ||
 313:         db_load(zp->z_source, zp->z_origin, zp) != 0) {
 314:         /*
 315: 		 * Set zone to be refreshed immediately.
 316: 		 */
 317:         zp->z_refresh = INIT_REFRESH;
 318:         zp->z_retry = INIT_REFRESH;
 319:         zp->z_time = tt.tv_sec;
 320:     } else
 321:         zp->z_auth = 1;
 322: }
 323: 
 324: #ifdef ALLOW_UPDATES
 325: /*
 326:  * Look for the authoritative zone with the longest matching RHS of dname
 327:  * and return its zone # or zero if not found.
 328:  */
 329: findzone(dname, class)
 330:     char *dname;
 331:     int class;
 332: {
 333:     char *dZoneName, *zoneName, *index(), *dotPos;
 334:     int dZoneNameLen, zoneNameLen;
 335:     int maxMatchLen = 0;
 336:     int maxMatchZoneNum = 0;
 337:     int zoneNum;
 338: 
 339: #ifdef DEBUG
 340:     if (debug >= 4)
 341:         fprintf(ddt, "findzone(dname=%s, class=%d)\n", dname, class);
 342:     if (debug >= 5) {
 343:         fprintf(ddt, "zone dump:\n");
 344:         for (zoneNum = 1; zoneNum < nzones; zoneNum++)
 345:             printzoneinfo(zoneNum);
 346:     }
 347: #endif DEBUG
 348: 
 349:     dZoneName = index(dname, '.');
 350:     if (dZoneName == NULL)
 351:         dZoneName = ""; /* root */
 352:     else
 353:         dZoneName++;    /* There is a '.' in dname, so use remainder of
 354: 				   string as the zone name */
 355:     dZoneNameLen = strlen(dZoneName);
 356:     for (zoneNum = 1; zoneNum < nzones; zoneNum++) {
 357:         zoneName = (zones[zoneNum]).z_origin;
 358:         zoneNameLen = strlen(zoneName);
 359:         /* The zone name may or may not end with a '.' */
 360:         dotPos = index(zoneName, '.');
 361:         if (dotPos)
 362:             zoneNameLen--;
 363:         if (dZoneNameLen != zoneNameLen)
 364:             continue;
 365: #ifdef DEBUG
 366:         if (debug >= 5)
 367:             fprintf(ddt, "about to strncasecmp('%s', '%s', %d)\n",
 368:                     dZoneName, zoneName, dZoneNameLen);
 369: #endif
 370:         if (strncasecmp(dZoneName, zoneName, dZoneNameLen) == 0) {
 371: #ifdef DEBUG
 372:             if (debug >= 5)
 373:                 fprintf(ddt, "match\n");
 374: #endif
 375:             /*
 376: 			 * See if this is as long a match as any so far.
 377: 			 * Check if "<=" instead of just "<" so that if
 378: 			 * root domain (whose name length is 0) matches,
 379: 			 * we use it's zone number instead of just 0
 380: 			 */
 381:             if (maxMatchLen <= zoneNameLen) {
 382:                 maxMatchZoneNum = zoneNum;
 383:                 maxMatchLen = zoneNameLen;
 384:             }
 385:         }
 386: #ifdef DEBUG
 387:         else
 388:             if (debug >= 5)
 389:                 fprintf(ddt, "no match\n");
 390: #endif
 391:     }
 392: #ifdef DEBUG
 393:     if (debug >= 4)
 394:         fprintf(ddt, "findzone: returning %d\n", maxMatchZoneNum);
 395: #endif DEBUG
 396:     return (maxMatchZoneNum);
 397: }
 398: #endif ALLOW_UPDATES
 399: 
 400: soa_zinfo(zp, cp, eom)
 401:     register struct zoneinfo *zp;
 402:     register u_char *cp;
 403:     u_char *eom;
 404: {
 405:     cp += 3 * sizeof(u_short);
 406:     cp += sizeof(u_long);
 407:     cp += dn_skipname(cp, eom);
 408:     cp += dn_skipname(cp, eom);
 409:     GETLONG(zp->z_serial, cp);
 410:     GETLONG(zp->z_refresh, cp);
 411:     gettime(&tt);
 412:     zp->z_time = tt.tv_sec + zp->z_refresh;
 413:     GETLONG(zp->z_retry, cp);
 414:     GETLONG(zp->z_expire, cp);
 415:     GETLONG(zp->z_minimum, cp);
 416: }
 417: 
 418: get_forwarders(fp)
 419:     FILE *fp;
 420: {
 421:     char buf[BUFSIZ];
 422:     struct fwdinfo *fip = NULL, *ftp = NULL;
 423: 
 424:     extern struct   sockaddr_in nsaddr;
 425:     extern struct   fwdinfo *fwdtab;
 426: 
 427: #ifdef DEBUG
 428:     if (debug)
 429:         fprintf(ddt,"forwarders ");
 430: #endif
 431:     while (getword(buf, sizeof(buf), fp)) {
 432:         if (strlen(buf) == 0)
 433:             break;
 434: #ifdef DEBUG
 435:         if (debug)
 436:             fprintf(ddt," %s",buf);
 437: #endif
 438:         if (ftp == NULL)
 439:             ftp = (struct fwdinfo *)malloc(sizeof(struct fwdinfo));
 440:         if ( isdigit(buf[0]) &&
 441:             (ftp->fwdaddr.sin_addr.s_addr = inet_addr(buf))
 442:             != (unsigned)-1) {
 443:             ftp->fwdaddr.sin_port = nsaddr.sin_port;
 444:             ftp->fwdaddr.sin_family = AF_INET;
 445:         } else {
 446:             syslog(LOG_ERR, "'%s' (ignored, NOT dotted quad)", buf);
 447: #ifdef DEBUG
 448:             if (debug)
 449:                 fprintf(ddt," (ignored, NOT dotted quad)");
 450: #endif
 451:             continue;
 452:         }
 453:         ftp->next = NULL;
 454:         if (fwdtab == NULL)
 455:             fwdtab = ftp;   /* First time only */
 456:         else
 457:             fip->next = ftp;
 458:         fip = ftp;
 459:         ftp = NULL;
 460:     }
 461:     if (ftp)
 462:         free((char *)ftp);
 463: 
 464: #ifdef DEBUG
 465:     if (debug)
 466:         fprintf(ddt,"\n");
 467:     if (debug > 2)
 468:         for (ftp = fwdtab; ftp != NULL; ftp = ftp->next)
 469:             fprintf(ddt,"ftp x%x %s next x%x\n", ftp,
 470:                 inet_ntoa(ftp->fwdaddr.sin_addr), ftp->next);
 471: #endif
 472: }

Defined functions

get_forwarders defined in line 418; used 1 times
soa_zinfo defined in line 400; used 2 times
zoneinit defined in line 296; used 1 times

Defined variables

cache_file defined in line 33; used 7 times
forward_only defined in line 32; used 2 times
localdomain defined in line 34; used 6 times
maint_interval defined in line 35; used 5 times
sccsid defined in line 14; never used
Last modified: 1988-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4720
Valid CSS Valid XHTML 1.0 Strict