xref: /openbsd-src/usr.sbin/nsd/nsd.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*
2  * nsd.c -- nsd(8)
3  *
4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 
10 #include "config.h"
11 
12 #include <sys/types.h>
13 #include <sys/param.h>
14 #include <sys/socket.h>
15 #include <sys/stat.h>
16 #include <sys/uio.h>
17 #include <sys/wait.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #ifdef HAVE_GRP_H
21 #include <grp.h>
22 #endif /* HAVE_GRP_H */
23 #ifdef HAVE_SETUSERCONTEXT
24 #ifdef HAVE_LOGIN_CAP_H
25 #include <login_cap.h>
26 #endif /* HAVE_LOGIN_CAP_H */
27 #endif /* HAVE_SETUSERCONTEXT */
28 
29 #include <assert.h>
30 #include <ctype.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <limits.h>
34 #include <netdb.h>
35 #include <pwd.h>
36 #include <signal.h>
37 #include <stdarg.h>
38 #include <stddef.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <time.h>
43 #include <unistd.h>
44 
45 #include "nsd.h"
46 #include "options.h"
47 #include "tsig.h"
48 #include "remote.h"
49 #include "xfrd-disk.h"
50 #ifdef USE_DNSTAP
51 #include "dnstap/dnstap_collector.h"
52 #endif
53 
54 /* The server handler... */
55 struct nsd nsd;
56 static char hostname[MAXHOSTNAMELEN];
57 extern config_parser_state_type* cfg_parser;
58 static void version(void) ATTR_NORETURN;
59 
60 /*
61  * Print the help text.
62  *
63  */
64 static void
65 usage (void)
66 {
67 	fprintf(stderr, "Usage: nsd [OPTION]...\n");
68 	fprintf(stderr, "Name Server Daemon.\n\n");
69 	fprintf(stderr,
70 		"Supported options:\n"
71 		"  -4                   Only listen to IPv4 connections.\n"
72 		"  -6                   Only listen to IPv6 connections.\n"
73 		"  -a ip-address[@port] Listen to the specified incoming IP address (and port)\n"
74 		"                       May be specified multiple times).\n"
75 		"  -c configfile        Read specified configfile instead of %s.\n"
76 		"  -d                   do not fork as a daemon process.\n"
77 #ifndef NDEBUG
78 		"  -F facilities        Specify the debug facilities.\n"
79 #endif /* NDEBUG */
80 		"  -f database          Specify the database to load.\n"
81 		"  -h                   Print this help information.\n"
82 		, CONFIGFILE);
83 	fprintf(stderr,
84 		"  -i identity          Specify the identity when queried for id.server CHAOS TXT.\n"
85 		"  -I nsid              Specify the NSID. This must be a hex string.\n"
86 #ifndef NDEBUG
87 		"  -L level             Specify the debug level.\n"
88 #endif /* NDEBUG */
89 		"  -l filename          Specify the log file.\n"
90 		"  -N server-count      The number of servers to start.\n"
91 		"  -n tcp-count         The maximum number of TCP connections per server.\n"
92 		"  -P pidfile           Specify the PID file to write.\n"
93 		"  -p port              Specify the port to listen to.\n"
94 		"  -s seconds           Dump statistics every SECONDS seconds.\n"
95 		"  -t chrootdir         Change root to specified directory on startup.\n"
96 		);
97 	fprintf(stderr,
98 		"  -u user              Change effective uid to the specified user.\n"
99 		"  -V level             Specify verbosity level.\n"
100 		"  -v                   Print version information.\n"
101 		);
102 	fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
103 		PACKAGE_VERSION, PACKAGE_BUGREPORT);
104 }
105 
106 /*
107  * Print the version exit.
108  *
109  */
110 static void
111 version(void)
112 {
113 	fprintf(stderr, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
114 	fprintf(stderr, "Written by NLnet Labs.\n\n");
115 	fprintf(stderr,
116 		"Copyright (C) 2001-2006 NLnet Labs.  This is free software.\n"
117 		"There is NO warranty; not even for MERCHANTABILITY or FITNESS\n"
118 		"FOR A PARTICULAR PURPOSE.\n");
119 	exit(0);
120 }
121 
122 static void
123 copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src)
124 {
125 	dest->ai_flags = src->ai_flags;
126 	dest->ai_family = src->ai_family;
127 	dest->ai_socktype = src->ai_socktype;
128 	dest->ai_addrlen = src->ai_addrlen;
129 	memcpy(&dest->ai_addr, src->ai_addr, src->ai_addrlen);
130 }
131 
132 static void
133 setup_socket(struct nsd_socket *sock, const char *node, const char *port, struct addrinfo *hints)
134 {
135 	int ret;
136 	char *sep = NULL;
137 	char *host, host_buf[INET6_ADDRSTRLEN + 1 /* '\0' */];
138 	const char *service;
139 	char service_buf[6 + 1 /* '\0' */]; /* 65535 */
140 	struct addrinfo *addr = NULL;
141 
142 	if(node) {
143 		host = host_buf;
144 		sep = strchr(node, '@');
145 		if(sep) {
146 			size_t len = (sep - node) + 1;
147 			if (len > sizeof(host_buf)) {
148 				len = sizeof(host_buf);
149 			}
150 			strlcpy(host_buf, node, len);
151 			strlcpy(service_buf, sep + 1, sizeof(service_buf));
152 			service = service_buf;
153 		} else {
154 			strlcpy(host_buf, node, sizeof(host_buf));
155 			service = port;
156 		}
157 	} else {
158 		host = NULL;
159 		service = port;
160 	}
161 
162 	if((ret = getaddrinfo(host, service, hints, &addr)) == 0) {
163 		copyaddrinfo(&sock->addr, addr);
164 		freeaddrinfo(addr);
165 	} else {
166 		error("cannot parse address '%s': getaddrinfo: %s %s",
167 		      host ? host : "(null)",
168 		      gai_strerror(ret),
169 		      ret==EAI_SYSTEM ? strerror(errno) : "");
170 	}
171 }
172 
173 static void
174 figure_default_sockets(
175 	struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs,
176 	const char *udp_port, const char *tcp_port,
177 	const struct addrinfo *hints)
178 {
179 	int r;
180 	size_t i = 0, n = 1;
181 	struct addrinfo ai[2] = { *hints, *hints };
182 
183 	assert(udp != NULL);
184 	assert(tcp != NULL);
185 	assert(ifs != NULL);
186 
187 	ai[0].ai_socktype = SOCK_DGRAM;
188 	ai[1].ai_socktype = SOCK_STREAM;
189 
190 #ifdef INET6
191 #ifdef IPV6_V6ONLY
192 	if (hints->ai_family == AF_UNSPEC) {
193 		ai[0].ai_family = AF_INET6;
194 		ai[1].ai_family = AF_INET6;
195 		n++;
196 	}
197 #endif /* IPV6_V6ONLY */
198 #endif /* INET6 */
199 
200 	*udp = xalloc_zero((n + 1) * sizeof(struct nsd_socket));
201 	*tcp = xalloc_zero((n + 1) * sizeof(struct nsd_socket));
202 	region_add_cleanup(nsd.region, free, *udp);
203 	region_add_cleanup(nsd.region, free, *tcp);
204 
205 #ifdef INET6
206 	if(hints->ai_family == AF_UNSPEC) {
207 		/*
208 		 * With IPv6 we'd like to open two separate sockets,
209 		 * one for IPv4 and one for IPv6, both listening to
210 		 * the wildcard address (unless the -4 or -6 flags are
211 		 * specified).
212 		 *
213 		 * However, this is only supported on platforms where
214 		 * we can turn the socket option IPV6_V6ONLY _on_.
215 		 * Otherwise we just listen to a single IPv6 socket
216 		 * and any incoming IPv4 connections will be
217 		 * automatically mapped to our IPv6 socket.
218 		 */
219 #ifdef IPV6_V6ONLY
220 		struct addrinfo *addrs[2] = { NULL, NULL };
221 
222 		if((r = getaddrinfo(NULL, udp_port, &ai[0], &addrs[0])) == 0 &&
223 		   (r = getaddrinfo(NULL, tcp_port, &ai[1], &addrs[1])) == 0)
224 		{
225 			(*udp)[i].flags |= NSD_SOCKET_IS_OPTIONAL;
226 			copyaddrinfo(&(*udp)[i].addr, addrs[0]);
227 			(*tcp)[i].flags |= NSD_SOCKET_IS_OPTIONAL;
228 			copyaddrinfo(&(*tcp)[i].addr, addrs[1]);
229 			i++;
230 		} else {
231 			log_msg(LOG_WARNING, "No IPv6, fallback to IPv4. getaddrinfo: %s",
232 			  r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
233 		}
234 
235 		if(addrs[0])
236 			freeaddrinfo(addrs[0]);
237 		if(addrs[1])
238 			freeaddrinfo(addrs[1]);
239 
240 		ai[0].ai_family = AF_INET;
241 		ai[1].ai_family = AF_INET;
242 #endif /* IPV6_V6ONLY */
243 	}
244 #endif /* INET6 */
245 
246 	*ifs = i + 1;
247 	setup_socket(&(*udp)[i], NULL, udp_port, &ai[0]);
248 	setup_socket(&(*tcp)[i], NULL, tcp_port, &ai[1]);
249 }
250 
251 static void
252 figure_sockets(
253 	struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs,
254 	struct ip_address_option *ips,
255 	const char *udp_port, const char *tcp_port,
256 	const struct addrinfo *hints)
257 {
258 	size_t i = 0;
259 	struct addrinfo ai = *hints;
260 	struct ip_address_option *ip;
261 
262 	if(!ips) {
263 		figure_default_sockets(udp, tcp, ifs, udp_port, tcp_port, hints);
264 		return;
265 	}
266 
267 	*ifs = 0;
268 	for(ip = ips; ip; ip = ip->next) {
269 		(*ifs)++;
270 	}
271 
272 	*udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
273 	*tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
274 	region_add_cleanup(nsd.region, free, *udp);
275 	region_add_cleanup(nsd.region, free, *tcp);
276 
277 	ai.ai_flags |= AI_NUMERICHOST;
278 	for(ip = ips, i = 0; ip; ip = ip->next, i++) {
279 		ai.ai_socktype = SOCK_DGRAM;
280 		setup_socket(&(*udp)[i], ip->address, udp_port, &ai);
281 		ai.ai_socktype = SOCK_STREAM;
282 		setup_socket(&(*tcp)[i], ip->address, tcp_port, &ai);
283 	}
284 
285 	assert(i == *ifs);
286 }
287 
288 /*
289  * Fetch the nsd parent process id from the nsd pidfile
290  *
291  */
292 pid_t
293 readpid(const char *file)
294 {
295 	int fd;
296 	pid_t pid;
297 	char pidbuf[16];
298 	char *t;
299 	int l;
300 
301 	if ((fd = open(file, O_RDONLY)) == -1) {
302 		return -1;
303 	}
304 
305 	if (((l = read(fd, pidbuf, sizeof(pidbuf)))) == -1) {
306 		close(fd);
307 		return -1;
308 	}
309 
310 	close(fd);
311 
312 	/* Empty pidfile means no pidfile... */
313 	if (l == 0) {
314 		errno = ENOENT;
315 		return -1;
316 	}
317 
318 	pid = (pid_t) strtol(pidbuf, &t, 10);
319 
320 	if (*t && *t != '\n') {
321 		return -1;
322 	}
323 	return pid;
324 }
325 
326 /*
327  * Store the nsd parent process id in the nsd pidfile
328  *
329  */
330 int
331 writepid(struct nsd *nsd)
332 {
333 	FILE * fd;
334 	char pidbuf[32];
335 	if(!nsd->pidfile || !nsd->pidfile[0])
336 		return 0;
337 
338 	snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) nsd->pid);
339 
340 	if ((fd = fopen(nsd->pidfile, "w")) ==  NULL ) {
341 		log_msg(LOG_ERR, "cannot open pidfile %s: %s",
342 			nsd->pidfile, strerror(errno));
343 		return -1;
344 	}
345 
346 	if (!write_data(fd, pidbuf, strlen(pidbuf))) {
347 		log_msg(LOG_ERR, "cannot write pidfile %s: %s",
348 			nsd->pidfile, strerror(errno));
349 		fclose(fd);
350 		return -1;
351 	}
352 	fclose(fd);
353 
354 	if (chown(nsd->pidfile, nsd->uid, nsd->gid) == -1) {
355 		log_msg(LOG_ERR, "cannot chown %u.%u %s: %s",
356 			(unsigned) nsd->uid, (unsigned) nsd->gid,
357 			nsd->pidfile, strerror(errno));
358 		return -1;
359 	}
360 
361 	return 0;
362 }
363 
364 void
365 unlinkpid(const char* file)
366 {
367 	int fd = -1;
368 
369 	if (file && file[0]) {
370 		/* truncate pidfile */
371 		fd = open(file, O_WRONLY | O_TRUNC, 0644);
372 		if (fd == -1) {
373 			/* Truncate the pid file.  */
374 			log_msg(LOG_ERR, "can not truncate the pid file %s: %s", file, strerror(errno));
375 		} else
376 			close(fd);
377 
378 		/* unlink pidfile */
379 		if (unlink(file) == -1)
380 			log_msg(LOG_WARNING, "failed to unlink pidfile %s: %s",
381 				file, strerror(errno));
382 	}
383 }
384 
385 /*
386  * Incoming signals, set appropriate actions.
387  *
388  */
389 void
390 sig_handler(int sig)
391 {
392 	/* To avoid race cond. We really don't want to use log_msg() in this handler */
393 
394 	/* Are we a child server? */
395 	if (nsd.server_kind != NSD_SERVER_MAIN) {
396 		switch (sig) {
397 		case SIGCHLD:
398 			nsd.signal_hint_child = 1;
399 			break;
400 		case SIGALRM:
401 			break;
402 		case SIGINT:
403 		case SIGTERM:
404 			nsd.signal_hint_quit = 1;
405 			break;
406 		case SIGILL:
407 		case SIGUSR1:	/* Dump stats on SIGUSR1.  */
408 			nsd.signal_hint_statsusr = 1;
409 			break;
410 		default:
411 			break;
412 		}
413 		return;
414 	}
415 
416 	/* We are the main process */
417 	switch (sig) {
418 	case SIGCHLD:
419 		nsd.signal_hint_child = 1;
420 		return;
421 	case SIGHUP:
422 		nsd.signal_hint_reload_hup = 1;
423 		return;
424 	case SIGALRM:
425 		nsd.signal_hint_stats = 1;
426 		break;
427 	case SIGILL:
428 		/*
429 		 * For backwards compatibility with BIND 8 and older
430 		 * versions of NSD.
431 		 */
432 		nsd.signal_hint_statsusr = 1;
433 		break;
434 	case SIGUSR1:
435 		/* Dump statistics.  */
436 		nsd.signal_hint_statsusr = 1;
437 		break;
438 	case SIGINT:
439 	case SIGTERM:
440 	default:
441 		nsd.signal_hint_shutdown = 1;
442 		break;
443 	}
444 }
445 
446 /*
447  * Statistic output...
448  *
449  */
450 #ifdef BIND8_STATS
451 void
452 bind8_stats (struct nsd *nsd)
453 {
454 	char buf[MAXSYSLOGMSGLEN];
455 	char *msg, *t;
456 	int i, len;
457 
458 	/* Current time... */
459 	time_t now;
460 	if(!nsd->st.period)
461 		return;
462 	time(&now);
463 
464 	/* NSTATS */
465 	t = msg = buf + snprintf(buf, MAXSYSLOGMSGLEN, "NSTATS %lld %lu",
466 				 (long long) now, (unsigned long) nsd->st.boot);
467 	for (i = 0; i <= 255; i++) {
468 		/* How much space left? */
469 		if ((len = buf + MAXSYSLOGMSGLEN - t) < 32) {
470 			log_msg(LOG_INFO, "%s", buf);
471 			t = msg;
472 			len = buf + MAXSYSLOGMSGLEN - t;
473 		}
474 
475 		if (nsd->st.qtype[i] != 0) {
476 			t += snprintf(t, len, " %s=%lu", rrtype_to_string(i), nsd->st.qtype[i]);
477 		}
478 	}
479 	if (t > msg)
480 		log_msg(LOG_INFO, "%s", buf);
481 
482 	/* XSTATS */
483 	/* Only print it if we're in the main daemon or have anything to report... */
484 	if (nsd->server_kind == NSD_SERVER_MAIN
485 	    || nsd->st.dropped || nsd->st.raxfr || (nsd->st.qudp + nsd->st.qudp6 - nsd->st.dropped)
486 	    || nsd->st.txerr || nsd->st.opcode[OPCODE_QUERY] || nsd->st.opcode[OPCODE_IQUERY]
487 	    || nsd->st.wrongzone || nsd->st.ctcp + nsd->st.ctcp6 || nsd->st.rcode[RCODE_SERVFAIL]
488 	    || nsd->st.rcode[RCODE_FORMAT] || nsd->st.nona || nsd->st.rcode[RCODE_NXDOMAIN]
489 	    || nsd->st.opcode[OPCODE_UPDATE]) {
490 
491 		log_msg(LOG_INFO, "XSTATS %lld %lu"
492 			" RR=%lu RNXD=%lu RFwdR=%lu RDupR=%lu RFail=%lu RFErr=%lu RErr=%lu RAXFR=%lu"
493 			" RLame=%lu ROpts=%lu SSysQ=%lu SAns=%lu SFwdQ=%lu SDupQ=%lu SErr=%lu RQ=%lu"
494 			" RIQ=%lu RFwdQ=%lu RDupQ=%lu RTCP=%lu SFwdR=%lu SFail=%lu SFErr=%lu SNaAns=%lu"
495 			" SNXD=%lu RUQ=%lu RURQ=%lu RUXFR=%lu RUUpd=%lu",
496 			(long long) now, (unsigned long) nsd->st.boot,
497 			nsd->st.dropped, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0,
498 			(unsigned long)0, (unsigned long)0, nsd->st.raxfr, (unsigned long)0, (unsigned long)0,
499 			(unsigned long)0, nsd->st.qudp + nsd->st.qudp6 - nsd->st.dropped, (unsigned long)0,
500 			(unsigned long)0, nsd->st.txerr,
501 			nsd->st.opcode[OPCODE_QUERY], nsd->st.opcode[OPCODE_IQUERY], nsd->st.wrongzone,
502 			(unsigned long)0, nsd->st.ctcp + nsd->st.ctcp6,
503 			(unsigned long)0, nsd->st.rcode[RCODE_SERVFAIL], nsd->st.rcode[RCODE_FORMAT],
504 			nsd->st.nona, nsd->st.rcode[RCODE_NXDOMAIN],
505 			(unsigned long)0, (unsigned long)0, (unsigned long)0, nsd->st.opcode[OPCODE_UPDATE]);
506 	}
507 
508 }
509 #endif /* BIND8_STATS */
510 
511 extern char *optarg;
512 extern int optind;
513 
514 int
515 main(int argc, char *argv[])
516 {
517 	/* Scratch variables... */
518 	int c;
519 	pid_t	oldpid;
520 	size_t i;
521 	struct sigaction action;
522 #ifdef HAVE_GETPWNAM
523 	struct passwd *pwd = NULL;
524 #endif /* HAVE_GETPWNAM */
525 
526 	struct ip_address_option *ip;
527 	struct addrinfo hints;
528 	const char *udp_port = 0;
529 	const char *tcp_port = 0;
530 
531 	const char *configfile = CONFIGFILE;
532 
533 	char* argv0 = (argv0 = strrchr(argv[0], '/')) ? argv0 + 1 : argv[0];
534 
535 	log_init(argv0);
536 
537 	/* Initialize the server handler... */
538 	memset(&nsd, 0, sizeof(struct nsd));
539 	nsd.region      = region_create(xalloc, free);
540 	nsd.dbfile	= 0;
541 	nsd.pidfile	= 0;
542 	nsd.server_kind = NSD_SERVER_MAIN;
543 	memset(&hints, 0, sizeof(hints));
544 	hints.ai_family = DEFAULT_AI_FAMILY;
545 	hints.ai_flags = AI_PASSIVE;
546 	nsd.identity	= 0;
547 	nsd.version	= VERSION;
548 	nsd.username	= 0;
549 	nsd.chrootdir	= 0;
550 	nsd.nsid 	= NULL;
551 	nsd.nsid_len 	= 0;
552 
553 	nsd.child_count = 0;
554 	nsd.maximum_tcp_count = 0;
555 	nsd.current_tcp_count = 0;
556 	nsd.file_rotation_ok = 0;
557 
558 	/* Set up our default identity to gethostname(2) */
559 	if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
560 		nsd.identity = hostname;
561 	} else {
562 		log_msg(LOG_ERR,
563 			"failed to get the host name: %s - using default identity",
564 			strerror(errno));
565 		nsd.identity = IDENTITY;
566 	}
567 
568 	/* Create region where options will be stored and set defaults */
569 	nsd.options = nsd_options_create(region_create_custom(xalloc, free,
570 		DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE,
571 		DEFAULT_INITIAL_CLEANUP_SIZE, 1));
572 
573 	/* Parse the command line... */
574 	while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v"
575 #ifndef NDEBUG /* <mattthijs> only when configured with --enable-checking */
576 		"F:L:"
577 #endif /* NDEBUG */
578 		)) != -1) {
579 		switch (c) {
580 		case '4':
581 			hints.ai_family = AF_INET;
582 			break;
583 		case '6':
584 #ifdef INET6
585 			hints.ai_family = AF_INET6;
586 #else /* !INET6 */
587 			error("IPv6 support not enabled.");
588 #endif /* INET6 */
589 			break;
590 		case 'a':
591 			ip = region_alloc_zero(
592 				nsd.options->region, sizeof(*ip));
593 			ip->address = region_strdup(
594 				nsd.options->region, optarg);
595 			ip->next = nsd.options->ip_addresses;
596 			nsd.options->ip_addresses = ip;
597 			break;
598 		case 'c':
599 			configfile = optarg;
600 			break;
601 		case 'd':
602 			nsd.debug = 1;
603 			break;
604 		case 'f':
605 			nsd.dbfile = optarg;
606 			break;
607 		case 'h':
608 			usage();
609 			exit(0);
610 		case 'i':
611 			nsd.identity = optarg;
612 			break;
613 		case 'I':
614 			if (nsd.nsid_len != 0) {
615 				/* can only be given once */
616 				break;
617 			}
618 			if (strncasecmp(optarg, "ascii_", 6) == 0) {
619 				nsd.nsid = xalloc(strlen(optarg+6));
620 				nsd.nsid_len = strlen(optarg+6);
621 				memmove(nsd.nsid, optarg+6, nsd.nsid_len);
622 			} else {
623 				if (strlen(optarg) % 2 != 0) {
624 					error("the NSID must be a hex string of an even length.");
625 				}
626 				nsd.nsid = xalloc(strlen(optarg) / 2);
627 				nsd.nsid_len = strlen(optarg) / 2;
628 				if (hex_pton(optarg, nsd.nsid, nsd.nsid_len) == -1) {
629 					error("hex string cannot be parsed '%s' in NSID.", optarg);
630 				}
631 			}
632 			break;
633 		case 'l':
634 			nsd.log_filename = optarg;
635 			break;
636 		case 'N':
637 			i = atoi(optarg);
638 			if (i <= 0) {
639 				error("number of child servers must be greater than zero.");
640 			} else {
641 				nsd.child_count = i;
642 			}
643 			break;
644 		case 'n':
645 			i = atoi(optarg);
646 			if (i <= 0) {
647 				error("number of concurrent TCP connections must greater than zero.");
648 			} else {
649 				nsd.maximum_tcp_count = i;
650 			}
651 			break;
652 		case 'P':
653 			nsd.pidfile = optarg;
654 			break;
655 		case 'p':
656 			if (atoi(optarg) == 0) {
657 				error("port argument must be numeric.");
658 			}
659 			tcp_port = optarg;
660 			udp_port = optarg;
661 			break;
662 		case 's':
663 #ifdef BIND8_STATS
664 			nsd.st.period = atoi(optarg);
665 #else /* !BIND8_STATS */
666 			error("BIND 8 statistics not enabled.");
667 #endif /* BIND8_STATS */
668 			break;
669 		case 't':
670 #ifdef HAVE_CHROOT
671 			nsd.chrootdir = optarg;
672 #else /* !HAVE_CHROOT */
673 			error("chroot not supported on this platform.");
674 #endif /* HAVE_CHROOT */
675 			break;
676 		case 'u':
677 			nsd.username = optarg;
678 			break;
679 		case 'V':
680 			verbosity = atoi(optarg);
681 			break;
682 		case 'v':
683 			version();
684 			/* version exits */
685 			break;
686 #ifndef NDEBUG
687 		case 'F':
688 			sscanf(optarg, "%x", &nsd_debug_facilities);
689 			break;
690 		case 'L':
691 			sscanf(optarg, "%d", &nsd_debug_level);
692 			break;
693 #endif /* NDEBUG */
694 		case '?':
695 		default:
696 			usage();
697 			exit(1);
698 		}
699 	}
700 	argc -= optind;
701 	/* argv += optind; */
702 
703 	/* Commandline parse error */
704 	if (argc != 0) {
705 		usage();
706 		exit(1);
707 	}
708 
709 	if (strlen(nsd.identity) > UCHAR_MAX) {
710 		error("server identity too long (%u characters)",
711 		      (unsigned) strlen(nsd.identity));
712 	}
713 	if(!tsig_init(nsd.region))
714 		error("init tsig failed");
715 
716 	/* Read options */
717 	if(!parse_options_file(nsd.options, configfile, NULL, NULL)) {
718 		error("could not read config: %s\n", configfile);
719 	}
720 	if(!parse_zone_list_file(nsd.options)) {
721 		error("could not read zonelist file %s\n",
722 			nsd.options->zonelistfile);
723 	}
724 	if(nsd.options->do_ip4 && !nsd.options->do_ip6) {
725 		hints.ai_family = AF_INET;
726 	}
727 #ifdef INET6
728 	if(nsd.options->do_ip6 && !nsd.options->do_ip4) {
729 		hints.ai_family = AF_INET6;
730 	}
731 #endif /* INET6 */
732 	if (verbosity == 0)
733 		verbosity = nsd.options->verbosity;
734 #ifndef NDEBUG
735 	if (nsd_debug_level > 0 && verbosity == 0)
736 		verbosity = nsd_debug_level;
737 #endif /* NDEBUG */
738 	if(nsd.options->debug_mode) nsd.debug=1;
739 	if(!nsd.dbfile)
740 	{
741 		if(nsd.options->database)
742 			nsd.dbfile = nsd.options->database;
743 		else
744 			nsd.dbfile = DBFILE;
745 	}
746 	if(!nsd.pidfile)
747 	{
748 		if(nsd.options->pidfile)
749 			nsd.pidfile = nsd.options->pidfile;
750 		else
751 			nsd.pidfile = PIDFILE;
752 	}
753 	if(strcmp(nsd.identity, hostname)==0 || strcmp(nsd.identity,IDENTITY)==0)
754 	{
755 		if(nsd.options->identity)
756 			nsd.identity = nsd.options->identity;
757 	}
758 	if(nsd.options->version) {
759 		nsd.version = nsd.options->version;
760 	}
761 	if (nsd.options->logfile && !nsd.log_filename) {
762 		nsd.log_filename = nsd.options->logfile;
763 	}
764 	if(nsd.child_count == 0) {
765 		nsd.child_count = nsd.options->server_count;
766 	}
767 #ifdef SO_REUSEPORT
768 	if(nsd.options->reuseport && nsd.child_count > 1) {
769 		nsd.reuseport = nsd.child_count;
770 	}
771 #endif /* SO_REUSEPORT */
772 	if(nsd.maximum_tcp_count == 0) {
773 		nsd.maximum_tcp_count = nsd.options->tcp_count;
774 	}
775 	nsd.tcp_timeout = nsd.options->tcp_timeout;
776 	nsd.tcp_query_count = nsd.options->tcp_query_count;
777 	nsd.tcp_mss = nsd.options->tcp_mss;
778 	nsd.outgoing_tcp_mss = nsd.options->outgoing_tcp_mss;
779 	nsd.ipv4_edns_size = nsd.options->ipv4_edns_size;
780 	nsd.ipv6_edns_size = nsd.options->ipv6_edns_size;
781 #ifdef HAVE_SSL
782 	nsd.tls_ctx = NULL;
783 #endif
784 
785 	if(udp_port == 0)
786 	{
787 		if(nsd.options->port != 0) {
788 			udp_port = nsd.options->port;
789 			tcp_port = nsd.options->port;
790 		} else {
791 			udp_port = UDP_PORT;
792 			tcp_port = TCP_PORT;
793 		}
794 	}
795 #ifdef BIND8_STATS
796 	if(nsd.st.period == 0) {
797 		nsd.st.period = nsd.options->statistics;
798 	}
799 #endif /* BIND8_STATS */
800 #ifdef HAVE_CHROOT
801 	if(nsd.chrootdir == 0) nsd.chrootdir = nsd.options->chroot;
802 #ifdef CHROOTDIR
803 	/* if still no chrootdir, fallback to default */
804 	if(nsd.chrootdir == 0) nsd.chrootdir = CHROOTDIR;
805 #endif /* CHROOTDIR */
806 #endif /* HAVE_CHROOT */
807 	if(nsd.username == 0) {
808 		if(nsd.options->username) nsd.username = nsd.options->username;
809 		else nsd.username = USER;
810 	}
811 	if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
812 		if(chdir(nsd.options->zonesdir)) {
813 			error("cannot chdir to '%s': %s",
814 				nsd.options->zonesdir, strerror(errno));
815 		}
816 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
817 			nsd.options->zonesdir));
818 	}
819 
820 	/* EDNS0 */
821 	edns_init_data(&nsd.edns_ipv4, nsd.options->ipv4_edns_size);
822 #if defined(INET6)
823 #if defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU)
824 	edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
825 #else /* no way to set IPV6 MTU, send no bigger than that. */
826 	if (nsd.options->ipv6_edns_size < IPV6_MIN_MTU)
827 		edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
828 	else
829 		edns_init_data(&nsd.edns_ipv6, IPV6_MIN_MTU);
830 #endif /* IPV6 MTU) */
831 #endif /* defined(INET6) */
832 
833 	if (nsd.nsid_len == 0 && nsd.options->nsid) {
834 		if (strlen(nsd.options->nsid) % 2 != 0) {
835 			error("the NSID must be a hex string of an even length.");
836 		}
837 		nsd.nsid = xalloc(strlen(nsd.options->nsid) / 2);
838 		nsd.nsid_len = strlen(nsd.options->nsid) / 2;
839 		if (hex_pton(nsd.options->nsid, nsd.nsid, nsd.nsid_len) == -1) {
840 			error("hex string cannot be parsed '%s' in NSID.", nsd.options->nsid);
841 		}
842 	}
843 	edns_init_nsid(&nsd.edns_ipv4, nsd.nsid_len);
844 #if defined(INET6)
845 	edns_init_nsid(&nsd.edns_ipv6, nsd.nsid_len);
846 #endif /* defined(INET6) */
847 
848 	/* Number of child servers to fork.  */
849 	nsd.children = (struct nsd_child *) region_alloc_array(
850 		nsd.region, nsd.child_count, sizeof(struct nsd_child));
851 	for (i = 0; i < nsd.child_count; ++i) {
852 		nsd.children[i].kind = NSD_SERVER_BOTH;
853 		nsd.children[i].pid = -1;
854 		nsd.children[i].child_fd = -1;
855 		nsd.children[i].parent_fd = -1;
856 		nsd.children[i].handler = NULL;
857 		nsd.children[i].need_to_send_STATS = 0;
858 		nsd.children[i].need_to_send_QUIT = 0;
859 		nsd.children[i].need_to_exit = 0;
860 		nsd.children[i].has_exited = 0;
861 #ifdef  BIND8_STATS
862 		nsd.children[i].query_count = 0;
863 #endif
864 	}
865 
866 	nsd.this_child = NULL;
867 
868 	figure_sockets(&nsd.udp, &nsd.tcp, &nsd.ifs,
869 		nsd.options->ip_addresses, udp_port, tcp_port, &hints);
870 
871 	/* Parse the username into uid and gid */
872 	nsd.gid = getgid();
873 	nsd.uid = getuid();
874 #ifdef HAVE_GETPWNAM
875 	/* Parse the username into uid and gid */
876 	if (*nsd.username) {
877 		if (isdigit((unsigned char)*nsd.username)) {
878 			char *t;
879 			nsd.uid = strtol(nsd.username, &t, 10);
880 			if (*t != 0) {
881 				if (*t != '.' || !isdigit((unsigned char)*++t)) {
882 					error("-u user or -u uid or -u uid.gid");
883 				}
884 				nsd.gid = strtol(t, &t, 10);
885 			} else {
886 				/* Lookup the group id in /etc/passwd */
887 				if ((pwd = getpwuid(nsd.uid)) == NULL) {
888 					error("user id %u does not exist.", (unsigned) nsd.uid);
889 				} else {
890 					nsd.gid = pwd->pw_gid;
891 				}
892 			}
893 		} else {
894 			/* Lookup the user id in /etc/passwd */
895 			if ((pwd = getpwnam(nsd.username)) == NULL) {
896 				error("user '%s' does not exist.", nsd.username);
897 			} else {
898 				nsd.uid = pwd->pw_uid;
899 				nsd.gid = pwd->pw_gid;
900 			}
901 		}
902 	}
903 	/* endpwent(); */
904 #endif /* HAVE_GETPWNAM */
905 
906 #if defined(HAVE_SSL)
907 	key_options_tsig_add(nsd.options);
908 #endif
909 
910 	append_trailing_slash(&nsd.options->xfrdir, nsd.options->region);
911 	/* Check relativity of pathnames to chroot */
912 	if (nsd.chrootdir && nsd.chrootdir[0]) {
913 		/* existing chrootdir: append trailing slash for strncmp checking */
914 		append_trailing_slash(&nsd.chrootdir, nsd.region);
915 		append_trailing_slash(&nsd.options->zonesdir, nsd.options->region);
916 
917 		/* zonesdir must be absolute and within chroot,
918 		 * all other pathnames may be relative to zonesdir */
919 		if (strncmp(nsd.options->zonesdir, nsd.chrootdir, strlen(nsd.chrootdir)) != 0) {
920 			error("zonesdir %s has to be an absolute path that starts with the chroot path %s",
921 				nsd.options->zonesdir, nsd.chrootdir);
922 		} else if (!file_inside_chroot(nsd.pidfile, nsd.chrootdir)) {
923 			error("pidfile %s is not relative to %s: chroot not possible",
924 				nsd.pidfile, nsd.chrootdir);
925 		} else if (!file_inside_chroot(nsd.dbfile, nsd.chrootdir)) {
926 			error("database %s is not relative to %s: chroot not possible",
927 				nsd.dbfile, nsd.chrootdir);
928 		} else if (!file_inside_chroot(nsd.options->xfrdfile, nsd.chrootdir)) {
929 			error("xfrdfile %s is not relative to %s: chroot not possible",
930 				nsd.options->xfrdfile, nsd.chrootdir);
931 		} else if (!file_inside_chroot(nsd.options->zonelistfile, nsd.chrootdir)) {
932 			error("zonelistfile %s is not relative to %s: chroot not possible",
933 				nsd.options->zonelistfile, nsd.chrootdir);
934 		} else if (!file_inside_chroot(nsd.options->xfrdir, nsd.chrootdir)) {
935 			error("xfrdir %s is not relative to %s: chroot not possible",
936 				nsd.options->xfrdir, nsd.chrootdir);
937 		}
938 	}
939 
940 	/* Set up the logging */
941 	log_open(LOG_PID, FACILITY, nsd.log_filename);
942 	if (!nsd.log_filename)
943 		log_set_log_function(log_syslog);
944 	else if (nsd.uid && nsd.gid) {
945 		if(chown(nsd.log_filename, nsd.uid, nsd.gid) != 0)
946 			VERBOSITY(2, (LOG_WARNING, "chown %s failed: %s",
947 				nsd.log_filename, strerror(errno)));
948 	}
949 	log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING);
950 
951 	/* Do we have a running nsd? */
952 	if(nsd.pidfile && nsd.pidfile[0]) {
953 		if ((oldpid = readpid(nsd.pidfile)) == -1) {
954 			if (errno != ENOENT) {
955 				log_msg(LOG_ERR, "can't read pidfile %s: %s",
956 					nsd.pidfile, strerror(errno));
957 			}
958 		} else {
959 			if (kill(oldpid, 0) == 0 || errno == EPERM) {
960 				log_msg(LOG_WARNING,
961 					"%s is already running as %u, continuing",
962 					argv0, (unsigned) oldpid);
963 			} else {
964 				log_msg(LOG_ERR,
965 					"...stale pid file from process %u",
966 					(unsigned) oldpid);
967 			}
968 		}
969 	}
970 
971 	/* Setup the signal handling... */
972 	action.sa_handler = sig_handler;
973 	sigfillset(&action.sa_mask);
974 	action.sa_flags = 0;
975 	sigaction(SIGTERM, &action, NULL);
976 	sigaction(SIGHUP, &action, NULL);
977 	sigaction(SIGINT, &action, NULL);
978 	sigaction(SIGILL, &action, NULL);
979 	sigaction(SIGUSR1, &action, NULL);
980 	sigaction(SIGALRM, &action, NULL);
981 	sigaction(SIGCHLD, &action, NULL);
982 	action.sa_handler = SIG_IGN;
983 	sigaction(SIGPIPE, &action, NULL);
984 
985 	/* Initialize... */
986 	nsd.mode = NSD_RUN;
987 	nsd.signal_hint_child = 0;
988 	nsd.signal_hint_reload = 0;
989 	nsd.signal_hint_reload_hup = 0;
990 	nsd.signal_hint_quit = 0;
991 	nsd.signal_hint_shutdown = 0;
992 	nsd.signal_hint_stats = 0;
993 	nsd.signal_hint_statsusr = 0;
994 	nsd.quit_sync_done = 0;
995 
996 	/* Initialize the server... */
997 	if (server_init(&nsd) != 0) {
998 		error("server initialization failed, %s could "
999 			"not be started", argv0);
1000 	}
1001 #if defined(HAVE_SSL)
1002 	if(nsd.options->control_enable || (nsd.options->tls_service_key && nsd.options->tls_service_key[0])) {
1003 		perform_openssl_init();
1004 	}
1005 	if(nsd.options->control_enable) {
1006 		/* read ssl keys while superuser and outside chroot */
1007 		if(!(nsd.rc = daemon_remote_create(nsd.options)))
1008 			error("could not perform remote control setup");
1009 	}
1010 	if(nsd.options->tls_service_key && nsd.options->tls_service_key[0]
1011 	   && nsd.options->tls_service_pem && nsd.options->tls_service_pem[0]) {
1012 		if(!(nsd.tls_ctx = server_tls_ctx_create(&nsd, NULL,
1013 			nsd.options->tls_service_ocsp)))
1014 			error("could not set up tls SSL_CTX");
1015 	}
1016 #endif /* HAVE_SSL */
1017 
1018 	/* Unless we're debugging, fork... */
1019 	if (!nsd.debug) {
1020 		int fd;
1021 
1022 		/* Take off... */
1023 		switch (fork()) {
1024 		case 0:
1025 			/* Child */
1026 			break;
1027 		case -1:
1028 			error("fork() failed: %s", strerror(errno));
1029 			break;
1030 		default:
1031 			/* Parent is done */
1032 			server_close_all_sockets(nsd.udp, nsd.ifs);
1033 			server_close_all_sockets(nsd.tcp, nsd.ifs);
1034 			exit(0);
1035 		}
1036 
1037 		/* Detach ourselves... */
1038 		if (setsid() == -1) {
1039 			error("setsid() failed: %s", strerror(errno));
1040 		}
1041 
1042 		if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
1043 			(void)dup2(fd, STDIN_FILENO);
1044 			(void)dup2(fd, STDOUT_FILENO);
1045 			(void)dup2(fd, STDERR_FILENO);
1046 			if (fd > 2)
1047 				(void)close(fd);
1048 		}
1049 	}
1050 
1051 	/* Get our process id */
1052 	nsd.pid = getpid();
1053 
1054 	/* Set user context */
1055 #ifdef HAVE_GETPWNAM
1056 	if (*nsd.username) {
1057 #ifdef HAVE_SETUSERCONTEXT
1058 		/* setusercontext does initgroups, setuid, setgid, and
1059 		 * also resource limits from login config, but we
1060 		 * still call setresuid, setresgid to be sure to set all uid */
1061 		if (setusercontext(NULL, pwd, nsd.uid,
1062 			LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
1063 			log_msg(LOG_WARNING, "unable to setusercontext %s: %s",
1064 				nsd.username, strerror(errno));
1065 #endif /* HAVE_SETUSERCONTEXT */
1066 	}
1067 #endif /* HAVE_GETPWNAM */
1068 
1069 	/* Chroot */
1070 #ifdef HAVE_CHROOT
1071 	if (nsd.chrootdir && nsd.chrootdir[0]) {
1072 		int l = strlen(nsd.chrootdir)-1; /* ends in trailing slash */
1073 
1074 		if (file_inside_chroot(nsd.log_filename, nsd.chrootdir))
1075 			nsd.file_rotation_ok = 1;
1076 
1077 		/* strip chroot from pathnames if they're absolute */
1078 		nsd.options->zonesdir += l;
1079 		if (nsd.log_filename){
1080 			if (nsd.log_filename[0] == '/')
1081 				nsd.log_filename += l;
1082 		}
1083 		if (nsd.pidfile && nsd.pidfile[0] == '/')
1084 			nsd.pidfile += l;
1085 		if (nsd.dbfile[0] == '/')
1086 			nsd.dbfile += l;
1087 		if (nsd.options->xfrdfile[0] == '/')
1088 			nsd.options->xfrdfile += l;
1089 		if (nsd.options->zonelistfile[0] == '/')
1090 			nsd.options->zonelistfile += l;
1091 		if (nsd.options->xfrdir[0] == '/')
1092 			nsd.options->xfrdir += l;
1093 
1094 		/* strip chroot from pathnames of "include:" statements
1095 		 * on subsequent repattern commands */
1096 		cfg_parser->chroot = nsd.chrootdir;
1097 
1098 #ifdef HAVE_TZSET
1099 		/* set timezone whilst not yet in chroot */
1100 		tzset();
1101 #endif
1102 		if (chroot(nsd.chrootdir)) {
1103 			error("unable to chroot: %s", strerror(errno));
1104 		}
1105 		if (chdir("/")) {
1106 			error("unable to chdir to chroot: %s", strerror(errno));
1107 		}
1108 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed root directory to %s",
1109 			nsd.chrootdir));
1110 		/* chdir to zonesdir again after chroot */
1111 		if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
1112 			if(chdir(nsd.options->zonesdir)) {
1113 				error("unable to chdir to '%s': %s",
1114 					nsd.options->zonesdir, strerror(errno));
1115 			}
1116 			DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
1117 				nsd.options->zonesdir));
1118 		}
1119 	}
1120 	else
1121 #endif /* HAVE_CHROOT */
1122 		nsd.file_rotation_ok = 1;
1123 
1124 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "file rotation on %s %sabled",
1125 		nsd.log_filename, nsd.file_rotation_ok?"en":"dis"));
1126 
1127 	/* Write pidfile */
1128 	if (writepid(&nsd) == -1) {
1129 		log_msg(LOG_ERR, "cannot overwrite the pidfile %s: %s",
1130 			nsd.pidfile, strerror(errno));
1131 	}
1132 
1133 	/* Drop the permissions */
1134 #ifdef HAVE_GETPWNAM
1135 	if (*nsd.username) {
1136 #ifdef HAVE_INITGROUPS
1137 		if(initgroups(nsd.username, nsd.gid) != 0)
1138 			log_msg(LOG_WARNING, "unable to initgroups %s: %s",
1139 				nsd.username, strerror(errno));
1140 #endif /* HAVE_INITGROUPS */
1141 		endpwent();
1142 
1143 #ifdef HAVE_SETRESGID
1144 		if(setresgid(nsd.gid,nsd.gid,nsd.gid) != 0)
1145 #elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
1146 			if(setregid(nsd.gid,nsd.gid) != 0)
1147 #else /* use setgid */
1148 				if(setgid(nsd.gid) != 0)
1149 #endif /* HAVE_SETRESGID */
1150 					error("unable to set group id of %s: %s",
1151 						nsd.username, strerror(errno));
1152 
1153 #ifdef HAVE_SETRESUID
1154 		if(setresuid(nsd.uid,nsd.uid,nsd.uid) != 0)
1155 #elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
1156 			if(setreuid(nsd.uid,nsd.uid) != 0)
1157 #else /* use setuid */
1158 				if(setuid(nsd.uid) != 0)
1159 #endif /* HAVE_SETRESUID */
1160 					error("unable to set user id of %s: %s",
1161 						nsd.username, strerror(errno));
1162 
1163 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "dropped user privileges, run as %s",
1164 			nsd.username));
1165 	}
1166 #endif /* HAVE_GETPWNAM */
1167 
1168 	if (pledge("stdio rpath wpath cpath dns inet proc", NULL) == -1)
1169 		error("pledge");
1170 
1171 	xfrd_make_tempdir(&nsd);
1172 #ifdef USE_ZONE_STATS
1173 	options_zonestatnames_create(nsd.options);
1174 	server_zonestat_alloc(&nsd);
1175 #endif /* USE_ZONE_STATS */
1176 #ifdef USE_DNSTAP
1177 	if(nsd.options->dnstap_enable) {
1178 		nsd.dt_collector = dt_collector_create(&nsd);
1179 		dt_collector_start(nsd.dt_collector, &nsd);
1180 	}
1181 #endif /* USE_DNSTAP */
1182 
1183 	if(nsd.server_kind == NSD_SERVER_MAIN) {
1184 		server_prepare_xfrd(&nsd);
1185 		/* xfrd forks this before reading database, so it does not get
1186 		 * the memory size of the database */
1187 		server_start_xfrd(&nsd, 0, 0);
1188 		/* close zonelistfile in non-xfrd processes */
1189 		zone_list_close(nsd.options);
1190 	}
1191 	if (server_prepare(&nsd) != 0) {
1192 		unlinkpid(nsd.pidfile);
1193 		error("server preparation failed, %s could "
1194 			"not be started", argv0);
1195 	}
1196 	if(nsd.server_kind == NSD_SERVER_MAIN) {
1197 		server_send_soa_xfrd(&nsd, 0);
1198 	}
1199 
1200 	/* Really take off */
1201 	log_msg(LOG_NOTICE, "%s started (%s), pid %d",
1202 		argv0, PACKAGE_STRING, (int) nsd.pid);
1203 
1204 	if (nsd.server_kind == NSD_SERVER_MAIN) {
1205 		server_main(&nsd);
1206 	} else {
1207 		server_child(&nsd);
1208 	}
1209 
1210 	/* NOTREACH */
1211 	exit(0);
1212 }
1213