1999-01-28 05:03:25 +00:00
|
|
|
/*
|
2018-02-23 09:53:12 +01:00
|
|
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2000-08-01 01:33:37 +00:00
|
|
|
*
|
2016-06-27 14:56:38 +10:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
2020-09-14 16:20:40 -07:00
|
|
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
2018-02-23 09:53:12 +01:00
|
|
|
*
|
|
|
|
* See the COPYRIGHT file distributed with this work for additional
|
|
|
|
* information regarding copyright ownership.
|
1999-01-28 05:03:25 +00:00
|
|
|
*/
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*! \file */
|
1999-01-28 05:03:25 +00:00
|
|
|
|
2018-03-28 14:19:37 +02:00
|
|
|
#include <inttypes.h>
|
2018-04-17 08:29:14 -07:00
|
|
|
#include <stdbool.h>
|
2018-03-28 14:19:37 +02:00
|
|
|
|
2019-05-20 16:43:32 +02:00
|
|
|
#include <isc/atomic.h>
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <isc/event.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <isc/lex.h>
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <isc/magic.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <isc/mem.h>
|
2000-09-19 01:47:53 +00:00
|
|
|
#include <isc/print.h>
|
2019-05-20 16:43:32 +02:00
|
|
|
#include <isc/refcount.h>
|
2021-10-04 17:14:53 +02:00
|
|
|
#include <isc/result.h>
|
2002-11-12 19:50:51 +00:00
|
|
|
#include <isc/serial.h>
|
2005-06-20 01:05:33 +00:00
|
|
|
#include <isc/stdio.h>
|
1999-06-08 10:35:23 +00:00
|
|
|
#include <isc/stdtime.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <isc/string.h>
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <isc/task.h>
|
2000-04-28 01:12:23 +00:00
|
|
|
#include <isc/util.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <dns/callbacks.h>
|
2000-08-15 03:33:52 +00:00
|
|
|
#include <dns/events.h>
|
|
|
|
#include <dns/fixedname.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <dns/master.h>
|
2000-05-08 14:38:29 +00:00
|
|
|
#include <dns/name.h>
|
|
|
|
#include <dns/rdata.h>
|
|
|
|
#include <dns/rdataclass.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <dns/rdatalist.h>
|
|
|
|
#include <dns/rdataset.h>
|
2001-07-24 18:49:06 +00:00
|
|
|
#include <dns/rdatastruct.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
#include <dns/rdatatype.h>
|
2001-05-22 01:44:37 +00:00
|
|
|
#include <dns/soa.h>
|
1999-06-08 10:35:23 +00:00
|
|
|
#include <dns/time.h>
|
1999-11-02 13:07:53 +00:00
|
|
|
#include <dns/ttl.h>
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*!
|
2020-02-12 13:59:18 +01:00
|
|
|
* Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ)
|
|
|
|
* structures by these sizes when we need to.
|
1999-03-22 06:21:29 +00:00
|
|
|
*
|
2005-04-27 04:57:32 +00:00
|
|
|
*/
|
|
|
|
/*% RDLSZ reflects the number of different types with the same name expected. */
|
|
|
|
#define RDLSZ 32
|
|
|
|
/*%
|
1999-03-22 06:21:29 +00:00
|
|
|
* RDSZ reflects the number of rdata expected at a give name that can fit into
|
2000-08-01 01:33:37 +00:00
|
|
|
* 64k.
|
1999-03-22 06:21:29 +00:00
|
|
|
*/
|
|
|
|
#define RDSZ 512
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define NBUFS 4
|
1999-03-22 06:21:29 +00:00
|
|
|
#define MAXWIRESZ 255
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
1999-03-24 00:29:54 +00:00
|
|
|
* Target buffer size and minimum target size.
|
2000-02-02 00:36:34 +00:00
|
|
|
* MINTSIZ must be big enough to hold the largest rdata record.
|
2005-04-27 04:57:32 +00:00
|
|
|
* \brief
|
1999-03-22 06:21:29 +00:00
|
|
|
* TSIZ >= MINTSIZ
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
#define TSIZ (128 * 1024)
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
1999-03-22 06:21:29 +00:00
|
|
|
* max message size - header - root - type - class - ttl - rdlen
|
|
|
|
*/
|
2012-08-16 09:42:14 +10:00
|
|
|
#define MINTSIZ DNS_RDATA_MAXLENGTH
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2000-08-01 01:33:37 +00:00
|
|
|
* Size for tokens in the presentation format,
|
1999-10-26 18:05:23 +00:00
|
|
|
* The largest tokens are the base64 blocks in KEY and CERT records,
|
2000-08-01 01:33:37 +00:00
|
|
|
* Largest key allowed is about 1372 bytes but
|
2000-03-22 17:59:13 +00:00
|
|
|
* there is no fixed upper bound on CERT records.
|
|
|
|
* 2K is too small for some X.509s, 8K is overkill.
|
1999-10-26 18:05:23 +00:00
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
#define TOKENSIZ (8 * 1024)
|
1999-03-22 06:21:29 +00:00
|
|
|
|
2008-11-30 23:49:21 +00:00
|
|
|
/*%
|
|
|
|
* Buffers sizes for $GENERATE.
|
|
|
|
*/
|
|
|
|
#define DNS_MASTER_LHS 2048
|
|
|
|
#define DNS_MASTER_RHS MINTSIZ
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define CHECKNAMESFAIL(x) (((x)&DNS_MASTER_CHECKNAMESFAIL) != 0)
|
2014-04-24 18:58:03 +10:00
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t;
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
typedef struct dns_incctx dns_incctx_t;
|
|
|
|
|
2005-04-27 04:57:32 +00:00
|
|
|
/*%
|
2001-01-30 13:23:32 +00:00
|
|
|
* Master file load state.
|
2000-03-22 19:27:51 +00:00
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
struct dns_loadctx {
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int magic;
|
|
|
|
isc_mem_t *mctx;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_masterformat_t format;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_rdatacallbacks_t *callbacks;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_task_t *task;
|
|
|
|
dns_loaddonefunc_t done;
|
|
|
|
void *done_arg;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
/* Common methods */
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_result_t (*openfile)(dns_loadctx_t *lctx, const char *filename);
|
|
|
|
isc_result_t (*load)(dns_loadctx_t *lctx);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2014-02-18 23:26:50 -08:00
|
|
|
/* Members used by all formats */
|
2020-02-12 13:59:18 +01:00
|
|
|
uint32_t maxttl;
|
2014-02-18 23:26:50 -08:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
/* Members specific to the text format: */
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_lex_t *lex;
|
|
|
|
bool keep_lex;
|
|
|
|
unsigned int options;
|
|
|
|
bool ttl_known;
|
|
|
|
bool default_ttl_known;
|
|
|
|
bool warn_1035;
|
|
|
|
bool warn_tcr;
|
|
|
|
bool warn_sigexpired;
|
|
|
|
bool seen_include;
|
|
|
|
uint32_t ttl;
|
|
|
|
uint32_t default_ttl;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_rdataclass_t zclass;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_fixedname_t fixed_top;
|
|
|
|
dns_name_t *top; /*%< top of zone */
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
/* Members specific to the raw format: */
|
2020-02-13 14:44:37 -08:00
|
|
|
FILE *f;
|
|
|
|
bool first;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_masterrawheader_t header;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
/* Which fixed buffers we are using? */
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int loop_cnt; /*% records per quantum,
|
|
|
|
* 0 => all. */
|
|
|
|
isc_result_t result;
|
2019-05-20 16:43:32 +02:00
|
|
|
|
|
|
|
/* Atomic */
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_refcount_t references;
|
2020-02-13 14:44:37 -08:00
|
|
|
atomic_bool canceled;
|
2019-05-20 16:43:32 +02:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
/* locked by lock */
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_incctx_t *inc;
|
2020-02-13 14:44:37 -08:00
|
|
|
uint32_t resign;
|
2020-02-12 13:59:18 +01:00
|
|
|
isc_stdtime_t now;
|
2012-01-31 03:35:41 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_masterincludecb_t include_cb;
|
2020-02-13 14:44:37 -08:00
|
|
|
void *include_arg;
|
2001-02-14 13:14:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct dns_incctx {
|
2020-02-13 14:44:37 -08:00
|
|
|
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;
|
|
|
|
bool origin_changed;
|
|
|
|
bool drop;
|
|
|
|
unsigned int glue_line;
|
|
|
|
unsigned int current_line;
|
2000-08-15 03:33:52 +00:00
|
|
|
};
|
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
#define DNS_LCTX_MAGIC ISC_MAGIC('L', 'c', 't', 'x')
|
2001-02-14 13:14:50 +00:00
|
|
|
#define DNS_LCTX_VALID(lctx) ISC_MAGIC_VALID(lctx, DNS_LCTX_MAGIC)
|
2000-03-22 19:27:51 +00:00
|
|
|
|
2002-01-21 01:07:32 +00:00
|
|
|
#define DNS_AS_STR(t) ((t).value.as_textregion.base)
|
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
openfile_text(dns_loadctx_t *lctx, const char *master_file);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
load_text(dns_loadctx_t *lctx);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
openfile_raw(dns_loadctx_t *lctx, const char *master_file);
|
2012-06-20 14:13:12 -05:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
load_raw(dns_loadctx_t *lctx);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx);
|
2000-05-08 14:38:29 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
commit(dns_rdatacallbacks_t *, dns_loadctx_t *, rdatalist_head_t *,
|
|
|
|
dns_name_t *, const char *, unsigned int);
|
2000-05-08 14:38:29 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static bool
|
|
|
|
is_glue(rdatalist_head_t *, dns_name_t *);
|
2000-05-08 14:38:29 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static dns_rdatalist_t *
|
|
|
|
grow_rdatalist(int, dns_rdatalist_t *, int, rdatalist_head_t *,
|
|
|
|
rdatalist_head_t *, isc_mem_t *mctx);
|
2000-05-08 14:38:29 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static dns_rdata_t *
|
|
|
|
grow_rdata(int, dns_rdata_t *, int, rdatalist_head_t *, rdatalist_head_t *,
|
|
|
|
isc_mem_t *);
|
2000-05-08 14:38:29 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
load_quantum(isc_task_t *task, isc_event_t *event);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static isc_result_t
|
|
|
|
task_send(dns_loadctx_t *lctx);
|
2000-09-05 03:35:24 +00:00
|
|
|
|
2020-02-14 08:14:03 +01:00
|
|
|
static void
|
|
|
|
loadctx_destroy(dns_loadctx_t *lctx);
|
2000-09-05 03:35:24 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define GETTOKENERR(lexer, options, token, eol, err) \
|
|
|
|
do { \
|
2000-01-22 00:28:00 +00:00
|
|
|
result = gettoken(lexer, options, token, eol, callbacks); \
|
2020-02-12 13:59:18 +01:00
|
|
|
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 = 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 = true; \
|
|
|
|
goto next_line; \
|
|
|
|
} else \
|
|
|
|
goto log_and_cleanup; \
|
|
|
|
} \
|
2000-07-10 05:15:04 +00:00
|
|
|
} while (0)
|
2014-10-05 08:29:34 +11:00
|
|
|
#define GETTOKEN(lexer, options, token, eol) \
|
2020-02-12 13:59:18 +01:00
|
|
|
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; \
|
2000-08-15 03:33:52 +00:00
|
|
|
} while (0)
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define WARNUNEXPECTEDEOF(lexer) \
|
|
|
|
do { \
|
|
|
|
if (isc_lex_isfile(lexer)) \
|
|
|
|
(*callbacks->warn)(callbacks, \
|
|
|
|
"%s: file does not end with " \
|
|
|
|
"newline", \
|
|
|
|
source); \
|
2000-07-10 05:15:04 +00:00
|
|
|
} while (0)
|
1999-03-23 00:04:01 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define EXPECTEOL \
|
|
|
|
do { \
|
|
|
|
GETTOKEN(lctx->lex, 0, &token, true); \
|
|
|
|
if (token.type != isc_tokentype_eol) { \
|
2001-02-14 13:14:50 +00:00
|
|
|
isc_lex_ungettoken(lctx->lex, &token); \
|
2020-02-12 13:59:18 +01:00
|
|
|
result = DNS_R_EXTRATOKEN; \
|
|
|
|
if (MANYERRS(lctx, result)) { \
|
|
|
|
SETRESULT(lctx, result); \
|
|
|
|
LOGIT(result); \
|
|
|
|
read_till_eol = true; \
|
|
|
|
break; \
|
|
|
|
} else if (result != ISC_R_SUCCESS) \
|
|
|
|
goto log_and_cleanup; \
|
|
|
|
} \
|
2001-02-09 14:34:52 +00:00
|
|
|
} while (0)
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define MANYERRS(lctx, result) \
|
|
|
|
((result != ISC_R_SUCCESS) && (result != ISC_R_IOERROR) && \
|
|
|
|
((lctx)->options & DNS_MASTER_MANYERRORS) != 0)
|
2001-01-09 00:43:24 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#define SETRESULT(lctx, r) \
|
|
|
|
do { \
|
|
|
|
if ((lctx)->result == ISC_R_SUCCESS) \
|
|
|
|
(lctx)->result = r; \
|
|
|
|
} while (0)
|
2004-02-27 20:41:51 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
#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, \
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result)); \
|
2020-02-12 13:59:18 +01:00
|
|
|
else \
|
|
|
|
LOGIT(result)
|
|
|
|
|
|
|
|
#define LOGIT(result) \
|
|
|
|
if (result == ISC_R_NOMEMORY) \
|
|
|
|
(*callbacks->error)(callbacks, "dns_master_load: %s", \
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result)); \
|
2020-02-12 13:59:18 +01:00
|
|
|
else \
|
|
|
|
(*callbacks->error)(callbacks, "%s: %s:%lu: %s", \
|
|
|
|
"dns_master_load", source, line, \
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result))
|
2020-02-12 13:59:18 +01:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
static unsigned char in_addr_arpa_data[] = "\007IN-ADDR\004ARPA";
|
|
|
|
static unsigned char in_addr_arpa_offsets[] = { 0, 8, 13 };
|
2017-11-13 16:58:12 +11:00
|
|
|
static dns_name_t const in_addr_arpa =
|
|
|
|
DNS_NAME_INITABSOLUTE(in_addr_arpa_data, in_addr_arpa_offsets);
|
2004-02-27 20:41:51 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
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);
|
2004-02-27 20:41:51 +00:00
|
|
|
|
2020-02-13 14:44:37 -08:00
|
|
|
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);
|
2004-02-27 20:41:51 +00:00
|
|
|
|
2020-04-28 15:37:19 +10:00
|
|
|
static inline bool
|
|
|
|
dns_master_isprimary(dns_loadctx_t *lctx) {
|
|
|
|
return ((lctx->options & DNS_MASTER_ZONE) != 0 &&
|
2021-10-05 11:28:24 +02:00
|
|
|
(lctx->options & DNS_MASTER_SECONDARY) == 0 &&
|
2020-04-28 15:37:19 +10:00
|
|
|
(lctx->options & DNS_MASTER_KEY) == 0);
|
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static inline isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, bool eol,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatacallbacks_t *callbacks) {
|
1999-03-23 00:04:01 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
1999-06-09 11:56:45 +00:00
|
|
|
options |= ISC_LEXOPT_EOL | ISC_LEXOPT_EOF | ISC_LEXOPT_DNSMULTILINE |
|
2020-02-12 13:59:18 +01:00
|
|
|
ISC_LEXOPT_ESCAPE;
|
1999-03-23 00:04:01 +00:00
|
|
|
result = isc_lex_gettoken(lex, options, token);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
switch (result) {
|
|
|
|
case ISC_R_NOMEMORY:
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_NOMEMORY);
|
1999-03-23 00:04:01 +00:00
|
|
|
default:
|
2001-01-04 23:43:53 +00:00
|
|
|
(*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);
|
1999-03-23 00:04:01 +00:00
|
|
|
}
|
|
|
|
/*NOTREACHED*/
|
|
|
|
}
|
2020-02-13 18:16:57 +01:00
|
|
|
if (eol != true) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (token->type == isc_tokentype_eol ||
|
|
|
|
token->type == isc_tokentype_eof) {
|
2020-02-13 18:16:57 +01:00
|
|
|
{
|
|
|
|
unsigned long int line;
|
2020-02-13 14:44:37 -08:00
|
|
|
const char *what;
|
|
|
|
const char *file;
|
2020-02-13 18:16:57 +01:00
|
|
|
file = isc_lex_getsourcename(lex);
|
|
|
|
line = isc_lex_getsourceline(lex);
|
|
|
|
if (token->type == isc_tokentype_eol) {
|
|
|
|
line--;
|
|
|
|
what = "line";
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2020-02-13 18:16:57 +01:00
|
|
|
what = "file";
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-13 18:16:57 +01:00
|
|
|
(*callbacks->error)(callbacks,
|
|
|
|
"dns_master_load: %s:%lu: "
|
|
|
|
"unexpected end of %s",
|
|
|
|
file, line, what);
|
|
|
|
return (ISC_R_UNEXPECTEDEND);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-13 18:16:57 +01:00
|
|
|
}
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-03-23 00:04:01 +00:00
|
|
|
}
|
1999-01-28 05:03:25 +00:00
|
|
|
|
2000-09-05 03:35:24 +00:00
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) {
|
2000-09-05 03:35:24 +00:00
|
|
|
REQUIRE(target != NULL && *target == NULL);
|
|
|
|
REQUIRE(DNS_LCTX_VALID(source));
|
|
|
|
|
2019-05-20 16:43:32 +02:00
|
|
|
isc_refcount_increment(&source->references);
|
2000-09-05 03:35:24 +00:00
|
|
|
|
|
|
|
*target = source;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_loadctx_detach(dns_loadctx_t **lctxp) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
REQUIRE(lctxp != NULL);
|
|
|
|
lctx = *lctxp;
|
2019-05-20 16:43:32 +02:00
|
|
|
*lctxp = NULL;
|
2020-02-08 04:37:54 -08:00
|
|
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
2000-09-05 03:35:24 +00:00
|
|
|
|
2019-05-20 16:43:32 +02:00
|
|
|
if (isc_refcount_decrement(&lctx->references) == 1) {
|
2001-02-14 13:14:50 +00:00
|
|
|
loadctx_destroy(lctx);
|
2019-05-20 16:43:32 +02:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_incctx_t *parent;
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
again:
|
2001-02-14 13:14:50 +00:00
|
|
|
parent = ictx->parent;
|
|
|
|
ictx->parent = NULL;
|
|
|
|
|
2001-11-12 19:05:39 +00:00
|
|
|
isc_mem_put(mctx, ictx, sizeof(*ictx));
|
2001-02-14 13:14:50 +00:00
|
|
|
|
|
|
|
if (parent != NULL) {
|
|
|
|
ictx = parent;
|
|
|
|
goto again;
|
|
|
|
}
|
2000-09-05 03:35:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
loadctx_destroy(dns_loadctx_t *lctx) {
|
2001-02-14 13:14:50 +00:00
|
|
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2019-07-23 08:27:30 -04:00
|
|
|
isc_refcount_destroy(&lctx->references);
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->magic = 0;
|
2019-07-23 08:27:30 -04:00
|
|
|
if (lctx->inc != NULL) {
|
2001-02-14 13:14:50 +00:00
|
|
|
incctx_destroy(lctx->mctx, lctx->inc);
|
2019-07-23 08:27:30 -04:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
if (lctx->f != NULL) {
|
2019-07-23 08:27:30 -04:00
|
|
|
isc_result_t result = isc_stdio_close(lctx->f);
|
2005-06-20 01:05:33 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
|
|
|
"isc_stdio_close() failed: %s",
|
|
|
|
isc_result_totext(result));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-11-30 03:14:50 +00:00
|
|
|
/* isc_lex_destroy() will close all open streams */
|
2019-07-23 08:27:30 -04:00
|
|
|
if (lctx->lex != NULL && !lctx->keep_lex) {
|
2001-02-14 13:14:50 +00:00
|
|
|
isc_lex_destroy(&lctx->lex);
|
2019-07-23 08:27:30 -04:00
|
|
|
}
|
2001-11-30 03:14:50 +00:00
|
|
|
|
2019-07-23 17:16:57 -04:00
|
|
|
if (lctx->task != NULL) {
|
2001-02-14 13:14:50 +00:00
|
|
|
isc_task_detach(&lctx->task);
|
2019-07-23 17:16:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
isc_mem_putanddetach(&lctx->mctx, lctx, sizeof(*lctx));
|
2000-08-15 03:33:52 +00:00
|
|
|
}
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_incctx_t *ictx;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_region_t r;
|
|
|
|
int i;
|
2001-02-14 13:14:50 +00:00
|
|
|
|
2001-11-12 19:05:39 +00:00
|
|
|
ictx = isc_mem_get(mctx, sizeof(*ictx));
|
2001-02-14 13:14:50 +00:00
|
|
|
|
|
|
|
for (i = 0; i < NBUFS; i++) {
|
|
|
|
dns_fixedname_init(&ictx->fixed[i]);
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->in_use[i] = false;
|
2001-02-14 13:14:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ictx->origin_in_use = 0;
|
|
|
|
ictx->origin = dns_fixedname_name(&ictx->fixed[ictx->origin_in_use]);
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->in_use[ictx->origin_in_use] = true;
|
2001-02-14 13:14:50 +00:00
|
|
|
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;
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->drop = false;
|
2001-05-09 03:41:47 +00:00
|
|
|
ictx->glue_line = 0;
|
|
|
|
ictx->current_line = 0;
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->origin_changed = true;
|
2001-02-14 13:14:50 +00:00
|
|
|
|
|
|
|
*ictxp = ictx;
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
static isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, 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,
|
2012-01-31 03:35:41 +00:00
|
|
|
dns_masterincludecb_t include_cb, void *include_arg,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_lex_t *lex, dns_loadctx_t **lctxp) {
|
|
|
|
dns_loadctx_t *lctx;
|
|
|
|
isc_result_t result;
|
|
|
|
isc_region_t r;
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_lexspecials_t specials;
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
REQUIRE(lctxp != NULL && *lctxp == NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
REQUIRE(callbacks != NULL);
|
|
|
|
REQUIRE(callbacks->add != NULL);
|
|
|
|
REQUIRE(callbacks->error != NULL);
|
|
|
|
REQUIRE(callbacks->warn != NULL);
|
|
|
|
REQUIRE(mctx != NULL);
|
|
|
|
REQUIRE(dns_name_isabsolute(top));
|
|
|
|
REQUIRE(dns_name_isabsolute(origin));
|
|
|
|
REQUIRE((task == NULL && done == NULL) ||
|
2000-09-18 06:50:35 +00:00
|
|
|
(task != NULL && done != NULL));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx = isc_mem_get(mctx, sizeof(*lctx));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->inc = NULL;
|
|
|
|
result = incctx_create(mctx, origin, &lctx->inc);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup_ctx;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
|
2014-02-18 23:26:50 -08:00
|
|
|
lctx->maxttl = 0;
|
2014-02-20 10:53:11 +11:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
lctx->format = format;
|
|
|
|
switch (format) {
|
|
|
|
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;
|
2018-06-04 13:41:09 +02:00
|
|
|
default:
|
|
|
|
INSIST(0);
|
|
|
|
ISC_UNREACHABLE();
|
2005-06-20 01:05:33 +00:00
|
|
|
}
|
|
|
|
|
2002-02-21 00:56:14 +00:00
|
|
|
if (lex != NULL) {
|
2002-02-21 00:45:11 +00:00
|
|
|
lctx->lex = lex;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->keep_lex = true;
|
2002-02-21 00:56:14 +00:00
|
|
|
} else {
|
2002-02-21 00:45:11 +00:00
|
|
|
lctx->lex = NULL;
|
|
|
|
result = isc_lex_create(mctx, TOKENSIZ, &lctx->lex);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2002-02-21 00:45:11 +00:00
|
|
|
goto cleanup_inc;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->keep_lex = false;
|
2019-02-28 17:00:15 +11:00
|
|
|
/*
|
|
|
|
* If specials change update dns_test_rdatafromstring()
|
|
|
|
* in lib/dns/tests/dnstest.c.
|
|
|
|
*/
|
2002-02-21 00:45:11 +00:00
|
|
|
memset(specials, 0, sizeof(specials));
|
2013-03-21 19:30:10 -07:00
|
|
|
specials[0] = 1;
|
2002-02-21 00:45:11 +00:00
|
|
|
specials['('] = 1;
|
|
|
|
specials[')'] = 1;
|
|
|
|
specials['"'] = 1;
|
|
|
|
isc_lex_setspecials(lctx->lex, specials);
|
|
|
|
isc_lex_setcomments(lctx->lex, ISC_LEXCOMMENT_DNSMASTERFILE);
|
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
|
2018-10-11 11:57:57 +02:00
|
|
|
lctx->ttl_known = ((options & DNS_MASTER_NOTTL) != 0);
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->ttl = 0;
|
2013-09-04 13:53:02 +10:00
|
|
|
lctx->default_ttl_known = lctx->ttl_known;
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->default_ttl = 0;
|
2020-02-12 13:59:18 +01:00
|
|
|
lctx->warn_1035 = true; /* XXX Argument? */
|
|
|
|
lctx->warn_tcr = true; /* XXX Argument? */
|
|
|
|
lctx->warn_sigexpired = true; /* XXX Argument? */
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->options = options;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->seen_include = false;
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->zclass = zclass;
|
2008-04-02 02:37:42 +00:00
|
|
|
lctx->resign = resign;
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->result = ISC_R_SUCCESS;
|
2012-01-31 03:35:41 +00:00
|
|
|
lctx->include_cb = include_cb;
|
|
|
|
lctx->include_arg = include_arg;
|
2016-03-10 17:01:08 +11:00
|
|
|
isc_stdtime_get(&lctx->now);
|
2001-02-14 13:14:50 +00:00
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
lctx->top = dns_fixedname_initname(&lctx->fixed_top);
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_name_toregion(top, &r);
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_name_fromregion(lctx->top, &r);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
lctx->f = NULL;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->first = true;
|
2011-12-08 16:07:22 +00:00
|
|
|
dns_master_initrawheader(&lctx->header);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->loop_cnt = (done != NULL) ? 100 : 0;
|
|
|
|
lctx->callbacks = callbacks;
|
|
|
|
lctx->task = NULL;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (task != NULL) {
|
2001-02-14 13:14:50 +00:00
|
|
|
isc_task_attach(task, &lctx->task);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->done = done;
|
|
|
|
lctx->done_arg = done_arg;
|
2019-05-20 16:43:32 +02:00
|
|
|
atomic_init(&lctx->canceled, false);
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->mctx = NULL;
|
|
|
|
isc_mem_attach(mctx, &lctx->mctx);
|
2019-05-20 16:43:32 +02:00
|
|
|
|
|
|
|
isc_refcount_init(&lctx->references, 1); /* Implicit attach. */
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->magic = DNS_LCTX_MAGIC;
|
|
|
|
*lctxp = lctx;
|
2000-08-15 03:33:52 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_inc:
|
2001-02-14 13:14:50 +00:00
|
|
|
incctx_destroy(mctx, lctx->inc);
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup_ctx:
|
2001-02-14 13:14:50 +00:00
|
|
|
isc_mem_put(mctx, lctx, sizeof(*lctx));
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
2000-03-22 19:27:51 +00:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
2009-01-30 04:35:44 +00:00
|
|
|
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
|
2020-02-13 14:44:37 -08:00
|
|
|
nibbles(char *numbuf, size_t length, unsigned int width, char mode, int value) {
|
2009-01-30 04:35:44 +00:00
|
|
|
unsigned int count = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This reserve space for the NUL string terminator.
|
|
|
|
*/
|
2009-02-16 03:19:40 +00:00
|
|
|
if (length > 0U) {
|
2009-01-30 04:35:44 +00:00
|
|
|
*numbuf = '\0';
|
|
|
|
length--;
|
|
|
|
}
|
|
|
|
do {
|
|
|
|
char val = hex[(value & 0x0f) + ((mode == 'n') ? 0 : 16)];
|
|
|
|
value >>= 4;
|
2009-02-16 03:19:40 +00:00
|
|
|
if (length > 0U) {
|
2009-01-30 04:35:44 +00:00
|
|
|
*numbuf++ = val;
|
|
|
|
*numbuf = '\0';
|
|
|
|
length--;
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (width > 0) {
|
2009-01-30 04:35:44 +00:00
|
|
|
width--;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-30 04:35:44 +00:00
|
|
|
count++;
|
|
|
|
/*
|
2020-02-20 14:49:36 -08:00
|
|
|
* If width is non zero then we need to add a label separator.
|
2009-01-30 04:35:44 +00:00
|
|
|
* If value is non zero then we need to add another label and
|
2020-02-20 14:49:36 -08:00
|
|
|
* that requires a label separator.
|
2009-01-30 04:35:44 +00:00
|
|
|
*/
|
|
|
|
if (width > 0 || value != 0) {
|
2009-02-16 03:19:40 +00:00
|
|
|
if (length > 0U) {
|
2009-01-30 04:35:44 +00:00
|
|
|
*numbuf++ = '.';
|
|
|
|
*numbuf = '\0';
|
|
|
|
length--;
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (width > 0) {
|
2009-01-30 04:35:44 +00:00
|
|
|
width--;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2009-01-30 04:35:44 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
} while (value != 0 || width > 0);
|
|
|
|
return (count);
|
|
|
|
}
|
|
|
|
|
2000-09-18 06:50:35 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
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;
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_textregion_t r;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int n;
|
|
|
|
unsigned int width;
|
|
|
|
bool nibblemode;
|
2000-09-18 06:50:35 +00:00
|
|
|
|
|
|
|
r.base = buffer;
|
2013-12-04 12:47:23 +11:00
|
|
|
r.length = (unsigned int)length;
|
2000-09-18 06:50:35 +00:00
|
|
|
|
|
|
|
while (*name != '\0') {
|
|
|
|
if (*name == '$') {
|
|
|
|
name++;
|
2000-11-02 05:18:33 +00:00
|
|
|
if (*name == '$') {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (r.length == 0) {
|
2000-11-02 05:18:33 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-11-02 05:18:33 +00:00
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
continue;
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
nibblemode = false;
|
2017-09-13 00:14:37 -07:00
|
|
|
strlcpy(fmt, "%d", sizeof(fmt));
|
2000-09-18 06:50:35 +00:00
|
|
|
/* Get format specifier. */
|
2020-02-12 13:59:18 +01:00
|
|
|
if (*name == '{') {
|
|
|
|
n = sscanf(name, "{%d,%u,%1[doxXnN]}", &delta,
|
|
|
|
&width, mode);
|
2000-09-18 06:50:35 +00:00
|
|
|
switch (n) {
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 2:
|
2020-02-12 13:59:18 +01:00
|
|
|
n = snprintf(fmt, sizeof(fmt), "%%0%ud",
|
|
|
|
width);
|
2000-09-18 06:50:35 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (mode[0] == 'n' || mode[0] == 'N') {
|
2018-04-17 08:29:14 -07:00
|
|
|
nibblemode = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
n = snprintf(fmt, sizeof(fmt),
|
2001-01-16 07:04:30 +00:00
|
|
|
"%%0%u%c", width, mode[0]);
|
2000-09-18 06:50:35 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return (DNS_R_SYNTAX);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (n >= sizeof(fmt)) {
|
2000-09-18 06:50:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
/* Skip past closing brace. */
|
2020-02-13 21:48:23 +01:00
|
|
|
while (*name != '\0' && *name++ != '}') {
|
2000-09-18 06:50:35 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (nibblemode) {
|
2009-01-30 04:35:44 +00:00
|
|
|
n = nibbles(numbuf, sizeof(numbuf), width,
|
|
|
|
mode[0], it + delta);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2009-01-30 04:35:44 +00:00
|
|
|
n = snprintf(numbuf, sizeof(numbuf), fmt,
|
|
|
|
it + delta);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (n >= sizeof(numbuf)) {
|
2000-09-18 06:50:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
cp = numbuf;
|
|
|
|
while (*cp != '\0') {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (r.length == 0) {
|
2000-09-18 06:50:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
r.base[0] = *cp++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
}
|
|
|
|
} else if (*name == '\\') {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (r.length == 0) {
|
2000-09-18 06:50:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (*name == '\0') {
|
2000-09-18 06:50:35 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (r.length == 0) {
|
2000-09-18 06:50:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
} else {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (r.length == 0) {
|
2000-09-18 06:50:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
r.base[0] = *name++;
|
|
|
|
isc_textregion_consume(&r, 1);
|
|
|
|
}
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (r.length == 0) {
|
2000-09-18 06:50:35 +00:00
|
|
|
return (ISC_R_NOSPACE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
r.base[0] = '\0';
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2001-05-09 03:41:47 +00:00
|
|
|
generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
|
2020-02-13 14:44:37 -08:00
|
|
|
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;
|
2000-09-18 06:50:35 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks;
|
2020-02-13 14:44:37 -08:00
|
|
|
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;
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_textregion_t r;
|
2020-02-13 14:44:37 -08:00
|
|
|
int i, n, start, stop, step = 0;
|
|
|
|
dns_incctx_t *ictx;
|
|
|
|
char dummy[2];
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx = lctx->inc;
|
|
|
|
callbacks = lctx->callbacks;
|
2018-03-28 14:38:09 +02:00
|
|
|
owner = dns_fixedname_initname(&ownerfixed);
|
2000-09-18 06:50:35 +00:00
|
|
|
ISC_LIST_INIT(head);
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
target_mem = isc_mem_get(lctx->mctx, target_size);
|
2008-11-30 23:49:21 +00:00
|
|
|
rhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_RHS);
|
|
|
|
lhsbuf = isc_mem_get(lctx->mctx, DNS_MASTER_LHS);
|
2000-09-18 06:50:35 +00:00
|
|
|
if (target_mem == NULL || rhsbuf == NULL || lhsbuf == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto error_cleanup;
|
|
|
|
}
|
|
|
|
isc_buffer_init(&target, target_mem, target_size);
|
|
|
|
|
2015-09-18 23:30:01 +10:00
|
|
|
n = sscanf(range, "%d-%d%1[/]%d", &start, &stop, dummy, &step);
|
2015-01-06 11:31:34 +11:00
|
|
|
if ((n != 2 && n != 4) || (start < 0) || (stop < 0) ||
|
2020-02-13 14:44:37 -08:00
|
|
|
(n == 4 && step < 1) || (stop < start))
|
|
|
|
{
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks, "%s: %s:%lu: invalid range '%s'",
|
|
|
|
"$GENERATE", source, line, range);
|
2000-09-18 06:50:35 +00:00
|
|
|
result = DNS_R_SYNTAX;
|
|
|
|
goto insist_cleanup;
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (n == 2) {
|
2000-09-18 06:50:35 +00:00
|
|
|
step = 1;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Get type.
|
|
|
|
*/
|
|
|
|
r.base = gtype;
|
|
|
|
r.length = strlen(gtype);
|
|
|
|
result = dns_rdatatype_fromtext(&type, &r);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
2001-05-09 03:41:47 +00:00
|
|
|
(*callbacks->error)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s: %s:%lu: unknown RR type '%s'",
|
|
|
|
"$GENERATE", source, line, gtype);
|
2000-09-18 06:50:35 +00:00
|
|
|
goto insist_cleanup;
|
|
|
|
}
|
|
|
|
|
2018-01-22 14:26:04 +05:30
|
|
|
/*
|
|
|
|
* RFC2930: TKEY and TSIG are not allowed to be loaded
|
|
|
|
* from master files.
|
|
|
|
*/
|
2020-04-28 15:37:19 +10:00
|
|
|
if (dns_master_isprimary(lctx) && dns_rdatatype_ismeta(type)) {
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks, "%s: %s:%lu: meta RR type '%s'",
|
|
|
|
"$GENERATE", source, line, gtype);
|
2018-01-22 14:26:04 +05:30
|
|
|
result = DNS_R_METATYPE;
|
|
|
|
goto insist_cleanup;
|
|
|
|
}
|
|
|
|
|
2001-01-19 20:45:33 +00:00
|
|
|
for (i = start; i <= stop; i += step) {
|
2008-11-30 23:49:21 +00:00
|
|
|
result = genname(lhs, i, lhsbuf, DNS_MASTER_LHS);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-18 06:50:35 +00:00
|
|
|
goto error_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-11-30 23:49:21 +00:00
|
|
|
result = genname(rhs, i, rhsbuf, DNS_MASTER_RHS);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-18 06:50:35 +00:00
|
|
|
goto error_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
|
|
|
isc_buffer_init(&buffer, lhsbuf, strlen(lhsbuf));
|
|
|
|
isc_buffer_add(&buffer, strlen(lhsbuf));
|
|
|
|
isc_buffer_setactive(&buffer, strlen(lhsbuf));
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_name_fromtext(owner, &buffer, ictx->origin, 0,
|
|
|
|
NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-18 06:50:35 +00:00
|
|
|
goto error_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2020-04-28 15:37:19 +10:00
|
|
|
if (dns_master_isprimary(lctx) &&
|
|
|
|
!dns_name_issubdomain(owner, lctx->top)) {
|
2001-05-09 03:41:47 +00:00
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
|
|
|
dns_name_format(owner, namebuf, sizeof(namebuf));
|
|
|
|
/*
|
|
|
|
* Ignore out-of-zone data.
|
|
|
|
*/
|
|
|
|
(*callbacks->warn)(callbacks,
|
2002-03-05 00:59:42 +00:00
|
|
|
"%s:%lu: "
|
2001-05-09 03:41:47 +00:00
|
|
|
"ignoring out-of-zone data (%s)",
|
|
|
|
source, line, namebuf);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_buffer_init(&buffer, rhsbuf, strlen(rhsbuf));
|
|
|
|
isc_buffer_add(&buffer, strlen(rhsbuf));
|
|
|
|
isc_buffer_setactive(&buffer, strlen(rhsbuf));
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = isc_lex_openbuffer(lctx->lex, &buffer);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-18 06:50:35 +00:00
|
|
|
goto error_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
|
|
|
isc_buffer_init(&target, target_mem, target_size);
|
2001-02-14 13:14:50 +00:00
|
|
|
result = dns_rdata_fromtext(&rdata, lctx->zclass, type,
|
2004-02-27 20:41:51 +00:00
|
|
|
lctx->lex, ictx->origin, 0,
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->mctx, &target, callbacks);
|
2001-11-30 01:59:49 +00:00
|
|
|
RUNTIME_CHECK(isc_lex_close(lctx->lex) == ISC_R_SUCCESS);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-18 06:50:35 +00:00
|
|
|
goto error_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2015-03-03 16:43:42 +11:00
|
|
|
dns_rdatalist_init(&rdatalist);
|
2000-09-18 06:50:35 +00:00
|
|
|
rdatalist.type = type;
|
2001-02-14 13:14:50 +00:00
|
|
|
rdatalist.rdclass = lctx->zclass;
|
|
|
|
rdatalist.ttl = lctx->ttl;
|
2000-09-18 06:50:35 +00:00
|
|
|
ISC_LIST_PREPEND(head, &rdatalist, link);
|
|
|
|
ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
|
2001-05-09 03:41:47 +00:00
|
|
|
result = commit(callbacks, lctx, &head, owner, source, line);
|
2000-10-25 04:26:57 +00:00
|
|
|
ISC_LIST_UNLINK(rdatalist.rdata, &rdata, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-09-18 06:50:35 +00:00
|
|
|
goto error_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-10-31 03:22:05 +00:00
|
|
|
dns_rdata_reset(&rdata);
|
2000-09-18 06:50:35 +00:00
|
|
|
}
|
|
|
|
result = ISC_R_SUCCESS;
|
|
|
|
goto cleanup;
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
error_cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_NOMEMORY) {
|
2000-09-18 06:50:35 +00:00
|
|
|
(*callbacks->error)(callbacks, "$GENERATE: %s",
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result));
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks, "$GENERATE: %s:%lu: %s", source,
|
2021-10-04 17:14:53 +02:00
|
|
|
line, isc_result_totext(result));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
insist_cleanup:
|
2000-09-18 06:50:35 +00:00
|
|
|
INSIST(result != ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (target_mem != NULL) {
|
2001-02-14 13:14:50 +00:00
|
|
|
isc_mem_put(lctx->mctx, target_mem, target_size);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (lhsbuf != NULL) {
|
2008-11-30 23:49:21 +00:00
|
|
|
isc_mem_put(lctx->mctx, lhsbuf, DNS_MASTER_LHS);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (rhsbuf != NULL) {
|
2008-11-30 23:49:21 +00:00
|
|
|
isc_mem_put(lctx->mctx, rhsbuf, DNS_MASTER_RHS);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2001-05-22 01:44:37 +00:00
|
|
|
static void
|
2012-06-20 14:13:12 -05:00
|
|
|
limit_ttl(dns_rdatacallbacks_t *callbacks, const char *source,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int line, uint32_t *ttlp) {
|
2001-05-22 01:44:37 +00:00
|
|
|
if (*ttlp > 0x7fffffffUL) {
|
|
|
|
(callbacks->warn)(callbacks,
|
|
|
|
"%s: %s:%lu: "
|
|
|
|
"$TTL %lu > MAXTTL, "
|
|
|
|
"setting $TTL to 0",
|
2020-02-12 13:59:18 +01:00
|
|
|
"dns_master_load", source, line, *ttlp);
|
2001-05-22 01:44:37 +00:00
|
|
|
*ttlp = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-07-19 02:34:58 +00:00
|
|
|
static isc_result_t
|
|
|
|
check_ns(dns_loadctx_t *lctx, isc_token_t *token, const char *source,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned long line) {
|
|
|
|
char *tmp = NULL;
|
2002-07-19 02:34:58 +00:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
void (*callback)(struct dns_rdatacallbacks *, const char *, ...);
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if ((lctx->options & DNS_MASTER_FATALNS) != 0) {
|
2002-07-19 02:34:58 +00:00
|
|
|
callback = lctx->callbacks->error;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2002-07-19 02:34:58 +00:00
|
|
|
callback = lctx->callbacks->warn;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2002-07-19 02:34:58 +00:00
|
|
|
if (token->type == isc_tokentype_string) {
|
2020-02-13 14:44:37 -08:00
|
|
|
struct in_addr addr;
|
2002-07-19 02:34:58 +00:00
|
|
|
struct in6_addr addr6;
|
|
|
|
|
|
|
|
tmp = isc_mem_strdup(lctx->mctx, DNS_AS_STR(*token));
|
|
|
|
/*
|
|
|
|
* Catch both "1.2.3.4" and "1.2.3.4."
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (tmp[strlen(tmp) - 1] == '.') {
|
2002-07-19 02:34:58 +00:00
|
|
|
tmp[strlen(tmp) - 1] = '\0';
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-10-30 15:38:23 +01:00
|
|
|
if (inet_pton(AF_INET, tmp, &addr) == 1 ||
|
2020-02-13 14:44:37 -08:00
|
|
|
inet_pton(AF_INET6, tmp, &addr6) == 1)
|
|
|
|
{
|
2002-07-19 02:34:58 +00:00
|
|
|
result = DNS_R_NSISADDRESS;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-07-19 02:34:58 +00:00
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callback)(lctx->callbacks,
|
|
|
|
"%s:%lu: NS record '%s' "
|
2002-07-19 02:34:58 +00:00
|
|
|
"appears to be an address",
|
|
|
|
source, line, DNS_AS_STR(*token));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (tmp != NULL) {
|
2002-07-19 02:34:58 +00:00
|
|
|
isc_mem_free(lctx->mctx, tmp);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-07-19 02:34:58 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2005-01-09 23:40:04 +00:00
|
|
|
static void
|
|
|
|
check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatacallbacks_t *callbacks) {
|
2005-01-09 23:40:04 +00:00
|
|
|
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));
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->warn)(callbacks,
|
|
|
|
"%s:%lu: warning: ownername "
|
2005-01-09 23:40:04 +00:00
|
|
|
"'%s' contains an non-terminal wildcard",
|
|
|
|
source, line, namebuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-21 12:58:46 -07:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
openfile_text(dns_loadctx_t *lctx, const char *master_file) {
|
2012-06-21 12:58:46 -07:00
|
|
|
return (isc_lex_openfile(lctx->lex, master_file));
|
|
|
|
}
|
|
|
|
|
2018-05-28 17:26:39 +10:00
|
|
|
static int
|
2020-02-13 14:44:37 -08:00
|
|
|
find_free_name(dns_incctx_t *incctx) {
|
2018-05-28 17:26:39 +10:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < (NBUFS - 1); i++) {
|
|
|
|
if (!incctx->in_use[i]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
INSIST(!incctx->in_use[i]);
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
load_text(dns_loadctx_t *lctx) {
|
1999-03-04 02:48:47 +00:00
|
|
|
dns_rdataclass_t rdclass;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatatype_t type, covers;
|
|
|
|
uint32_t ttl_offset = 0;
|
|
|
|
dns_name_t *new_name;
|
|
|
|
bool current_has_delegation = false;
|
|
|
|
bool done = false;
|
|
|
|
bool finish_origin = false;
|
|
|
|
bool finish_include = false;
|
|
|
|
bool read_till_eol = false;
|
|
|
|
bool initialws;
|
|
|
|
char *include_file = NULL;
|
|
|
|
isc_token_t token;
|
|
|
|
isc_result_t result = ISC_R_UNEXPECTED;
|
1999-01-27 13:38:21 +00:00
|
|
|
rdatalist_head_t glue_list;
|
|
|
|
rdatalist_head_t current_list;
|
|
|
|
dns_rdatalist_t *this;
|
2020-02-13 14:44:37 -08:00
|
|
|
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;
|
|
|
|
isc_mem_t *mctx;
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_incctx_t *ictx;
|
|
|
|
char *range = NULL;
|
|
|
|
char *lhs = NULL;
|
|
|
|
char *gtype = NULL;
|
|
|
|
char *rhs = NULL;
|
|
|
|
const char *source = "";
|
|
|
|
unsigned long line = 0;
|
|
|
|
bool explicit_ttl;
|
|
|
|
char classname1[DNS_RDATACLASS_FORMATSIZE];
|
|
|
|
char classname2[DNS_RDATACLASS_FORMATSIZE];
|
|
|
|
unsigned int options = 0;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
|
|
|
callbacks = lctx->callbacks;
|
|
|
|
mctx = lctx->mctx;
|
|
|
|
ictx = lctx->inc;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
ISC_LIST_INIT(glue_list);
|
|
|
|
ISC_LIST_INIT(current_list);
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Allocate target_size of buffer space. This is greater than twice
|
|
|
|
* the maximum individual RR data size.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
target_mem = isc_mem_get(mctx, target_size);
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
isc_buffer_init(&target, target_mem, target_size);
|
1999-01-27 13:38:21 +00:00
|
|
|
target_save = target;
|
1999-03-22 06:21:29 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) {
|
2004-02-27 20:41:51 +00:00
|
|
|
options |= DNS_RDATA_CHECKNAMES;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) {
|
2004-02-27 20:41:51 +00:00
|
|
|
options |= DNS_RDATA_CHECKNAMESFAIL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if ((lctx->options & DNS_MASTER_CHECKMX) != 0) {
|
2005-05-19 04:59:05 +00:00
|
|
|
options |= DNS_RDATA_CHECKMX;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0) {
|
2005-05-19 04:59:05 +00:00
|
|
|
options |= DNS_RDATA_CHECKMXFAIL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-05-11 02:35:37 +00:00
|
|
|
source = isc_lex_getsourcename(lctx->lex);
|
1999-01-27 13:38:21 +00:00
|
|
|
do {
|
2018-04-17 08:29:14 -07:00
|
|
|
initialws = false;
|
2001-05-11 02:35:37 +00:00
|
|
|
line = isc_lex_getsourceline(lctx->lex);
|
2005-05-19 04:59:05 +00:00
|
|
|
GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING,
|
2018-04-17 08:29:14 -07:00
|
|
|
&token, true);
|
2001-05-11 02:35:37 +00:00
|
|
|
line = isc_lex_getsourceline(lctx->lex);
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
if (token.type == isc_tokentype_eof) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (read_till_eol) {
|
2001-02-14 13:14:50 +00:00
|
|
|
WARNUNEXPECTEDEOF(lctx->lex);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
/* Pop the include stack? */
|
2001-02-14 13:14:50 +00:00
|
|
|
if (ictx->parent != NULL) {
|
2000-08-15 03:33:52 +00:00
|
|
|
COMMITALL;
|
2001-02-21 03:53:11 +00:00
|
|
|
lctx->inc = ictx->parent;
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->parent = NULL;
|
|
|
|
incctx_destroy(lctx->mctx, ictx);
|
2020-02-12 13:59:18 +01:00
|
|
|
RUNTIME_CHECK(isc_lex_close(lctx->lex) ==
|
|
|
|
ISC_R_SUCCESS);
|
2001-05-09 03:41:47 +00:00
|
|
|
line = isc_lex_getsourceline(lctx->lex);
|
2015-09-30 14:14:47 +10:00
|
|
|
POST(line);
|
2001-05-09 03:41:47 +00:00
|
|
|
source = isc_lex_getsourcename(lctx->lex);
|
2001-02-21 03:53:11 +00:00
|
|
|
ictx = lctx->inc;
|
2000-08-15 03:33:52 +00:00
|
|
|
continue;
|
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
done = true;
|
1999-01-27 13:38:21 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
1999-01-28 05:03:25 +00:00
|
|
|
if (token.type == isc_tokentype_eol) {
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = false;
|
2020-02-12 13:59:18 +01:00
|
|
|
continue; /* blank line */
|
1999-01-28 05:03:25 +00:00
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (read_till_eol) {
|
1999-01-28 05:03:25 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
if (token.type == isc_tokentype_initialws) {
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Still working on the same name.
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
initialws = true;
|
2005-05-19 04:59:05 +00:00
|
|
|
} else if (token.type == isc_tokentype_string ||
|
2020-02-13 14:44:37 -08:00
|
|
|
token.type == isc_tokentype_qstring)
|
|
|
|
{
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* "$" Support.
|
|
|
|
*
|
|
|
|
* "$ORIGIN" and "$INCLUDE" can both take domain names.
|
|
|
|
* The processing of "$ORIGIN" and "$INCLUDE" extends
|
|
|
|
* across the normal domain name processing.
|
|
|
|
*/
|
|
|
|
|
2002-01-21 01:07:32 +00:00
|
|
|
if (strcasecmp(DNS_AS_STR(token), "$ORIGIN") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
|
|
|
finish_origin = true;
|
2020-02-12 13:59:18 +01:00
|
|
|
} else if (strcasecmp(DNS_AS_STR(token), "$TTL") == 0) {
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKENERR(lctx->lex, 0, &token, false,
|
2014-10-04 23:45:22 +00:00
|
|
|
lctx->ttl = 0;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->default_ttl_known = true;);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_ttl_fromtext(
|
|
|
|
&token.value.as_textregion, &lctx->ttl);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
|
|
|
lctx->ttl = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2000-09-17 13:08:46 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-05-22 01:44:37 +00:00
|
|
|
limit_ttl(callbacks, source, line, &lctx->ttl);
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->default_ttl = lctx->ttl;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->default_ttl_known = true;
|
2001-02-09 14:34:52 +00:00
|
|
|
EXPECTEOL;
|
1999-01-28 01:16:59 +00:00
|
|
|
continue;
|
2020-02-12 13:59:18 +01:00
|
|
|
} else if (strcasecmp(DNS_AS_STR(token), "$INCLUDE") ==
|
|
|
|
0) {
|
2000-08-15 03:33:52 +00:00
|
|
|
COMMITALL;
|
2020-02-13 14:44:37 -08:00
|
|
|
if ((lctx->options & DNS_MASTER_NOINCLUDE) != 0)
|
|
|
|
{
|
2001-01-30 23:12:27 +00:00
|
|
|
(callbacks->error)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"$INCLUDE not "
|
|
|
|
"allowed",
|
|
|
|
"dns_master_load",
|
|
|
|
source, line);
|
2001-01-30 23:12:27 +00:00
|
|
|
result = DNS_R_REFUSED;
|
|
|
|
goto insist_and_cleanup;
|
|
|
|
}
|
1999-06-08 10:35:23 +00:00
|
|
|
if (ttl_offset != 0) {
|
|
|
|
(callbacks->error)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"$INCLUDE "
|
|
|
|
"may not be used "
|
|
|
|
"with $DATE",
|
|
|
|
"dns_master_load",
|
|
|
|
source, line);
|
2000-09-17 13:08:46 +00:00
|
|
|
result = DNS_R_SYNTAX;
|
|
|
|
goto insist_and_cleanup;
|
1999-06-08 10:35:23 +00:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token,
|
2018-04-17 08:29:14 -07:00
|
|
|
false);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (include_file != NULL) {
|
1999-01-28 01:16:59 +00:00
|
|
|
isc_mem_free(mctx, include_file);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
include_file =
|
|
|
|
isc_mem_strdup(mctx, DNS_AS_STR(token));
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, true);
|
2000-07-10 05:15:04 +00:00
|
|
|
|
1999-01-28 01:16:59 +00:00
|
|
|
if (token.type == isc_tokentype_eol ||
|
|
|
|
token.type == isc_tokentype_eof) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (token.type == isc_tokentype_eof) {
|
2001-02-14 13:14:50 +00:00
|
|
|
WARNUNEXPECTEDEOF(lctx->lex);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
/*
|
|
|
|
* No origin field.
|
|
|
|
*/
|
2000-08-15 03:33:52 +00:00
|
|
|
result = pushfile(include_file,
|
2001-02-21 03:53:11 +00:00
|
|
|
ictx->origin, lctx);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2001-09-11 04:56:06 +00:00
|
|
|
LOGITFILE(result, include_file);
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2001-09-11 04:56:06 +00:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
|
|
|
LOGITFILE(result, include_file);
|
|
|
|
goto insist_and_cleanup;
|
|
|
|
}
|
2001-02-21 03:53:11 +00:00
|
|
|
ictx = lctx->inc;
|
2020-02-12 13:59:18 +01:00
|
|
|
source = isc_lex_getsourcename(
|
|
|
|
lctx->lex);
|
2011-03-11 06:11:27 +00:00
|
|
|
line = isc_lex_getsourceline(lctx->lex);
|
|
|
|
POST(line);
|
1999-01-28 01:16:59 +00:00
|
|
|
continue;
|
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
/*
|
|
|
|
* There is an origin field. Fall through
|
|
|
|
* to domain name processing code and do
|
|
|
|
* the actual inclusion later.
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
finish_include = true;
|
2020-02-13 14:44:37 -08:00
|
|
|
} else if (strcasecmp(DNS_AS_STR(token), "$DATE") == 0)
|
|
|
|
{
|
|
|
|
int64_t dump_time64;
|
1999-06-08 10:35:23 +00:00
|
|
|
isc_stdtime_t dump_time, current_time;
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
1999-12-16 23:29:07 +00:00
|
|
|
isc_stdtime_get(¤t_time);
|
2002-01-21 01:07:32 +00:00
|
|
|
result = dns_time64_fromtext(DNS_AS_STR(token),
|
|
|
|
&dump_time64);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2001-01-09 00:43:24 +00:00
|
|
|
LOGIT(result);
|
|
|
|
dump_time64 = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-10-08 23:26:55 +00:00
|
|
|
dump_time = (isc_stdtime_t)dump_time64;
|
1999-06-08 10:35:23 +00:00
|
|
|
if (dump_time != dump_time64) {
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s: %s:%lu: $DATE "
|
|
|
|
"outside epoch",
|
|
|
|
"dns_master_load",
|
|
|
|
source, line);
|
2000-09-17 13:08:46 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
|
|
|
goto insist_and_cleanup;
|
1999-06-08 10:35:23 +00:00
|
|
|
}
|
|
|
|
if (dump_time > current_time) {
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"$DATE in future, "
|
|
|
|
"using current date",
|
|
|
|
"dns_master_load",
|
|
|
|
source, line);
|
1999-06-08 10:35:23 +00:00
|
|
|
dump_time = current_time;
|
|
|
|
}
|
|
|
|
ttl_offset = current_time - dump_time;
|
2001-02-09 14:34:52 +00:00
|
|
|
EXPECTEOL;
|
1999-06-08 10:35:23 +00:00
|
|
|
continue;
|
2020-02-12 13:59:18 +01:00
|
|
|
} else if (strcasecmp(DNS_AS_STR(token), "$GENERATE") ==
|
|
|
|
0) {
|
2000-09-18 06:50:35 +00:00
|
|
|
/*
|
|
|
|
* Lazy cleanup.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (range != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, range);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (lhs != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, lhs);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (gtype != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, gtype);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (rhs != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, rhs);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2006-12-07 04:46:27 +00:00
|
|
|
range = lhs = gtype = rhs = NULL;
|
2003-04-17 11:31:02 +00:00
|
|
|
/* RANGE */
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2020-02-12 13:59:18 +01:00
|
|
|
range = isc_mem_strdup(mctx, DNS_AS_STR(token));
|
2000-09-18 06:50:35 +00:00
|
|
|
/* LHS */
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2002-01-21 01:07:32 +00:00
|
|
|
lhs = isc_mem_strdup(mctx, DNS_AS_STR(token));
|
2003-04-17 11:31:02 +00:00
|
|
|
rdclass = 0;
|
2018-04-17 08:29:14 -07:00
|
|
|
explicit_ttl = false;
|
2003-04-17 11:31:02 +00:00
|
|
|
/* CLASS? */
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2020-02-12 13:59:18 +01:00
|
|
|
if (dns_rdataclass_fromtext(
|
|
|
|
&rdclass,
|
|
|
|
&token.value.as_textregion) ==
|
2020-02-13 14:44:37 -08:00
|
|
|
ISC_R_SUCCESS)
|
|
|
|
{
|
2020-02-12 13:59:18 +01:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2003-04-17 11:31:02 +00:00
|
|
|
}
|
|
|
|
/* TTL? */
|
|
|
|
if (dns_ttl_fromtext(&token.value.as_textregion,
|
2020-02-12 13:59:18 +01:00
|
|
|
&lctx->ttl) ==
|
|
|
|
ISC_R_SUCCESS) {
|
2003-04-17 11:31:02 +00:00
|
|
|
limit_ttl(callbacks, source, line,
|
|
|
|
&lctx->ttl);
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->ttl_known = true;
|
|
|
|
explicit_ttl = true;
|
2020-02-12 13:59:18 +01:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2003-04-17 11:31:02 +00:00
|
|
|
}
|
|
|
|
/* CLASS? */
|
|
|
|
if (rdclass == 0 &&
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_rdataclass_fromtext(
|
|
|
|
&rdclass,
|
|
|
|
&token.value.as_textregion) ==
|
2020-02-13 14:44:37 -08:00
|
|
|
ISC_R_SUCCESS)
|
|
|
|
{
|
2020-02-12 13:59:18 +01:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2003-04-17 11:31:02 +00:00
|
|
|
/* TYPE */
|
2020-02-12 13:59:18 +01:00
|
|
|
gtype = isc_mem_strdup(mctx, DNS_AS_STR(token));
|
2000-09-18 06:50:35 +00:00
|
|
|
/* RHS */
|
2020-02-12 13:59:18 +01:00
|
|
|
GETTOKEN(lctx->lex, ISC_LEXOPT_QSTRING, &token,
|
|
|
|
false);
|
2002-01-21 01:07:32 +00:00
|
|
|
rhs = isc_mem_strdup(mctx, DNS_AS_STR(token));
|
2003-04-17 11:31:02 +00:00
|
|
|
if (!lctx->ttl_known &&
|
|
|
|
!lctx->default_ttl_known) {
|
|
|
|
(*callbacks->error)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s: %s:%lu: no "
|
|
|
|
"TTL specified",
|
|
|
|
"dns_master_load",
|
|
|
|
source, line);
|
2003-04-17 11:31:02 +00:00
|
|
|
result = DNS_R_NOTTL;
|
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
|
|
|
lctx->ttl = 0;
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2003-04-17 11:31:02 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
2003-04-17 11:31:02 +00:00
|
|
|
} 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;
|
|
|
|
}
|
2001-05-09 03:41:47 +00:00
|
|
|
result = generate(lctx, range, lhs, gtype, rhs,
|
|
|
|
source, line);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2000-09-18 06:50:35 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-09 14:34:52 +00:00
|
|
|
EXPECTEOL;
|
2000-09-18 06:50:35 +00:00
|
|
|
continue;
|
2020-02-13 14:44:37 -08:00
|
|
|
} else if (strncasecmp(DNS_AS_STR(token), "$", 1) == 0)
|
|
|
|
{
|
2000-08-01 01:33:37 +00:00
|
|
|
(callbacks->error)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s: %s:%lu: "
|
|
|
|
"unknown $ directive '%s'",
|
|
|
|
"dns_master_load", source,
|
|
|
|
line, DNS_AS_STR(token));
|
2000-09-17 13:08:46 +00:00
|
|
|
result = DNS_R_SYNTAX;
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
1999-01-27 23:57:46 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Normal processing resumes.
|
|
|
|
*/
|
2018-05-28 17:26:39 +10:00
|
|
|
new_in_use = find_free_name(ictx);
|
2020-02-12 13:59:18 +01:00
|
|
|
new_name = dns_fixedname_initname(
|
|
|
|
&ictx->fixed[new_in_use]);
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_buffer_init(&buffer, token.value.as_region.base,
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
token.value.as_region.length);
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_buffer_add(&buffer, token.value.as_region.length);
|
|
|
|
isc_buffer_setactive(&buffer,
|
|
|
|
token.value.as_region.length);
|
2000-08-15 03:33:52 +00:00
|
|
|
result = dns_name_fromtext(new_name, &buffer,
|
2020-02-12 13:59:18 +01:00
|
|
|
ictx->origin, 0, NULL);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2002-02-21 01:00:41 +00:00
|
|
|
LOGIT(result);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = true;
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2002-02-21 00:51:22 +00:00
|
|
|
goto log_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Finish $ORIGIN / $INCLUDE processing if required.
|
|
|
|
*/
|
1999-01-27 23:57:46 +00:00
|
|
|
if (finish_origin) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ictx->origin_in_use != -1) {
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->in_use[ictx->origin_in_use] =
|
2018-04-17 08:29:14 -07:00
|
|
|
false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->origin_in_use = new_in_use;
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->in_use[ictx->origin_in_use] = true;
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->origin = new_name;
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->origin_changed = true;
|
|
|
|
finish_origin = false;
|
2001-02-09 14:34:52 +00:00
|
|
|
EXPECTEOL;
|
1999-01-27 23:57:46 +00:00
|
|
|
continue;
|
|
|
|
}
|
1999-01-28 01:16:59 +00:00
|
|
|
if (finish_include) {
|
2018-04-17 08:29:14 -07:00
|
|
|
finish_include = false;
|
2014-12-03 09:42:30 +11:00
|
|
|
EXPECTEOL;
|
2001-02-21 03:53:11 +00:00
|
|
|
result = pushfile(include_file, new_name, lctx);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2001-09-11 05:09:41 +00:00
|
|
|
LOGITFILE(result, include_file);
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2001-09-11 04:56:06 +00:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
|
|
|
LOGITFILE(result, include_file);
|
|
|
|
goto insist_and_cleanup;
|
|
|
|
}
|
2001-02-21 03:53:11 +00:00
|
|
|
ictx = lctx->inc;
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->origin_changed = true;
|
2001-05-14 06:22:40 +00:00
|
|
|
source = isc_lex_getsourcename(lctx->lex);
|
2011-03-11 06:11:27 +00:00
|
|
|
line = isc_lex_getsourceline(lctx->lex);
|
|
|
|
POST(line);
|
1999-01-28 01:16:59 +00:00
|
|
|
continue;
|
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* "$" Processing Finished
|
|
|
|
*/
|
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
/*
|
1999-03-22 06:21:29 +00:00
|
|
|
* 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
|
1999-03-23 00:04:01 +00:00
|
|
|
* state. Linked lists are undone by commit().
|
1999-01-27 13:38:21 +00:00
|
|
|
*/
|
2001-02-14 13:14:50 +00:00
|
|
|
if (ictx->glue != NULL &&
|
2018-07-17 04:56:51 +10:00
|
|
|
!dns_name_caseequal(ictx->glue, new_name)) {
|
2001-02-14 13:14:50 +00:00
|
|
|
result = commit(callbacks, lctx, &glue_list,
|
2001-05-09 03:41:47 +00:00
|
|
|
ictx->glue, source,
|
|
|
|
ictx->glue_line);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2001-02-19 13:24:04 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (ictx->glue_in_use != -1) {
|
2020-02-12 13:59:18 +01:00
|
|
|
ictx->in_use[ictx->glue_in_use] = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->glue_in_use = -1;
|
|
|
|
ictx->glue = NULL;
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount = rdcount_save;
|
|
|
|
rdlcount = rdlcount_save;
|
|
|
|
target = target_save;
|
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
if ((ictx->glue == NULL) &&
|
|
|
|
(ictx->current == NULL ||
|
2020-02-13 14:44:37 -08:00
|
|
|
!dns_name_caseequal(ictx->current, new_name)))
|
|
|
|
{
|
1999-01-27 13:38:21 +00:00
|
|
|
if (current_has_delegation &&
|
2020-02-12 13:59:18 +01:00
|
|
|
is_glue(¤t_list, new_name)) {
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount_save = rdcount;
|
|
|
|
rdlcount_save = rdlcount;
|
|
|
|
target_save = target;
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->glue = new_name;
|
|
|
|
ictx->glue_in_use = new_in_use;
|
2020-02-12 13:59:18 +01:00
|
|
|
ictx->in_use[ictx->glue_in_use] = true;
|
1999-01-27 13:38:21 +00:00
|
|
|
} else {
|
2001-02-14 13:14:50 +00:00
|
|
|
result = commit(callbacks, lctx,
|
1999-02-09 08:02:21 +00:00
|
|
|
¤t_list,
|
2020-02-12 13:59:18 +01:00
|
|
|
ictx->current, source,
|
2001-05-09 03:41:47 +00:00
|
|
|
ictx->current_line);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2001-02-19 13:24:04 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount = 0;
|
|
|
|
rdlcount = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ictx->current_in_use != -1) {
|
2020-02-12 13:59:18 +01:00
|
|
|
ictx->in_use
|
|
|
|
[ictx->current_in_use] =
|
|
|
|
false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->current_in_use = new_in_use;
|
|
|
|
ictx->in_use[ictx->current_in_use] =
|
2018-04-17 08:29:14 -07:00
|
|
|
true;
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx->current = new_name;
|
2018-04-17 08:29:14 -07:00
|
|
|
current_has_delegation = false;
|
1999-01-27 23:17:57 +00:00
|
|
|
isc_buffer_init(&target, target_mem,
|
103. [func] libisc buffer API changes for <isc/buffer.h>:
Added:
isc_buffer_base(b) (pointer)
isc_buffer_current(b) (pointer)
isc_buffer_active(b) (pointer)
isc_buffer_used(b) (pointer)
isc_buffer_length(b) (int)
isc_buffer_usedlength(b) (int)
isc_buffer_consumedlength(b) (int)
isc_buffer_remaininglength(b) (int)
isc_buffer_activelength(b) (int)
isc_buffer_availablelength(b) (int)
Removed:
ISC_BUFFER_USEDCOUNT(b)
ISC_BUFFER_AVAILABLECOUNT(b)
isc_buffer_type(b)
Changed names:
isc_buffer_used(b, r) ->
isc_buffer_usedregion(b, r)
isc_buffer_available(b, r) ->
isc_buffer_available_region(b, r)
isc_buffer_consumed(b, r) ->
isc_buffer_consumedregion(b, r)
isc_buffer_active(b, r) ->
isc_buffer_activeregion(b, r)
isc_buffer_remaining(b, r) ->
isc_buffer_remainingregion(b, r)
Buffer types were removed, so the ISC_BUFFERTYPE_*
macros are no more, and the type argument to
isc_buffer_init and isc_buffer_allocate were removed.
isc_buffer_putstr is now void (instead of isc_result_t)
and requires that the caller ensure that there
is enough available buffer space for the string.
2000-04-27 00:03:12 +00:00
|
|
|
target_size);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
2005-01-09 23:40:04 +00:00
|
|
|
/*
|
|
|
|
* Check for internal wildcards.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
if ((lctx->options &
|
2020-02-13 21:48:23 +01:00
|
|
|
DNS_MASTER_CHECKWILDCARD) != 0) {
|
2005-01-09 23:40:04 +00:00
|
|
|
check_wildcard(ictx, source, line,
|
|
|
|
callbacks);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
2020-04-28 15:37:19 +10:00
|
|
|
if (dns_master_isprimary(lctx) &&
|
|
|
|
!dns_name_issubdomain(new_name, lctx->top)) {
|
2001-05-09 03:41:47 +00:00
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
|
|
|
dns_name_format(new_name, namebuf,
|
|
|
|
sizeof(namebuf));
|
|
|
|
/*
|
|
|
|
* Ignore out-of-zone data.
|
|
|
|
*/
|
|
|
|
(*callbacks->warn)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s:%lu: "
|
|
|
|
"ignoring out-of-zone data "
|
|
|
|
"(%s)",
|
|
|
|
source, line, namebuf);
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->drop = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->drop = false;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
} else {
|
1999-02-10 05:25:37 +00:00
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2000-05-24 15:07:59 +00:00
|
|
|
"%s:%lu: isc_lex_gettoken() returned "
|
2007-05-16 06:58:33 +00:00
|
|
|
"unexpected token type (%d)",
|
2001-05-09 03:41:47 +00:00
|
|
|
source, line, token.type);
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2001-01-09 00:43:24 +00:00
|
|
|
LOGIT(result);
|
|
|
|
continue;
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
*/
|
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
type = 0;
|
1999-03-04 02:48:47 +00:00
|
|
|
rdclass = 0;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, initialws);
|
2000-07-09 12:52:34 +00:00
|
|
|
|
|
|
|
if (initialws) {
|
|
|
|
if (token.type == isc_tokentype_eol) {
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = false;
|
2020-02-12 13:59:18 +01:00
|
|
|
continue; /* blank line */
|
2000-07-09 12:52:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (token.type == isc_tokentype_eof) {
|
2001-02-14 13:14:50 +00:00
|
|
|
WARNUNEXPECTEDEOF(lctx->lex);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = false;
|
2001-02-14 13:14:50 +00:00
|
|
|
isc_lex_ungettoken(lctx->lex, &token);
|
2000-07-10 05:15:04 +00:00
|
|
|
continue;
|
2000-07-09 12:52:34 +00:00
|
|
|
}
|
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
if (ictx->current == NULL) {
|
2000-07-09 12:52:34 +00:00
|
|
|
(*callbacks->error)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s:%lu: no current owner "
|
|
|
|
"name",
|
|
|
|
source, line);
|
2000-07-09 12:52:34 +00:00
|
|
|
result = DNS_R_NOOWNER;
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = true;
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
2000-07-09 12:52:34 +00:00
|
|
|
}
|
2012-12-18 16:17:55 -08:00
|
|
|
|
|
|
|
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));
|
2013-01-04 11:23:18 +11:00
|
|
|
(*callbacks->warn)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"%s:%lu: record with "
|
|
|
|
"inherited "
|
|
|
|
"owner (%s) immediately "
|
|
|
|
"after "
|
|
|
|
"$ORIGIN (%s)",
|
|
|
|
source, line, cbuf, obuf);
|
2012-12-18 16:17:55 -08:00
|
|
|
}
|
2000-07-09 12:52:34 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
ictx->origin_changed = false;
|
2012-12-18 16:17:55 -08:00
|
|
|
|
1999-11-02 13:07:53 +00:00
|
|
|
if (dns_rdataclass_fromtext(&rdclass,
|
2020-02-12 13:59:18 +01:00
|
|
|
&token.value.as_textregion) ==
|
2020-02-13 14:44:37 -08:00
|
|
|
ISC_R_SUCCESS)
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
explicit_ttl = false;
|
2014-02-18 23:26:50 -08:00
|
|
|
result = dns_ttl_fromtext(&token.value.as_textregion,
|
|
|
|
&lctx->ttl);
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
2001-05-22 01:44:37 +00:00
|
|
|
limit_ttl(callbacks, source, line, &lctx->ttl);
|
2018-04-17 08:29:14 -07:00
|
|
|
explicit_ttl = true;
|
|
|
|
lctx->ttl_known = true;
|
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2000-08-01 01:33:37 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-01-28 05:03:25 +00:00
|
|
|
if (token.type != isc_tokentype_string) {
|
1999-02-10 05:25:37 +00:00
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2020-02-12 13:59:18 +01:00
|
|
|
"isc_lex_gettoken() returned "
|
|
|
|
"unexpected token type");
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = true;
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
if (rdclass == 0 &&
|
1999-10-25 18:41:36 +00:00
|
|
|
dns_rdataclass_fromtext(&rdclass,
|
2020-02-12 13:59:18 +01:00
|
|
|
&token.value.as_textregion) ==
|
2020-02-13 14:44:37 -08:00
|
|
|
ISC_R_SUCCESS)
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2001-01-05 01:02:47 +00:00
|
|
|
if (token.type != isc_tokentype_string) {
|
1999-02-10 05:25:37 +00:00
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
2020-02-12 13:59:18 +01:00
|
|
|
"isc_lex_gettoken() returned "
|
|
|
|
"unexpected token type");
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_UNEXPECTED;
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = true;
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
1999-01-28 05:03:25 +00:00
|
|
|
result = dns_rdatatype_fromtext(&type,
|
|
|
|
&token.value.as_textregion);
|
2000-09-18 06:50:35 +00:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->warn)(
|
|
|
|
callbacks, "%s:%lu: unknown RR type '%.*s'",
|
|
|
|
source, line, token.value.as_textregion.length,
|
|
|
|
token.value.as_textregion.base);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = true;
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* If the class specified does not match the zone's class
|
|
|
|
* print out a error message and exit.
|
|
|
|
*/
|
2001-02-14 13:14:50 +00:00
|
|
|
if (rdclass != 0 && rdclass != lctx->zclass) {
|
2020-02-12 13:59:18 +01:00
|
|
|
bad_class:
|
2000-11-15 19:06:04 +00:00
|
|
|
|
|
|
|
dns_rdataclass_format(rdclass, classname1,
|
|
|
|
sizeof(classname1));
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_rdataclass_format(lctx->zclass, classname2,
|
2000-11-15 19:06:04 +00:00
|
|
|
sizeof(classname2));
|
1999-02-10 05:25:37 +00:00
|
|
|
(*callbacks->error)(callbacks,
|
2002-03-05 00:59:42 +00:00
|
|
|
"%s:%lu: class '%s' != "
|
2000-11-15 19:06:04 +00:00
|
|
|
"zone class '%s'",
|
2020-02-12 13:59:18 +01:00
|
|
|
source, line, classname1,
|
|
|
|
classname2);
|
1999-02-10 05:25:37 +00:00
|
|
|
result = DNS_R_BADCLASS;
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = true;
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (type == dns_rdatatype_ns && ictx->glue == NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
current_has_delegation = true;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-28 05:03:25 +00:00
|
|
|
|
2001-12-11 20:37:16 +00:00
|
|
|
/*
|
2005-04-27 04:57:32 +00:00
|
|
|
* RFC1123: MD and MF are not allowed to be loaded from
|
2001-12-11 20:37:16 +00:00
|
|
|
* master files.
|
|
|
|
*/
|
2020-04-28 15:37:19 +10:00
|
|
|
if (dns_master_isprimary(lctx) &&
|
2020-02-13 14:44:37 -08:00
|
|
|
(type == dns_rdatatype_md || type == dns_rdatatype_mf))
|
|
|
|
{
|
2018-11-13 14:12:02 +11:00
|
|
|
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
2001-12-11 20:37:16 +00:00
|
|
|
|
|
|
|
result = DNS_R_OBSOLETE;
|
|
|
|
|
2018-11-13 14:12:02 +11:00
|
|
|
dns_rdatatype_format(type, typebuf, sizeof(typebuf));
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks, "%s:%lu: %s '%s': %s",
|
|
|
|
source, line, "type", typebuf,
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result));
|
2018-01-22 14:26:04 +05:30
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2018-01-22 14:26:04 +05:30
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2018-01-22 14:26:04 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* RFC2930: TKEY and TSIG are not allowed to be loaded
|
|
|
|
* from master files.
|
|
|
|
*/
|
2020-04-28 15:37:19 +10:00
|
|
|
if (dns_master_isprimary(lctx) && dns_rdatatype_ismeta(type)) {
|
2018-11-13 14:12:02 +11:00
|
|
|
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
2018-01-22 14:26:04 +05:30
|
|
|
|
|
|
|
result = DNS_R_METATYPE;
|
|
|
|
|
2018-11-13 14:12:02 +11:00
|
|
|
dns_rdatatype_format(type, typebuf, sizeof(typebuf));
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks, "%s:%lu: %s '%s': %s",
|
|
|
|
source, line, "type", typebuf,
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result));
|
2001-12-11 20:37:16 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2001-12-11 20:37:16 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-12-11 20:37:16 +00:00
|
|
|
}
|
|
|
|
|
1999-08-31 22:14:06 +00:00
|
|
|
/*
|
|
|
|
* Find a rdata structure.
|
|
|
|
*/
|
|
|
|
if (rdcount == rdata_size) {
|
|
|
|
new_rdata = grow_rdata(rdata_size + RDSZ, rdata,
|
|
|
|
rdata_size, ¤t_list,
|
|
|
|
&glue_list, mctx);
|
|
|
|
if (new_rdata == NULL) {
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_NOMEMORY;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-08-31 22:14:06 +00:00
|
|
|
}
|
|
|
|
rdata_size += RDSZ;
|
|
|
|
rdata = new_rdata;
|
|
|
|
}
|
|
|
|
|
2002-07-19 02:34:58 +00:00
|
|
|
/*
|
|
|
|
* Peek at the NS record.
|
|
|
|
*/
|
|
|
|
if (type == dns_rdatatype_ns &&
|
|
|
|
lctx->zclass == dns_rdataclass_in &&
|
2020-02-13 14:44:37 -08:00
|
|
|
(lctx->options & DNS_MASTER_CHECKNS) != 0)
|
|
|
|
{
|
2018-04-17 08:29:14 -07:00
|
|
|
GETTOKEN(lctx->lex, 0, &token, false);
|
2002-07-19 02:34:58 +00:00
|
|
|
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);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2002-07-19 02:34:58 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-07-19 02:34:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-27 20:41:51 +00:00
|
|
|
/*
|
|
|
|
* Check owner name.
|
|
|
|
*/
|
|
|
|
options &= ~DNS_RDATA_CHECKREVERSE;
|
|
|
|
if ((lctx->options & DNS_MASTER_CHECKNAMES) != 0) {
|
2020-02-13 14:44:37 -08:00
|
|
|
bool ok;
|
2004-02-27 20:41:51 +00:00
|
|
|
dns_name_t *name;
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
name = (ictx->glue != NULL) ? ictx->glue
|
|
|
|
: ictx->current;
|
2004-02-27 20:41:51 +00:00
|
|
|
ok = dns_rdata_checkowner(name, lctx->zclass, type,
|
2018-04-17 08:29:14 -07:00
|
|
|
true);
|
2004-02-27 20:41:51 +00:00
|
|
|
if (!ok) {
|
2020-02-13 14:44:37 -08:00
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
2004-02-27 20:41:51 +00:00
|
|
|
const char *desc;
|
|
|
|
dns_name_format(name, namebuf, sizeof(namebuf));
|
|
|
|
result = DNS_R_BADOWNERNAME;
|
2021-10-04 17:14:53 +02:00
|
|
|
desc = isc_result_totext(result);
|
2014-04-24 18:58:03 +10:00
|
|
|
if (CHECKNAMESFAIL(lctx->options) ||
|
|
|
|
type == dns_rdatatype_nsec3) {
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(
|
|
|
|
callbacks, "%s:%lu: %s: %s",
|
|
|
|
source, line, namebuf, desc);
|
2004-02-27 20:41:51 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2004-02-27 20:41:51 +00:00
|
|
|
goto cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
2004-02-27 20:41:51 +00:00
|
|
|
} else {
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->warn)(
|
|
|
|
callbacks, "%s:%lu: %s: %s",
|
|
|
|
source, line, namebuf, desc);
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (type == dns_rdatatype_ptr &&
|
2015-08-25 14:46:06 +10:00
|
|
|
!dns_name_isdnssd(name) &&
|
2004-02-27 20:41:51 +00:00
|
|
|
(dns_name_issubdomain(name, &in_addr_arpa) ||
|
|
|
|
dns_name_issubdomain(name, &ip6_arpa) ||
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_name_issubdomain(name, &ip6_int)))
|
|
|
|
{
|
2004-02-27 20:41:51 +00:00
|
|
|
options |= DNS_RDATA_CHECKREVERSE;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2004-02-27 20:41:51 +00:00
|
|
|
}
|
|
|
|
|
1999-08-31 22:14:06 +00:00
|
|
|
/*
|
|
|
|
* Read rdata contents.
|
|
|
|
*/
|
2000-10-20 02:21:58 +00:00
|
|
|
dns_rdata_init(&rdata[rdcount]);
|
2001-05-09 03:41:47 +00:00
|
|
|
target_ft = target;
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_rdata_fromtext(&rdata[rdcount], lctx->zclass, type,
|
|
|
|
lctx->lex, ictx->origin, options,
|
|
|
|
lctx->mctx, &target, callbacks);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2001-01-09 00:43:24 +00:00
|
|
|
continue;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2001-01-09 00:43:24 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-05-09 03:41:47 +00:00
|
|
|
|
|
|
|
if (ictx->drop) {
|
|
|
|
target = target_ft;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2001-09-04 00:35:19 +00:00
|
|
|
if (type == dns_rdatatype_soa &&
|
|
|
|
(lctx->options & DNS_MASTER_ZONE) != 0 &&
|
2020-02-13 14:44:37 -08:00
|
|
|
!dns_name_equal(ictx->current, lctx->top))
|
|
|
|
{
|
2001-09-04 00:35:19 +00:00
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
|
|
|
dns_name_format(ictx->current, namebuf,
|
|
|
|
sizeof(namebuf));
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks,
|
|
|
|
"%s:%lu: SOA "
|
2008-01-18 23:46:58 +00:00
|
|
|
"record not at top of zone (%s)",
|
|
|
|
source, line, namebuf);
|
2001-09-04 00:35:19 +00:00
|
|
|
result = DNS_R_NOTZONETOP;
|
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2018-04-17 08:29:14 -07:00
|
|
|
read_till_eol = true;
|
2001-09-04 00:35:19 +00:00
|
|
|
target = target_ft;
|
|
|
|
continue;
|
2018-03-20 09:22:57 +00:00
|
|
|
} else {
|
2001-09-04 00:35:19 +00:00
|
|
|
goto insist_and_cleanup;
|
2018-03-20 09:22:57 +00:00
|
|
|
}
|
2001-09-04 00:35:19 +00:00
|
|
|
}
|
|
|
|
|
2020-04-28 15:37:19 +10:00
|
|
|
if (dns_rdatatype_atparent(type) &&
|
|
|
|
dns_master_isprimary(lctx) &&
|
|
|
|
dns_name_equal(ictx->current, lctx->top))
|
|
|
|
{
|
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
|
|
|
char typebuf[DNS_RDATATYPE_FORMATSIZE];
|
|
|
|
|
|
|
|
dns_name_format(ictx->current, namebuf,
|
|
|
|
sizeof(namebuf));
|
|
|
|
dns_rdatatype_format(type, typebuf, sizeof(typebuf));
|
|
|
|
(*callbacks->error)(
|
|
|
|
callbacks,
|
|
|
|
"%s:%lu: %s record at top of zone (%s)", source,
|
|
|
|
line, typebuf, namebuf);
|
|
|
|
result = DNS_R_ATZONETOP;
|
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
|
|
|
target = target_ft;
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
goto insist_and_cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (type == dns_rdatatype_rrsig || type == dns_rdatatype_sig) {
|
1999-08-31 22:14:06 +00:00
|
|
|
covers = dns_rdata_covers(&rdata[rdcount]);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
1999-08-31 22:14:06 +00:00
|
|
|
covers = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-31 22:14:06 +00:00
|
|
|
|
2001-05-22 01:44:37 +00:00
|
|
|
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;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->default_ttl_known = true;
|
2001-09-30 04:31:28 +00:00
|
|
|
} else if ((lctx->options & DNS_MASTER_HINT) != 0) {
|
|
|
|
/*
|
|
|
|
* Zero TTL's are fine for hints.
|
|
|
|
*/
|
|
|
|
lctx->ttl = 0;
|
|
|
|
lctx->default_ttl = lctx->ttl;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->default_ttl_known = true;
|
2001-05-22 01:44:37 +00:00
|
|
|
} 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;
|
|
|
|
}
|
|
|
|
}
|
2001-08-01 17:58:45 +00:00
|
|
|
} else if (!explicit_ttl && lctx->default_ttl_known) {
|
2001-05-22 01:44:37 +00:00
|
|
|
lctx->ttl = lctx->default_ttl;
|
2001-06-05 06:34:45 +00:00
|
|
|
} else if (!explicit_ttl && lctx->warn_1035) {
|
2001-05-22 01:44:37 +00:00
|
|
|
(*callbacks->warn)(callbacks,
|
2002-03-05 00:59:42 +00:00
|
|
|
"%s:%lu: "
|
2005-04-27 04:57:32 +00:00
|
|
|
"using RFC1035 TTL semantics",
|
2002-03-05 00:59:42 +00:00
|
|
|
source, line);
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->warn_1035 = false;
|
2001-05-22 01:44:37 +00:00
|
|
|
}
|
|
|
|
|
2003-09-30 06:00:40 +00:00
|
|
|
if (type == dns_rdatatype_rrsig && lctx->warn_sigexpired) {
|
|
|
|
dns_rdata_rrsig_t sig;
|
2020-02-13 14:44:37 -08:00
|
|
|
result = dns_rdata_tostruct(&rdata[rdcount], &sig,
|
|
|
|
NULL);
|
2008-01-14 23:24:24 +00:00
|
|
|
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
2016-03-10 17:01:08 +11:00
|
|
|
if (isc_serial_lt(sig.timeexpire, lctx->now)) {
|
2001-07-24 18:49:06 +00:00
|
|
|
(*callbacks->warn)(callbacks,
|
2002-03-05 00:59:42 +00:00
|
|
|
"%s:%lu: "
|
2001-07-24 18:49:06 +00:00
|
|
|
"signature has expired",
|
|
|
|
source, line);
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->warn_sigexpired = false;
|
2001-07-24 18:49:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-09-30 06:00:40 +00:00
|
|
|
if ((type == dns_rdatatype_sig || type == dns_rdatatype_nxt) &&
|
2020-04-28 15:37:19 +10:00
|
|
|
lctx->warn_tcr && dns_master_isprimary(lctx))
|
2020-02-13 14:44:37 -08:00
|
|
|
{
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->warn)(callbacks,
|
|
|
|
"%s:%lu: old style DNSSEC "
|
|
|
|
" zone detected",
|
|
|
|
source, line);
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->warn_tcr = false;
|
2003-09-30 06:00:40 +00:00
|
|
|
}
|
|
|
|
|
2001-05-22 01:44:37 +00:00
|
|
|
if ((lctx->options & DNS_MASTER_AGETTL) != 0) {
|
|
|
|
/*
|
2017-09-06 09:58:29 +10:00
|
|
|
* Adjust the TTL for $DATE. If the RR has
|
|
|
|
* already expired, set its TTL to 0. This
|
|
|
|
* should be okay even if the TTL stretching
|
|
|
|
* feature is not in effect, because it will
|
|
|
|
* just be quickly expired by the cache, and the
|
|
|
|
* way this was written before the patch it
|
|
|
|
* could potentially add 0 TTLs anyway.
|
2001-05-22 01:44:37 +00:00
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (lctx->ttl < ttl_offset) {
|
2017-09-06 09:58:29 +10:00
|
|
|
lctx->ttl = 0;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2017-09-06 09:58:29 +10:00
|
|
|
lctx->ttl -= ttl_offset;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-05-22 01:44:37 +00:00
|
|
|
}
|
1999-08-31 22:14:06 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Find type in rdatalist.
|
2000-02-02 00:36:34 +00:00
|
|
|
* If it does not exist create new one and prepend to list
|
2009-01-17 14:45:17 +00:00
|
|
|
* as this will minimise list traversal.
|
1999-03-22 06:21:29 +00:00
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ictx->glue != NULL) {
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_HEAD(glue_list);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_HEAD(current_list);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
1999-01-27 23:17:57 +00:00
|
|
|
while (this != NULL) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (this->type == type && this->covers == covers) {
|
1999-01-27 13:38:21 +00:00
|
|
|
break;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
1999-01-27 13:38:21 +00:00
|
|
|
if (this == NULL) {
|
|
|
|
if (rdlcount == rdatalist_size) {
|
2020-02-12 13:59:18 +01:00
|
|
|
new_rdatalist = grow_rdatalist(
|
|
|
|
rdatalist_size + RDLSZ, rdatalist,
|
|
|
|
rdatalist_size, ¤t_list,
|
|
|
|
&glue_list, mctx);
|
1999-01-27 13:38:21 +00:00
|
|
|
if (new_rdatalist == NULL) {
|
2000-04-06 22:03:35 +00:00
|
|
|
result = ISC_R_NOMEMORY;
|
2000-09-17 13:08:46 +00:00
|
|
|
goto log_and_cleanup;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
rdatalist = new_rdatalist;
|
1999-03-22 06:21:29 +00:00
|
|
|
rdatalist_size += RDLSZ;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
this = &rdatalist[rdlcount++];
|
2015-03-03 16:43:42 +11:00
|
|
|
dns_rdatalist_init(this);
|
1999-01-27 13:38:21 +00:00
|
|
|
this->type = type;
|
1999-08-31 22:14:06 +00:00
|
|
|
this->covers = covers;
|
2001-02-14 13:14:50 +00:00
|
|
|
this->rdclass = lctx->zclass;
|
|
|
|
this->ttl = lctx->ttl;
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ictx->glue != NULL) {
|
2000-12-07 20:15:58 +00:00
|
|
|
ISC_LIST_INITANDPREPEND(glue_list, this, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2000-12-07 20:15:58 +00:00
|
|
|
ISC_LIST_INITANDPREPEND(current_list, this,
|
2008-01-18 23:46:58 +00:00
|
|
|
link);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2001-02-14 13:14:50 +00:00
|
|
|
} else if (this->ttl != lctx->ttl) {
|
1999-02-10 05:25:37 +00:00
|
|
|
(*callbacks->warn)(callbacks,
|
2002-03-05 00:59:42 +00:00
|
|
|
"%s:%lu: "
|
2000-05-24 15:07:59 +00:00
|
|
|
"TTL set to prior TTL (%lu)",
|
2001-05-09 03:41:47 +00:00
|
|
|
source, line, this->ttl);
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx->ttl = this->ttl;
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
1999-02-10 05:25:37 +00:00
|
|
|
|
2014-02-18 23:26:50 -08:00
|
|
|
if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 &&
|
2020-02-12 13:59:18 +01:00
|
|
|
lctx->ttl > lctx->maxttl) {
|
2014-02-18 23:26:50 -08:00
|
|
|
(callbacks->error)(callbacks,
|
2020-02-12 13:59:18 +01:00
|
|
|
"dns_master_load: %s:%lu: "
|
|
|
|
"TTL %d exceeds configured "
|
|
|
|
"max-zone-ttl %d",
|
|
|
|
source, line, lctx->ttl,
|
|
|
|
lctx->maxttl);
|
2014-02-18 23:26:50 -08:00
|
|
|
result = ISC_R_RANGE;
|
|
|
|
goto log_and_cleanup;
|
|
|
|
}
|
|
|
|
|
2000-09-23 01:05:35 +00:00
|
|
|
ISC_LIST_APPEND(this->rdata, &rdata[rdcount], link);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (ictx->glue != NULL) {
|
2001-05-09 03:41:47 +00:00
|
|
|
ictx->glue_line = line;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2001-05-09 03:41:47 +00:00
|
|
|
ictx->current_line = line;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-23 01:05:35 +00:00
|
|
|
rdcount++;
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We must have at least 64k as rdlen is 16 bits.
|
|
|
|
* If we don't commit everything we have so far.
|
|
|
|
*/
|
2020-02-13 21:48:23 +01:00
|
|
|
if ((target.length - target.used) < MINTSIZ) {
|
2000-08-15 03:33:52 +00:00
|
|
|
COMMITALL;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
next_line:;
|
2001-02-14 13:14:50 +00:00
|
|
|
} while (!done && (lctx->loop_cnt == 0 || loop_cnt++ < lctx->loop_cnt));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Commit what has not yet been committed.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
result = commit(callbacks, lctx, ¤t_list, ictx->current, source,
|
|
|
|
ictx->current_line);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2001-02-19 13:24:04 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
result = commit(callbacks, lctx, &glue_list, ictx->glue, source,
|
|
|
|
ictx->glue_line);
|
2001-02-14 13:14:50 +00:00
|
|
|
if (MANYERRS(lctx, result)) {
|
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2001-02-19 13:24:04 +00:00
|
|
|
goto insist_and_cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
if (!done) {
|
2001-02-14 13:14:50 +00:00
|
|
|
INSIST(lctx->done != NULL && lctx->task != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
result = DNS_R_CONTINUE;
|
2001-02-14 13:14:50 +00:00
|
|
|
} else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
|
|
|
|
result = lctx->result;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result == ISC_R_SUCCESS && lctx->seen_include) {
|
2000-10-17 07:22:39 +00:00
|
|
|
result = DNS_R_SEENINCLUDE;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-02-10 05:25:37 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
log_and_cleanup:
|
2001-01-09 00:43:24 +00:00
|
|
|
LOGIT(result);
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
insist_and_cleanup:
|
2000-09-17 13:08:46 +00:00
|
|
|
INSIST(result != ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
while ((this = ISC_LIST_HEAD(current_list)) != NULL) {
|
1999-01-27 13:38:21 +00:00
|
|
|
ISC_LIST_UNLINK(current_list, this, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
while ((this = ISC_LIST_HEAD(glue_list)) != NULL) {
|
1999-01-27 13:38:21 +00:00
|
|
|
ISC_LIST_UNLINK(glue_list, this, link);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (rdatalist != NULL) {
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_mem_put(mctx, rdatalist,
|
2001-11-12 19:05:39 +00:00
|
|
|
rdatalist_size * sizeof(*rdatalist));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (rdata != NULL) {
|
2001-11-12 19:05:39 +00:00
|
|
|
isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (target_mem != NULL) {
|
1999-01-27 13:38:21 +00:00
|
|
|
isc_mem_put(mctx, target_mem, target_size);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (include_file != NULL) {
|
1999-01-28 01:16:59 +00:00
|
|
|
isc_mem_free(mctx, include_file);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (range != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, range);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (lhs != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, lhs);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (gtype != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, gtype);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (rhs != NULL) {
|
2000-09-18 06:50:35 +00:00
|
|
|
isc_mem_free(mctx, rhs);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-03-22 19:27:51 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) {
|
|
|
|
isc_result_t result;
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_incctx_t *ictx;
|
2017-07-21 11:52:24 +10:00
|
|
|
dns_incctx_t *newctx = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_region_t r;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
|
|
|
REQUIRE(master_file != NULL);
|
2001-02-14 13:14:50 +00:00
|
|
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
ictx = lctx->inc;
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->seen_include = true;
|
2000-10-17 07:22:39 +00:00
|
|
|
|
2017-07-21 11:52:24 +10:00
|
|
|
result = incctx_create(lctx->mctx, origin, &newctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
1999-08-05 22:10:23 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2014-12-03 09:42:30 +11:00
|
|
|
/*
|
|
|
|
* Push origin_changed.
|
|
|
|
*/
|
2017-07-21 11:52:24 +10:00
|
|
|
newctx->origin_changed = ictx->origin_changed;
|
2014-12-03 09:42:30 +11:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
/* Set current domain. */
|
2001-02-14 13:14:50 +00:00
|
|
|
if (ictx->glue != NULL || ictx->current != NULL) {
|
2018-05-28 17:26:39 +10:00
|
|
|
newctx->current_in_use = find_free_name(newctx);
|
2020-02-12 13:59:18 +01:00
|
|
|
newctx->current = dns_fixedname_name(
|
|
|
|
&newctx->fixed[newctx->current_in_use]);
|
2018-04-17 08:29:14 -07:00
|
|
|
newctx->in_use[newctx->current_in_use] = true;
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_name_toregion(
|
|
|
|
(ictx->glue != NULL) ? ictx->glue : ictx->current, &r);
|
2017-07-21 11:52:24 +10:00
|
|
|
dns_name_fromregion(newctx->current, &r);
|
|
|
|
newctx->drop = ictx->drop;
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->openfile)(lctx, master_file);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-07-21 11:52:24 +10:00
|
|
|
newctx->parent = ictx;
|
|
|
|
lctx->inc = newctx;
|
2012-01-31 03:35:41 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (lctx->include_cb != NULL) {
|
2012-01-31 03:35:41 +00:00
|
|
|
lctx->include_cb(master_file, lctx->include_arg);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2017-07-21 11:52:24 +10:00
|
|
|
incctx_destroy(lctx->mctx, newctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
2000-03-22 19:27:51 +00:00
|
|
|
}
|
|
|
|
|
2016-01-21 15:33:08 +11:00
|
|
|
/*
|
|
|
|
* Fill/check exists buffer with 'len' bytes. Track remaining bytes to be
|
|
|
|
* read when incrementally filling the buffer.
|
|
|
|
*/
|
2005-06-20 01:05:33 +00:00
|
|
|
static inline isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
read_and_check(bool do_read, isc_buffer_t *buffer, size_t len, FILE *f,
|
2020-02-13 14:44:37 -08:00
|
|
|
uint32_t *totallen) {
|
2005-06-20 01:05:33 +00:00
|
|
|
isc_result_t result;
|
|
|
|
|
2016-01-21 15:33:08 +11:00
|
|
|
REQUIRE(totallen != NULL);
|
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
if (do_read) {
|
|
|
|
INSIST(isc_buffer_availablelength(buffer) >= len);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = isc_stdio_read(isc_buffer_used(buffer), 1, len, f,
|
|
|
|
NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-12-04 12:47:23 +11:00
|
|
|
isc_buffer_add(buffer, (unsigned int)len);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (*totallen < len) {
|
2016-01-21 15:33:08 +11:00
|
|
|
return (ISC_R_RANGE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2018-03-28 14:19:37 +02:00
|
|
|
*totallen -= (uint32_t)len;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (isc_buffer_remaininglength(buffer) < len) {
|
2005-06-20 01:05:33 +00:00
|
|
|
return (ISC_R_RANGE);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2012-06-20 14:13:12 -05:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
load_header(dns_loadctx_t *lctx) {
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2012-06-20 14:13:12 -05:00
|
|
|
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)];
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_buffer_t target;
|
2012-06-20 14:13:12 -05:00
|
|
|
|
|
|
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
|
|
|
|
2021-09-16 11:46:13 +02:00
|
|
|
if (lctx->format != dns_masterformat_raw) {
|
2012-06-20 14:13:12 -05:00
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-06-20 14:13:12 -05:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2013-12-04 12:47:23 +11:00
|
|
|
isc_buffer_add(&target, (unsigned int)commonlen);
|
2012-06-20 14:13:12 -05:00
|
|
|
header.format = isc_buffer_getuint32(&target);
|
|
|
|
if (header.format != lctx->format) {
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks,
|
|
|
|
"dns_master_load: "
|
2021-09-16 11:46:13 +02:00
|
|
|
"file format mismatch (not raw)");
|
2012-06-20 14:13:12 -05:00
|
|
|
return (ISC_R_NOTIMPLEMENTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
header.version = isc_buffer_getuint32(&target);
|
2012-06-20 23:46:40 +00:00
|
|
|
|
2012-06-20 14:13:12 -05:00
|
|
|
switch (header.version) {
|
|
|
|
case 0:
|
|
|
|
remainder = sizeof(header.dumptime);
|
|
|
|
break;
|
|
|
|
case DNS_RAWFORMAT_VERSION:
|
|
|
|
remainder = sizeof(header) - commonlen;
|
|
|
|
break;
|
|
|
|
default:
|
2020-02-12 13:59:18 +01:00
|
|
|
(*callbacks->error)(callbacks, "dns_master_load: "
|
|
|
|
"unsupported file format "
|
|
|
|
"version");
|
2012-06-20 14:13:12 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2013-12-04 12:47:23 +11:00
|
|
|
isc_buffer_add(&target, (unsigned int)remainder);
|
2012-06-20 14:13:12 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
lctx->first = false;
|
2012-06-20 14:13:12 -05:00
|
|
|
lctx->header = header;
|
2012-06-20 23:46:40 +00:00
|
|
|
|
2012-06-20 14:13:12 -05:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2012-06-21 12:58:46 -07:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
openfile_raw(dns_loadctx_t *lctx, const char *master_file) {
|
2012-06-21 12:58:46 -07:00
|
|
|
isc_result_t result;
|
|
|
|
|
2013-01-09 17:03:03 +11:00
|
|
|
result = isc_stdio_open(master_file, "rb", &lctx->f);
|
2012-06-21 12:58:46 -07:00
|
|
|
if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
|
|
|
"isc_stdio_open() failed: %s",
|
|
|
|
isc_result_totext(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2005-08-23 04:05:50 +00:00
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
load_raw(dns_loadctx_t *lctx) {
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
bool done = false;
|
|
|
|
unsigned int loop_cnt = 0;
|
2005-06-20 01:05:33 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks;
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned char namebuf[DNS_NAME_MAXWIRE];
|
|
|
|
dns_fixedname_t fixed;
|
|
|
|
dns_name_t *name;
|
|
|
|
rdatalist_head_t head, dummy;
|
|
|
|
dns_rdatalist_t rdatalist;
|
|
|
|
isc_mem_t *mctx = lctx->mctx;
|
|
|
|
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;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
callbacks = lctx->callbacks;
|
2012-09-12 11:44:24 +10:00
|
|
|
dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
if (lctx->first) {
|
2012-06-20 14:13:12 -05:00
|
|
|
result = load_header(lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2011-12-08 16:07:22 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 = isc_mem_get(mctx, target_size);
|
|
|
|
isc_buffer_init(&target, target_mem, target_size);
|
|
|
|
|
2018-03-28 14:38:09 +02:00
|
|
|
name = dns_fixedname_initname(&fixed);
|
2012-09-12 11:44:24 +10:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2020-02-12 13:59:18 +01:00
|
|
|
for (loop_cnt = 0; (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt);
|
2020-02-13 14:44:37 -08:00
|
|
|
loop_cnt++)
|
|
|
|
{
|
2012-09-12 11:44:24 +10:00
|
|
|
unsigned int i, rdcount;
|
2020-02-13 14:44:37 -08:00
|
|
|
uint16_t namelen;
|
|
|
|
uint32_t totallen;
|
|
|
|
size_t minlen, readlen;
|
|
|
|
bool sequential_read = false;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
/* Read the data length */
|
|
|
|
isc_buffer_clear(&target);
|
2020-02-12 13:59:18 +01:00
|
|
|
INSIST(isc_buffer_availablelength(&target) >= sizeof(totallen));
|
2005-06-20 01:05:33 +00:00
|
|
|
result = isc_stdio_read(target.base, 1, sizeof(totallen),
|
|
|
|
lctx->f, NULL);
|
|
|
|
if (result == ISC_R_EOF) {
|
|
|
|
result = ISC_R_SUCCESS;
|
2018-04-17 08:29:14 -07:00
|
|
|
done = true;
|
2005-06-20 01:05:33 +00:00
|
|
|
break;
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
isc_buffer_add(&target, sizeof(totallen));
|
|
|
|
totallen = isc_buffer_getuint32(&target);
|
2016-01-21 15:33:08 +11:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
/*
|
|
|
|
* Validation: the input data must at least contain the common
|
|
|
|
* header.
|
|
|
|
*/
|
2018-03-28 14:19:37 +02:00
|
|
|
minlen = sizeof(totallen) + sizeof(uint16_t) +
|
2020-02-12 13:59:18 +01:00
|
|
|
sizeof(uint16_t) + sizeof(uint16_t) +
|
|
|
|
sizeof(uint32_t) + sizeof(uint32_t);
|
2005-06-20 01:05:33 +00:00
|
|
|
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).
|
|
|
|
*/
|
2018-04-17 08:29:14 -07:00
|
|
|
sequential_read = true;
|
2005-06-20 01:05:33 +00:00
|
|
|
readlen = minlen - sizeof(totallen);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Typical case. We can read the whole RRset at once
|
|
|
|
* with the default buffer.
|
|
|
|
*/
|
|
|
|
readlen = totallen;
|
|
|
|
}
|
2020-02-12 13:59:18 +01:00
|
|
|
result = isc_stdio_read(target.base, 1, readlen, lctx->f, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2013-12-04 12:47:23 +11:00
|
|
|
isc_buffer_add(&target, (unsigned int)readlen);
|
2018-03-28 14:19:37 +02:00
|
|
|
totallen -= (uint32_t)readlen;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
/* Construct RRset headers */
|
2015-03-03 16:43:42 +11:00
|
|
|
dns_rdatalist_init(&rdatalist);
|
2005-06-20 01:05:33 +00:00
|
|
|
rdatalist.rdclass = isc_buffer_getuint16(&target);
|
2015-09-16 10:43:22 +10:00
|
|
|
if (lctx->zclass != rdatalist.rdclass) {
|
|
|
|
result = DNS_R_BADCLASS;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
rdatalist.type = isc_buffer_getuint16(&target);
|
|
|
|
rdatalist.covers = isc_buffer_getuint16(&target);
|
2020-02-12 13:59:18 +01:00
|
|
|
rdatalist.ttl = isc_buffer_getuint32(&target);
|
2005-06-20 01:05:33 +00:00
|
|
|
rdcount = isc_buffer_getuint32(&target);
|
2014-06-04 13:16:42 +10:00
|
|
|
if (rdcount == 0 || rdcount > 0xffff) {
|
2005-11-30 03:33:49 +00:00
|
|
|
result = ISC_R_RANGE;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
INSIST(isc_buffer_consumedlength(&target) <= readlen);
|
|
|
|
|
|
|
|
/* Owner name: length followed by name */
|
|
|
|
result = read_and_check(sequential_read, &target,
|
2016-01-21 15:33:08 +11:00
|
|
|
sizeof(namelen), lctx->f, &totallen);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
namelen = isc_buffer_getuint16(&target);
|
|
|
|
if (namelen > sizeof(namebuf)) {
|
|
|
|
result = ISC_R_RANGE;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = read_and_check(sequential_read, &target, namelen,
|
2016-01-21 15:33:08 +11:00
|
|
|
lctx->f, &totallen);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2012-09-12 11:44:24 +10:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
isc_buffer_setactive(&target, (unsigned int)namelen);
|
2012-09-12 11:44:24 +10:00
|
|
|
result = dns_name_fromwire(name, &target, &dctx, 0, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2012-09-12 11:44:24 +10:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2014-02-18 23:26:50 -08:00
|
|
|
if ((lctx->options & DNS_MASTER_CHECKTTL) != 0 &&
|
2020-02-12 13:59:18 +01:00
|
|
|
rdatalist.ttl > lctx->maxttl) {
|
2014-02-18 23:26:50 -08:00
|
|
|
(callbacks->error)(callbacks,
|
|
|
|
"dns_master_load: "
|
|
|
|
"TTL %d exceeds configured "
|
2014-02-20 10:53:11 +11:00
|
|
|
"max-zone-ttl %d",
|
2014-02-18 23:26:50 -08:00
|
|
|
rdatalist.ttl, lctx->maxttl);
|
|
|
|
result = ISC_R_RANGE;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
/* Rdata contents. */
|
|
|
|
if (rdcount > rdata_size) {
|
|
|
|
dns_rdata_t *new_rdata = NULL;
|
|
|
|
|
2012-02-13 23:46:24 +00:00
|
|
|
new_rdata = grow_rdata(rdcount + RDSZ, rdata,
|
2020-02-12 13:59:18 +01:00
|
|
|
rdata_size, &head, &dummy, mctx);
|
2005-06-20 01:05:33 +00:00
|
|
|
if (new_rdata == NULL) {
|
|
|
|
result = ISC_R_NOMEMORY;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
2012-02-13 23:46:24 +00:00
|
|
|
rdata_size = rdcount + RDSZ;
|
2005-06-20 01:05:33 +00:00
|
|
|
rdata = new_rdata;
|
|
|
|
}
|
|
|
|
|
|
|
|
continue_read:
|
|
|
|
for (i = 0; i < rdcount; i++) {
|
2018-03-28 14:19:37 +02:00
|
|
|
uint16_t rdlen;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
dns_rdata_init(&rdata[i]);
|
2008-01-18 23:46:58 +00:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
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);
|
2012-09-12 11:44:24 +10:00
|
|
|
result = commit(callbacks, lctx, &head, name,
|
2005-06-20 01:05:33 +00:00
|
|
|
NULL, 0);
|
|
|
|
for (j = 0; j < i; j++) {
|
|
|
|
ISC_LIST_UNLINK(rdatalist.rdata,
|
|
|
|
&rdata[j], link);
|
|
|
|
dns_rdata_reset(&rdata[j]);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
/* Rewind the buffer and continue */
|
|
|
|
isc_buffer_clear(&target);
|
|
|
|
|
|
|
|
rdcount -= i;
|
|
|
|
|
|
|
|
goto continue_read;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* rdata length */
|
|
|
|
result = read_and_check(sequential_read, &target,
|
2016-01-21 15:33:08 +11:00
|
|
|
sizeof(rdlen), lctx->f,
|
|
|
|
&totallen);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
rdlen = isc_buffer_getuint16(&target);
|
|
|
|
|
|
|
|
/* rdata */
|
2020-02-12 13:59:18 +01:00
|
|
|
result = read_and_check(sequential_read, &target, rdlen,
|
|
|
|
lctx->f, &totallen);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
isc_buffer_setactive(&target, (unsigned int)rdlen);
|
2012-09-12 11:44:24 +10:00
|
|
|
/*
|
|
|
|
* 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);
|
2020-02-12 13:59:18 +01:00
|
|
|
result = dns_rdata_fromwire(
|
|
|
|
&rdata[i], rdatalist.rdclass, rdatalist.type,
|
|
|
|
&target, &dctx, 0, &buf);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2012-09-12 11:44:24 +10:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
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.
|
|
|
|
*/
|
2016-01-21 15:33:08 +11:00
|
|
|
if (isc_buffer_remaininglength(&target) != 0 || totallen != 0) {
|
2005-06-20 01:05:33 +00:00
|
|
|
result = ISC_R_RANGE;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_LIST_APPEND(head, &rdatalist, link);
|
|
|
|
|
|
|
|
/* Commit this RRset. rdatalist will be unlinked. */
|
2012-09-12 11:44:24 +10:00
|
|
|
result = commit(callbacks, lctx, &head, name, NULL, 0);
|
2005-06-20 01:05:33 +00:00
|
|
|
|
|
|
|
for (i = 0; i < rdcount; i++) {
|
|
|
|
ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link);
|
|
|
|
dns_rdata_reset(&rdata[i]);
|
|
|
|
}
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!done) {
|
|
|
|
INSIST(lctx->done != NULL && lctx->task != NULL);
|
|
|
|
result = DNS_R_CONTINUE;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) {
|
2005-06-20 01:05:33 +00:00
|
|
|
result = lctx->result;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL) {
|
2012-06-20 14:13:12 -05:00
|
|
|
(*callbacks->rawdata)(callbacks->zone, &lctx->header);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2011-12-08 16:07:22 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (rdata != NULL) {
|
2005-06-20 01:05:33 +00:00
|
|
|
isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
|
|
|
if (target_mem != NULL) {
|
2005-06-20 01:05:33 +00:00
|
|
|
isc_mem_put(mctx, target_mem, target_size);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2005-06-20 01:05:33 +00:00
|
|
|
if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) {
|
|
|
|
(*callbacks->error)(callbacks, "dns_master_load: %s",
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result));
|
2005-06-20 01:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2000-03-22 19:27:51 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_master_loadfile(const char *master_file, dns_name_t *top,
|
2018-04-03 13:09:55 +02:00
|
|
|
dns_name_t *origin, dns_rdataclass_t zclass,
|
2018-03-28 14:19:37 +02:00
|
|
|
unsigned int options, uint32_t resign,
|
2018-04-03 13:09:55 +02:00
|
|
|
dns_rdatacallbacks_t *callbacks,
|
|
|
|
dns_masterincludecb_t include_cb, void *include_arg,
|
|
|
|
isc_mem_t *mctx, dns_masterformat_t format,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_ttl_t maxttl) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
2000-03-22 19:27:51 +00:00
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(format, mctx, options, resign, top, zclass,
|
2020-02-12 13:59:18 +01:00
|
|
|
origin, callbacks, NULL, NULL, NULL, include_cb,
|
|
|
|
include_arg, NULL, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2014-02-18 23:26:50 -08:00
|
|
|
lctx->maxttl = maxttl;
|
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->openfile)(lctx, master_file);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->load)(lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
INSIST(result != DNS_R_CONTINUE);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2007-08-27 03:32:27 +00:00
|
|
|
dns_loadctx_detach(&lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_result_t
|
|
|
|
dns_master_loadfileinc(const char *master_file, dns_name_t *top,
|
|
|
|
dns_name_t *origin, dns_rdataclass_t zclass,
|
2018-03-28 14:19:37 +02:00
|
|
|
unsigned int options, uint32_t resign,
|
2020-02-12 13:59:18 +01:00
|
|
|
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, isc_mem_t *mctx,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_masterformat_t format, uint32_t maxttl) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
2005-06-20 01:05:33 +00:00
|
|
|
|
2000-12-17 23:43:12 +00:00
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(done != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(format, mctx, options, resign, top, zclass,
|
2012-01-31 03:35:41 +00:00
|
|
|
origin, callbacks, task, done, done_arg,
|
|
|
|
include_cb, include_arg, NULL, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2014-02-18 23:26:50 -08:00
|
|
|
lctx->maxttl = maxttl;
|
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->openfile)(lctx, master_file);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = task_send(lctx);
|
2001-02-01 21:29:41 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_attach(lctx, lctxp);
|
2000-12-17 23:43:12 +00:00
|
|
|
return (DNS_R_CONTINUE);
|
2001-02-01 21:29:41 +00:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2007-08-27 03:32:27 +00:00
|
|
|
dns_loadctx_detach(&lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
1999-08-05 22:10:23 +00:00
|
|
|
dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
2001-01-05 03:12:45 +00:00
|
|
|
dns_rdataclass_t zclass, unsigned int options,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) {
|
|
|
|
isc_result_t result;
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
|
|
|
REQUIRE(stream != NULL);
|
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
2005-06-20 01:05:33 +00:00
|
|
|
zclass, origin, callbacks, NULL, NULL, NULL,
|
2012-01-31 03:35:41 +00:00
|
|
|
NULL, NULL, NULL, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-22 19:27:51 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = isc_lex_openstream(lctx->lex, stream);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->load)(lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
INSIST(result != DNS_R_CONTINUE);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (lctx != NULL) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_detach(&lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin,
|
2001-01-05 03:12:45 +00:00
|
|
|
dns_rdataclass_t zclass, unsigned int options,
|
2000-08-15 03:33:52 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks, isc_task_t *task,
|
|
|
|
dns_loaddonefunc_t done, void *done_arg,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_loadctx_t **lctxp, isc_mem_t *mctx) {
|
|
|
|
isc_result_t result;
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
REQUIRE(stream != NULL);
|
2000-12-17 23:43:12 +00:00
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(done != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
2020-02-12 13:59:18 +01:00
|
|
|
zclass, origin, callbacks, task, done, done_arg,
|
|
|
|
NULL, NULL, NULL, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = isc_lex_openstream(lctx->lex, stream);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = task_send(lctx);
|
2001-02-01 21:29:41 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_attach(lctx, lctxp);
|
2000-12-17 23:43:12 +00:00
|
|
|
return (DNS_R_CONTINUE);
|
2001-02-01 21:29:41 +00:00
|
|
|
}
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2020-02-13 21:48:23 +01:00
|
|
|
if (lctx != NULL) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_detach(&lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, dns_name_t *origin,
|
|
|
|
dns_rdataclass_t zclass, unsigned int options,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) {
|
|
|
|
isc_result_t result;
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
1999-08-05 22:10:23 +00:00
|
|
|
|
|
|
|
REQUIRE(buffer != NULL);
|
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
2005-06-20 01:05:33 +00:00
|
|
|
zclass, origin, callbacks, NULL, NULL, NULL,
|
2012-01-31 03:35:41 +00:00
|
|
|
NULL, NULL, NULL, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
1999-08-05 22:10:23 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = isc_lex_openbuffer(lctx->lex, buffer);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->load)(lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
INSIST(result != DNS_R_CONTINUE);
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2007-08-27 03:32:27 +00:00
|
|
|
dns_loadctx_detach(&lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
|
|
|
dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top,
|
|
|
|
dns_name_t *origin, dns_rdataclass_t zclass,
|
2020-02-12 13:59:18 +01:00
|
|
|
unsigned int options, dns_rdatacallbacks_t *callbacks,
|
|
|
|
isc_task_t *task, dns_loaddonefunc_t done,
|
2020-02-13 14:44:37 -08:00
|
|
|
void *done_arg, dns_loadctx_t **lctxp,
|
|
|
|
isc_mem_t *mctx) {
|
|
|
|
isc_result_t result;
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
REQUIRE(buffer != NULL);
|
2000-12-17 23:43:12 +00:00
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(done != NULL);
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
2020-02-12 13:59:18 +01:00
|
|
|
zclass, origin, callbacks, task, done, done_arg,
|
|
|
|
NULL, NULL, NULL, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
1999-08-05 22:10:23 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-09-18 06:50:35 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = isc_lex_openbuffer(lctx->lex, buffer);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2000-08-15 03:33:52 +00:00
|
|
|
goto cleanup;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2001-02-14 13:14:50 +00:00
|
|
|
result = task_send(lctx);
|
2001-02-01 21:29:41 +00:00
|
|
|
if (result == ISC_R_SUCCESS) {
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_attach(lctx, lctxp);
|
2000-12-17 23:43:12 +00:00
|
|
|
return (DNS_R_CONTINUE);
|
2001-02-01 21:29:41 +00:00
|
|
|
}
|
1999-08-05 22:10:23 +00:00
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
cleanup:
|
2007-08-27 03:32:27 +00:00
|
|
|
dns_loadctx_detach(&lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (result);
|
1999-08-05 22:10:23 +00:00
|
|
|
}
|
|
|
|
|
2002-02-21 00:45:11 +00:00
|
|
|
isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
|
|
|
|
dns_rdataclass_t zclass, unsigned int options,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) {
|
|
|
|
isc_result_t result;
|
2002-02-21 00:45:11 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
|
|
|
|
|
|
|
REQUIRE(lex != NULL);
|
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
2005-06-20 01:05:33 +00:00
|
|
|
zclass, origin, callbacks, NULL, NULL, NULL,
|
2012-01-31 03:35:41 +00:00
|
|
|
NULL, NULL, lex, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2002-02-21 00:45:11 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-02-21 00:45:11 +00:00
|
|
|
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->load)(lctx);
|
2002-02-21 00:45:11 +00:00
|
|
|
INSIST(result != DNS_R_CONTINUE);
|
|
|
|
|
|
|
|
dns_loadctx_detach(&lctx);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
isc_result_t
|
2020-02-12 13:59:18 +01:00
|
|
|
dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
|
|
|
|
dns_rdataclass_t zclass, unsigned int options,
|
2002-02-21 00:45:11 +00:00
|
|
|
dns_rdatacallbacks_t *callbacks, isc_task_t *task,
|
|
|
|
dns_loaddonefunc_t done, void *done_arg,
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_loadctx_t **lctxp, isc_mem_t *mctx) {
|
|
|
|
isc_result_t result;
|
2002-02-21 00:45:11 +00:00
|
|
|
dns_loadctx_t *lctx = NULL;
|
|
|
|
|
|
|
|
REQUIRE(lex != NULL);
|
|
|
|
REQUIRE(task != NULL);
|
|
|
|
REQUIRE(done != NULL);
|
|
|
|
|
2008-04-02 02:37:42 +00:00
|
|
|
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
|
2020-02-12 13:59:18 +01:00
|
|
|
zclass, origin, callbacks, task, done, done_arg,
|
|
|
|
NULL, NULL, lex, &lctx);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (result != ISC_R_SUCCESS) {
|
2002-02-21 00:45:11 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2002-02-21 00:45:11 +00:00
|
|
|
|
|
|
|
result = task_send(lctx);
|
|
|
|
if (result == ISC_R_SUCCESS) {
|
|
|
|
dns_loadctx_attach(lctx, lctxp);
|
|
|
|
return (DNS_R_CONTINUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
dns_loadctx_detach(&lctx);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Grow the slab of dns_rdatalist_t structures.
|
|
|
|
* Re-link glue and current list.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
static dns_rdatalist_t *
|
2017-07-21 11:52:24 +10:00
|
|
|
grow_rdatalist(int new_len, dns_rdatalist_t *oldlist, int old_len,
|
1999-01-27 13:38:21 +00:00
|
|
|
rdatalist_head_t *current, rdatalist_head_t *glue,
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_mem_t *mctx) {
|
2017-07-21 11:52:24 +10:00
|
|
|
dns_rdatalist_t *newlist;
|
2020-02-13 14:44:37 -08:00
|
|
|
int rdlcount = 0;
|
1999-01-27 13:38:21 +00:00
|
|
|
ISC_LIST(dns_rdatalist_t) save;
|
|
|
|
dns_rdatalist_t *this;
|
|
|
|
|
2017-07-21 11:52:24 +10:00
|
|
|
newlist = isc_mem_get(mctx, new_len * sizeof(*newlist));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (newlist == NULL) {
|
1999-01-27 13:38:21 +00:00
|
|
|
return (NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
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);
|
2012-02-13 23:46:24 +00:00
|
|
|
INSIST(rdlcount < new_len);
|
2017-07-21 11:52:24 +10:00
|
|
|
newlist[rdlcount] = *this;
|
|
|
|
ISC_LIST_APPEND(*current, &newlist[rdlcount], link);
|
1999-01-27 13:38:21 +00:00
|
|
|
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);
|
2012-02-13 23:46:24 +00:00
|
|
|
INSIST(rdlcount < new_len);
|
2017-07-21 11:52:24 +10:00
|
|
|
newlist[rdlcount] = *this;
|
|
|
|
ISC_LIST_APPEND(*glue, &newlist[rdlcount], link);
|
1999-01-27 13:38:21 +00:00
|
|
|
rdlcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
INSIST(rdlcount == old_len);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (oldlist != NULL) {
|
2017-07-21 11:52:24 +10:00
|
|
|
isc_mem_put(mctx, oldlist, old_len * sizeof(*oldlist));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-07-21 11:52:24 +10:00
|
|
|
return (newlist);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Grow the slab of rdata structs.
|
|
|
|
* Re-link the current and glue chains.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
static dns_rdata_t *
|
2017-07-21 11:52:24 +10:00
|
|
|
grow_rdata(int new_len, dns_rdata_t *oldlist, int old_len,
|
2020-02-13 14:44:37 -08:00
|
|
|
rdatalist_head_t *current, rdatalist_head_t *glue, isc_mem_t *mctx) {
|
2017-07-21 11:52:24 +10:00
|
|
|
dns_rdata_t *newlist;
|
2020-02-13 14:44:37 -08:00
|
|
|
int rdcount = 0;
|
1999-01-27 13:38:21 +00:00
|
|
|
ISC_LIST(dns_rdata_t) save;
|
|
|
|
dns_rdatalist_t *this;
|
|
|
|
dns_rdata_t *rdata;
|
|
|
|
|
2017-07-21 11:52:24 +10:00
|
|
|
newlist = isc_mem_get(mctx, new_len * sizeof(*newlist));
|
2020-02-13 21:48:23 +01:00
|
|
|
if (newlist == NULL) {
|
1999-01-27 13:38:21 +00:00
|
|
|
return (NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-07-21 11:52:24 +10:00
|
|
|
memset(newlist, 0, new_len * sizeof(*newlist));
|
1999-03-22 06:21:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy current relinking.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
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);
|
2012-02-13 23:46:24 +00:00
|
|
|
INSIST(rdcount < new_len);
|
2017-07-21 11:52:24 +10:00
|
|
|
newlist[rdcount] = *rdata;
|
|
|
|
ISC_LIST_APPEND(this->rdata, &newlist[rdcount], link);
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount++;
|
|
|
|
}
|
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
2000-08-01 01:33:37 +00:00
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Copy glue relinking.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
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);
|
2012-02-13 23:46:24 +00:00
|
|
|
INSIST(rdcount < new_len);
|
2017-07-21 11:52:24 +10:00
|
|
|
newlist[rdcount] = *rdata;
|
|
|
|
ISC_LIST_APPEND(this->rdata, &newlist[rdcount], link);
|
1999-01-27 13:38:21 +00:00
|
|
|
rdcount++;
|
|
|
|
}
|
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
2012-02-13 23:46:24 +00:00
|
|
|
INSIST(rdcount == old_len || rdcount == 0);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (oldlist != NULL) {
|
2017-07-21 11:52:24 +10:00
|
|
|
isc_mem_put(mctx, oldlist, old_len * sizeof(*oldlist));
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2017-07-21 11:52:24 +10:00
|
|
|
return (newlist);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
2018-03-28 14:19:37 +02:00
|
|
|
static uint32_t
|
2020-02-13 14:44:37 -08:00
|
|
|
resign_fromlist(dns_rdatalist_t *this, dns_loadctx_t *lctx) {
|
|
|
|
dns_rdata_t *rdata;
|
2008-04-01 01:37:25 +00:00
|
|
|
dns_rdata_rrsig_t sig;
|
2020-02-13 14:44:37 -08:00
|
|
|
uint32_t when;
|
2008-04-01 01:37:25 +00:00
|
|
|
|
|
|
|
rdata = ISC_LIST_HEAD(this->rdata);
|
|
|
|
INSIST(rdata != NULL);
|
|
|
|
(void)dns_rdata_tostruct(rdata, &sig, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (isc_serial_gt(sig.timesigned, lctx->now)) {
|
2016-03-10 17:01:08 +11:00
|
|
|
when = lctx->now;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else {
|
2016-03-10 17:01:08 +11:00
|
|
|
when = sig.timeexpire - lctx->resign;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-01 01:37:25 +00:00
|
|
|
|
|
|
|
rdata = ISC_LIST_NEXT(rdata, link);
|
|
|
|
while (rdata != NULL) {
|
|
|
|
(void)dns_rdata_tostruct(rdata, &sig, NULL);
|
2020-02-13 21:48:23 +01:00
|
|
|
if (isc_serial_gt(sig.timesigned, lctx->now)) {
|
2016-03-10 17:01:08 +11:00
|
|
|
when = lctx->now;
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (sig.timeexpire - lctx->resign < when) {
|
2016-03-10 17:01:08 +11:00
|
|
|
when = sig.timeexpire - lctx->resign;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2008-04-01 01:37:25 +00:00
|
|
|
rdata = ISC_LIST_NEXT(rdata, link);
|
|
|
|
}
|
|
|
|
return (when);
|
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
|
|
|
* Convert each element from a rdatalist_t to rdataset then call commit.
|
|
|
|
* Unlink each element as we go.
|
|
|
|
*/
|
|
|
|
|
1999-12-23 00:09:04 +00:00
|
|
|
static isc_result_t
|
2001-02-14 13:14:50 +00:00
|
|
|
commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx,
|
2020-02-12 13:59:18 +01:00
|
|
|
rdatalist_head_t *head, dns_name_t *owner, const char *source,
|
2020-02-13 14:44:37 -08:00
|
|
|
unsigned int line) {
|
1999-01-27 13:38:21 +00:00
|
|
|
dns_rdatalist_t *this;
|
|
|
|
dns_rdataset_t dataset;
|
2020-02-13 14:44:37 -08:00
|
|
|
isc_result_t result;
|
|
|
|
char namebuf[DNS_NAME_FORMATSIZE];
|
2020-02-12 13:59:18 +01:00
|
|
|
void (*error)(struct dns_rdatacallbacks *, const char *, ...);
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2000-03-29 21:01:30 +00:00
|
|
|
this = ISC_LIST_HEAD(*head);
|
2001-02-19 13:24:04 +00:00
|
|
|
error = callbacks->error;
|
|
|
|
|
2020-02-13 21:48:23 +01:00
|
|
|
if (this == NULL) {
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-29 21:01:30 +00:00
|
|
|
do {
|
2001-05-09 07:18:38 +00:00
|
|
|
dns_rdataset_init(&dataset);
|
2020-02-12 13:59:18 +01:00
|
|
|
RUNTIME_CHECK(dns_rdatalist_tordataset(this, &dataset) ==
|
|
|
|
ISC_R_SUCCESS);
|
2001-05-09 07:18:38 +00:00
|
|
|
dataset.trust = dns_trust_ultimate;
|
2008-04-01 01:37:25 +00:00
|
|
|
/*
|
|
|
|
* If this is a secure dynamic zone set the re-signing time.
|
|
|
|
*/
|
|
|
|
if (dataset.type == dns_rdatatype_rrsig &&
|
2020-02-13 14:44:37 -08:00
|
|
|
(lctx->options & DNS_MASTER_RESIGN) != 0)
|
|
|
|
{
|
2008-04-01 01:37:25 +00:00
|
|
|
dataset.attributes |= DNS_RDATASETATTR_RESIGN;
|
2016-03-10 17:01:08 +11:00
|
|
|
dataset.resign = resign_fromlist(this, lctx);
|
2008-04-01 01:37:25 +00:00
|
|
|
}
|
2001-05-09 07:18:38 +00:00
|
|
|
result = ((*callbacks->add)(callbacks->add_private, owner,
|
|
|
|
&dataset));
|
|
|
|
if (result == ISC_R_NOMEMORY) {
|
|
|
|
(*error)(callbacks, "dns_master_load: %s",
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result));
|
2001-05-09 07:18:38 +00:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2008-04-01 01:37:25 +00:00
|
|
|
dns_name_format(owner, namebuf, sizeof(namebuf));
|
2005-06-20 01:05:33 +00:00
|
|
|
if (source != NULL) {
|
|
|
|
(*error)(callbacks, "%s: %s:%lu: %s: %s",
|
|
|
|
"dns_master_load", source, line,
|
2021-10-04 17:14:53 +02:00
|
|
|
namebuf, isc_result_totext(result));
|
2005-06-20 01:05:33 +00:00
|
|
|
} else {
|
|
|
|
(*error)(callbacks, "%s: %s: %s",
|
|
|
|
"dns_master_load", namebuf,
|
2021-10-04 17:14:53 +02:00
|
|
|
isc_result_totext(result));
|
2005-06-20 01:05:33 +00:00
|
|
|
}
|
2000-03-29 21:01:30 +00:00
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (MANYERRS(lctx, result)) {
|
2001-05-09 07:18:38 +00:00
|
|
|
SETRESULT(lctx, result);
|
2020-02-13 21:48:23 +01:00
|
|
|
} else if (result != ISC_R_SUCCESS) {
|
2001-05-09 07:18:38 +00:00
|
|
|
return (result);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
2000-03-29 21:01:30 +00:00
|
|
|
ISC_LIST_UNLINK(*head, this, link);
|
|
|
|
this = ISC_LIST_HEAD(*head);
|
|
|
|
} while (this != NULL);
|
2000-04-06 22:03:35 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
|
|
|
|
1999-03-22 06:21:29 +00:00
|
|
|
/*
|
2018-04-17 08:29:14 -07:00
|
|
|
* Returns true if one of the NS rdata's contains 'owner'.
|
1999-03-22 06:21:29 +00:00
|
|
|
*/
|
|
|
|
|
2018-04-17 08:29:14 -07:00
|
|
|
static bool
|
2020-02-13 14:44:37 -08:00
|
|
|
is_glue(rdatalist_head_t *head, dns_name_t *owner) {
|
1999-01-27 13:38:21 +00:00
|
|
|
dns_rdatalist_t *this;
|
|
|
|
dns_rdata_t *rdata;
|
|
|
|
isc_region_t region;
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_name_t name;
|
1999-01-27 13:38:21 +00:00
|
|
|
|
2000-05-08 14:38:29 +00:00
|
|
|
/*
|
|
|
|
* Find NS rrset.
|
|
|
|
*/
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_HEAD(*head);
|
|
|
|
while (this != NULL) {
|
2020-02-13 21:48:23 +01:00
|
|
|
if (this->type == dns_rdatatype_ns) {
|
1999-01-27 13:38:21 +00:00
|
|
|
break;
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
this = ISC_LIST_NEXT(this, link);
|
|
|
|
}
|
2020-02-13 21:48:23 +01:00
|
|
|
if (this == NULL) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
2020-02-13 21:48:23 +01:00
|
|
|
}
|
1999-01-27 13:38:21 +00:00
|
|
|
|
|
|
|
rdata = ISC_LIST_HEAD(this->rdata);
|
|
|
|
while (rdata != NULL) {
|
|
|
|
dns_name_init(&name, NULL);
|
|
|
|
dns_rdata_toregion(rdata, ®ion);
|
|
|
|
dns_name_fromregion(&name, ®ion);
|
2018-07-17 04:56:51 +10:00
|
|
|
if (dns_name_equal(&name, owner)) {
|
2018-04-17 08:29:14 -07:00
|
|
|
return (true);
|
2018-07-17 04:56:51 +10:00
|
|
|
}
|
1999-01-27 23:17:57 +00:00
|
|
|
rdata = ISC_LIST_NEXT(rdata, link);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
2018-04-17 08:29:14 -07:00
|
|
|
return (false);
|
1999-01-27 13:38:21 +00:00
|
|
|
}
|
1999-03-22 06:21:29 +00:00
|
|
|
|
2000-08-15 03:33:52 +00:00
|
|
|
static void
|
2020-02-13 14:44:37 -08:00
|
|
|
load_quantum(isc_task_t *task, isc_event_t *event) {
|
|
|
|
isc_result_t result;
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_t *lctx;
|
2000-08-15 03:33:52 +00:00
|
|
|
|
|
|
|
REQUIRE(event != NULL);
|
2001-02-14 13:14:50 +00:00
|
|
|
lctx = event->ev_arg;
|
|
|
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
2000-08-15 03:33:52 +00:00
|
|
|
|
2019-05-20 16:43:32 +02:00
|
|
|
if (atomic_load_acquire(&lctx->canceled)) {
|
2000-09-05 03:35:24 +00:00
|
|
|
result = ISC_R_CANCELED;
|
2019-05-20 16:43:32 +02:00
|
|
|
} else {
|
2005-06-20 01:05:33 +00:00
|
|
|
result = (lctx->load)(lctx);
|
2019-05-20 16:43:32 +02:00
|
|
|
}
|
2000-08-15 03:33:52 +00:00
|
|
|
if (result == DNS_R_CONTINUE) {
|
2001-02-14 13:14:50 +00:00
|
|
|
event->ev_arg = lctx;
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_task_send(task, &event);
|
|
|
|
} else {
|
2001-02-14 13:14:50 +00:00
|
|
|
(lctx->done)(lctx->done_arg, result);
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_event_free(&event);
|
2001-02-14 13:14:50 +00:00
|
|
|
dns_loadctx_detach(&lctx);
|
2000-08-15 03:33:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static isc_result_t
|
2020-02-13 14:44:37 -08:00
|
|
|
task_send(dns_loadctx_t *lctx) {
|
2000-08-15 03:33:52 +00:00
|
|
|
isc_event_t *event;
|
|
|
|
|
2020-02-12 13:59:18 +01:00
|
|
|
event = isc_event_allocate(lctx->mctx, NULL, DNS_EVENT_MASTERQUANTUM,
|
2001-02-14 13:14:50 +00:00
|
|
|
load_quantum, lctx, sizeof(*event));
|
|
|
|
isc_task_send(lctx->task, &event);
|
2000-08-15 03:33:52 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
2000-09-05 03:35:24 +00:00
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_loadctx_cancel(dns_loadctx_t *lctx) {
|
2001-02-14 13:14:50 +00:00
|
|
|
REQUIRE(DNS_LCTX_VALID(lctx));
|
2000-09-05 03:35:24 +00:00
|
|
|
|
2019-05-20 16:43:32 +02:00
|
|
|
atomic_store_release(&lctx->canceled, true);
|
2000-09-05 03:35:24 +00:00
|
|
|
}
|
2011-12-08 16:07:22 +00:00
|
|
|
|
|
|
|
void
|
2020-02-13 14:44:37 -08:00
|
|
|
dns_master_initrawheader(dns_masterrawheader_t *header) {
|
2011-12-08 16:07:22 +00:00
|
|
|
memset(header, 0, sizeof(dns_masterrawheader_t));
|
|
|
|
}
|