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