Annotation of 43BSDTahoe/etc/named/ns_init.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.