diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2020-01-25 10:44:28 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2020-01-25 10:44:28 +0000 |
commit | 3ff36b88d2d7beac0737f05cc7dccc415856dd0e (patch) | |
tree | ab26c1e3808abcfd8fd867203d0f60dca7201bce | |
parent | 605392dd44716a40bb62d3ed393926fb694aec08 (diff) |
dns/master is unused
-rw-r--r-- | usr.sbin/bind/lib/dns/Makefile.in | 4 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/include/dns/Makefile.in | 4 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/include/dns/master.h | 382 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/master.c | 3217 | ||||
-rw-r--r-- | usr.sbin/bind/lib/dns/masterdump.c | 2 |
5 files changed, 5 insertions, 3604 deletions
diff --git a/usr.sbin/bind/lib/dns/Makefile.in b/usr.sbin/bind/lib/dns/Makefile.in index d2c269b43f0..fbebacbd798 100644 --- a/usr.sbin/bind/lib/dns/Makefile.in +++ b/usr.sbin/bind/lib/dns/Makefile.in @@ -60,7 +60,7 @@ DNSOBJS = byaddr.@O@ \ dnssec.@O@ ds.@O@ \ keydata.@O@ \ lib.@O@ log.@O@ \ - master.@O@ masterdump.@O@ message.@O@ \ + masterdump.@O@ message.@O@ \ name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ \ rcode.@O@ rdata.@O@ \ rdatalist.@O@ rdataset.@O@ \ @@ -89,7 +89,7 @@ DNSSRCS = byaddr.c \ callbacks.c compress.c \ dnssec.c ds.c \ keydata.c lib.c log.c \ - master.c masterdump.c message.c \ + masterdump.c message.c \ name.c ncache.c nsec.c nsec3.c \ rcode.c rdata.c rdatalist.c \ rdataset.c \ diff --git a/usr.sbin/bind/lib/dns/include/dns/Makefile.in b/usr.sbin/bind/lib/dns/include/dns/Makefile.in index c39a752411c..cc2e2dc7efc 100644 --- a/usr.sbin/bind/lib/dns/include/dns/Makefile.in +++ b/usr.sbin/bind/lib/dns/include/dns/Makefile.in @@ -12,7 +12,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.9 2020/01/23 07:46:26 florian Exp $ +# $Id: Makefile.in,v 1.10 2020/01/25 10:44:27 florian Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -25,7 +25,7 @@ HEADERS = bit.h byaddr.h callbacks.h cert.h \ dnssec.h ds.h dsdigest.h \ events.h fixedname.h \ keydata.h keyflags.h keyvalues.h \ - lib.h log.h master.h masterdump.h message.h \ + lib.h log.h masterdump.h message.h \ name.h ncache.h nsec.h nsec3.h opcode.h \ rcode.h rdata.h rdataclass.h rdatalist.h \ rdataset.h rdatatype.h \ diff --git a/usr.sbin/bind/lib/dns/include/dns/master.h b/usr.sbin/bind/lib/dns/include/dns/master.h deleted file mode 100644 index ab5ec206858..00000000000 --- a/usr.sbin/bind/lib/dns/include/dns/master.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: master.h,v 1.8 2020/01/20 18:51:52 florian Exp $ */ - -#ifndef DNS_MASTER_H -#define DNS_MASTER_H 1 - -/*! \file dns/master.h */ - -/*** - *** Imports - ***/ - -#include <stdio.h> - -#include <isc/lang.h> - -#include <dns/types.h> - -/* - * Flags to be passed in the 'options' argument in the functions below. - */ -#define DNS_MASTER_AGETTL 0x00000001 /*%< Age the ttl based on $DATE. */ -#define DNS_MASTER_MANYERRORS 0x00000002 /*%< Continue processing on errors. */ -#define DNS_MASTER_NOINCLUDE 0x00000004 /*%< Disallow $INCLUDE directives. */ -#define DNS_MASTER_ZONE 0x00000008 /*%< Loading a zone master file. */ -#define DNS_MASTER_HINT 0x00000010 /*%< Loading a hint master file. */ -#define DNS_MASTER_SLAVE 0x00000020 /*%< Loading a slave master file. */ -#define DNS_MASTER_CHECKNS 0x00000040 /*%< - * Check NS records to see - * if they are an address - */ -#define DNS_MASTER_FATALNS 0x00000080 /*%< - * Treat DNS_MASTER_CHECKNS - * matches as fatal - */ -#define DNS_MASTER_CHECKNAMES 0x00000100 -#define DNS_MASTER_CHECKNAMESFAIL 0x00000200 -#define DNS_MASTER_CHECKWILDCARD 0x00000400 /* Check for internal wildcards. */ -#define DNS_MASTER_CHECKMX 0x00000800 -#define DNS_MASTER_CHECKMXFAIL 0x00001000 - -#define DNS_MASTER_RESIGN 0x00002000 -#define DNS_MASTER_KEY 0x00004000 /*%< Loading a key zone master file. */ -#define DNS_MASTER_NOTTL 0x00008000 /*%< Don't require ttl. */ -#define DNS_MASTER_CHECKTTL 0x00010000 /*%< Check max-zone-ttl */ - -ISC_LANG_BEGINDECLS - -/* - * Structures that implement the "raw" format for master dump. - * These are provided for a reference purpose only; in the actual - * encoding, we directly read/write each field so that the encoded data - * is always "packed", regardless of the hardware architecture. - */ -#define DNS_RAWFORMAT_VERSION 1 - -/* - * Flags to indicate the status of the data in the raw file header - */ -#define DNS_MASTERRAW_COMPAT 0x01 -#define DNS_MASTERRAW_SOURCESERIALSET 0x02 -#define DNS_MASTERRAW_LASTXFRINSET 0x04 - -/* Common header */ -struct dns_masterrawheader { - uint32_t format; /* must be - * dns_masterformat_raw - * or - * dns_masterformat_map */ - uint32_t version; /* compatibility for future - * extensions */ - uint32_t dumptime; /* timestamp on creation - * (currently unused) */ - uint32_t flags; /* Flags */ - uint32_t sourceserial; /* Source serial number (used - * by inline-signing zones) */ - uint32_t lastxfrin; /* timestamp of last transfer - * (used by slave zones) */ -}; - -/* The structure for each RRset */ -typedef struct { - uint32_t totallen; /* length of the data for this - * RRset, including the - * "header" part */ - dns_rdataclass_t rdclass; /* 16-bit class */ - dns_rdatatype_t type; /* 16-bit type */ - dns_rdatatype_t covers; /* same as type */ - dns_ttl_t ttl; /* 32-bit TTL */ - uint32_t nrdata; /* number of RRs in this set */ - /* followed by encoded owner name, and then rdata */ -} dns_masterrawrdataset_t; - -/* - * Method prototype: a callback to register each include file as - * it is encountered. - */ -typedef void -(*dns_masterincludecb_t)(const char *file, void *arg); - -/*** - *** Function - ***/ - -isc_result_t -dns_master_loadfile(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks); - -isc_result_t -dns_master_loadfile2(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfile3(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfile4(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, - void *include_arg, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfile5(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, - void *include_arg, - dns_masterformat_t format, - dns_ttl_t maxttl); - -isc_result_t -dns_master_loadstream(FILE *stream, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks); - -isc_result_t -dns_master_loadbuffer(isc_buffer_t *buffer, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks); - -isc_result_t -dns_master_loadlexer(isc_lex_t *lex, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks); - -isc_result_t -dns_master_loadfileinc(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp); - -isc_result_t -dns_master_loadfileinc2(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfileinc3(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfileinc4(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, - dns_masterincludecb_t include_cb, void *include_arg, - dns_masterformat_t format); - -isc_result_t -dns_master_loadfileinc5(const char *master_file, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp, - dns_masterincludecb_t include_cb, void *include_arg, - dns_masterformat_t format, - uint32_t maxttl); - -isc_result_t -dns_master_loadstreaminc(FILE *stream, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp); - -isc_result_t -dns_master_loadbufferinc(isc_buffer_t *buffer, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp); - -isc_result_t -dns_master_loadlexerinc(isc_lex_t *lex, - dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **ctxp); - -/*%< - * Loads a RFC1305 master file from a file, stream, buffer, or existing - * lexer into rdatasets and then calls 'callbacks->commit' to commit the - * rdatasets. Rdata memory belongs to dns_master_load and will be - * reused / released when the callback completes. dns_load_master will - * abort if callbacks->commit returns any value other than ISC_R_SUCCESS. - * - * If 'DNS_MASTER_AGETTL' is set and the master file contains one or more - * $DATE directives, the TTLs of the data will be aged accordingly. - * - * 'callbacks->commit' is assumed to call 'callbacks->error' or - * 'callbacks->warn' to generate any error messages required. - * - * 'done' is called with 'done_arg' and a result code when the loading - * is completed or has failed. If the initial setup fails 'done' is - * not called. - * - * 'resign' the number of seconds before a RRSIG expires that it should - * be re-signed. 0 is used if not provided. - * - * Requires: - *\li 'master_file' points to a valid string. - *\li 'lexer' points to a valid lexer. - *\li 'top' points to a valid name. - *\li 'origin' points to a valid name. - *\li 'callbacks->commit' points to a valid function. - *\li 'callbacks->error' points to a valid function. - *\li 'callbacks->warn' points to a valid function. - *\li 'mctx' points to a valid memory context. - *\li 'task' and 'done' to be valid. - *\li 'lmgr' to be valid. - *\li 'ctxp != NULL && ctxp == NULL'. - * - * Returns: - *\li ISC_R_SUCCESS upon successfully loading the master file. - *\li ISC_R_SEENINCLUDE upon successfully loading the master file with - * a $INCLUDE statement. - *\li ISC_R_NOMEMORY out of memory. - *\li ISC_R_UNEXPECTEDEND expected to be able to read a input token and - * there was not one. - *\li ISC_R_UNEXPECTED - *\li DNS_R_NOOWNER failed to specify a ownername. - *\li DNS_R_NOTTL failed to specify a ttl. - *\li DNS_R_BADCLASS record class did not match zone class. - *\li DNS_R_CONTINUE load still in progress (dns_master_load*inc() only). - *\li Any dns_rdata_fromtext() error code. - *\li Any error code from callbacks->commit(). - */ - -void -dns_loadctx_detach(dns_loadctx_t **ctxp); -/*%< - * Detach from the load context. - * - * Requires: - *\li '*ctxp' to be valid. - * - * Ensures: - *\li '*ctxp == NULL' - */ - -void -dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target); -/*%< - * Attach to the load context. - * - * Requires: - *\li 'source' to be valid. - *\li 'target != NULL && *target == NULL'. - */ - -void -dns_loadctx_cancel(dns_loadctx_t *ctx); -/*%< - * Cancel loading the zone file associated with this load context. - * - * Requires: - *\li 'ctx' to be valid - */ - -void -dns_master_initrawheader(dns_masterrawheader_t *header); -/*%< - * Initializes the header for a raw master file, setting all - * values to zero. - */ -ISC_LANG_ENDDECLS - -#endif /* DNS_MASTER_H */ diff --git a/usr.sbin/bind/lib/dns/master.c b/usr.sbin/bind/lib/dns/master.c deleted file mode 100644 index 25091bb41f1..00000000000 --- a/usr.sbin/bind/lib/dns/master.c +++ /dev/null @@ -1,3217 +0,0 @@ -/* - * Copyright (C) Internet Systems Consortium, Inc. ("ISC") - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: master.c,v 1.14 2020/01/22 13:02:09 florian Exp $ */ - -/*! \file */ - - -#include <stdlib.h> -#include <isc/event.h> -#include <isc/lex.h> -#include <isc/magic.h> - -#include <isc/serial.h> -#include <isc/stdio.h> -#include <isc/stdtime.h> -#include <string.h> -#include <isc/task.h> -#include <isc/util.h> - -#include <dns/callbacks.h> -#include <dns/events.h> -#include <dns/fixedname.h> -#include <dns/master.h> -#include <dns/name.h> -#include <dns/rdata.h> -#include <dns/rdataclass.h> -#include <dns/rdatalist.h> -#include <dns/rdataset.h> -#include <dns/rdatastruct.h> -#include <dns/rdatatype.h> -#include <dns/result.h> -#include <dns/soa.h> -#include <dns/time.h> -#include <dns/ttl.h> - -/*! - * Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ) structures - * by these sizes when we need to. - * - */ -/*% RDLSZ reflects the number of different types with the same name expected. */ -#define RDLSZ 32 -/*% - * RDSZ reflects the number of rdata expected at a give name that can fit into - * 64k. - */ -#define RDSZ 512 - -#define NBUFS 4 -#define MAXWIRESZ 255 - -/*% - * Target buffer size and minimum target size. - * MINTSIZ must be big enough to hold the largest rdata record. - * \brief - * TSIZ >= MINTSIZ - */ -#define TSIZ (128*1024) -/*% - * max message size - header - root - type - class - ttl - rdlen - */ -#define MINTSIZ DNS_RDATA_MAXLENGTH -/*% - * Size for tokens in the presentation format, - * The largest tokens are the base64 blocks in KEY and CERT records, - * Largest key allowed is about 1372 bytes but - * there is no fixed upper bound on CERT records. - * 2K is too small for some X.509s, 8K is overkill. - */ -#define TOKENSIZ (8*1024) - -/*% - * Buffers sizes for $GENERATE. - */ -#define DNS_MASTER_LHS 2048 -#define DNS_MASTER_RHS MINTSIZ - -#define CHECKNAMESFAIL(x) (((x) & DNS_MASTER_CHECKNAMESFAIL) != 0) - -#ifndef DNS_NAME_INITABSOLUTE -#define DNS_NAME_INITABSOLUTE(A,B) { \ - DNS_NAME_MAGIC, \ - A, sizeof(A), sizeof(B), \ - DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \ - B, NULL, { (void *)-1, (void *)-1}, \ - {NULL, NULL} \ -} -#endif - -typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t; - -typedef struct dns_incctx dns_incctx_t; - -/*% - * Master file load state. - */ - -struct dns_loadctx { - unsigned int magic; - dns_masterformat_t format; - - dns_rdatacallbacks_t *callbacks; - isc_task_t *task; - dns_loaddonefunc_t done; - void *done_arg; - - /* Common methods */ - isc_result_t (*openfile)(dns_loadctx_t *lctx, - const char *filename); - isc_result_t (*load)(dns_loadctx_t *lctx); - - /* Members used by all formats */ - uint32_t maxttl; - - /* Members specific to the text format: */ - isc_lex_t *lex; - isc_boolean_t keep_lex; - unsigned int options; - isc_boolean_t ttl_known; - isc_boolean_t default_ttl_known; - isc_boolean_t warn_1035; - isc_boolean_t warn_tcr; - isc_boolean_t warn_sigexpired; - isc_boolean_t seen_include; - uint32_t ttl; - uint32_t default_ttl; - dns_rdataclass_t zclass; - dns_fixedname_t fixed_top; - dns_name_t *top; /*%< top of zone */ - - /* Members specific to the raw format: */ - FILE *f; - isc_boolean_t first; - dns_masterrawheader_t header; - - /* Which fixed buffers we are using? */ - unsigned int loop_cnt; /*% records per quantum, - * 0 => all. */ - isc_boolean_t canceled; - isc_result_t result; - /* locked by lock */ - uint32_t references; - dns_incctx_t *inc; - uint32_t resign; - isc_stdtime_t now; - - dns_masterincludecb_t include_cb; - void *include_arg; -}; - -struct dns_incctx { - dns_incctx_t *parent; - dns_name_t *origin; - dns_name_t *current; - dns_name_t *glue; - dns_fixedname_t fixed[NBUFS]; /* working buffers */ - unsigned int in_use[NBUFS]; /* covert to bitmap? */ - int glue_in_use; - int current_in_use; - int origin_in_use; - isc_boolean_t origin_changed; - isc_boolean_t drop; - unsigned int glue_line; - unsigned int current_line; -}; - -#define DNS_LCTX_MAGIC ISC_MAGIC('L','c','t','x') -#define DNS_LCTX_VALID(lctx) ISC_MAGIC_VALID(lctx, DNS_LCTX_MAGIC) - -#define DNS_AS_STR(t) ((t).value.as_textregion.base) - -static isc_result_t -openfile_text(dns_loadctx_t *lctx, const char *master_file); - -static isc_result_t -load_text(dns_loadctx_t *lctx); - -static isc_result_t -openfile_raw(dns_loadctx_t *lctx, const char *master_file); - -static isc_result_t -load_raw(dns_loadctx_t *lctx); - -static isc_result_t -openfile_map(dns_loadctx_t *lctx, const char *master_file); - -static isc_result_t -load_map(dns_loadctx_t *lctx); - -static isc_result_t -pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx); - -static isc_result_t -commit(dns_rdatacallbacks_t *, dns_loadctx_t *, rdatalist_head_t *, - dns_name_t *, const char *, unsigned int); - -static isc_boolean_t -is_glue(rdatalist_head_t *, dns_name_t *); - -static dns_rdatalist_t * -grow_rdatalist(int, dns_rdatalist_t *, int, rdatalist_head_t *, - rdatalist_head_t *); - -static dns_rdata_t * -grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *); - -static void -load_quantum(isc_task_t *task, isc_event_t *event); - -static isc_result_t -task_send(dns_loadctx_t *lctx); - -static void -loadctx_destroy(dns_loadctx_t *lctx); - -#define GETTOKENERR(lexer, options, token, eol, err) \ - do { \ - result = gettoken(lexer, options, token, eol, callbacks); \ - switch (result) { \ - case ISC_R_SUCCESS: \ - break; \ - case ISC_R_UNEXPECTED: \ - goto insist_and_cleanup; \ - default: \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - LOGIT(result); \ - read_till_eol = ISC_TRUE; \ - err \ - goto next_line; \ - } else \ - goto log_and_cleanup; \ - } \ - if ((token)->type == isc_tokentype_special) { \ - result = DNS_R_SYNTAX; \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - LOGIT(result); \ - read_till_eol = ISC_TRUE; \ - goto next_line; \ - } else \ - goto log_and_cleanup; \ - } \ - } while (0) -#define GETTOKEN(lexer, options, token, eol) \ - GETTOKENERR(lexer, options, token, eol, {} ) - -#define COMMITALL \ - do { \ - result = commit(callbacks, lctx, ¤t_list, \ - ictx->current, source, ictx->current_line); \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - } else if (result != ISC_R_SUCCESS) \ - goto insist_and_cleanup; \ - result = commit(callbacks, lctx, &glue_list, \ - ictx->glue, source, ictx->glue_line); \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - } else if (result != ISC_R_SUCCESS) \ - goto insist_and_cleanup; \ - rdcount = 0; \ - rdlcount = 0; \ - isc_buffer_init(&target, target_mem, target_size); \ - rdcount_save = rdcount; \ - rdlcount_save = rdlcount; \ - } while (0) - -#define WARNUNEXPECTEDEOF(lexer) \ - do { \ - if (isc_lex_isfile(lexer)) \ - (*callbacks->warn)(callbacks, \ - "%s: file does not end with newline", \ - source); \ - } while (0) - -#define EXPECTEOL \ - do { \ - GETTOKEN(lctx->lex, 0, &token, ISC_TRUE); \ - if (token.type != isc_tokentype_eol) { \ - isc_lex_ungettoken(lctx->lex, &token); \ - result = DNS_R_EXTRATOKEN; \ - if (MANYERRS(lctx, result)) { \ - SETRESULT(lctx, result); \ - LOGIT(result); \ - read_till_eol = ISC_TRUE; \ - break; \ - } else if (result != ISC_R_SUCCESS) \ - goto log_and_cleanup; \ - } \ - } while (0) - -#define MANYERRS(lctx, result) \ - ((result != ISC_R_SUCCESS) && \ - (result != ISC_R_IOERROR) && \ - ((lctx)->options & DNS_MASTER_MANYERRORS) != 0) - -#define SETRESULT(lctx, r) \ - do { \ - if ((lctx)->result == ISC_R_SUCCESS) \ - (lctx)->result = r; \ - } while (0) - -#define LOGITFILE(result, filename) \ - if (result == ISC_R_INVALIDFILE || result == ISC_R_FILENOTFOUND || \ - result == ISC_R_IOERROR || result == ISC_R_TOOMANYOPENFILES || \ - result == ISC_R_NOPERM) \ - (*callbacks->error)(callbacks, "%s: %s:%lu: %s: %s", \ - "dns_master_load", source, line, \ - filename, dns_result_totext(result)); \ - else LOGIT(result) - -#define LOGIT(result) \ - if (result == ISC_R_NOMEMORY) \ - (*callbacks->error)(callbacks, "dns_master_load: %s", \ - dns_result_totext(result)); \ - else \ - (*callbacks->error)(callbacks, "%s: %s:%lu: %s", \ - "dns_master_load", \ - source, line, dns_result_totext(result)) - - -static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA"; -static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 }; -static dns_name_t const in_addr_arpa = - DNS_NAME_INITABSOLUTE(in_addr_arpa_data, in_addr_arpa_offsets); - -static unsigned char ip6_int_data[] = "\003IP6\003INT"; -static unsigned char ip6_int_offsets[] = { 0, 4, 8 }; -static dns_name_t const ip6_int = - DNS_NAME_INITABSOLUTE(ip6_int_data, ip6_int_offsets); - -static unsigned char ip6_arpa_data[] = "\003IP6\004ARPA"; -static unsigned char ip6_arpa_offsets[] = { 0, 4, 9 }; -static dns_name_t const ip6_arpa = - DNS_NAME_INITABSOLUTE(ip6_arpa_data, ip6_arpa_offsets); - -static inline isc_result_t -gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, - isc_boolean_t eol, dns_rdatacallbacks_t *callbacks) -{ - isc_result_t result; - - options |= ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE | - ISC_LEXOPT_ESCAPE; - result = isc_lex_gettoken(lex, options, token); - if (result != ISC_R_SUCCESS) { - switch (result) { - case ISC_R_NOMEMORY: - return (ISC_R_NOMEMORY); - default: - (*callbacks->error)(callbacks, - "dns_master_load: %s:%lu:" - " isc_lex_gettoken() failed: %s", - isc_lex_getsourcename(lex), - isc_lex_getsourceline(lex), - isc_result_totext(result)); - return (result); - } - /*NOTREACHED*/ - } - if (eol != ISC_TRUE) - if (token->type == isc_tokentype_eol || - token->type == isc_tokentype_eof) { - unsigned long int line; - const char *what; - const char *file; - file = isc_lex_getsourcename(lex); - line = isc_lex_getsourceline(lex); - if (token->type == isc_tokentype_eol) { - line--; - what = "line"; - } else - what = "file"; - (*callbacks->error)(callbacks, - "dns_master_load: %s:%lu: unexpected end of %s", - file, line, what); - return (ISC_R_UNEXPECTEDEND); - } - return (ISC_R_SUCCESS); -} - - -void -dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) { - - REQUIRE(target != NULL && *target == NULL); - REQUIRE(DNS_LCTX_VALID(source)); - - INSIST(source->references > 0); - source->references++; - INSIST(source->references != 0); /* Overflow? */ - - *target = source; -} - -void -dns_loadctx_detach(dns_loadctx_t **lctxp) { - dns_loadctx_t *lctx; - isc_boolean_t need_destroy = ISC_FALSE; - - REQUIRE(lctxp != NULL); - lctx = *lctxp; - REQUIRE(DNS_LCTX_VALID(lctx)); - - INSIST(lctx->references > 0); - lctx->references--; - if (lctx->references == 0) - need_destroy = ISC_TRUE; - - if (need_destroy) - loadctx_destroy(lctx); - *lctxp = NULL; -} - -static void -incctx_destroy(dns_incctx_t *ictx) { - dns_incctx_t *parent; - - again: - parent = ictx->parent; - ictx->parent = NULL; - - free(ictx); - - if (parent != NULL) { - ictx = parent; - goto again; - } -} - -static void -loadctx_destroy(dns_loadctx_t *lctx) { - isc_result_t result; - - REQUIRE(DNS_LCTX_VALID(lctx)); - - lctx->magic = 0; - if (lctx->inc != NULL) - incctx_destroy(lctx->inc); - - if (lctx->f != NULL) { - result = isc_stdio_close(lctx->f); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_close() failed: %s", - isc_result_totext(result)); - } - } - - /* isc_lex_destroy() will close all open streams */ - if (lctx->lex != NULL && !lctx->keep_lex) - isc_lex_destroy(&lctx->lex); - - if (lctx->task != NULL) - isc_task_detach(&lctx->task); - free(lctx); -} - -static isc_result_t -incctx_create(dns_name_t *origin, dns_incctx_t **ictxp) { - dns_incctx_t *ictx; - isc_region_t r; - int i; - - ictx = malloc(sizeof(*ictx)); - if (ictx == NULL) - return (ISC_R_NOMEMORY); - - for (i = 0; i < NBUFS; i++) { - dns_fixedname_init(&ictx->fixed[i]); - ictx->in_use[i] = ISC_FALSE; - } - - ictx->origin_in_use = 0; - ictx->origin = dns_fixedname_name(&ictx->fixed[ictx->origin_in_use]); - ictx->in_use[ictx->origin_in_use] = ISC_TRUE; - dns_name_toregion(origin, &r); - dns_name_fromregion(ictx->origin, &r); - - ictx->glue = NULL; - ictx->current = NULL; - ictx->glue_in_use = -1; - ictx->current_in_use = -1; - ictx->parent = NULL; - ictx->drop = ISC_FALSE; - ictx->glue_line = 0; - ictx->current_line = 0; - ictx->origin_changed = ISC_TRUE; - - *ictxp = ictx; - return (ISC_R_SUCCESS); -} - -static isc_result_t -loadctx_create(dns_masterformat_t format, - unsigned int options, uint32_t resign, dns_name_t *top, - dns_rdataclass_t zclass, dns_name_t *origin, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_masterincludecb_t include_cb, void *include_arg, - isc_lex_t *lex, dns_loadctx_t **lctxp) -{ - dns_loadctx_t *lctx; - isc_result_t result; - isc_region_t r; - isc_lexspecials_t specials; - - REQUIRE(lctxp != NULL && *lctxp == NULL); - REQUIRE(callbacks != NULL); - REQUIRE(callbacks->add != NULL); - REQUIRE(callbacks->error != NULL); - REQUIRE(callbacks->warn != NULL); - REQUIRE(dns_name_isabsolute(top)); - REQUIRE(dns_name_isabsolute(origin)); - REQUIRE((task == NULL && done == NULL) || - (task != NULL && done != NULL)); - - lctx = malloc(sizeof(*lctx)); - if (lctx == NULL) - return (ISC_R_NOMEMORY); - - lctx->inc = NULL; - result = incctx_create(origin, &lctx->inc); - if (result != ISC_R_SUCCESS) - goto cleanup_ctx; - - lctx->maxttl = 0; - - lctx->format = format; - switch (format) { - default: - INSIST(0); - case dns_masterformat_text: - lctx->openfile = openfile_text; - lctx->load = load_text; - break; - case dns_masterformat_raw: - lctx->openfile = openfile_raw; - lctx->load = load_raw; - break; - case dns_masterformat_map: - lctx->openfile = openfile_map; - lctx->load = load_map; - break; - } - - if (lex != NULL) { - lctx->lex = lex; - lctx->keep_lex = ISC_TRUE; - } else { - lctx->lex = NULL; - result = isc_lex_create(TOKENSIZ, &lctx->lex); - if (result != ISC_R_SUCCESS) - goto cleanup_inc; - lctx->keep_lex = ISC_FALSE; - memset(specials, 0, sizeof(specials)); - specials[0] = 1; - specials['('] = 1; - specials[')'] = 1; - specials['"'] = 1; - isc_lex_setspecials(lctx->lex, specials); - isc_lex_setcomments(lctx->lex, ISC_LEXCOMMENT_DNSMASTERFILE); - } - - lctx->ttl_known = ISC_TF((options & DNS_MASTER_NOTTL) != 0); - lctx->ttl = 0; - lctx->default_ttl_known = lctx->ttl_known; - lctx->default_ttl = 0; - lctx->warn_1035 = ISC_TRUE; /* XXX Argument? */ - lctx->warn_tcr = ISC_TRUE; /* XXX Argument? */ - lctx->warn_sigexpired = ISC_TRUE; /* XXX Argument? */ - lctx->options = options; - lctx->seen_include = ISC_FALSE; - lctx->zclass = zclass; - lctx->resign = resign; - lctx->result = ISC_R_SUCCESS; - lctx->include_cb = include_cb; - lctx->include_arg = include_arg; - isc_stdtime_get(&lctx->now); - - dns_fixedname_init(&lctx->fixed_top); - lctx->top = dns_fixedname_name(&lctx->fixed_top); - dns_name_toregion(top, &r); - dns_name_fromregion(lctx->top, &r); - - lctx->f = NULL; - lctx->first = ISC_TRUE; - dns_master_initrawheader(&lctx->header); - - lctx->loop_cnt = (done != NULL) ? 100 : 0; - lctx->callbacks = callbacks; - lctx->task = NULL; - if (task != NULL) - isc_task_attach(task, &lctx->task); - lctx->done = done; - lctx->done_arg = done_arg; - lctx->canceled = ISC_FALSE; - lctx->references = 1; /* Implicit attach. */ - lctx->magic = DNS_LCTX_MAGIC; - *lctxp = lctx; - return (ISC_R_SUCCESS); - - cleanup_inc: - incctx_destroy(lctx->inc); - cleanup_ctx: - free(lctx); - return (result); -} - -static const char *hex = "0123456789abcdef0123456789ABCDEF"; - -/*% - * Convert value into a nibble sequence from least significant to most - * significant nibble. Zero fill upper most significant nibbles if - * required to make the width. - * - * Returns the number of characters that should have been written without - * counting the terminating NUL. - */ -static unsigned int -nibbles(char *numbuf, size_t length, unsigned int width, char mode, int value) { - unsigned int count = 0; - - /* - * This reserve space for the NUL string terminator. - */ - if (length > 0U) { - *numbuf = '\0'; - length--; - } - do { - char val = hex[(value & 0x0f) + ((mode == 'n') ? 0 : 16)]; - value >>= 4; - if (length > 0U) { - *numbuf++ = val; - *numbuf = '\0'; - length--; - } - if (width > 0) - width--; - count++; - /* - * If width is non zero then we need to add a label seperator. - * If value is non zero then we need to add another label and - * that requires a label seperator. - */ - if (width > 0 || value != 0) { - if (length > 0U) { - *numbuf++ = '.'; - *numbuf = '\0'; - length--; - } - if (width > 0) - width--; - count++; - } - } while (value != 0 || width > 0); - return (count); -} - -static isc_result_t -genname(char *name, int it, char *buffer, size_t length) { - char fmt[sizeof("%04000000000d")]; - char numbuf[128]; - char *cp; - char mode[2]; - int delta = 0; - isc_textregion_t r; - unsigned int n; - unsigned int width; - isc_boolean_t nibblemode; - - r.base = buffer; - r.length = (unsigned int)length; - - while (*name != '\0') { - if (*name == '$') { - name++; - if (*name == '$') { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - continue; - } - nibblemode = ISC_FALSE; - strlcpy(fmt, "%d", sizeof(fmt)); - /* Get format specifier. */ - if (*name == '{' ) { - n = sscanf(name, "{%d,%u,%1[doxXnN]}", - &delta, &width, mode); - switch (n) { - case 1: - break; - case 2: - n = snprintf(fmt, sizeof(fmt), - "%%0%ud", width); - break; - case 3: - if (mode[0] == 'n' || mode[0] == 'N') - nibblemode = ISC_TRUE; - n = snprintf(fmt, sizeof(fmt), - "%%0%u%c", width, mode[0]); - break; - default: - return (DNS_R_SYNTAX); - } - if (n >= sizeof(fmt)) - return (ISC_R_NOSPACE); - /* Skip past closing brace. */ - while (*name != '\0' && *name++ != '}') - continue; - } - if (nibblemode) - n = nibbles(numbuf, sizeof(numbuf), width, - mode[0], it + delta); - else - n = snprintf(numbuf, sizeof(numbuf), fmt, - it + delta); - if (n >= sizeof(numbuf)) - return (ISC_R_NOSPACE); - cp = numbuf; - while (*cp != '\0') { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *cp++; - isc_textregion_consume(&r, 1); - } - } else if (*name == '\\') { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - if (*name == '\0') - continue; - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - } else { - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = *name++; - isc_textregion_consume(&r, 1); - } - } - if (r.length == 0) - return (ISC_R_NOSPACE); - r.base[0] = '\0'; - return (ISC_R_SUCCESS); -} - -static isc_result_t -generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs, - const char *source, unsigned int line) -{ - char *target_mem = NULL; - char *lhsbuf = NULL; - char *rhsbuf = NULL; - dns_fixedname_t ownerfixed; - dns_name_t *owner; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdatacallbacks_t *callbacks; - dns_rdatalist_t rdatalist; - dns_rdatatype_t type; - rdatalist_head_t head; - int target_size = MINTSIZ; /* only one rdata at a time */ - isc_buffer_t buffer; - isc_buffer_t target; - isc_result_t result; - isc_textregion_t r; - int i, n, start, stop, step = 0; - dns_incctx_t *ictx; - char dummy[2]; - - ictx = lctx->inc; - callbacks = lctx->callbacks; - dns_fixedname_init(&ownerfixed); - owner = dns_fixedname_name(&ownerfixed); - ISC_LIST_INIT(head); - - target_mem = malloc(target_size); - rhsbuf = malloc(DNS_MASTER_RHS); - lhsbuf = malloc(DNS_MASTER_LHS); - if (target_mem == NULL || rhsbuf == NULL || lhsbuf == NULL) { - result = ISC_R_NOMEMORY; - goto error_cleanup; - } - isc_buffer_init(&target, target_mem, target_size); - - n = sscanf(range, "%d-%d%1[/]%d", &start, &stop, dummy, &step); - if ((n != 2 && n != 4) || (start < 0) || (stop < 0) || - (n == 4 && step < 1) || (stop < start)) - { - (*callbacks->error)(callbacks, - "%s: %s:%lu: invalid range '%s'", - "$GENERATE", source, line, range); - result = DNS_R_SYNTAX; - goto insist_cleanup; - } - if (n == 2) - step = 1; - - /* - * Get type. - */ - r.base = gtype; - r.length = strlen(gtype); - result = dns_rdatatype_fromtext(&type, &r); - if (result != ISC_R_SUCCESS) { - (*callbacks->error)(callbacks, - "%s: %s:%lu: unknown RR type '%s'", - "$GENERATE", source, line, gtype); - goto insist_cleanup; - } - - /* - * RFC2930: TKEY and TSIG are not allowed to be loaded - * from master files. - */ - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - dns_rdatatype_ismeta(type)) - { - (*callbacks->error)(callbacks, - "%s: %s:%lu: meta RR type '%s'", - "$GENERATE", - source, line, gtype); - result = DNS_R_METATYPE; - goto insist_cleanup; - } - - for (i = start; i <= stop; i += step) { - result = genname(lhs, i, lhsbuf, DNS_MASTER_LHS); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - result = genname(rhs, i, rhsbuf, DNS_MASTER_RHS); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - isc_buffer_init(&buffer, lhsbuf, strlen(lhsbuf)); - isc_buffer_add(&buffer, strlen(lhsbuf)); - isc_buffer_setactive(&buffer, strlen(lhsbuf)); - result = dns_name_fromtext(owner, &buffer, ictx->origin, - 0, NULL); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - (lctx->options & DNS_MASTER_KEY) == 0 && - !dns_name_issubdomain(owner, lctx->top)) - { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(owner, namebuf, sizeof(namebuf)); - /* - * Ignore out-of-zone data. - */ - (*callbacks->warn)(callbacks, - "%s:%lu: " - "ignoring out-of-zone data (%s)", - source, line, namebuf); - continue; - } - - isc_buffer_init(&buffer, rhsbuf, strlen(rhsbuf)); - isc_buffer_add(&buffer, strlen(rhsbuf)); - isc_buffer_setactive(&buffer, strlen(rhsbuf)); - - result = isc_lex_openbuffer(lctx->lex, &buffer); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - isc_buffer_init(&target, target_mem, target_size); - result = dns_rdata_fromtext(&rdata, lctx->zclass, type, - lctx->lex, ictx->origin, 0, - &target, callbacks); - RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - - dns_rdatalist_init(&rdatalist); - rdatalist.type = type; - rdatalist.rdclass = lctx->zclass; - rdatalist.ttl = lctx->ttl; - ISC_LIST_PREPEND(head, &rdatalist, link); - ISC_LIST_APPEND(rdatalist.rdata, &rdata, link); - result = commit(callbacks, lctx, &head, owner, source, line); - ISC_LIST_UNLINK(rdatalist.rdata, &rdata, link); - if (result != ISC_R_SUCCESS) - goto error_cleanup; - dns_rdata_reset(&rdata); - } - result = ISC_R_SUCCESS; - goto cleanup; - - error_cleanup: - if (result == ISC_R_NOMEMORY) - (*callbacks->error)(callbacks, "$GENERATE: %s", - dns_result_totext(result)); - else - (*callbacks->error)(callbacks, "$GENERATE: %s:%lu: %s", - source, line, dns_result_totext(result)); - - insist_cleanup: - INSIST(result != ISC_R_SUCCESS); - - cleanup: - if (target_mem != NULL) - free(target_mem); - if (lhsbuf != NULL) - free(lhsbuf); - if (rhsbuf != NULL) - free(rhsbuf); - return (result); -} - -static void -limit_ttl(dns_rdatacallbacks_t *callbacks, const char *source, - unsigned int line, uint32_t *ttlp) -{ - if (*ttlp > 0x7fffffffUL) { - (callbacks->warn)(callbacks, - "%s: %s:%lu: " - "$TTL %lu > MAXTTL, " - "setting $TTL to 0", - "dns_master_load", - source, line, - *ttlp); - *ttlp = 0; - } -} - -static isc_result_t -check_ns(dns_loadctx_t *lctx, isc_token_t *token, const char *source, - unsigned long line) -{ - char *tmp = NULL; - isc_result_t result = ISC_R_SUCCESS; - void (*callback)(struct dns_rdatacallbacks *, const char *, ...); - - if ((lctx->options & DNS_MASTER_FATALNS) != 0) - callback = lctx->callbacks->error; - else - callback = lctx->callbacks->warn; - - if (token->type == isc_tokentype_string) { - struct in_addr addr; - struct in6_addr addr6; - - tmp = strdup(DNS_AS_STR(*token)); - if (tmp == NULL) - return (ISC_R_NOMEMORY); - /* - * Catch both "1.2.3.4" and "1.2.3.4." - */ - if (tmp[strlen(tmp) - 1] == '.') - tmp[strlen(tmp) - 1] = '\0'; - if (inet_aton(tmp, &addr) == 1 || - inet_pton(AF_INET6, tmp, &addr6) == 1) - result = DNS_R_NSISADDRESS; - } - if (result != ISC_R_SUCCESS) - (*callback)(lctx->callbacks, "%s:%lu: NS record '%s' " - "appears to be an address", - source, line, DNS_AS_STR(*token)); - if (tmp != NULL) - free(tmp); - return (result); -} - -static void -check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line, - dns_rdatacallbacks_t *callbacks) -{ - dns_name_t *name; - - name = (ictx->glue != NULL) ? ictx->glue : ictx->current; - if (dns_name_internalwildcard(name)) { - char namebuf[DNS_NAME_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - (*callbacks->warn)(callbacks, "%s:%lu: warning: ownername " - "'%s' contains an non-terminal wildcard", - source, line, namebuf); - } -} - -static isc_result_t -openfile_text(dns_loadctx_t *lctx, const char *master_file) { - return (isc_lex_openfile(lctx->lex, master_file)); -} - -static int -find_free_name(dns_incctx_t *incctx) { - int i; - - for (i = 0; i < (NBUFS - 1); i++) { - if (!incctx->in_use[i]) { - break; - } - } - INSIST(!incctx->in_use[i]); - return (i); -} - -static isc_result_t -load_text(dns_loadctx_t *lctx) { - dns_rdataclass_t rdclass; - dns_rdatatype_t type, covers; - uint32_t ttl_offset = 0; - dns_name_t *new_name; - isc_boolean_t current_has_delegation = ISC_FALSE; - isc_boolean_t done = ISC_FALSE; - isc_boolean_t finish_origin = ISC_FALSE; - isc_boolean_t finish_include = ISC_FALSE; - isc_boolean_t read_till_eol = ISC_FALSE; - isc_boolean_t initialws; - char *include_file = NULL; - isc_token_t token; - isc_result_t result = ISC_R_UNEXPECTED; - rdatalist_head_t glue_list; - rdatalist_head_t current_list; - dns_rdatalist_t *this; - dns_rdatalist_t *rdatalist = NULL; - dns_rdatalist_t *new_rdatalist; - int rdlcount = 0; - int rdlcount_save = 0; - int rdatalist_size = 0; - isc_buffer_t buffer; - isc_buffer_t target; - isc_buffer_t target_ft; - isc_buffer_t target_save; - dns_rdata_t *rdata = NULL; - dns_rdata_t *new_rdata; - int rdcount = 0; - int rdcount_save = 0; - int rdata_size = 0; - unsigned char *target_mem = NULL; - int target_size = TSIZ; - int new_in_use; - unsigned int loop_cnt = 0; - dns_rdatacallbacks_t *callbacks; - dns_incctx_t *ictx; - char *range = NULL; - char *lhs = NULL; - char *gtype = NULL; - char *rhs = NULL; - const char *source = ""; - unsigned long line = 0; - isc_boolean_t explicit_ttl; - char classname1[DNS_RDATACLASS_FORMATSIZE]; - char classname2[DNS_RDATACLASS_FORMATSIZE]; - unsigned int options = 0; - - REQUIRE(DNS_LCTX_VALID(lctx)); - callbacks = lctx->callbacks; - ictx = lctx->inc; - - ISC_LIST_INIT(glue_list); - ISC_LIST_INIT(current_list); - - - /* - * Allocate target_size of buffer space. This is greater than twice - * the maximum individual RR data size. - */ - target_mem = malloc(target_size); - if (target_mem == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - isc_buffer_init(&target, target_mem, target_size); - target_save = target; - - if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) - options |= DNS_RDATA_CHECKNAMES; - if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) - options |= DNS_RDATA_CHECKNAMESFAIL; - if ((lctx->options & DNS_MASTER_CHECKMX) != 0) - options |= DNS_RDATA_CHECKMX; - if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0) - options |= DNS_RDATA_CHECKMXFAIL; - source = isc_lex_getsourcename(lctx->lex); - do { - initialws = ISC_FALSE; - line = isc_lex_getsourceline(lctx->lex); - GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING, - &token, ISC_TRUE); - line = isc_lex_getsourceline(lctx->lex); - - if (token.type == isc_tokentype_eof) { - if (read_till_eol) - WARNUNEXPECTEDEOF(lctx->lex); - /* Pop the include stack? */ - if (ictx->parent != NULL) { - COMMITALL; - lctx->inc = ictx->parent; - ictx->parent = NULL; - incctx_destroy(ictx); - RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS); - line = isc_lex_getsourceline(lctx->lex); - POST(line); - source = isc_lex_getsourcename(lctx->lex); - ictx = lctx->inc; - continue; - } - done = ISC_TRUE; - continue; - } - - if (token.type == isc_tokentype_eol) { - read_till_eol = ISC_FALSE; - continue; /* blank line */ - } - - if (read_till_eol) - continue; - - if (token.type == isc_tokentype_initialws) { - /* - * Still working on the same name. - */ - initialws = ISC_TRUE; - } else if (token.type == isc_tokentype_string || - token.type == isc_tokentype_qstring) { - - /* - * "$" Support. - * - * "$ORIGIN" and "$INCLUDE" can both take domain names. - * The processing of "$ORIGIN" and "$INCLUDE" extends - * across the normal domain name processing. - */ - - if (strcasecmp(DNS_AS_STR(token), "$ORIGIN") == 0) { - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - finish_origin = ISC_TRUE; - } else if (strcasecmp(DNS_AS_STR(token), - "$TTL") == 0) { - GETTOKENERR(lctx->lex, 0, &token, ISC_FALSE, - lctx->ttl = 0; - lctx->default_ttl_known = ISC_TRUE;); - result = - dns_ttl_fromtext(&token.value.as_textregion, - &lctx->ttl); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - lctx->ttl = 0; - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - limit_ttl(callbacks, source, line, &lctx->ttl); - lctx->default_ttl = lctx->ttl; - lctx->default_ttl_known = ISC_TRUE; - EXPECTEOL; - continue; - } else if (strcasecmp(DNS_AS_STR(token), - "$INCLUDE") == 0) { - COMMITALL; - if ((lctx->options & DNS_MASTER_NOINCLUDE) - != 0) - { - (callbacks->error)(callbacks, - "%s: %s:%lu: $INCLUDE not allowed", - "dns_master_load", - source, line); - result = DNS_R_REFUSED; - goto insist_and_cleanup; - } - if (ttl_offset != 0) { - (callbacks->error)(callbacks, - "%s: %s:%lu: $INCLUDE " - "may not be used with $DATE", - "dns_master_load", - source, line); - result = DNS_R_SYNTAX; - goto insist_and_cleanup; - } - GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token, - ISC_FALSE); - if (include_file != NULL) - free(include_file); - include_file = strdup(DNS_AS_STR(token)); - if (include_file == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - GETTOKEN(lctx->lex, 0, &token, ISC_TRUE); - - if (token.type == isc_tokentype_eol || - token.type == isc_tokentype_eof) { - if (token.type == isc_tokentype_eof) - WARNUNEXPECTEDEOF(lctx->lex); - /* - * No origin field. - */ - result = pushfile(include_file, - ictx->origin, lctx); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGITFILE(result, include_file); - continue; - } else if (result != ISC_R_SUCCESS) { - LOGITFILE(result, include_file); - goto insist_and_cleanup; - } - ictx = lctx->inc; - source = - isc_lex_getsourcename(lctx->lex); - line = isc_lex_getsourceline(lctx->lex); - POST(line); - continue; - } - /* - * There is an origin field. Fall through - * to domain name processing code and do - * the actual inclusion later. - */ - finish_include = ISC_TRUE; - } else if (strcasecmp(DNS_AS_STR(token), - "$DATE") == 0) { - int64_t dump_time64; - isc_stdtime_t dump_time, current_time; - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - isc_stdtime_get(¤t_time); - result = dns_time64_fromtext(DNS_AS_STR(token), - &dump_time64); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGIT(result); - dump_time64 = 0; - } else if (result != ISC_R_SUCCESS) - goto log_and_cleanup; - dump_time = (isc_stdtime_t)dump_time64; - if (dump_time != dump_time64) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s: %s:%lu: $DATE outside epoch", - "dns_master_load", source, line); - result = ISC_R_UNEXPECTED; - goto insist_and_cleanup; - } - if (dump_time > current_time) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s: %s:%lu: " - "$DATE in future, using current date", - "dns_master_load", source, line); - dump_time = current_time; - } - ttl_offset = current_time - dump_time; - EXPECTEOL; - continue; - } else if (strcasecmp(DNS_AS_STR(token), - "$GENERATE") == 0) { - /* - * Lazy cleanup. - */ - if (range != NULL) - free(range); - if (lhs != NULL) - free(lhs); - if (gtype != NULL) - free(gtype); - if (rhs != NULL) - free(rhs); - range = lhs = gtype = rhs = NULL; - /* RANGE */ - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - range = strdup(DNS_AS_STR(token)); - if (range == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - /* LHS */ - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - lhs = strdup(DNS_AS_STR(token)); - if (lhs == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - rdclass = 0; - explicit_ttl = ISC_FALSE; - /* CLASS? */ - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - if (dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) { - GETTOKEN(lctx->lex, 0, &token, - ISC_FALSE); - } - /* TTL? */ - if (dns_ttl_fromtext(&token.value.as_textregion, - &lctx->ttl) - == ISC_R_SUCCESS) { - limit_ttl(callbacks, source, line, - &lctx->ttl); - lctx->ttl_known = ISC_TRUE; - explicit_ttl = ISC_TRUE; - GETTOKEN(lctx->lex, 0, &token, - ISC_FALSE); - } - /* CLASS? */ - if (rdclass == 0 && - dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) - GETTOKEN(lctx->lex, 0, &token, - ISC_FALSE); - /* TYPE */ - gtype = strdup(DNS_AS_STR(token)); - if (gtype == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - /* RHS */ - GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, - &token, ISC_FALSE); - rhs = strdup(DNS_AS_STR(token)); - if (rhs == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - if (!lctx->ttl_known && - !lctx->default_ttl_known) { - (*callbacks->error)(callbacks, - "%s: %s:%lu: no TTL specified", - "dns_master_load", source, line); - result = DNS_R_NOTTL; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - lctx->ttl = 0; - } else { - goto insist_and_cleanup; - } - } else if (!explicit_ttl && - lctx->default_ttl_known) { - lctx->ttl = lctx->default_ttl; - } - /* - * If the class specified does not match the - * zone's class print out a error message and - * exit. - */ - if (rdclass != 0 && rdclass != lctx->zclass) { - goto bad_class; - } - result = generate(lctx, range, lhs, gtype, rhs, - source, line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - EXPECTEOL; - continue; - } else if (strncasecmp(DNS_AS_STR(token), - "$", 1) == 0) { - (callbacks->error)(callbacks, - "%s: %s:%lu: " - "unknown $ directive '%s'", - "dns_master_load", source, line, - DNS_AS_STR(token)); - result = DNS_R_SYNTAX; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else { - goto insist_and_cleanup; - } - } - - /* - * Normal processing resumes. - */ - new_in_use = find_free_name(ictx); - new_name = dns_fixedname_name(&ictx->fixed[new_in_use]); - isc_buffer_init(&buffer, token.value.as_region.base, - token.value.as_region.length); - isc_buffer_add(&buffer, token.value.as_region.length); - isc_buffer_setactive(&buffer, - token.value.as_region.length); - result = dns_name_fromtext(new_name, &buffer, - ictx->origin, 0, NULL); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGIT(result); - read_till_eol = ISC_TRUE; - continue; - } else if (result != ISC_R_SUCCESS) - goto log_and_cleanup; - - /* - * Finish $ORIGIN / $INCLUDE processing if required. - */ - if (finish_origin) { - if (ictx->origin_in_use != -1) - ictx->in_use[ictx->origin_in_use] = - ISC_FALSE; - ictx->origin_in_use = new_in_use; - ictx->in_use[ictx->origin_in_use] = ISC_TRUE; - ictx->origin = new_name; - ictx->origin_changed = ISC_TRUE; - finish_origin = ISC_FALSE; - EXPECTEOL; - continue; - } - if (finish_include) { - finish_include = ISC_FALSE; - EXPECTEOL; - result = pushfile(include_file, new_name, lctx); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGITFILE(result, include_file); - continue; - } else if (result != ISC_R_SUCCESS) { - LOGITFILE(result, include_file); - goto insist_and_cleanup; - } - ictx = lctx->inc; - ictx->origin_changed = ISC_TRUE; - source = isc_lex_getsourcename(lctx->lex); - line = isc_lex_getsourceline(lctx->lex); - POST(line); - continue; - } - - /* - * "$" Processing Finished - */ - - /* - * If we are processing glue and the new name does - * not match the current glue name, commit the glue - * and pop stacks leaving us in 'normal' processing - * state. Linked lists are undone by commit(). - */ - if (ictx->glue != NULL && - dns_name_compare(ictx->glue, new_name) != 0) { - result = commit(callbacks, lctx, &glue_list, - ictx->glue, source, - ictx->glue_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - if (ictx->glue_in_use != -1) - ictx->in_use[ictx->glue_in_use] = - ISC_FALSE; - ictx->glue_in_use = -1; - ictx->glue = NULL; - rdcount = rdcount_save; - rdlcount = rdlcount_save; - target = target_save; - } - - /* - * If we are in 'normal' processing state and the new - * name does not match the current name, see if the - * new name is for glue and treat it as such, - * otherwise we have a new name so commit what we - * have. - */ - if ((ictx->glue == NULL) && (ictx->current == NULL || - dns_name_compare(ictx->current, new_name) != 0)) { - if (current_has_delegation && - is_glue(¤t_list, new_name)) { - rdcount_save = rdcount; - rdlcount_save = rdlcount; - target_save = target; - ictx->glue = new_name; - ictx->glue_in_use = new_in_use; - ictx->in_use[ictx->glue_in_use] = - ISC_TRUE; - } else { - result = commit(callbacks, lctx, - ¤t_list, - ictx->current, - source, - ictx->current_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - rdcount = 0; - rdlcount = 0; - if (ictx->current_in_use != -1) - ictx->in_use[ictx->current_in_use] = - ISC_FALSE; - ictx->current_in_use = new_in_use; - ictx->in_use[ictx->current_in_use] = - ISC_TRUE; - ictx->current = new_name; - current_has_delegation = ISC_FALSE; - isc_buffer_init(&target, target_mem, - target_size); - } - /* - * Check for internal wildcards. - */ - if ((lctx->options & DNS_MASTER_CHECKWILDCARD) - != 0) - check_wildcard(ictx, source, line, - callbacks); - - } - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - (lctx->options & DNS_MASTER_KEY) == 0 && - !dns_name_issubdomain(new_name, lctx->top)) - { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(new_name, namebuf, - sizeof(namebuf)); - /* - * Ignore out-of-zone data. - */ - (*callbacks->warn)(callbacks, - "%s:%lu: " - "ignoring out-of-zone data (%s)", - source, line, namebuf); - ictx->drop = ISC_TRUE; - } else - ictx->drop = ISC_FALSE; - } else { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "%s:%lu: isc_lex_gettoken() returned " - "unexpected token type (%d)", - source, line, token.type); - result = ISC_R_UNEXPECTED; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - LOGIT(result); - continue; - } else { - goto insist_and_cleanup; - } - } - - /* - * Find TTL, class and type. Both TTL and class are optional - * and may occur in any order if they exist. TTL and class - * come before type which must exist. - * - * [<TTL>] [<class>] <type> <RDATA> - * [<class>] [<TTL>] <type> <RDATA> - */ - - type = 0; - rdclass = 0; - - GETTOKEN(lctx->lex, 0, &token, initialws); - - if (initialws) { - if (token.type == isc_tokentype_eol) { - read_till_eol = ISC_FALSE; - continue; /* blank line */ - } - - if (token.type == isc_tokentype_eof) { - WARNUNEXPECTEDEOF(lctx->lex); - read_till_eol = ISC_FALSE; - isc_lex_ungettoken(lctx->lex, &token); - continue; - } - - if (ictx->current == NULL) { - (*callbacks->error)(callbacks, - "%s:%lu: no current owner name", - source, line); - result = DNS_R_NOOWNER; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = ISC_TRUE; - continue; - } else { - goto insist_and_cleanup; - } - } - - if (ictx->origin_changed) { - char cbuf[DNS_NAME_FORMATSIZE]; - char obuf[DNS_NAME_FORMATSIZE]; - dns_name_format(ictx->current, cbuf, - sizeof(cbuf)); - dns_name_format(ictx->origin, obuf, - sizeof(obuf)); - (*callbacks->warn)(callbacks, - "%s:%lu: record with inherited " - "owner (%s) immediately after " - "$ORIGIN (%s)", source, line, - cbuf, obuf); - } - } - - ictx->origin_changed = ISC_FALSE; - - if (dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - - explicit_ttl = ISC_FALSE; - result = dns_ttl_fromtext(&token.value.as_textregion, - &lctx->ttl); - if (result == ISC_R_SUCCESS) { - limit_ttl(callbacks, source, line, &lctx->ttl); - explicit_ttl = ISC_TRUE; - lctx->ttl_known = ISC_TRUE; - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - } - - if (token.type != isc_tokentype_string) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_lex_gettoken() returned unexpected token type"); - result = ISC_R_UNEXPECTED; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = ISC_TRUE; - continue; - } else { - goto insist_and_cleanup; - } - } - - if (rdclass == 0 && - dns_rdataclass_fromtext(&rdclass, - &token.value.as_textregion) - == ISC_R_SUCCESS) - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - - if (token.type != isc_tokentype_string) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_lex_gettoken() returned unexpected token type"); - result = ISC_R_UNEXPECTED; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = ISC_TRUE; - continue; - } else { - goto insist_and_cleanup; - } - } - - result = dns_rdatatype_fromtext(&type, - &token.value.as_textregion); - if (result != ISC_R_SUCCESS) { - (*callbacks->warn)(callbacks, - "%s:%lu: unknown RR type '%.*s'", - source, line, - token.value.as_textregion.length, - token.value.as_textregion.base); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = ISC_TRUE; - continue; - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - } - - /* - * If the class specified does not match the zone's class - * print out a error message and exit. - */ - if (rdclass != 0 && rdclass != lctx->zclass) { - bad_class: - - dns_rdataclass_format(rdclass, classname1, - sizeof(classname1)); - dns_rdataclass_format(lctx->zclass, classname2, - sizeof(classname2)); - (*callbacks->error)(callbacks, - "%s:%lu: class '%s' != " - "zone class '%s'", - source, line, - classname1, classname2); - result = DNS_R_BADCLASS; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = ISC_TRUE; - continue; - } else { - goto insist_and_cleanup; - } - } - - if (type == dns_rdatatype_ns && ictx->glue == NULL) - current_has_delegation = ISC_TRUE; - - /* - * RFC1123: MD and MF are not allowed to be loaded from - * master files. - */ - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - (type == dns_rdatatype_md || type == dns_rdatatype_mf)) { - char typename[DNS_RDATATYPE_FORMATSIZE]; - - result = DNS_R_OBSOLETE; - - dns_rdatatype_format(type, typename, sizeof(typename)); - (*callbacks->error)(callbacks, - "%s:%lu: %s '%s': %s", - source, line, - "type", typename, - dns_result_totext(result)); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else - goto insist_and_cleanup; - } - - /* - * RFC2930: TKEY and TSIG are not allowed to be loaded - * from master files. - */ - if ((lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0 && - dns_rdatatype_ismeta(type)) - { - char typename[DNS_RDATATYPE_FORMATSIZE]; - - result = DNS_R_METATYPE; - - dns_rdatatype_format(type, typename, sizeof(typename)); - (*callbacks->error)(callbacks, - "%s:%lu: %s '%s': %s", - source, line, - "type", typename, - dns_result_totext(result)); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else - goto insist_and_cleanup; - } - - /* - * Find a rdata structure. - */ - if (rdcount == rdata_size) { - new_rdata = grow_rdata(rdata_size + RDSZ, rdata, - rdata_size, ¤t_list, - &glue_list); - if (new_rdata == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - rdata_size += RDSZ; - rdata = new_rdata; - } - - /* - * Peek at the NS record. - */ - if (type == dns_rdatatype_ns && - lctx->zclass == dns_rdataclass_in && - (lctx->options & DNS_MASTER_CHECKNS) != 0) { - - GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); - result = check_ns(lctx, &token, source, line); - isc_lex_ungettoken(lctx->lex, &token); - if ((lctx->options & DNS_MASTER_FATALNS) != 0) { - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - } - } - - /* - * Check owner name. - */ - options &= ~DNS_RDATA_CHECKREVERSE; - if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) { - isc_boolean_t ok; - dns_name_t *name; - - name = (ictx->glue != NULL) ? ictx->glue : - ictx->current; - ok = dns_rdata_checkowner(name, lctx->zclass, type, - ISC_TRUE); - if (!ok) { - char namebuf[DNS_NAME_FORMATSIZE]; - const char *desc; - dns_name_format(name, namebuf, sizeof(namebuf)); - result = DNS_R_BADOWNERNAME; - desc = dns_result_totext(result); - if (CHECKNAMESFAIL(lctx->options) || - type == dns_rdatatype_nsec3) { - (*callbacks->error)(callbacks, - "%s:%lu: %s: %s", - source, line, - namebuf, desc); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else { - goto cleanup; - } - } else { - (*callbacks->warn)(callbacks, - "%s:%lu: %s: %s", - source, line, - namebuf, desc); - } - } - if (type == dns_rdatatype_ptr && - !dns_name_isdnssd(name) && - (dns_name_issubdomain(name, &in_addr_arpa) || - dns_name_issubdomain(name, &ip6_arpa) || - dns_name_issubdomain(name, &ip6_int))) - options |= DNS_RDATA_CHECKREVERSE; - } - - /* - * Read rdata contents. - */ - dns_rdata_init(&rdata[rdcount]); - target_ft = target; - result = dns_rdata_fromtext(&rdata[rdcount], lctx->zclass, - type, lctx->lex, ictx->origin, - options, &target, - callbacks); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - continue; - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - - if (ictx->drop) { - target = target_ft; - continue; - } - - if (type == dns_rdatatype_soa && - (lctx->options & DNS_MASTER_ZONE) != 0 && - dns_name_compare(ictx->current, lctx->top) != 0) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(ictx->current, namebuf, - sizeof(namebuf)); - (*callbacks->error)(callbacks, "%s:%lu: SOA " - "record not at top of zone (%s)", - source, line, namebuf); - result = DNS_R_NOTZONETOP; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - read_till_eol = ISC_TRUE; - target = target_ft; - continue; - } else { - goto insist_and_cleanup; - } - } - - - if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_sig) - covers = dns_rdata_covers(&rdata[rdcount]); - else - covers = 0; - - if (!lctx->ttl_known && !lctx->default_ttl_known) { - if (type == dns_rdatatype_soa) { - (*callbacks->warn)(callbacks, - "%s:%lu: no TTL specified; " - "using SOA MINTTL instead", - source, line); - lctx->ttl = dns_soa_getminimum(&rdata[rdcount]); - limit_ttl(callbacks, source, line, &lctx->ttl); - lctx->default_ttl = lctx->ttl; - lctx->default_ttl_known = ISC_TRUE; - } else if ((lctx->options & DNS_MASTER_HINT) != 0) { - /* - * Zero TTL's are fine for hints. - */ - lctx->ttl = 0; - lctx->default_ttl = lctx->ttl; - lctx->default_ttl_known = ISC_TRUE; - } else { - (*callbacks->warn)(callbacks, - "%s:%lu: no TTL specified; " - "zone rejected", - source, line); - result = DNS_R_NOTTL; - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - lctx->ttl = 0; - } else { - goto insist_and_cleanup; - } - } - } else if (!explicit_ttl && lctx->default_ttl_known) { - lctx->ttl = lctx->default_ttl; - } else if (!explicit_ttl && lctx->warn_1035) { - (*callbacks->warn)(callbacks, - "%s:%lu: " - "using RFC1035 TTL semantics", - source, line); - lctx->warn_1035 = ISC_FALSE; - } - - if (type == dns_rdatatype_rrsig && lctx->warn_sigexpired) { - dns_rdata_rrsig_t sig; - result = dns_rdata_tostruct(&rdata[rdcount], &sig); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (isc_serial_lt(sig.timeexpire, lctx->now)) { - (*callbacks->warn)(callbacks, - "%s:%lu: " - "signature has expired", - source, line); - lctx->warn_sigexpired = ISC_FALSE; - } - } - - if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) && - lctx->warn_tcr && (lctx->options & DNS_MASTER_ZONE) != 0 && - (lctx->options & DNS_MASTER_SLAVE) == 0) { - (*callbacks->warn)(callbacks, "%s:%lu: old style DNSSEC " - " zone detected", source, line); - lctx->warn_tcr = ISC_FALSE; - } - - if ((lctx->options & DNS_MASTER_AGETTL) != 0) { - /* - * Adjust the TTL for $DATE. If the RR has already - * expired, ignore it. - */ - if (lctx->ttl < ttl_offset) - continue; - lctx->ttl -= ttl_offset; - } - - /* - * Find type in rdatalist. - * If it does not exist create new one and prepend to list - * as this will minimise list traversal. - */ - if (ictx->glue != NULL) - this = ISC_LIST_HEAD(glue_list); - else - this = ISC_LIST_HEAD(current_list); - - while (this != NULL) { - if (this->type == type && this->covers == covers) - break; - this = ISC_LIST_NEXT(this, link); - } - - if (this == NULL) { - if (rdlcount == rdatalist_size) { - new_rdatalist = - grow_rdatalist(rdatalist_size + RDLSZ, - rdatalist, - rdatalist_size, - ¤t_list, - &glue_list); - if (new_rdatalist == NULL) { - result = ISC_R_NOMEMORY; - goto log_and_cleanup; - } - rdatalist = new_rdatalist; - rdatalist_size += RDLSZ; - } - this = &rdatalist[rdlcount++]; - dns_rdatalist_init(this); - this->type = type; - this->covers = covers; - this->rdclass = lctx->zclass; - this->ttl = lctx->ttl; - if (ictx->glue != NULL) - ISC_LIST_INITANDPREPEND(glue_list, this, link); - else - ISC_LIST_INITANDPREPEND(current_list, this, - link); - } else if (this->ttl != lctx->ttl) { - (*callbacks->warn)(callbacks, - "%s:%lu: " - "TTL set to prior TTL (%lu)", - source, line, this->ttl); - lctx->ttl = this->ttl; - } - - if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 && - lctx->ttl > lctx->maxttl) - { - (callbacks->error)(callbacks, - "dns_master_load: %s:%lu: " - "TTL %d exceeds configured max-zone-ttl %d", - source, line, lctx->ttl, lctx->maxttl); - result = ISC_R_RANGE; - goto log_and_cleanup; - } - - ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link); - if (ictx->glue != NULL) - ictx->glue_line = line; - else - ictx->current_line = line; - rdcount++; - - /* - * We must have at least 64k as rdlen is 16 bits. - * If we don't commit everything we have so far. - */ - if ((target.length - target.used) < MINTSIZ) - COMMITALL; - next_line: - ; - } while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt)); - - /* - * Commit what has not yet been committed. - */ - result = commit(callbacks, lctx, ¤t_list, ictx->current, - source, ictx->current_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - result = commit(callbacks, lctx, &glue_list, ictx->glue, - source, ictx->glue_line); - if (MANYERRS(lctx, result)) { - SETRESULT(lctx, result); - } else if (result != ISC_R_SUCCESS) - goto insist_and_cleanup; - - if (!done) { - INSIST(lctx->done != NULL && lctx->task != NULL); - result = DNS_R_CONTINUE; - } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) { - result = lctx->result; - } else if (result == ISC_R_SUCCESS && lctx->seen_include) - result = DNS_R_SEENINCLUDE; - goto cleanup; - - log_and_cleanup: - LOGIT(result); - - insist_and_cleanup: - INSIST(result != ISC_R_SUCCESS); - - cleanup: - while ((this = ISC_LIST_HEAD(current_list)) != NULL) - ISC_LIST_UNLINK(current_list, this, link); - while ((this = ISC_LIST_HEAD(glue_list)) != NULL) - ISC_LIST_UNLINK(glue_list, this, link); - free(rdatalist); - free(rdata); - free(target_mem); - free(include_file); - free(range); - free(lhs); - free(gtype); - free(rhs); - return (result); -} - -static isc_result_t -pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { - isc_result_t result; - dns_incctx_t *ictx; - dns_incctx_t *newctx = NULL; - isc_region_t r; - - REQUIRE(master_file != NULL); - REQUIRE(DNS_LCTX_VALID(lctx)); - - ictx = lctx->inc; - lctx->seen_include = ISC_TRUE; - - result = incctx_create(origin, &newctx); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Push origin_changed. - */ - newctx->origin_changed = ictx->origin_changed; - - /* Set current domain. */ - if (ictx->glue != NULL || ictx->current != NULL) { - newctx->current_in_use = find_free_name(newctx); - newctx->current = - dns_fixedname_name(&newctx->fixed[newctx->current_in_use]); - newctx->in_use[newctx->current_in_use] = ISC_TRUE; - dns_name_toregion((ictx->glue != NULL) ? - ictx->glue : ictx->current, &r); - dns_name_fromregion(newctx->current, &r); - newctx->drop = ictx->drop; - } - - result = (lctx->openfile)(lctx, master_file); - if (result != ISC_R_SUCCESS) - goto cleanup; - newctx->parent = ictx; - lctx->inc = newctx; - - if (lctx->include_cb != NULL) - lctx->include_cb(master_file, lctx->include_arg); - return (ISC_R_SUCCESS); - - cleanup: - incctx_destroy(newctx); - return (result); -} - -/* - * Fill/check exists buffer with 'len' bytes. Track remaining bytes to be - * read when incrementally filling the buffer. - */ -static inline isc_result_t -read_and_check(isc_boolean_t do_read, isc_buffer_t *buffer, - size_t len, FILE *f, uint32_t *totallen) -{ - isc_result_t result; - - REQUIRE(totallen != NULL); - - if (do_read) { - INSIST(isc_buffer_availablelength(buffer) >= len); - result = isc_stdio_read(isc_buffer_used(buffer), 1, len, - f, NULL); - if (result != ISC_R_SUCCESS) - return (result); - isc_buffer_add(buffer, (unsigned int)len); - if (*totallen < len) - return (ISC_R_RANGE); - *totallen -= (uint32_t)len; - } else if (isc_buffer_remaininglength(buffer) < len) - return (ISC_R_RANGE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -load_header(dns_loadctx_t *lctx) { - isc_result_t result = ISC_R_SUCCESS; - dns_masterrawheader_t header; - dns_rdatacallbacks_t *callbacks; - size_t commonlen = sizeof(header.format) + sizeof(header.version); - size_t remainder; - unsigned char data[sizeof(header)]; - isc_buffer_t target; - - REQUIRE(DNS_LCTX_VALID(lctx)); - - if (lctx->format != dns_masterformat_raw && - lctx->format != dns_masterformat_map) - return (ISC_R_NOTIMPLEMENTED); - - callbacks = lctx->callbacks; - dns_master_initrawheader(&header); - - INSIST(commonlen <= sizeof(header)); - isc_buffer_init(&target, data, sizeof(data)); - - result = isc_stdio_read(data, 1, commonlen, lctx->f, NULL); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_read failed: %s", - isc_result_totext(result)); - return (result); - } - - isc_buffer_add(&target, (unsigned int)commonlen); - header.format = isc_buffer_getuint32(&target); - if (header.format != lctx->format) { - (*callbacks->error)(callbacks, "dns_master_load: " - "file format mismatch (not %s)", - lctx->format == dns_masterformat_map - ? "map" - : "raw"); - return (ISC_R_NOTIMPLEMENTED); - } - - header.version = isc_buffer_getuint32(&target); - - switch (header.version) { - case 0: - remainder = sizeof(header.dumptime); - break; - case DNS_RAWFORMAT_VERSION: - remainder = sizeof(header) - commonlen; - break; - default: - (*callbacks->error)(callbacks, - "dns_master_load: " - "unsupported file format version"); - return (ISC_R_NOTIMPLEMENTED); - } - - result = isc_stdio_read(data + commonlen, 1, remainder, lctx->f, NULL); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_read failed: %s", - isc_result_totext(result)); - return (result); - } - - isc_buffer_add(&target, (unsigned int)remainder); - header.dumptime = isc_buffer_getuint32(&target); - if (header.version == DNS_RAWFORMAT_VERSION) { - header.flags = isc_buffer_getuint32(&target); - header.sourceserial = isc_buffer_getuint32(&target); - header.lastxfrin = isc_buffer_getuint32(&target); - } - - lctx->first = ISC_FALSE; - lctx->header = header; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -openfile_map(dns_loadctx_t *lctx, const char *master_file) { - isc_result_t result; - - result = isc_stdio_open(master_file, "rb", &lctx->f); - if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_open() failed: %s", - isc_result_totext(result)); - } - - return (result); -} - -/* - * Load a map format file, using mmap() to access RBT trees directly - */ -static isc_result_t -load_map(dns_loadctx_t *lctx) { - isc_result_t result = ISC_R_SUCCESS; - dns_rdatacallbacks_t *callbacks; - - REQUIRE(DNS_LCTX_VALID(lctx)); - - callbacks = lctx->callbacks; - - if (lctx->first) { - result = load_header(lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = (*callbacks->deserialize) - (callbacks->deserialize_private, - lctx->f, sizeof(dns_masterrawheader_t)); - } - - return (result); -} - -static isc_result_t -openfile_raw(dns_loadctx_t *lctx, const char *master_file) { - isc_result_t result; - - result = isc_stdio_open(master_file, "rb", &lctx->f); - if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_stdio_open() failed: %s", - isc_result_totext(result)); - } - - return (result); -} - -static isc_result_t -load_raw(dns_loadctx_t *lctx) { - isc_result_t result = ISC_R_SUCCESS; - isc_boolean_t done = ISC_FALSE; - unsigned int loop_cnt = 0; - dns_rdatacallbacks_t *callbacks; - unsigned char namebuf[DNS_NAME_MAXWIRE]; - dns_fixedname_t fixed; - dns_name_t *name; - rdatalist_head_t head, dummy; - dns_rdatalist_t rdatalist; - dns_rdata_t *rdata = NULL; - unsigned int rdata_size = 0; - int target_size = TSIZ; - isc_buffer_t target, buf; - unsigned char *target_mem = NULL; - dns_decompress_t dctx; - - callbacks = lctx->callbacks; - dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); - - if (lctx->first) { - result = load_header(lctx); - if (result != ISC_R_SUCCESS) - return (result); - } - - ISC_LIST_INIT(head); - ISC_LIST_INIT(dummy); - - /* - * Allocate target_size of buffer space. This is greater than twice - * the maximum individual RR data size. - */ - target_mem = malloc(target_size); - if (target_mem == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - isc_buffer_init(&target, target_mem, target_size); - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - - /* - * In the following loop, we regard any error fatal regardless of - * whether "MANYERRORS" is set in the context option. This is because - * normal errors should already have been checked at creation time. - * Besides, it is very unlikely that we can recover from an error - * in this format, and so trying to continue parsing erroneous data - * does not really make sense. - */ - for (loop_cnt = 0; - (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt); - loop_cnt++) { - unsigned int i, rdcount; - uint16_t namelen; - uint32_t totallen; - size_t minlen, readlen; - isc_boolean_t sequential_read = ISC_FALSE; - - /* Read the data length */ - isc_buffer_clear(&target); - INSIST(isc_buffer_availablelength(&target) >= - sizeof(totallen)); - result = isc_stdio_read(target.base, 1, sizeof(totallen), - lctx->f, NULL); - if (result == ISC_R_EOF) { - result = ISC_R_SUCCESS; - done = ISC_TRUE; - break; - } - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_add(&target, sizeof(totallen)); - totallen = isc_buffer_getuint32(&target); - - /* - * Validation: the input data must at least contain the common - * header. - */ - minlen = sizeof(totallen) + sizeof(uint16_t) + - sizeof(uint16_t) + sizeof(uint16_t) + - sizeof(uint32_t) + sizeof(uint32_t); - if (totallen < minlen) { - result = ISC_R_RANGE; - goto cleanup; - } - totallen -= sizeof(totallen); - - isc_buffer_clear(&target); - if (totallen > isc_buffer_availablelength(&target)) { - /* - * The default buffer size should typically be large - * enough to store the entire RRset. We could try to - * allocate enough space if this is not the case, but - * it might cause a hazardous result when "totallen" - * is forged. Thus, we'd rather take an inefficient - * but robust approach in this atypical case: read - * data step by step, and commit partial data when - * necessary. Note that the buffer must be large - * enough to store the "header part", owner name, and - * at least one rdata (however large it is). - */ - sequential_read = ISC_TRUE; - readlen = minlen - sizeof(totallen); - } else { - /* - * Typical case. We can read the whole RRset at once - * with the default buffer. - */ - readlen = totallen; - } - result = isc_stdio_read(target.base, 1, readlen, - lctx->f, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_add(&target, (unsigned int)readlen); - totallen -= (uint32_t)readlen; - - /* Construct RRset headers */ - dns_rdatalist_init(&rdatalist); - rdatalist.rdclass = isc_buffer_getuint16(&target); - if (lctx->zclass != rdatalist.rdclass) { - result = DNS_R_BADCLASS; - goto cleanup; - } - rdatalist.type = isc_buffer_getuint16(&target); - rdatalist.covers = isc_buffer_getuint16(&target); - rdatalist.ttl = isc_buffer_getuint32(&target); - rdcount = isc_buffer_getuint32(&target); - if (rdcount == 0 || rdcount > 0xffff) { - result = ISC_R_RANGE; - goto cleanup; - } - INSIST(isc_buffer_consumedlength(&target) <= readlen); - - /* Owner name: length followed by name */ - result = read_and_check(sequential_read, &target, - sizeof(namelen), lctx->f, &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - namelen = isc_buffer_getuint16(&target); - if (namelen > sizeof(namebuf)) { - result = ISC_R_RANGE; - goto cleanup; - } - - result = read_and_check(sequential_read, &target, namelen, - lctx->f, &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - - isc_buffer_setactive(&target, (unsigned int)namelen); - result = dns_name_fromwire(name, &target, &dctx, 0, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 && - rdatalist.ttl > lctx->maxttl) - { - (callbacks->error)(callbacks, - "dns_master_load: " - "TTL %d exceeds configured " - "max-zone-ttl %d", - rdatalist.ttl, lctx->maxttl); - result = ISC_R_RANGE; - goto cleanup; - } - - /* Rdata contents. */ - if (rdcount > rdata_size) { - dns_rdata_t *new_rdata = NULL; - - new_rdata = grow_rdata(rdcount + RDSZ, rdata, - rdata_size, &head, - &dummy); - if (new_rdata == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - rdata_size = rdcount + RDSZ; - rdata = new_rdata; - } - - continue_read: - for (i = 0; i < rdcount; i++) { - uint16_t rdlen; - - dns_rdata_init(&rdata[i]); - - if (sequential_read && - isc_buffer_availablelength(&target) < MINTSIZ) { - unsigned int j; - - INSIST(i > 0); /* detect an infinite loop */ - - /* Partial Commit. */ - ISC_LIST_APPEND(head, &rdatalist, link); - result = commit(callbacks, lctx, &head, name, - NULL, 0); - for (j = 0; j < i; j++) { - ISC_LIST_UNLINK(rdatalist.rdata, - &rdata[j], link); - dns_rdata_reset(&rdata[j]); - } - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* Rewind the buffer and continue */ - isc_buffer_clear(&target); - - rdcount -= i; - - goto continue_read; - } - - /* rdata length */ - result = read_and_check(sequential_read, &target, - sizeof(rdlen), lctx->f, - &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - rdlen = isc_buffer_getuint16(&target); - - /* rdata */ - result = read_and_check(sequential_read, &target, - rdlen, lctx->f, &totallen); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_setactive(&target, (unsigned int)rdlen); - /* - * It is safe to have the source active region and - * the target available region be the same if - * decompression is disabled (see dctx above) and we - * are not downcasing names (options == 0). - */ - isc_buffer_init(&buf, isc_buffer_current(&target), - (unsigned int)rdlen); - result = dns_rdata_fromwire(&rdata[i], - rdatalist.rdclass, - rdatalist.type, &target, - &dctx, 0, &buf); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link); - } - - /* - * Sanity check. Still having remaining space is not - * necessarily critical, but it very likely indicates broken - * or malformed data. - */ - if (isc_buffer_remaininglength(&target) != 0 || totallen != 0) { - result = ISC_R_RANGE; - goto cleanup; - } - - ISC_LIST_APPEND(head, &rdatalist, link); - - /* Commit this RRset. rdatalist will be unlinked. */ - result = commit(callbacks, lctx, &head, name, NULL, 0); - - for (i = 0; i < rdcount; i++) { - ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link); - dns_rdata_reset(&rdata[i]); - } - - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - if (!done) { - INSIST(lctx->done != NULL && lctx->task != NULL); - result = DNS_R_CONTINUE; - } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) - result = lctx->result; - - if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL) - (*callbacks->rawdata)(callbacks->zone, &lctx->header); - - cleanup: - if (rdata != NULL) - free(rdata); - if (target_mem != NULL) - free(target_mem); - if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) { - (*callbacks->error)(callbacks, "dns_master_load: %s", - dns_result_totext(result)); - } - - return (result); -} - -isc_result_t -dns_master_loadfile(const char *master_file, dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, 0, callbacks, NULL, NULL, - dns_masterformat_text, 0)); -} - -isc_result_t -dns_master_loadfile2(const char *master_file, dns_name_t *top, - dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks, - dns_masterformat_t format) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, 0, callbacks, NULL, NULL, - format, 0)); -} - -isc_result_t -dns_master_loadfile3(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterformat_t format) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, resign, callbacks, NULL, NULL, - format, 0)); -} - -isc_result_t -dns_master_loadfile4(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, void *include_arg, - dns_masterformat_t format) -{ - return (dns_master_loadfile5(master_file, top, origin, zclass, - options, resign, callbacks, - include_cb, include_arg, - format, 0)); -} - -isc_result_t -dns_master_loadfile5(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - dns_masterincludecb_t include_cb, void *include_arg, - dns_masterformat_t format, - dns_ttl_t maxttl) -{ - dns_loadctx_t *lctx = NULL; - isc_result_t result; - - result = loadctx_create(format, options, resign, top, zclass, - origin, callbacks, NULL, NULL, NULL, - include_cb, include_arg, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - lctx->maxttl = maxttl; - - result = (lctx->openfile)(lctx, master_file); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadfileinc(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp) -{ - return (dns_master_loadfileinc4(master_file, top, origin, zclass, - options, 0, callbacks, task, done, - done_arg, lctxp, NULL, NULL, - dns_masterformat_text)); -} - -isc_result_t -dns_master_loadfileinc2(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp, - dns_masterformat_t format) -{ - return (dns_master_loadfileinc4(master_file, top, origin, zclass, - options, 0, callbacks, task, done, - done_arg, lctxp, NULL, NULL, - format)); -} - -isc_result_t -dns_master_loadfileinc3(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp, - dns_masterformat_t format) -{ - return (dns_master_loadfileinc4(master_file, top, origin, zclass, - options, resign, callbacks, task, - done, done_arg, lctxp, NULL, NULL, - format)); -} - -isc_result_t -dns_master_loadfileinc4(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp, - dns_masterincludecb_t include_cb, void *include_arg, - dns_masterformat_t format) -{ - options &= ~DNS_MASTER_CHECKTTL; - return (dns_master_loadfileinc5(master_file, top, origin, zclass, - options, resign, callbacks, task, - done, done_arg, lctxp, include_cb, - include_arg, format, 0)); -} - -isc_result_t -dns_master_loadfileinc5(const char *master_file, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, uint32_t resign, - dns_rdatacallbacks_t *callbacks, - isc_task_t *task, dns_loaddonefunc_t done, - void *done_arg, dns_loadctx_t **lctxp, - dns_masterincludecb_t include_cb, void *include_arg, - dns_masterformat_t format, - uint32_t maxttl) -{ - dns_loadctx_t *lctx = NULL; - isc_result_t result; - - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(format, options, resign, top, zclass, - origin, callbacks, task, done, done_arg, - include_cb, include_arg, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - lctx->maxttl = maxttl; - - result = (lctx->openfile)(lctx, master_file); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(stream != NULL); - - result = loadctx_create(dns_masterformat_text, options, 0, top, - zclass, origin, callbacks, NULL, NULL, NULL, - NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_lex_openstream(lctx->lex, stream); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - cleanup: - if (lctx != NULL) - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin, - dns_rdataclass_t zclass, unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(stream != NULL); - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(dns_masterformat_text, options, 0, top, - zclass, origin, callbacks, task, done, - done_arg, NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = isc_lex_openstream(lctx->lex, stream); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - cleanup: - if (lctx != NULL) - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(buffer != NULL); - - result = loadctx_create(dns_masterformat_text, options, 0, top, - zclass, origin, callbacks, NULL, NULL, NULL, - NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_lex_openbuffer(lctx->lex, buffer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(buffer != NULL); - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(dns_masterformat_text, options, 0, top, - zclass, origin, callbacks, task, done, - done_arg, NULL, NULL, NULL, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_lex_openbuffer(lctx->lex, buffer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - cleanup: - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(lex != NULL); - - result = loadctx_create(dns_masterformat_text, options, 0, top, - zclass, origin, callbacks, NULL, NULL, NULL, - NULL, NULL, lex, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = (lctx->load)(lctx); - INSIST(result != DNS_R_CONTINUE); - - dns_loadctx_detach(&lctx); - return (result); -} - -isc_result_t -dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top, - dns_name_t *origin, dns_rdataclass_t zclass, - unsigned int options, - dns_rdatacallbacks_t *callbacks, isc_task_t *task, - dns_loaddonefunc_t done, void *done_arg, - dns_loadctx_t **lctxp) -{ - isc_result_t result; - dns_loadctx_t *lctx = NULL; - - REQUIRE(lex != NULL); - REQUIRE(task != NULL); - REQUIRE(done != NULL); - - result = loadctx_create(dns_masterformat_text, options, 0, top, - zclass, origin, callbacks, task, done, - done_arg, NULL, NULL, lex, &lctx); - if (result != ISC_R_SUCCESS) - return (result); - - result = task_send(lctx); - if (result == ISC_R_SUCCESS) { - dns_loadctx_attach(lctx, lctxp); - return (DNS_R_CONTINUE); - } - - dns_loadctx_detach(&lctx); - return (result); -} - -/* - * Grow the slab of dns_rdatalist_t structures. - * Re-link glue and current list. - */ -static dns_rdatalist_t * -grow_rdatalist(int new_len, dns_rdatalist_t *oldlist, int old_len, - rdatalist_head_t *current, rdatalist_head_t *glue) -{ - dns_rdatalist_t *newlist; - int rdlcount = 0; - ISC_LIST(dns_rdatalist_t) save; - dns_rdatalist_t *this; - - newlist = malloc(new_len * sizeof(*newlist)); - if (newlist == NULL) - return (NULL); - - ISC_LIST_INIT(save); - while ((this = ISC_LIST_HEAD(*current)) != NULL) { - ISC_LIST_UNLINK(*current, this, link); - ISC_LIST_APPEND(save, this, link); - } - while ((this = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, this, link); - INSIST(rdlcount < new_len); - newlist[rdlcount] = *this; - ISC_LIST_APPEND(*current, &newlist[rdlcount], link); - rdlcount++; - } - - ISC_LIST_INIT(save); - while ((this = ISC_LIST_HEAD(*glue)) != NULL) { - ISC_LIST_UNLINK(*glue, this, link); - ISC_LIST_APPEND(save, this, link); - } - while ((this = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, this, link); - INSIST(rdlcount < new_len); - newlist[rdlcount] = *this; - ISC_LIST_APPEND(*glue, &newlist[rdlcount], link); - rdlcount++; - } - - INSIST(rdlcount == old_len); - if (oldlist != NULL) - free(oldlist); - return (newlist); -} - -/* - * Grow the slab of rdata structs. - * Re-link the current and glue chains. - */ -static dns_rdata_t * -grow_rdata(int new_len, dns_rdata_t *oldlist, int old_len, - rdatalist_head_t *current, rdatalist_head_t *glue) -{ - dns_rdata_t *newlist; - int rdcount = 0; - ISC_LIST(dns_rdata_t) save; - dns_rdatalist_t *this; - dns_rdata_t *rdata; - - newlist = malloc(new_len * sizeof(*newlist)); - if (newlist == NULL) - return (NULL); - memset(newlist, 0, new_len * sizeof(*newlist)); - - /* - * Copy current relinking. - */ - this = ISC_LIST_HEAD(*current); - while (this != NULL) { - ISC_LIST_INIT(save); - while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { - ISC_LIST_UNLINK(this->rdata, rdata, link); - ISC_LIST_APPEND(save, rdata, link); - } - while ((rdata = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, rdata, link); - INSIST(rdcount < new_len); - newlist[rdcount] = *rdata; - ISC_LIST_APPEND(this->rdata, &newlist[rdcount], link); - rdcount++; - } - this = ISC_LIST_NEXT(this, link); - } - - /* - * Copy glue relinking. - */ - this = ISC_LIST_HEAD(*glue); - while (this != NULL) { - ISC_LIST_INIT(save); - while ((rdata = ISC_LIST_HEAD(this->rdata)) != NULL) { - ISC_LIST_UNLINK(this->rdata, rdata, link); - ISC_LIST_APPEND(save, rdata, link); - } - while ((rdata = ISC_LIST_HEAD(save)) != NULL) { - ISC_LIST_UNLINK(save, rdata, link); - INSIST(rdcount < new_len); - newlist[rdcount] = *rdata; - ISC_LIST_APPEND(this->rdata, &newlist[rdcount], link); - rdcount++; - } - this = ISC_LIST_NEXT(this, link); - } - INSIST(rdcount == old_len || rdcount == 0); - if (oldlist != NULL) - free(oldlist); - return (newlist); -} - -static uint32_t -resign_fromlist(dns_rdatalist_t *this, dns_loadctx_t *lctx) { - dns_rdata_t *rdata; - dns_rdata_rrsig_t sig; - uint32_t when; - - rdata = ISC_LIST_HEAD(this->rdata); - INSIST(rdata != NULL); - (void)dns_rdata_tostruct(rdata, &sig); - if (isc_serial_gt(sig.timesigned, lctx->now)) - when = lctx->now; - else - when = sig.timeexpire - lctx->resign; - - rdata = ISC_LIST_NEXT(rdata, link); - while (rdata != NULL) { - (void)dns_rdata_tostruct(rdata, &sig); - if (isc_serial_gt(sig.timesigned, lctx->now)) - when = lctx->now; - else if (sig.timeexpire - lctx->resign < when) - when = sig.timeexpire - lctx->resign; - rdata = ISC_LIST_NEXT(rdata, link); - } - return (when); -} - -/* - * Convert each element from a rdatalist_t to rdataset then call commit. - * Unlink each element as we go. - */ - -static isc_result_t -commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx, - rdatalist_head_t *head, dns_name_t *owner, - const char *source, unsigned int line) -{ - dns_rdatalist_t *this; - dns_rdataset_t dataset; - isc_result_t result; - char namebuf[DNS_NAME_FORMATSIZE]; - void (*error)(struct dns_rdatacallbacks *, const char *, ...); - - this = ISC_LIST_HEAD(*head); - error = callbacks->error; - - if (this == NULL) - return (ISC_R_SUCCESS); - do { - dns_rdataset_init(&dataset); - RUNTIME_CHECK(dns_rdatalist_tordataset(this, &dataset) - == ISC_R_SUCCESS); - dataset.trust = dns_trust_ultimate; - /* - * If this is a secure dynamic zone set the re-signing time. - */ - if (dataset.type == dns_rdatatype_rrsig && - (lctx->options & DNS_MASTER_RESIGN) != 0) { - dataset.attributes |= DNS_RDATASETATTR_RESIGN; - dataset.resign = resign_fromlist(this, lctx); - } - result = ((*callbacks->add)(callbacks->add_private, owner, - &dataset)); - if (result == ISC_R_NOMEMORY) { - (*error)(callbacks, "dns_master_load: %s", - dns_result_totext(result)); - } else if (result != ISC_R_SUCCESS) { - dns_name_format(owner, namebuf, sizeof(namebuf)); - if (source != NULL) { - (*error)(callbacks, "%s: %s:%lu: %s: %s", - "dns_master_load", source, line, - namebuf, dns_result_totext(result)); - } else { - (*error)(callbacks, "%s: %s: %s", - "dns_master_load", namebuf, - dns_result_totext(result)); - } - } - if (MANYERRS(lctx, result)) - SETRESULT(lctx, result); - else if (result != ISC_R_SUCCESS) - return (result); - ISC_LIST_UNLINK(*head, this, link); - this = ISC_LIST_HEAD(*head); - } while (this != NULL); - return (ISC_R_SUCCESS); -} - -/* - * Returns ISC_TRUE if one of the NS rdata's contains 'owner'. - */ - -static isc_boolean_t -is_glue(rdatalist_head_t *head, dns_name_t *owner) { - dns_rdatalist_t *this; - dns_rdata_t *rdata; - isc_region_t region; - dns_name_t name; - - /* - * Find NS rrset. - */ - this = ISC_LIST_HEAD(*head); - while (this != NULL) { - if (this->type == dns_rdatatype_ns) - break; - this = ISC_LIST_NEXT(this, link); - } - if (this == NULL) - return (ISC_FALSE); - - rdata = ISC_LIST_HEAD(this->rdata); - while (rdata != NULL) { - dns_name_init(&name, NULL); - dns_rdata_toregion(rdata, ®ion); - dns_name_fromregion(&name, ®ion); - if (dns_name_compare(&name, owner) == 0) - return (ISC_TRUE); - rdata = ISC_LIST_NEXT(rdata, link); - } - return (ISC_FALSE); -} - -static void -load_quantum(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_loadctx_t *lctx; - - REQUIRE(event != NULL); - lctx = event->ev_arg; - REQUIRE(DNS_LCTX_VALID(lctx)); - - if (lctx->canceled) - result = ISC_R_CANCELED; - else - result = (lctx->load)(lctx); - if (result == DNS_R_CONTINUE) { - event->ev_arg = lctx; - isc_task_send(task, &event); - } else { - (lctx->done)(lctx->done_arg, result); - isc_event_free(&event); - dns_loadctx_detach(&lctx); - } -} - -static isc_result_t -task_send(dns_loadctx_t *lctx) { - isc_event_t *event; - - event = isc_event_allocate(NULL, - DNS_EVENT_MASTERQUANTUM, - load_quantum, lctx, sizeof(*event)); - if (event == NULL) - return (ISC_R_NOMEMORY); - isc_task_send(lctx->task, &event); - return (ISC_R_SUCCESS); -} - -void -dns_loadctx_cancel(dns_loadctx_t *lctx) { - REQUIRE(DNS_LCTX_VALID(lctx)); - - lctx->canceled = ISC_TRUE; -} - -void -dns_master_initrawheader(dns_masterrawheader_t *header) { - memset(header, 0, sizeof(dns_masterrawheader_t)); -} diff --git a/usr.sbin/bind/lib/dns/masterdump.c b/usr.sbin/bind/lib/dns/masterdump.c index 0b15dcf05ad..44f6acad8a9 100644 --- a/usr.sbin/bind/lib/dns/masterdump.c +++ b/usr.sbin/bind/lib/dns/masterdump.c @@ -38,7 +38,7 @@ #include <dns/fixedname.h> #include <dns/lib.h> #include <dns/log.h> -#include <dns/master.h> + #include <dns/masterdump.h> #include <dns/ncache.h> #include <dns/rdata.h> |