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