Bug Summary

File:src/usr.sbin/nsd/options.c
Warning:line 2204, column 25
Null pointer passed as 1st argument to string comparison function

Annotated Source Code

Press '?' to see keyboard shortcuts

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