xref: /openbsd-src/usr.sbin/nsd/options.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*
2  * options.c -- options functions.
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 #include "config.h"
10 #include <string.h>
11 #include <stdio.h>
12 #include <errno.h>
13 #include "options.h"
14 #include "query.h"
15 #include "tsig.h"
16 #include "difffile.h"
17 #include "rrl.h"
18 
19 #include "configyyrename.h"
20 #include "configparser.h"
21 config_parser_state_type* cfg_parser = 0;
22 extern FILE* c_in, *c_out;
23 int c_parse(void);
24 int c_lex(void);
25 int c_wrap(void);
26 int c_lex_destroy(void);
27 extern char* c_text;
28 
29 static int
30 rbtree_strcmp(const void* p1, const void* p2)
31 {
32 	if(p1 == NULL && p2 == NULL) return 0;
33 	if(p1 == NULL) return -1;
34 	if(p2 == NULL) return 1;
35 	return strcmp((const char*)p1, (const char*)p2);
36 }
37 
38 struct nsd_options*
39 nsd_options_create(region_type* region)
40 {
41 	struct nsd_options* opt;
42 	opt = (struct nsd_options*)region_alloc(region, sizeof(
43 		struct nsd_options));
44 	opt->region = region;
45 	opt->zone_options = rbtree_create(region,
46 		(int (*)(const void *, const void *)) dname_compare);
47 	opt->configfile = NULL;
48 	opt->zonestatnames = rbtree_create(opt->region, rbtree_strcmp);
49 	opt->patterns = rbtree_create(region, rbtree_strcmp);
50 	opt->keys = rbtree_create(region, rbtree_strcmp);
51 	opt->ip_addresses = NULL;
52 	opt->ip_transparent = 0;
53 	opt->ip_freebind = 0;
54 	opt->send_buffer_size = 0;
55 	opt->receive_buffer_size = 0;
56 	opt->debug_mode = 0;
57 	opt->verbosity = 0;
58 	opt->hide_version = 0;
59 	opt->hide_identity = 0;
60 	opt->do_ip4 = 1;
61 	opt->do_ip6 = 1;
62 	opt->database = DBFILE;
63 	opt->identity = 0;
64 	opt->version = 0;
65 	opt->nsid = 0;
66 	opt->logfile = 0;
67 	opt->log_time_ascii = 1;
68 	opt->round_robin = 0; /* also packet.h::round_robin */
69 	opt->minimal_responses = 1; /* also packet.h::minimal_responses */
70 	opt->confine_to_zone = 0;
71 	opt->refuse_any = 1;
72 	opt->server_count = 1;
73 	opt->tcp_count = 100;
74 	opt->tcp_reject_overflow = 0;
75 	opt->tcp_query_count = 0;
76 	opt->tcp_timeout = TCP_TIMEOUT;
77 	opt->tcp_mss = 0;
78 	opt->outgoing_tcp_mss = 0;
79 	opt->ipv4_edns_size = EDNS_MAX_MESSAGE_LEN;
80 	opt->ipv6_edns_size = EDNS_MAX_MESSAGE_LEN;
81 	opt->pidfile = PIDFILE;
82 	opt->port = UDP_PORT;
83 /* deprecated?	opt->port = TCP_PORT; */
84 	opt->reuseport = 0;
85 	opt->statistics = 0;
86 	opt->chroot = 0;
87 	opt->username = USER;
88 	opt->zonesdir = ZONESDIR;
89 	opt->xfrdfile = XFRDFILE;
90 	opt->xfrdir = XFRDIR;
91 	opt->zonelistfile = ZONELISTFILE;
92 #ifdef RATELIMIT
93 	opt->rrl_size = RRL_BUCKETS;
94 	opt->rrl_slip = RRL_SLIP;
95 	opt->rrl_ipv4_prefix_length = RRL_IPV4_PREFIX_LENGTH;
96 	opt->rrl_ipv6_prefix_length = RRL_IPV6_PREFIX_LENGTH;
97 #  ifdef RATELIMIT_DEFAULT_OFF
98 	opt->rrl_ratelimit = 0;
99 	opt->rrl_whitelist_ratelimit = 0;
100 #  else
101 	opt->rrl_ratelimit = RRL_LIMIT/2;
102 	opt->rrl_whitelist_ratelimit = RRL_WLIST_LIMIT/2;
103 #  endif
104 #endif
105 #ifdef USE_DNSTAP
106 	opt->dnstap_enable = 0;
107 	opt->dnstap_socket_path = DNSTAP_SOCKET_PATH;
108 	opt->dnstap_send_identity = 0;
109 	opt->dnstap_send_version = 0;
110 	opt->dnstap_identity = NULL;
111 	opt->dnstap_version = NULL;
112 	opt->dnstap_log_auth_query_messages = 0;
113 	opt->dnstap_log_auth_response_messages = 0;
114 #endif
115 	opt->zonefiles_check = 1;
116 	if(opt->database == NULL || opt->database[0] == 0)
117 		opt->zonefiles_write = ZONEFILES_WRITE_INTERVAL;
118 	else	opt->zonefiles_write = 0;
119 	opt->xfrd_reload_timeout = 1;
120 	opt->tls_service_key = NULL;
121 	opt->tls_service_ocsp = NULL;
122 	opt->tls_service_pem = NULL;
123 	opt->tls_port = TLS_PORT;
124 	opt->control_enable = 0;
125 	opt->control_interface = NULL;
126 	opt->control_port = NSD_CONTROL_PORT;
127 	opt->server_key_file = CONFIGDIR"/nsd_server.key";
128 	opt->server_cert_file = CONFIGDIR"/nsd_server.pem";
129 	opt->control_key_file = CONFIGDIR"/nsd_control.key";
130 	opt->control_cert_file = CONFIGDIR"/nsd_control.pem";
131 	return opt;
132 }
133 
134 int
135 nsd_options_insert_zone(struct nsd_options* opt, struct zone_options* zone)
136 {
137 	/* create dname for lookup */
138 	const dname_type* dname = dname_parse(opt->region, zone->name);
139 	if(!dname)
140 		return 0;
141 	zone->node.key = dname;
142 	if(!rbtree_insert(opt->zone_options, (rbnode_type*)zone))
143 		return 0;
144 	return 1;
145 }
146 
147 int
148 nsd_options_insert_pattern(struct nsd_options* opt,
149 	struct pattern_options* pat)
150 {
151 	if(!pat->pname)
152 		return 0;
153 	pat->node.key = pat->pname;
154 	if(!rbtree_insert(opt->patterns, (rbnode_type*)pat))
155 		return 0;
156 	return 1;
157 }
158 
159 int
160 parse_options_file(struct nsd_options* opt, const char* file,
161 	void (*err)(void*,const char*), void* err_arg)
162 {
163 	FILE *in = 0;
164 	struct pattern_options* pat;
165 	struct acl_options* acl;
166 
167 	if(!cfg_parser) {
168 		cfg_parser = (config_parser_state_type*)region_alloc(
169 			opt->region, sizeof(config_parser_state_type));
170 		cfg_parser->chroot = 0;
171 	}
172 	cfg_parser->err = err;
173 	cfg_parser->err_arg = err_arg;
174 	cfg_parser->filename = (char*)file;
175 	cfg_parser->line = 1;
176 	cfg_parser->errors = 0;
177 	cfg_parser->opt = opt;
178 	cfg_parser->pattern = NULL;
179 	cfg_parser->zone = NULL;
180 	cfg_parser->key = NULL;
181 
182 	in = fopen(cfg_parser->filename, "r");
183 	if(!in) {
184 		if(err) {
185 			char m[MAXSYSLOGMSGLEN];
186 			snprintf(m, sizeof(m), "Could not open %s: %s\n",
187 				file, strerror(errno));
188 			err(err_arg, m);
189 		} else {
190 			fprintf(stderr, "Could not open %s: %s\n",
191 				file, strerror(errno));
192 		}
193 		return 0;
194 	}
195 	c_in = in;
196 	c_parse();
197 	fclose(in);
198 
199 	opt->configfile = region_strdup(opt->region, file);
200 
201 	RBTREE_FOR(pat, struct pattern_options*, opt->patterns)
202 	{
203 		/* lookup keys for acls */
204 		for(acl=pat->allow_notify; acl; acl=acl->next)
205 		{
206 			if(acl->nokey || acl->blocked)
207 				continue;
208 			acl->key_options = key_options_find(opt, acl->key_name);
209 			if(!acl->key_options)
210 				c_error("key %s in pattern %s could not be found",
211 					acl->key_name, pat->pname);
212 		}
213 		for(acl=pat->notify; acl; acl=acl->next)
214 		{
215 			if(acl->nokey || acl->blocked)
216 				continue;
217 			acl->key_options = key_options_find(opt, acl->key_name);
218 			if(!acl->key_options)
219 				c_error("key %s in pattern %s could not be found",
220 					acl->key_name, pat->pname);
221 		}
222 		for(acl=pat->request_xfr; acl; acl=acl->next)
223 		{
224 			if(acl->nokey || acl->blocked)
225 				continue;
226 			acl->key_options = key_options_find(opt, acl->key_name);
227 			if(!acl->key_options)
228 				c_error("key %s in pattern %s could not be found",
229 					acl->key_name, pat->pname);
230 		}
231 		for(acl=pat->provide_xfr; acl; acl=acl->next)
232 		{
233 			if(acl->nokey || acl->blocked)
234 				continue;
235 			acl->key_options = key_options_find(opt, acl->key_name);
236 			if(!acl->key_options)
237 				c_error("key %s in pattern %s could not be found",
238 					acl->key_name, pat->pname);
239 		}
240 	}
241 
242 	if(cfg_parser->errors > 0)
243 	{
244 		if(err) {
245 			char m[MAXSYSLOGMSGLEN];
246 			snprintf(m, sizeof(m), "read %s failed: %d errors in "
247 				"configuration file\n", file,
248 				cfg_parser->errors);
249 			err(err_arg, m);
250 		} else {
251 			fprintf(stderr, "read %s failed: %d errors in "
252 				"configuration file\n", file,
253 				cfg_parser->errors);
254 		}
255 		return 0;
256 	}
257 	return 1;
258 }
259 
260 void options_zonestatnames_create(struct nsd_options* opt)
261 {
262 	struct zone_options* zopt;
263 	/* allocate "" as zonestat 0, for zones without a zonestat */
264 	if(!rbtree_search(opt->zonestatnames, "")) {
265 		struct zonestatname* n;
266 		n = (struct zonestatname*)region_alloc_zero(opt->region,
267 			sizeof(*n));
268 		n->node.key = region_strdup(opt->region, "");
269 		if(!n->node.key) {
270 			log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
271 			exit(1);
272 		}
273 		n->id = (unsigned)(opt->zonestatnames->count);
274 		rbtree_insert(opt->zonestatnames, (rbnode_type*)n);
275 	}
276 	RBTREE_FOR(zopt, struct zone_options*, opt->zone_options) {
277 		/* insert into tree, so that when read in later id exists */
278 		(void)getzonestatid(opt, zopt);
279 	}
280 }
281 
282 #define ZONELIST_HEADER "# NSD zone list\n# name pattern\n"
283 static int
284 comp_zonebucket(const void* a, const void* b)
285 {
286 	/* the line size is much smaller than max-int, and positive,
287 	 * so the subtraction works */
288 	return *(const int*)b - *(const int*)a;
289 }
290 
291 /* insert free entry into zonelist free buckets */
292 static void
293 zone_list_free_insert(struct nsd_options* opt, int linesize, off_t off)
294 {
295 	struct zonelist_free* e;
296 	struct zonelist_bucket* b = (struct zonelist_bucket*)rbtree_search(
297 		opt->zonefree, &linesize);
298 	if(!b) {
299 		b = region_alloc_zero(opt->region, sizeof(*b));
300 		b->linesize = linesize;
301 		b->node = *RBTREE_NULL;
302 		b->node.key = &b->linesize;
303 		rbtree_insert(opt->zonefree, &b->node);
304 	}
305 	e = (struct zonelist_free*)region_alloc_zero(opt->region, sizeof(*e));
306 	e->next = b->list;
307 	b->list = e;
308 	e->off = off;
309 	opt->zonefree_number++;
310 }
311 
312 struct zone_options*
313 zone_list_zone_insert(struct nsd_options* opt, const char* nm,
314 	const char* patnm, int linesize, off_t off)
315 {
316 	struct pattern_options* pat = pattern_options_find(opt, patnm);
317 	struct zone_options* zone;
318 	if(!pat) {
319 		log_msg(LOG_ERR, "pattern does not exist for zone %s "
320 			"pattern %s", nm, patnm);
321 		return NULL;
322 	}
323 	zone = zone_options_create(opt->region);
324 	zone->part_of_config = 0;
325 	zone->name = region_strdup(opt->region, nm);
326 	zone->linesize = linesize;
327 	zone->off = off;
328 	zone->pattern = pat;
329 	if(!nsd_options_insert_zone(opt, zone)) {
330 		log_msg(LOG_ERR, "bad domain name or duplicate zone '%s' "
331 			"pattern %s", nm, patnm);
332 		region_recycle(opt->region, (void*)zone->name, strlen(nm)+1);
333 		region_recycle(opt->region, zone, sizeof(*zone));
334 		return NULL;
335 	}
336 	return zone;
337 }
338 
339 int
340 parse_zone_list_file(struct nsd_options* opt)
341 {
342 	/* zonelist looks like this:
343 	# name pattern
344 	add example.com master
345 	del example.net slave
346 	add foo.bar.nl slave
347 	add rutabaga.uk config
348 	*/
349 	char buf[1024];
350 
351 	/* create empty data structures */
352 	opt->zonefree = rbtree_create(opt->region, comp_zonebucket);
353 	opt->zonelist = NULL;
354 	opt->zonefree_number = 0;
355 	opt->zonelist_off = 0;
356 
357 	/* try to open the zonelist file, an empty or nonexist file is OK */
358 	opt->zonelist = fopen(opt->zonelistfile, "r+");
359 	if(!opt->zonelist) {
360 		if(errno == ENOENT)
361 			return 1; /* file does not exist, it is created later */
362 		log_msg(LOG_ERR, "could not open zone list %s: %s", opt->zonelistfile,
363 			strerror(errno));
364 		return 0;
365 	}
366 	/* read header */
367 	buf[strlen(ZONELIST_HEADER)] = 0;
368 	if(fread(buf, 1, strlen(ZONELIST_HEADER), opt->zonelist) !=
369 		strlen(ZONELIST_HEADER) || strncmp(buf, ZONELIST_HEADER,
370 		strlen(ZONELIST_HEADER)) != 0) {
371 		log_msg(LOG_ERR, "zone list %s contains bad header\n", opt->zonelistfile);
372 		fclose(opt->zonelist);
373 		opt->zonelist = NULL;
374 		return 0;
375 	}
376 
377 	/* read entries in file */
378 	while(fgets(buf, sizeof(buf), opt->zonelist)) {
379 		/* skip comments and empty lines */
380 		if(buf[0] == 0 || buf[0] == '\n' || buf[0] == '#')
381 			continue;
382 		if(strncmp(buf, "add ", 4) == 0) {
383 			int linesize = strlen(buf);
384 			/* parse the 'add' line */
385 			/* pick last space on the line, so that the domain
386 			 * name can have a space in it (but not the pattern)*/
387 			char* space = strrchr(buf+4, ' ');
388 			char* nm, *patnm;
389 			if(!space) {
390 				/* parse error */
391 				log_msg(LOG_ERR, "parse error in %s: '%s'",
392 					opt->zonelistfile, buf);
393 				continue;
394 			}
395 			nm = buf+4;
396 			*space = 0;
397 			patnm = space+1;
398 			if(linesize && buf[linesize-1] == '\n')
399 				buf[linesize-1] = 0;
400 
401 			/* store offset and line size for zone entry */
402 			/* and create zone entry in zonetree */
403 			(void)zone_list_zone_insert(opt, nm, patnm, linesize,
404 				ftello(opt->zonelist)-linesize);
405 		} else if(strncmp(buf, "del ", 4) == 0) {
406 			/* store offset and line size for deleted entry */
407 			int linesize = strlen(buf);
408 			zone_list_free_insert(opt, linesize,
409 				ftello(opt->zonelist)-linesize);
410 		} else {
411 			log_msg(LOG_WARNING, "bad data in %s, '%s'", opt->zonelistfile,
412 				buf);
413 		}
414 	}
415 	/* store EOF offset */
416 	opt->zonelist_off = ftello(opt->zonelist);
417 	return 1;
418 }
419 
420 void
421 zone_options_delete(struct nsd_options* opt, struct zone_options* zone)
422 {
423 	rbtree_delete(opt->zone_options, zone->node.key);
424 	region_recycle(opt->region, (void*)zone->node.key, dname_total_size(
425 		(dname_type*)zone->node.key));
426 	region_recycle(opt->region, zone, sizeof(*zone));
427 }
428 
429 /* add a new zone to the zonelist */
430 struct zone_options*
431 zone_list_add(struct nsd_options* opt, const char* zname, const char* pname)
432 {
433 	int r;
434 	struct zonelist_free* e;
435 	struct zonelist_bucket* b;
436 	int linesize = 6 + strlen(zname) + strlen(pname);
437 	/* create zone entry */
438 	struct zone_options* zone = zone_list_zone_insert(opt, zname, pname,
439 		linesize, 0);
440 	if(!zone)
441 		return NULL;
442 
443 	/* use free entry or append to file or create new file */
444 	if(!opt->zonelist || opt->zonelist_off == 0) {
445 		/* create new file */
446 		if(opt->zonelist) fclose(opt->zonelist);
447 		opt->zonelist = fopen(opt->zonelistfile, "w+");
448 		if(!opt->zonelist) {
449 			log_msg(LOG_ERR, "could not create zone list %s: %s",
450 				opt->zonelistfile, strerror(errno));
451 			log_msg(LOG_ERR, "zone %s could not be added", zname);
452 			zone_options_delete(opt, zone);
453 			return NULL;
454 		}
455 		r = fprintf(opt->zonelist, ZONELIST_HEADER);
456 		if(r != strlen(ZONELIST_HEADER)) {
457 			if(r == -1)
458 				log_msg(LOG_ERR, "could not write to %s: %s",
459 					opt->zonelistfile, strerror(errno));
460 			else log_msg(LOG_ERR, "partial write to %s: disk full",
461 				opt->zonelistfile);
462 			log_msg(LOG_ERR, "zone %s could not be added", zname);
463 			zone_options_delete(opt, zone);
464 			return NULL;
465 		}
466 		zone->off = ftello(opt->zonelist);
467 		if(zone->off == -1)
468 			log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno));
469 		r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
470 		if(r != zone->linesize) {
471 			if(r == -1)
472 				log_msg(LOG_ERR, "could not write to %s: %s",
473 					opt->zonelistfile, strerror(errno));
474 			else log_msg(LOG_ERR, "partial write to %s: disk full",
475 				opt->zonelistfile);
476 			log_msg(LOG_ERR, "zone %s could not be added", zname);
477 			zone_options_delete(opt, zone);
478 			return NULL;
479 		}
480 		opt->zonelist_off = ftello(opt->zonelist);
481 		if(opt->zonelist_off == -1)
482 			log_msg(LOG_ERR, "ftello(%s): %s", opt->zonelistfile, strerror(errno));
483 		if(fflush(opt->zonelist) != 0) {
484 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
485 		}
486 		return zone;
487 	}
488 	b = (struct zonelist_bucket*)rbtree_search(opt->zonefree,
489 		&zone->linesize);
490 	if(!b || b->list == NULL) {
491 		/* no empty place, append to file */
492 		zone->off = opt->zonelist_off;
493 		if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
494 			log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
495 			log_msg(LOG_ERR, "zone %s could not be added", zname);
496 			zone_options_delete(opt, zone);
497 			return NULL;
498 		}
499 		r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
500 		if(r != zone->linesize) {
501 			if(r == -1)
502 				log_msg(LOG_ERR, "could not write to %s: %s",
503 					opt->zonelistfile, strerror(errno));
504 			else log_msg(LOG_ERR, "partial write to %s: disk full",
505 				opt->zonelistfile);
506 			log_msg(LOG_ERR, "zone %s could not be added", zname);
507 			zone_options_delete(opt, zone);
508 			return NULL;
509 		}
510 		opt->zonelist_off += linesize;
511 		if(fflush(opt->zonelist) != 0) {
512 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
513 		}
514 		return zone;
515 	}
516 	/* reuse empty spot */
517 	e = b->list;
518 	zone->off = e->off;
519 	if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
520 		log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
521 		log_msg(LOG_ERR, "zone %s could not be added", zname);
522 		zone_options_delete(opt, zone);
523 		return NULL;
524 	}
525 	r = fprintf(opt->zonelist, "add %s %s\n", zname, pname);
526 	if(r != zone->linesize) {
527 		if(r == -1)
528 			log_msg(LOG_ERR, "could not write to %s: %s",
529 				opt->zonelistfile, strerror(errno));
530 		else log_msg(LOG_ERR, "partial write to %s: disk full",
531 			opt->zonelistfile);
532 		log_msg(LOG_ERR, "zone %s could not be added", zname);
533 		zone_options_delete(opt, zone);
534 		return NULL;
535 	}
536 	if(fflush(opt->zonelist) != 0) {
537 		log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
538 	}
539 
540 	/* snip off and recycle element */
541 	b->list = e->next;
542 	region_recycle(opt->region, e, sizeof(*e));
543 	if(b->list == NULL) {
544 		rbtree_delete(opt->zonefree, &b->linesize);
545 		region_recycle(opt->region, b, sizeof(*b));
546 	}
547 	opt->zonefree_number--;
548 	return zone;
549 }
550 
551 /* remove a zone on the zonelist */
552 void
553 zone_list_del(struct nsd_options* opt, struct zone_options* zone)
554 {
555 	/* put its space onto the free entry */
556 	if(fseeko(opt->zonelist, zone->off, SEEK_SET) == -1) {
557 		log_msg(LOG_ERR, "fseeko(%s): %s", opt->zonelistfile, strerror(errno));
558 		return;
559 	}
560 	fprintf(opt->zonelist, "del");
561 	zone_list_free_insert(opt, zone->linesize, zone->off);
562 
563 	/* remove zone_options */
564 	zone_options_delete(opt, zone);
565 
566 	/* see if we need to compact: it is going to halve the zonelist */
567 	if(opt->zonefree_number > opt->zone_options->count) {
568 		zone_list_compact(opt);
569 	} else {
570 		if(fflush(opt->zonelist) != 0) {
571 			log_msg(LOG_ERR, "fflush %s: %s", opt->zonelistfile, strerror(errno));
572 		}
573 	}
574 }
575 /* postorder delete of zonelist free space tree */
576 static void
577 delbucket(region_type* region, struct zonelist_bucket* b)
578 {
579 	struct zonelist_free* e, *f;
580 	if(!b || (rbnode_type*)b==RBTREE_NULL)
581 		return;
582 	delbucket(region, (struct zonelist_bucket*)b->node.left);
583 	delbucket(region, (struct zonelist_bucket*)b->node.right);
584 	e = b->list;
585 	while(e) {
586 		f = e->next;
587 		region_recycle(region, e, sizeof(*e));
588 		e = f;
589 	}
590 	region_recycle(region, b, sizeof(*b));
591 }
592 
593 /* compact zonelist file */
594 void
595 zone_list_compact(struct nsd_options* opt)
596 {
597 	char outname[1024];
598 	FILE* out;
599 	struct zone_options* zone;
600 	off_t off;
601 	int r;
602 	snprintf(outname, sizeof(outname), "%s~", opt->zonelistfile);
603 	/* useful, when : count-of-free > count-of-used */
604 	/* write zonelist to zonelist~ */
605 	out = fopen(outname, "w+");
606 	if(!out) {
607 		log_msg(LOG_ERR, "could not open %s: %s", outname, strerror(errno));
608 		return;
609 	}
610 	r = fprintf(out, ZONELIST_HEADER);
611 	if(r == -1) {
612 		log_msg(LOG_ERR, "write %s failed: %s", outname,
613 			strerror(errno));
614 		fclose(out);
615 		return;
616 	} else if(r != strlen(ZONELIST_HEADER)) {
617 		log_msg(LOG_ERR, "write %s was partial: disk full",
618 			outname);
619 		fclose(out);
620 		return;
621 	}
622 	off = ftello(out);
623 	if(off == -1) {
624 		log_msg(LOG_ERR, "ftello(%s): %s", outname, strerror(errno));
625 		fclose(out);
626 		return;
627 	}
628 	RBTREE_FOR(zone, struct zone_options*, opt->zone_options) {
629 		if(zone->part_of_config)
630 			continue;
631 		r = fprintf(out, "add %s %s\n", zone->name,
632 			zone->pattern->pname);
633 		if(r < 0) {
634 			log_msg(LOG_ERR, "write %s failed: %s", outname,
635 				strerror(errno));
636 			fclose(out);
637 			return;
638 		} else if(r != zone->linesize) {
639 			log_msg(LOG_ERR, "write %s was partial: disk full",
640 				outname);
641 			fclose(out);
642 			return;
643 		}
644 	}
645 	if(fflush(out) != 0) {
646 		log_msg(LOG_ERR, "fflush %s: %s", outname, strerror(errno));
647 	}
648 
649 	/* rename zonelist~ onto zonelist */
650 	if(rename(outname, opt->zonelistfile) == -1) {
651 		log_msg(LOG_ERR, "rename(%s to %s) failed: %s",
652 			outname, opt->zonelistfile, strerror(errno));
653 		fclose(out);
654 		return;
655 	}
656 	fclose(opt->zonelist);
657 	/* set offsets */
658 	RBTREE_FOR(zone, struct zone_options*, opt->zone_options) {
659 		if(zone->part_of_config)
660 			continue;
661 		zone->off = off;
662 		off += zone->linesize;
663 	}
664 	/* empty the free tree */
665 	delbucket(opt->region, (struct zonelist_bucket*)opt->zonefree->root);
666 	opt->zonefree->root = RBTREE_NULL;
667 	opt->zonefree->count = 0;
668 	opt->zonefree_number = 0;
669 	/* finish */
670 	opt->zonelist = out;
671 	opt->zonelist_off = off;
672 }
673 
674 /* close zonelist file */
675 void
676 zone_list_close(struct nsd_options* opt)
677 {
678 	if(opt->zonelist) {
679 		fclose(opt->zonelist);
680 		opt->zonelist = NULL;
681 	}
682 }
683 
684 static void
685 c_error_va_list_pos(int showpos, const char* fmt, va_list args)
686 {
687 	char* at = NULL;
688 	cfg_parser->errors++;
689 	if(showpos && c_text && c_text[0]!=0) {
690 		at = c_text;
691 	}
692 	if(cfg_parser->err) {
693 		char m[MAXSYSLOGMSGLEN];
694 		snprintf(m, sizeof(m), "%s:%d: ", cfg_parser->filename,
695 			cfg_parser->line);
696 		(*cfg_parser->err)(cfg_parser->err_arg, m);
697 		if(at) {
698 			snprintf(m, sizeof(m), "at '%s': ", at);
699 			(*cfg_parser->err)(cfg_parser->err_arg, m);
700 		}
701 		(*cfg_parser->err)(cfg_parser->err_arg, "error: ");
702 		vsnprintf(m, sizeof(m), fmt, args);
703 		(*cfg_parser->err)(cfg_parser->err_arg, m);
704 		(*cfg_parser->err)(cfg_parser->err_arg, "\n");
705 		return;
706 	}
707         fprintf(stderr, "%s:%d: ", cfg_parser->filename, cfg_parser->line);
708 	if(at) fprintf(stderr, "at '%s': ", at);
709 	fprintf(stderr, "error: ");
710 	vfprintf(stderr, fmt, args);
711 	fprintf(stderr, "\n");
712 }
713 
714 void
715 c_error(const char *fmt, ...)
716 {
717 	va_list ap;
718 	int showpos = 0;
719 
720 	if (strcmp(fmt, "syntax error") == 0 || strcmp(fmt, "parse error") == 0) {
721 		showpos = 1;
722 	}
723 
724 	va_start(ap, fmt);
725 	c_error_va_list_pos(showpos, fmt, ap);
726 	va_end(ap);
727 }
728 
729 int
730 c_wrap(void)
731 {
732 	return 1;
733 }
734 
735 struct zone_options*
736 zone_options_create(region_type* region)
737 {
738 	struct zone_options* zone;
739 	zone = (struct zone_options*)region_alloc(region, sizeof(
740 		struct zone_options));
741 	zone->node = *RBTREE_NULL;
742 	zone->name = 0;
743 	zone->pattern = 0;
744 	zone->part_of_config = 0;
745 	return zone;
746 }
747 
748 /* true is booleans are the same truth value */
749 #define booleq(x,y) ( ((x) && (y)) || (!(x) && !(y)) )
750 
751 int
752 acl_equal(struct acl_options* p, struct acl_options* q)
753 {
754 	if(!booleq(p->use_axfr_only, q->use_axfr_only)) return 0;
755 	if(!booleq(p->allow_udp, q->allow_udp)) return 0;
756 	if(strcmp(p->ip_address_spec, q->ip_address_spec)!=0) return 0;
757 	/* the ip6, port, addr, mask, type: are derived from the ip_address_spec */
758 	if(!booleq(p->nokey, q->nokey)) return 0;
759 	if(!booleq(p->blocked, q->blocked)) return 0;
760 	if(p->key_name && q->key_name) {
761 		if(strcmp(p->key_name, q->key_name)!=0) return 0;
762 	} else if(p->key_name && !q->key_name) return 0;
763 	else if(!p->key_name && q->key_name) return 0;
764 	/* key_options is derived from key_name */
765 	return 1;
766 }
767 
768 int
769 acl_list_equal(struct acl_options* p, struct acl_options* q)
770 {
771 	/* must be same and in same order */
772 	while(p && q) {
773 		if(!acl_equal(p, q))
774 			return 0;
775 		p = p->next;
776 		q = q->next;
777 	}
778 	if(!p && !q) return 1;
779 	/* different lengths */
780 	return 0;
781 }
782 
783 struct pattern_options*
784 pattern_options_create(region_type* region)
785 {
786 	struct pattern_options* p;
787 	p = (struct pattern_options*)region_alloc(region, sizeof(
788 		struct pattern_options));
789 	p->node = *RBTREE_NULL;
790 	p->pname = 0;
791 	p->zonefile = 0;
792 	p->zonestats = 0;
793 	p->allow_notify = 0;
794 	p->request_xfr = 0;
795 	p->size_limit_xfr = 0;
796 	p->notify = 0;
797 	p->provide_xfr = 0;
798 	p->outgoing_interface = 0;
799 	p->notify_retry = 5;
800 	p->notify_retry_is_default = 1;
801 	p->allow_axfr_fallback = 1;
802 	p->allow_axfr_fallback_is_default = 1;
803 	p->implicit = 0;
804 	p->xfrd_flags = 0;
805 	p->max_refresh_time = 2419200;	/* 4 weeks */
806 	p->max_refresh_time_is_default = 1;
807 	p->min_refresh_time = 0;
808 	p->min_refresh_time_is_default = 1;
809 	p->max_retry_time = 1209600;	/* 2 weeks */
810 	p->max_retry_time_is_default = 1;
811 	p->min_retry_time = 0;
812 	p->min_retry_time_is_default = 1;
813 #ifdef RATELIMIT
814 	p->rrl_whitelist = 0;
815 #endif
816 	p->multi_master_check = 0;
817 	return p;
818 }
819 
820 static void
821 acl_delete(region_type* region, struct acl_options* acl)
822 {
823 	if(acl->ip_address_spec)
824 		region_recycle(region, (void*)acl->ip_address_spec,
825 			strlen(acl->ip_address_spec)+1);
826 	if(acl->key_name)
827 		region_recycle(region, (void*)acl->key_name,
828 			strlen(acl->key_name)+1);
829 	/* key_options is a convenience pointer, not owned by the acl */
830 	region_recycle(region, acl, sizeof(*acl));
831 }
832 
833 static void
834 acl_list_delete(region_type* region, struct acl_options* list)
835 {
836 	struct acl_options* n;
837 	while(list) {
838 		n = list->next;
839 		acl_delete(region, list);
840 		list = n;
841 	}
842 }
843 
844 void
845 pattern_options_remove(struct nsd_options* opt, const char* name)
846 {
847 	struct pattern_options* p = (struct pattern_options*)rbtree_delete(
848 		opt->patterns, name);
849 	/* delete p and its contents */
850 	if (!p)
851 		return;
852 	if(p->pname)
853 		region_recycle(opt->region, (void*)p->pname,
854 			strlen(p->pname)+1);
855 	if(p->zonefile)
856 		region_recycle(opt->region, (void*)p->zonefile,
857 			strlen(p->zonefile)+1);
858 	if(p->zonestats)
859 		region_recycle(opt->region, (void*)p->zonestats,
860 			strlen(p->zonestats)+1);
861 	acl_list_delete(opt->region, p->allow_notify);
862 	acl_list_delete(opt->region, p->request_xfr);
863 	acl_list_delete(opt->region, p->notify);
864 	acl_list_delete(opt->region, p->provide_xfr);
865 	acl_list_delete(opt->region, p->outgoing_interface);
866 
867 	region_recycle(opt->region, p, sizeof(struct pattern_options));
868 }
869 
870 static struct acl_options*
871 copy_acl(region_type* region, struct acl_options* a)
872 {
873 	struct acl_options* b;
874 	if(!a) return NULL;
875 	b = (struct acl_options*)region_alloc(region, sizeof(*b));
876 	/* copy the whole lot */
877 	*b = *a;
878 	/* fix the pointers */
879 	if(a->ip_address_spec)
880 		b->ip_address_spec = region_strdup(region, a->ip_address_spec);
881 	if(a->key_name)
882 		b->key_name = region_strdup(region, a->key_name);
883 	b->next = NULL;
884 	b->key_options = NULL;
885 	return b;
886 }
887 
888 static struct acl_options*
889 copy_acl_list(struct nsd_options* opt, struct acl_options* a)
890 {
891 	struct acl_options* b, *blast = NULL, *blist = NULL;
892 	while(a) {
893 		b = copy_acl(opt->region, a);
894 		/* fixup key_options */
895 		if(b->key_name)
896 			b->key_options = key_options_find(opt, b->key_name);
897 		else	b->key_options = NULL;
898 
899 		/* link as last into list */
900 		b->next = NULL;
901 		if(!blist) blist = b;
902 		else blast->next = b;
903 		blast = b;
904 
905 		a = a->next;
906 	}
907 	return blist;
908 }
909 
910 static void
911 copy_changed_acl(struct nsd_options* opt, struct acl_options** orig,
912 	struct acl_options* anew)
913 {
914 	if(!acl_list_equal(*orig, anew)) {
915 		acl_list_delete(opt->region, *orig);
916 		*orig = copy_acl_list(opt, anew);
917 	}
918 }
919 
920 static void
921 copy_pat_fixed(region_type* region, struct pattern_options* orig,
922 	struct pattern_options* p)
923 {
924 	orig->allow_axfr_fallback = p->allow_axfr_fallback;
925 	orig->allow_axfr_fallback_is_default =
926 		p->allow_axfr_fallback_is_default;
927 	orig->notify_retry = p->notify_retry;
928 	orig->notify_retry_is_default = p->notify_retry_is_default;
929 	orig->implicit = p->implicit;
930 	if(p->zonefile)
931 		orig->zonefile = region_strdup(region, p->zonefile);
932 	else orig->zonefile = NULL;
933 	if(p->zonestats)
934 		orig->zonestats = region_strdup(region, p->zonestats);
935 	else orig->zonestats = NULL;
936 	orig->max_refresh_time = p->max_refresh_time;
937 	orig->max_refresh_time_is_default = p->max_refresh_time_is_default;
938 	orig->min_refresh_time = p->min_refresh_time;
939 	orig->min_refresh_time_is_default = p->min_refresh_time_is_default;
940 	orig->max_retry_time = p->max_retry_time;
941 	orig->max_retry_time_is_default = p->max_retry_time_is_default;
942 	orig->min_retry_time = p->min_retry_time;
943 	orig->min_retry_time_is_default = p->min_retry_time_is_default;
944 #ifdef RATELIMIT
945 	orig->rrl_whitelist = p->rrl_whitelist;
946 #endif
947 	orig->multi_master_check = p->multi_master_check;
948 }
949 
950 void
951 pattern_options_add_modify(struct nsd_options* opt, struct pattern_options* p)
952 {
953 	struct pattern_options* orig = pattern_options_find(opt, p->pname);
954 	if(!orig) {
955 		/* needs to be copied to opt region */
956 		orig = pattern_options_create(opt->region);
957 		orig->pname = region_strdup(opt->region, p->pname);
958 		copy_pat_fixed(opt->region, orig, p);
959 		orig->allow_notify = copy_acl_list(opt, p->allow_notify);
960 		orig->request_xfr = copy_acl_list(opt, p->request_xfr);
961 		orig->notify = copy_acl_list(opt, p->notify);
962 		orig->provide_xfr = copy_acl_list(opt, p->provide_xfr);
963 		orig->outgoing_interface = copy_acl_list(opt,
964 			p->outgoing_interface);
965 		nsd_options_insert_pattern(opt, orig);
966 	} else {
967 		/* modify in place so pointers stay valid (and copy
968 		   into region). Do not touch unchanged acls. */
969 		if(orig->zonefile)
970 			region_recycle(opt->region, (char*)orig->zonefile,
971 				strlen(orig->zonefile)+1);
972 		if(orig->zonestats)
973 			region_recycle(opt->region, (char*)orig->zonestats,
974 				strlen(orig->zonestats)+1);
975 		copy_pat_fixed(opt->region, orig, p);
976 		copy_changed_acl(opt, &orig->allow_notify, p->allow_notify);
977 		copy_changed_acl(opt, &orig->request_xfr, p->request_xfr);
978 		copy_changed_acl(opt, &orig->notify, p->notify);
979 		copy_changed_acl(opt, &orig->provide_xfr, p->provide_xfr);
980 		copy_changed_acl(opt, &orig->outgoing_interface,
981 			p->outgoing_interface);
982 	}
983 }
984 
985 struct pattern_options*
986 pattern_options_find(struct nsd_options* opt, const char* name)
987 {
988 	return (struct pattern_options*)rbtree_search(opt->patterns, name);
989 }
990 
991 int
992 pattern_options_equal(struct pattern_options* p, struct pattern_options* q)
993 {
994 	if(strcmp(p->pname, q->pname) != 0) return 0;
995 	if(!p->zonefile && q->zonefile) return 0;
996 	else if(p->zonefile && !q->zonefile) return 0;
997 	else if(p->zonefile && q->zonefile) {
998 		if(strcmp(p->zonefile, q->zonefile) != 0) return 0;
999 	}
1000 	if(!p->zonestats && q->zonestats) return 0;
1001 	else if(p->zonestats && !q->zonestats) return 0;
1002 	else if(p->zonestats && q->zonestats) {
1003 		if(strcmp(p->zonestats, q->zonestats) != 0) return 0;
1004 	}
1005 	if(!booleq(p->allow_axfr_fallback, q->allow_axfr_fallback)) return 0;
1006 	if(!booleq(p->allow_axfr_fallback_is_default,
1007 		q->allow_axfr_fallback_is_default)) return 0;
1008 	if(p->notify_retry != q->notify_retry) return 0;
1009 	if(!booleq(p->notify_retry_is_default,
1010 		q->notify_retry_is_default)) return 0;
1011 	if(!booleq(p->implicit, q->implicit)) return 0;
1012 	if(!acl_list_equal(p->allow_notify, q->allow_notify)) return 0;
1013 	if(!acl_list_equal(p->request_xfr, q->request_xfr)) return 0;
1014 	if(!acl_list_equal(p->notify, q->notify)) return 0;
1015 	if(!acl_list_equal(p->provide_xfr, q->provide_xfr)) return 0;
1016 	if(!acl_list_equal(p->outgoing_interface, q->outgoing_interface))
1017 		return 0;
1018 	if(p->max_refresh_time != q->max_refresh_time) return 0;
1019 	if(!booleq(p->max_refresh_time_is_default,
1020 		q->max_refresh_time_is_default)) return 0;
1021 	if(p->min_refresh_time != q->min_refresh_time) return 0;
1022 	if(!booleq(p->min_refresh_time_is_default,
1023 		q->min_refresh_time_is_default)) return 0;
1024 	if(p->max_retry_time != q->max_retry_time) return 0;
1025 	if(!booleq(p->max_retry_time_is_default,
1026 		q->max_retry_time_is_default)) return 0;
1027 	if(p->min_retry_time != q->min_retry_time) return 0;
1028 	if(!booleq(p->min_retry_time_is_default,
1029 		q->min_retry_time_is_default)) return 0;
1030 #ifdef RATELIMIT
1031 	if(p->rrl_whitelist != q->rrl_whitelist) return 0;
1032 #endif
1033 	if(!booleq(p->multi_master_check,q->multi_master_check)) return 0;
1034 	if(p->size_limit_xfr != q->size_limit_xfr) return 0;
1035 	return 1;
1036 }
1037 
1038 static void
1039 marshal_u8(struct buffer* b, uint8_t v)
1040 {
1041 	buffer_reserve(b, 1);
1042 	buffer_write_u8(b, v);
1043 }
1044 
1045 static uint8_t
1046 unmarshal_u8(struct buffer* b)
1047 {
1048 	return buffer_read_u8(b);
1049 }
1050 
1051 static void
1052 marshal_u64(struct buffer* b, uint64_t v)
1053 {
1054 	buffer_reserve(b, 8);
1055 	buffer_write_u64(b, v);
1056 }
1057 
1058 static uint64_t
1059 unmarshal_u64(struct buffer* b)
1060 {
1061 	return buffer_read_u64(b);
1062 }
1063 
1064 #ifdef RATELIMIT
1065 static void
1066 marshal_u16(struct buffer* b, uint16_t v)
1067 {
1068 	buffer_reserve(b, 2);
1069 	buffer_write_u16(b, v);
1070 }
1071 #endif
1072 
1073 #ifdef RATELIMIT
1074 static uint16_t
1075 unmarshal_u16(struct buffer* b)
1076 {
1077 	return buffer_read_u16(b);
1078 }
1079 #endif
1080 
1081 static void
1082 marshal_u32(struct buffer* b, uint32_t v)
1083 {
1084 	buffer_reserve(b, 4);
1085 	buffer_write_u32(b, v);
1086 }
1087 
1088 static uint32_t
1089 unmarshal_u32(struct buffer* b)
1090 {
1091 	return buffer_read_u32(b);
1092 }
1093 
1094 static void
1095 marshal_str(struct buffer* b, const char* s)
1096 {
1097 	if(!s) marshal_u8(b, 0);
1098 	else {
1099 		size_t len = strlen(s);
1100 		marshal_u8(b, 1);
1101 		buffer_reserve(b, len+1);
1102 		buffer_write(b, s, len+1);
1103 	}
1104 }
1105 
1106 static char*
1107 unmarshal_str(region_type* r, struct buffer* b)
1108 {
1109 	uint8_t nonnull = unmarshal_u8(b);
1110 	if(nonnull) {
1111 		char* result = region_strdup(r, (char*)buffer_current(b));
1112 		size_t len = strlen((char*)buffer_current(b));
1113 		buffer_skip(b, len+1);
1114 		return result;
1115 	} else return NULL;
1116 }
1117 
1118 static void
1119 marshal_acl(struct buffer* b, struct acl_options* acl)
1120 {
1121 	buffer_reserve(b, sizeof(*acl));
1122 	buffer_write(b, acl, sizeof(*acl));
1123 	marshal_str(b, acl->ip_address_spec);
1124 	marshal_str(b, acl->key_name);
1125 }
1126 
1127 static struct acl_options*
1128 unmarshal_acl(region_type* r, struct buffer* b)
1129 {
1130 	struct acl_options* acl = (struct acl_options*)region_alloc(r,
1131 		sizeof(*acl));
1132 	buffer_read(b, acl, sizeof(*acl));
1133 	acl->next = NULL;
1134 	acl->key_options = NULL;
1135 	acl->ip_address_spec = unmarshal_str(r, b);
1136 	acl->key_name = unmarshal_str(r, b);
1137 	return acl;
1138 }
1139 
1140 static void
1141 marshal_acl_list(struct buffer* b, struct acl_options* list)
1142 {
1143 	while(list) {
1144 		marshal_u8(b, 1); /* is there a next one marker */
1145 		marshal_acl(b, list);
1146 		list = list->next;
1147 	}
1148 	marshal_u8(b, 0); /* end of list marker */
1149 }
1150 
1151 static struct acl_options*
1152 unmarshal_acl_list(region_type* r, struct buffer* b)
1153 {
1154 	struct acl_options* a, *last=NULL, *list=NULL;
1155 	while(unmarshal_u8(b)) {
1156 		a = unmarshal_acl(r, b);
1157 		/* link in */
1158 		a->next = NULL;
1159 		if(!list) list = a;
1160 		else last->next = a;
1161 		last = a;
1162 	}
1163 	return list;
1164 }
1165 
1166 void
1167 pattern_options_marshal(struct buffer* b, struct pattern_options* p)
1168 {
1169 	marshal_str(b, p->pname);
1170 	marshal_str(b, p->zonefile);
1171 	marshal_str(b, p->zonestats);
1172 #ifdef RATELIMIT
1173 	marshal_u16(b, p->rrl_whitelist);
1174 #endif
1175 	marshal_u8(b, p->allow_axfr_fallback);
1176 	marshal_u8(b, p->allow_axfr_fallback_is_default);
1177 	marshal_u8(b, p->notify_retry);
1178 	marshal_u8(b, p->notify_retry_is_default);
1179 	marshal_u8(b, p->implicit);
1180 	marshal_u64(b, p->size_limit_xfr);
1181 	marshal_acl_list(b, p->allow_notify);
1182 	marshal_acl_list(b, p->request_xfr);
1183 	marshal_acl_list(b, p->notify);
1184 	marshal_acl_list(b, p->provide_xfr);
1185 	marshal_acl_list(b, p->outgoing_interface);
1186 	marshal_u32(b, p->max_refresh_time);
1187 	marshal_u8(b, p->max_refresh_time_is_default);
1188 	marshal_u32(b, p->min_refresh_time);
1189 	marshal_u8(b, p->min_refresh_time_is_default);
1190 	marshal_u32(b, p->max_retry_time);
1191 	marshal_u8(b, p->max_retry_time_is_default);
1192 	marshal_u32(b, p->min_retry_time);
1193 	marshal_u8(b, p->min_retry_time_is_default);
1194 	marshal_u8(b, p->multi_master_check);
1195 }
1196 
1197 struct pattern_options*
1198 pattern_options_unmarshal(region_type* r, struct buffer* b)
1199 {
1200 	struct pattern_options* p = pattern_options_create(r);
1201 	p->pname = unmarshal_str(r, b);
1202 	p->zonefile = unmarshal_str(r, b);
1203 	p->zonestats = unmarshal_str(r, b);
1204 #ifdef RATELIMIT
1205 	p->rrl_whitelist = unmarshal_u16(b);
1206 #endif
1207 	p->allow_axfr_fallback = unmarshal_u8(b);
1208 	p->allow_axfr_fallback_is_default = unmarshal_u8(b);
1209 	p->notify_retry = unmarshal_u8(b);
1210 	p->notify_retry_is_default = unmarshal_u8(b);
1211 	p->implicit = unmarshal_u8(b);
1212 	p->size_limit_xfr = unmarshal_u64(b);
1213 	p->allow_notify = unmarshal_acl_list(r, b);
1214 	p->request_xfr = unmarshal_acl_list(r, b);
1215 	p->notify = unmarshal_acl_list(r, b);
1216 	p->provide_xfr = unmarshal_acl_list(r, b);
1217 	p->outgoing_interface = unmarshal_acl_list(r, b);
1218 	p->max_refresh_time = unmarshal_u32(b);
1219 	p->max_refresh_time_is_default = unmarshal_u8(b);
1220 	p->min_refresh_time = unmarshal_u32(b);
1221 	p->min_refresh_time_is_default = unmarshal_u8(b);
1222 	p->max_retry_time = unmarshal_u32(b);
1223 	p->max_retry_time_is_default = unmarshal_u8(b);
1224 	p->min_retry_time = unmarshal_u32(b);
1225 	p->min_retry_time_is_default = unmarshal_u8(b);
1226 	p->multi_master_check = unmarshal_u8(b);
1227 	return p;
1228 }
1229 
1230 struct key_options*
1231 key_options_create(region_type* region)
1232 {
1233 	struct key_options* key;
1234 	key = (struct key_options*)region_alloc_zero(region,
1235 		sizeof(struct key_options));
1236 	return key;
1237 }
1238 
1239 void
1240 key_options_insert(struct nsd_options* opt, struct key_options* key)
1241 {
1242 	if(!key->name) return;
1243 	key->node.key = key->name;
1244 	(void)rbtree_insert(opt->keys, &key->node);
1245 }
1246 
1247 struct key_options*
1248 key_options_find(struct nsd_options* opt, const char* name)
1249 {
1250 	return (struct key_options*)rbtree_search(opt->keys, name);
1251 }
1252 
1253 /** remove tsig_key contents */
1254 void
1255 key_options_desetup(region_type* region, struct key_options* key)
1256 {
1257 	/* keep tsig_key pointer so that existing references keep valid */
1258 	if(!key->tsig_key)
1259 		return;
1260 	/* name stays the same */
1261 	if(key->tsig_key->data) {
1262 		/* wipe secret! */
1263 		memset(key->tsig_key->data, 0xdd, key->tsig_key->size);
1264 		region_recycle(region, key->tsig_key->data,
1265 			key->tsig_key->size);
1266 		key->tsig_key->data = NULL;
1267 		key->tsig_key->size = 0;
1268 	}
1269 }
1270 
1271 /** add tsig_key contents */
1272 void
1273 key_options_setup(region_type* region, struct key_options* key)
1274 {
1275 	uint8_t data[16384]; /* 16KB */
1276 	int size;
1277 	if(!key->tsig_key) {
1278 		/* create it */
1279 		key->tsig_key = (tsig_key_type *) region_alloc(region,
1280 			sizeof(tsig_key_type));
1281 		/* create name */
1282 		key->tsig_key->name = dname_parse(region, key->name);
1283 		if(!key->tsig_key->name) {
1284 			log_msg(LOG_ERR, "Failed to parse tsig key name %s",
1285 				key->name);
1286 			/* key and base64 were checked during syntax parse */
1287 			exit(1);
1288 		}
1289 		key->tsig_key->size = 0;
1290 		key->tsig_key->data = NULL;
1291 	}
1292 	size = __b64_pton(key->secret, data, sizeof(data));
1293 	if(size == -1) {
1294 		log_msg(LOG_ERR, "Failed to parse tsig key data %s",
1295 			key->name);
1296 		/* key and base64 were checked during syntax parse */
1297 		exit(1);
1298 	}
1299 	key->tsig_key->size = size;
1300 	key->tsig_key->data = (uint8_t *)region_alloc_init(region, data, size);
1301 }
1302 
1303 void
1304 key_options_remove(struct nsd_options* opt, const char* name)
1305 {
1306 	struct key_options* k = key_options_find(opt, name);
1307 	if(!k) return;
1308 	(void)rbtree_delete(opt->keys, name);
1309 	if(k->name)
1310 		region_recycle(opt->region, k->name, strlen(k->name)+1);
1311 	if(k->algorithm)
1312 		region_recycle(opt->region, k->algorithm, strlen(k->algorithm)+1);
1313 	if(k->secret) {
1314 		memset(k->secret, 0xdd, strlen(k->secret)); /* wipe secret! */
1315 		region_recycle(opt->region, k->secret, strlen(k->secret)+1);
1316 	}
1317 	if(k->tsig_key) {
1318 		tsig_del_key(k->tsig_key);
1319 		if(k->tsig_key->name)
1320 			region_recycle(opt->region, (void*)k->tsig_key->name,
1321 				dname_total_size(k->tsig_key->name));
1322 		key_options_desetup(opt->region, k);
1323 		region_recycle(opt->region, k->tsig_key, sizeof(tsig_key_type));
1324 	}
1325 	region_recycle(opt->region, k, sizeof(struct key_options));
1326 }
1327 
1328 int
1329 key_options_equal(struct key_options* p, struct key_options* q)
1330 {
1331 	return strcmp(p->name, q->name)==0 && strcmp(p->algorithm,
1332 		q->algorithm)==0 && strcmp(p->secret, q->secret)==0;
1333 }
1334 
1335 void
1336 key_options_add_modify(struct nsd_options* opt, struct key_options* key)
1337 {
1338 	struct key_options* orig = key_options_find(opt, key->name);
1339 	if(!orig) {
1340 		/* needs to be copied to opt region */
1341 		orig = key_options_create(opt->region);
1342 		orig->name = region_strdup(opt->region, key->name);
1343 		orig->algorithm = region_strdup(opt->region, key->algorithm);
1344 		orig->secret = region_strdup(opt->region, key->secret);
1345 		key_options_setup(opt->region, orig);
1346 		tsig_add_key(orig->tsig_key);
1347 		key_options_insert(opt, orig);
1348 	} else {
1349 		/* modify entries in existing key, and copy to opt region */
1350 		key_options_desetup(opt->region, orig);
1351 		region_recycle(opt->region, orig->algorithm,
1352 			strlen(orig->algorithm)+1);
1353 		orig->algorithm = region_strdup(opt->region, key->algorithm);
1354 		region_recycle(opt->region, orig->secret,
1355 			strlen(orig->secret)+1);
1356 		orig->secret = region_strdup(opt->region, key->secret);
1357 		key_options_setup(opt->region, orig);
1358 	}
1359 }
1360 
1361 int
1362 acl_check_incoming(struct acl_options* acl, struct query* q,
1363 	struct acl_options** reason)
1364 {
1365 	/* check each acl element.
1366 	   if 1 blocked element matches - return -1.
1367 	   if any element matches - return number.
1368 	   else return -1. */
1369 	int found_match = -1;
1370 	int number = 0;
1371 	struct acl_options* match = 0;
1372 
1373 	if(reason)
1374 		*reason = NULL;
1375 
1376 	while(acl)
1377 	{
1378 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s",
1379 			acl->ip_address_spec, acl->nokey?"NOKEY":
1380 			(acl->blocked?"BLOCKED":acl->key_name)));
1381 		if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) {
1382 			if(!match)
1383 			{
1384 				match = acl; /* remember first match */
1385 				found_match=number;
1386 			}
1387 			if(acl->blocked) {
1388 				if(reason)
1389 					*reason = acl;
1390 				return -1;
1391 			}
1392 		}
1393 		number++;
1394 		acl = acl->next;
1395 	}
1396 
1397 	if(reason)
1398 		*reason = match;
1399 	return found_match;
1400 }
1401 
1402 #ifdef INET6
1403 int
1404 acl_addr_matches_ipv6host(struct acl_options* acl, struct sockaddr_storage* addr_storage, unsigned int port)
1405 {
1406 	struct sockaddr_in6* addr = (struct sockaddr_in6*)addr_storage;
1407 	if(acl->port != 0 && acl->port != port)
1408 		return 0;
1409 	switch(acl->rangetype) {
1410 	case acl_range_mask:
1411 	case acl_range_subnet:
1412 		if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
1413 			(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
1414 			return 0;
1415 		break;
1416 	case acl_range_minmax:
1417 		if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr,
1418 			(uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr)))
1419 			return 0;
1420 		break;
1421 	case acl_range_single:
1422 	default:
1423 		if(memcmp(&addr->sin6_addr, &acl->addr.addr6,
1424 			sizeof(struct in6_addr)) != 0)
1425 			return 0;
1426 		break;
1427 	}
1428 	return 1;
1429 }
1430 #endif
1431 
1432 int
1433 acl_addr_matches_ipv4host(struct acl_options* acl, struct sockaddr_in* addr, unsigned int port)
1434 {
1435 	if(acl->port != 0 && acl->port != port)
1436 		return 0;
1437 	switch(acl->rangetype) {
1438 	case acl_range_mask:
1439 	case acl_range_subnet:
1440 		if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
1441 			(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
1442 			return 0;
1443 		break;
1444 	case acl_range_minmax:
1445 		if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr,
1446 			(uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr)))
1447 			return 0;
1448 		break;
1449 	case acl_range_single:
1450 	default:
1451 		if(memcmp(&addr->sin_addr, &acl->addr.addr,
1452 			sizeof(struct in_addr)) != 0)
1453 			return 0;
1454 		break;
1455 	}
1456 	return 1;
1457 }
1458 
1459 int
1460 acl_addr_matches_host(struct acl_options* acl, struct acl_options* host)
1461 {
1462 	if(acl->is_ipv6)
1463 	{
1464 #ifdef INET6
1465 		struct sockaddr_storage* addr = (struct sockaddr_storage*)&host->addr;
1466 		if(!host->is_ipv6) return 0;
1467 		return acl_addr_matches_ipv6host(acl, addr, host->port);
1468 #else
1469 		return 0; /* no inet6, no match */
1470 #endif
1471 	}
1472 	else
1473 	{
1474 		struct sockaddr_in* addr = (struct sockaddr_in*)&host->addr;
1475 		if(host->is_ipv6) return 0;
1476 		return acl_addr_matches_ipv4host(acl, addr, host->port);
1477 	}
1478 	/* ENOTREACH */
1479 	return 0;
1480 }
1481 
1482 int
1483 acl_addr_matches(struct acl_options* acl, struct query* q)
1484 {
1485 	if(acl->is_ipv6)
1486 	{
1487 #ifdef INET6
1488 		struct sockaddr_storage* addr = (struct sockaddr_storage*)&q->addr;
1489 		if(addr->ss_family != AF_INET6)
1490 			return 0;
1491 		return acl_addr_matches_ipv6host(acl, addr, ntohs(((struct sockaddr_in6*)addr)->sin6_port));
1492 #else
1493 		return 0; /* no inet6, no match */
1494 #endif
1495 	}
1496 	else
1497 	{
1498 		struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr;
1499 		if(addr->sin_family != AF_INET)
1500 			return 0;
1501 		return acl_addr_matches_ipv4host(acl, addr, ntohs(addr->sin_port));
1502 	}
1503 	/* ENOTREACH */
1504 	return 0;
1505 }
1506 
1507 int
1508 acl_addr_match_mask(uint32_t* a, uint32_t* b, uint32_t* mask, size_t sz)
1509 {
1510 	size_t i;
1511 #ifndef NDEBUG
1512 	assert(sz % 4 == 0);
1513 #endif
1514 	sz /= 4;
1515 	for(i=0; i<sz; ++i)
1516 	{
1517 		if(((*a++)&*mask) != ((*b++)&*mask))
1518 			return 0;
1519 		++mask;
1520 	}
1521 	return 1;
1522 }
1523 
1524 int
1525 acl_addr_match_range(uint32_t* minval, uint32_t* x, uint32_t* maxval, size_t sz)
1526 {
1527 	size_t i;
1528 	uint8_t checkmin = 1, checkmax = 1;
1529 #ifndef NDEBUG
1530 	assert(sz % 4 == 0);
1531 #endif
1532 	/* check treats x as one huge number */
1533 	sz /= 4;
1534 	for(i=0; i<sz; ++i)
1535 	{
1536 		/* if outside bounds, we are done */
1537 		if(checkmin)
1538 			if(minval[i] > x[i])
1539 				return 0;
1540 		if(checkmax)
1541 			if(maxval[i] < x[i])
1542 				return 0;
1543 		/* if x is equal to a bound, that bound needs further checks */
1544 		if(checkmin && minval[i]!=x[i])
1545 			checkmin = 0;
1546 		if(checkmax && maxval[i]!=x[i])
1547 			checkmax = 0;
1548 		if(!checkmin && !checkmax)
1549 			return 1; /* will always match */
1550 	}
1551 	return 1;
1552 }
1553 
1554 int
1555 acl_key_matches(struct acl_options* acl, struct query* q)
1556 {
1557 	if(acl->blocked)
1558 		return 1;
1559 	if(acl->nokey) {
1560 		if(q->tsig.status == TSIG_NOT_PRESENT)
1561 			return 1;
1562 		return 0;
1563 	}
1564 	/* check name of tsig key */
1565 	if(q->tsig.status != TSIG_OK) {
1566 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail query has no TSIG"));
1567 		return 0; /* query has no TSIG */
1568 	}
1569 	if(q->tsig.error_code != TSIG_ERROR_NOERROR) {
1570 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail, tsig has error"));
1571 		return 0; /* some tsig error */
1572 	}
1573 	if(!acl->key_options->tsig_key) {
1574 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail no config"));
1575 		return 0; /* key not properly configured */
1576 	}
1577 	if(dname_compare(q->tsig.key_name,
1578 		acl->key_options->tsig_key->name) != 0) {
1579 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "keymatch fail wrong key name"));
1580 		return 0; /* wrong key name */
1581 	}
1582 	if(tsig_strlowercmp(q->tsig.algorithm->short_name,
1583 		acl->key_options->algorithm) != 0 && (
1584 		strncmp("hmac-", q->tsig.algorithm->short_name, 5) != 0 ||
1585 		tsig_strlowercmp(q->tsig.algorithm->short_name+5,
1586 		acl->key_options->algorithm) != 0) ) {
1587 		DEBUG(DEBUG_XFRD,2, (LOG_ERR, "query tsig wrong algorithm"));
1588 		return 0; /* no such algo */
1589 	}
1590 	return 1;
1591 }
1592 
1593 int
1594 acl_same_host(struct acl_options* a, struct acl_options* b)
1595 {
1596 	if(a->is_ipv6 && !b->is_ipv6)
1597 		return 0;
1598 	if(!a->is_ipv6 && b->is_ipv6)
1599 		return 0;
1600 	if(a->port != b->port)
1601 		return 0;
1602 	if(a->rangetype != b->rangetype)
1603 		return 0;
1604 	if(!a->is_ipv6) {
1605 		if(memcmp(&a->addr.addr, &b->addr.addr,
1606 		   sizeof(struct in_addr)) != 0)
1607 			return 0;
1608 		if(a->rangetype != acl_range_single &&
1609 		   memcmp(&a->range_mask.addr, &b->range_mask.addr,
1610 		   sizeof(struct in_addr)) != 0)
1611 			return 0;
1612 	} else {
1613 #ifdef INET6
1614 		if(memcmp(&a->addr.addr6, &b->addr.addr6,
1615 		   sizeof(struct in6_addr)) != 0)
1616 			return 0;
1617 		if(a->rangetype != acl_range_single &&
1618 		   memcmp(&a->range_mask.addr6, &b->range_mask.addr6,
1619 		   sizeof(struct in6_addr)) != 0)
1620 			return 0;
1621 #else
1622 		return 0;
1623 #endif
1624 	}
1625 	return 1;
1626 }
1627 
1628 #if defined(HAVE_SSL)
1629 void
1630 key_options_tsig_add(struct nsd_options* opt)
1631 {
1632 	struct key_options* optkey;
1633 	RBTREE_FOR(optkey, struct key_options*, opt->keys) {
1634 		key_options_setup(opt->region, optkey);
1635 		tsig_add_key(optkey->tsig_key);
1636 	}
1637 }
1638 #endif
1639 
1640 int
1641 zone_is_slave(struct zone_options* opt)
1642 {
1643 	return opt && opt->pattern && opt->pattern->request_xfr != 0;
1644 }
1645 
1646 /* get a character in string (or replacement char if not long enough) */
1647 static const char*
1648 get_char(const char* str, size_t i)
1649 {
1650 	static char res[2];
1651 	if(i >= strlen(str))
1652 		return ".";
1653 	res[0] = str[i];
1654 	res[1] = 0;
1655 	return res;
1656 }
1657 /* get end label of the zone name (or .) */
1658 static const char*
1659 get_end_label(struct zone_options* zone, int i)
1660 {
1661 	const dname_type* d = (const dname_type*)zone->node.key;
1662 	if(i >= d->label_count) {
1663 		return ".";
1664 	}
1665 	return wirelabel2str(dname_label(d, i));
1666 }
1667 /* replace occurrences of one with two */
1668 void
1669 replace_str(char* str, size_t len, const char* one, const char* two)
1670 {
1671 	char* pos;
1672 	char* at = str;
1673 	while( (pos=strstr(at, one)) ) {
1674 		if(strlen(str)+strlen(two)-strlen(one) >= len)
1675 			return; /* no more space to replace */
1676 		/* stuff before pos is fine */
1677 		/* move the stuff after pos to make space for two, add
1678 		 * one to length of remainder to also copy the 0 byte end */
1679 		memmove(pos+strlen(two), pos+strlen(one),
1680 			strlen(pos+strlen(one))+1);
1681 		/* copy in two */
1682 		memmove(pos, two, strlen(two));
1683 		/* at is end of the newly inserted two (avoids recursion if
1684 		 * two contains one) */
1685 		at = pos+strlen(two);
1686 	}
1687 }
1688 
1689 const char*
1690 config_cook_string(struct zone_options* zone, const char* input)
1691 {
1692 	static char f[1024];
1693 	/* if not a template, return as-is */
1694 	if(!strchr(input, '%')) {
1695 		return input;
1696 	}
1697 	strlcpy(f, input, sizeof(f));
1698 	if(strstr(f, "%1"))
1699 		replace_str(f, sizeof(f), "%1", get_char(zone->name, 0));
1700 	if(strstr(f, "%2"))
1701 		replace_str(f, sizeof(f), "%2", get_char(zone->name, 1));
1702 	if(strstr(f, "%3"))
1703 		replace_str(f, sizeof(f), "%3", get_char(zone->name, 2));
1704 	if(strstr(f, "%z"))
1705 		replace_str(f, sizeof(f), "%z", get_end_label(zone, 1));
1706 	if(strstr(f, "%y"))
1707 		replace_str(f, sizeof(f), "%y", get_end_label(zone, 2));
1708 	if(strstr(f, "%x"))
1709 		replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
1710 	if(strstr(f, "%s"))
1711 		replace_str(f, sizeof(f), "%s", zone->name);
1712 	return f;
1713 }
1714 
1715 const char*
1716 config_make_zonefile(struct zone_options* zone, struct nsd* nsd)
1717 {
1718 	static char f[1024];
1719 	/* if not a template, return as-is */
1720 	if(!strchr(zone->pattern->zonefile, '%')) {
1721 		if (nsd->chrootdir && nsd->chrootdir[0] &&
1722 			zone->pattern->zonefile &&
1723 			zone->pattern->zonefile[0] == '/' &&
1724 			strncmp(zone->pattern->zonefile, nsd->chrootdir,
1725 			strlen(nsd->chrootdir)) == 0)
1726 			/* -1 because chrootdir ends in trailing slash */
1727 			return zone->pattern->zonefile + strlen(nsd->chrootdir) - 1;
1728 		return zone->pattern->zonefile;
1729 	}
1730 	strlcpy(f, zone->pattern->zonefile, sizeof(f));
1731 	if(strstr(f, "%1"))
1732 		replace_str(f, sizeof(f), "%1", get_char(zone->name, 0));
1733 	if(strstr(f, "%2"))
1734 		replace_str(f, sizeof(f), "%2", get_char(zone->name, 1));
1735 	if(strstr(f, "%3"))
1736 		replace_str(f, sizeof(f), "%3", get_char(zone->name, 2));
1737 	if(strstr(f, "%z"))
1738 		replace_str(f, sizeof(f), "%z", get_end_label(zone, 1));
1739 	if(strstr(f, "%y"))
1740 		replace_str(f, sizeof(f), "%y", get_end_label(zone, 2));
1741 	if(strstr(f, "%x"))
1742 		replace_str(f, sizeof(f), "%x", get_end_label(zone, 3));
1743 	if(strstr(f, "%s"))
1744 		replace_str(f, sizeof(f), "%s", zone->name);
1745 	if (nsd->chrootdir && nsd->chrootdir[0] && f[0] == '/' &&
1746 		strncmp(f, nsd->chrootdir, strlen(nsd->chrootdir)) == 0)
1747 		/* -1 because chrootdir ends in trailing slash */
1748 		return f + strlen(nsd->chrootdir) - 1;
1749 	return f;
1750 }
1751 
1752 struct zone_options*
1753 zone_options_find(struct nsd_options* opt, const struct dname* apex)
1754 {
1755 	return (struct zone_options*) rbtree_search(opt->zone_options, apex);
1756 }
1757 
1758 struct acl_options*
1759 acl_find_num(struct acl_options* acl, int num)
1760 {
1761 	int count = num;
1762 	if(num < 0)
1763 		return 0;
1764 	while(acl && count > 0) {
1765 		acl = acl->next;
1766 		count--;
1767 	}
1768 	if(count == 0)
1769 		return acl;
1770 	return 0;
1771 }
1772 
1773 /* true if ipv6 address, false if ipv4 */
1774 int
1775 parse_acl_is_ipv6(const char* p)
1776 {
1777 	/* see if addr is ipv6 or ipv4 -- by : and . */
1778 	while(*p) {
1779 		if(*p == '.') return 0;
1780 		if(*p == ':') return 1;
1781 		++p;
1782 	}
1783 	return 0;
1784 }
1785 
1786 /* returns range type. mask is the 2nd part of the range */
1787 int
1788 parse_acl_range_type(char* ip, char** mask)
1789 {
1790 	char *p;
1791 	if((p=strchr(ip, '&'))!=0) {
1792 		*p = 0;
1793 		*mask = p+1;
1794 		return acl_range_mask;
1795 	}
1796 	if((p=strchr(ip, '/'))!=0) {
1797 		*p = 0;
1798 		*mask = p+1;
1799 		return acl_range_subnet;
1800 	}
1801 	if((p=strchr(ip, '-'))!=0) {
1802 		*p = 0;
1803 		*mask = p+1;
1804 		return acl_range_minmax;
1805 	}
1806 	*mask = 0;
1807 	return acl_range_single;
1808 }
1809 
1810 /* parses subnet mask, fills 0 mask as well */
1811 void
1812 parse_acl_range_subnet(char* p, void* addr, int maxbits)
1813 {
1814 	int subnet_bits = atoi(p);
1815 	uint8_t* addr_bytes = (uint8_t*)addr;
1816 	if(subnet_bits == 0 && strcmp(p, "0")!=0) {
1817 		c_error("bad subnet range '%s'", p);
1818 		return;
1819 	}
1820 	if(subnet_bits < 0 || subnet_bits > maxbits) {
1821 		c_error("subnet of %d bits out of range [0..%d]", subnet_bits, maxbits);
1822 		return;
1823 	}
1824 	/* fill addr with n bits of 1s (struct has been zeroed) */
1825 	while(subnet_bits >= 8) {
1826 		*addr_bytes++ = 0xff;
1827 		subnet_bits -= 8;
1828 	}
1829 	if(subnet_bits > 0) {
1830 		uint8_t shifts[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1831 		*addr_bytes = shifts[subnet_bits];
1832 	}
1833 }
1834 
1835 struct acl_options*
1836 parse_acl_info(region_type* region, char* ip, const char* key)
1837 {
1838 	char* p;
1839 	struct acl_options* acl = (struct acl_options*)region_alloc(region,
1840 		sizeof(struct acl_options));
1841 	acl->next = 0;
1842 	/* ip */
1843 	acl->ip_address_spec = region_strdup(region, ip);
1844 	acl->use_axfr_only = 0;
1845 	acl->allow_udp = 0;
1846 	acl->ixfr_disabled = 0;
1847 	acl->bad_xfr_count = 0;
1848 	acl->key_options = 0;
1849 	acl->is_ipv6 = 0;
1850 	acl->port = 0;
1851 	memset(&acl->addr, 0, sizeof(union acl_addr_storage));
1852 	memset(&acl->range_mask, 0, sizeof(union acl_addr_storage));
1853 	if((p=strrchr(ip, '@'))!=0) {
1854 		if(atoi(p+1) == 0) c_error("expected port number after '@'");
1855 		else acl->port = atoi(p+1);
1856 		*p=0;
1857 	}
1858 	acl->rangetype = parse_acl_range_type(ip, &p);
1859 	if(parse_acl_is_ipv6(ip)) {
1860 		acl->is_ipv6 = 1;
1861 #ifdef INET6
1862 		if(inet_pton(AF_INET6, ip, &acl->addr.addr6) != 1)
1863 			c_error("Bad ip6 address '%s'", ip);
1864 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
1865 			assert(p);
1866 			if(inet_pton(AF_INET6, p, &acl->range_mask.addr6) != 1)
1867 				c_error("Bad ip6 address mask '%s'", p);
1868 		}
1869 		if(acl->rangetype==acl_range_subnet) {
1870 			assert(p);
1871 			parse_acl_range_subnet(p, &acl->range_mask.addr6, 128);
1872 		}
1873 #else
1874 		c_error("encountered IPv6 address '%s'.", ip);
1875 #endif /* INET6 */
1876 	} else {
1877 		acl->is_ipv6 = 0;
1878 		if(inet_pton(AF_INET, ip, &acl->addr.addr) != 1)
1879 			c_error("Bad ip4 address '%s'", ip);
1880 		if(acl->rangetype==acl_range_mask || acl->rangetype==acl_range_minmax) {
1881 			assert(p);
1882 			if(inet_pton(AF_INET, p, &acl->range_mask.addr) != 1)
1883 				c_error("Bad ip4 address mask '%s'", p);
1884 		}
1885 		if(acl->rangetype==acl_range_subnet) {
1886 			assert(p);
1887 			parse_acl_range_subnet(p, &acl->range_mask.addr, 32);
1888 		}
1889 	}
1890 
1891 	/* key */
1892 	if(strcmp(key, "NOKEY")==0) {
1893 		acl->nokey = 1;
1894 		acl->blocked = 0;
1895 		acl->key_name = 0;
1896 	} else if(strcmp(key, "BLOCKED")==0) {
1897 		acl->nokey = 0;
1898 		acl->blocked = 1;
1899 		acl->key_name = 0;
1900 	} else {
1901 		acl->nokey = 0;
1902 		acl->blocked = 0;
1903 		acl->key_name = region_strdup(region, key);
1904 	}
1905 	return acl;
1906 }
1907 
1908 /* copy acl list at end of parser start, update current */
1909 static
1910 void copy_and_append_acls(struct acl_options** start, struct acl_options* list)
1911 {
1912 	struct acl_options *tail = NULL;
1913 
1914 	assert(start != NULL);
1915 
1916 	tail = *start;
1917 	if(tail) {
1918 		while(tail->next) {
1919 			tail = tail->next;
1920 		}
1921 	}
1922 
1923 	while(list) {
1924 		struct acl_options* acl = copy_acl(cfg_parser->opt->region,
1925 			list);
1926 		acl->next = NULL;
1927 		if(tail) {
1928 			tail->next = acl;
1929 		} else {
1930 			*start = acl;
1931 		}
1932 		tail = acl;
1933 		list = list->next;
1934 	}
1935 }
1936 
1937 void
1938 config_apply_pattern(struct pattern_options *dest, const char* name)
1939 {
1940 	/* find the pattern */
1941 	struct pattern_options* pat = pattern_options_find(cfg_parser->opt,
1942 		name);
1943 	if(!pat) {
1944 		c_error("could not find pattern %s", name);
1945 		return;
1946 	}
1947 
1948 	/* apply settings */
1949 	if(pat->zonefile)
1950 		dest->zonefile = region_strdup(cfg_parser->opt->region,
1951 			pat->zonefile);
1952 	if(pat->zonestats)
1953 		dest->zonestats = region_strdup(cfg_parser->opt->region,
1954 			pat->zonestats);
1955 	if(!pat->allow_axfr_fallback_is_default) {
1956 		dest->allow_axfr_fallback = pat->allow_axfr_fallback;
1957 		dest->allow_axfr_fallback_is_default = 0;
1958 	}
1959 	if(!pat->notify_retry_is_default) {
1960 		dest->notify_retry = pat->notify_retry;
1961 		dest->notify_retry_is_default = 0;
1962 	}
1963 	if(!pat->max_refresh_time_is_default) {
1964 		dest->max_refresh_time = pat->max_refresh_time;
1965 		dest->max_refresh_time_is_default = 0;
1966 	}
1967 	if(!pat->min_refresh_time_is_default) {
1968 		dest->min_refresh_time = pat->min_refresh_time;
1969 		dest->min_refresh_time_is_default = 0;
1970 	}
1971 	if(!pat->max_retry_time_is_default) {
1972 		dest->max_retry_time = pat->max_retry_time;
1973 		dest->max_retry_time_is_default = 0;
1974 	}
1975 	if(!pat->min_retry_time_is_default) {
1976 		dest->min_retry_time = pat->min_retry_time;
1977 		dest->min_retry_time_is_default = 0;
1978 	}
1979 	dest->size_limit_xfr = pat->size_limit_xfr;
1980 #ifdef RATELIMIT
1981 	dest->rrl_whitelist |= pat->rrl_whitelist;
1982 #endif
1983 	/* append acl items */
1984 	copy_and_append_acls(&dest->allow_notify, pat->allow_notify);
1985 	copy_and_append_acls(&dest->request_xfr, pat->request_xfr);
1986 	copy_and_append_acls(&dest->notify, pat->notify);
1987 	copy_and_append_acls(&dest->provide_xfr, pat->provide_xfr);
1988 	copy_and_append_acls(&dest->outgoing_interface, pat->outgoing_interface);
1989 	if(pat->multi_master_check)
1990 		dest->multi_master_check = pat->multi_master_check;
1991 }
1992 
1993 void
1994 nsd_options_destroy(struct nsd_options* opt)
1995 {
1996 	region_destroy(opt->region);
1997 #ifdef MEMCLEAN /* OS collects memory pages */
1998 	c_lex_destroy();
1999 #endif
2000 }
2001 
2002 unsigned getzonestatid(struct nsd_options* opt, struct zone_options* zopt)
2003 {
2004 #ifdef USE_ZONE_STATS
2005 	const char* statname;
2006 	struct zonestatname* n;
2007 	rbnode_type* res;
2008 	/* try to find the instantiated zonestat name */
2009 	if(!zopt->pattern->zonestats || zopt->pattern->zonestats[0]==0)
2010 		return 0; /* no zone stats */
2011 	statname = config_cook_string(zopt, zopt->pattern->zonestats);
2012 	res = rbtree_search(opt->zonestatnames, statname);
2013 	if(res)
2014 		return ((struct zonestatname*)res)->id;
2015 	/* create it */
2016 	n = (struct zonestatname*)region_alloc_zero(opt->region, sizeof(*n));
2017 	n->node.key = region_strdup(opt->region, statname);
2018 	if(!n->node.key) {
2019 		log_msg(LOG_ERR, "malloc failed: %s", strerror(errno));
2020 		exit(1);
2021 	}
2022 	n->id = (unsigned)(opt->zonestatnames->count);
2023 	rbtree_insert(opt->zonestatnames, (rbnode_type*)n);
2024 	return n->id;
2025 #else /* USE_ZONE_STATS */
2026 	(void)opt; (void)zopt;
2027 	return 0;
2028 #endif /* USE_ZONE_STATS */
2029 }
2030 
2031 /** check if config turns on IP-address interface with certificates or a
2032  * named pipe without certificates. */
2033 int
2034 options_remote_is_address(struct nsd_options* cfg)
2035 {
2036 	if(!cfg->control_enable) return 0;
2037 	if(!cfg->control_interface) return 1;
2038 	if(!cfg->control_interface->address) return 1;
2039 	if(cfg->control_interface->address[0] == 0) return 1;
2040 	return (cfg->control_interface->address[0] != '/');
2041 }
2042