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