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 #ifdef HAVE_OPENSSL_RAND_H
29 #include <openssl/rand.h>
30 #endif
31
32 #include <assert.h>
33 #include <ctype.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <limits.h>
37 #include <netdb.h>
38 #include <pwd.h>
39 #include <signal.h>
40 #include <stdarg.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <time.h>
46 #include <unistd.h>
47 #ifdef HAVE_IFADDRS_H
48 #include <ifaddrs.h>
49 #endif
50
51 #include "nsd.h"
52 #include "options.h"
53 #include "tsig.h"
54 #include "remote.h"
55 #include "xfrd-disk.h"
56 #include "ipc.h"
57 #ifdef USE_DNSTAP
58 #include "dnstap/dnstap_collector.h"
59 #endif
60 #include "util/proxy_protocol.h"
61
62 /* The server handler... */
63 struct nsd nsd;
64 static char hostname[MAXHOSTNAMELEN];
65 extern config_parser_state_type* cfg_parser;
66 static void version(void) ATTR_NORETURN;
67
68 /*
69 * Print the help text.
70 *
71 */
72 static void
usage(void)73 usage (void)
74 {
75 fprintf(stderr, "Usage: nsd [OPTION]...\n");
76 fprintf(stderr, "Name Server Daemon.\n\n");
77 fprintf(stderr,
78 "Supported options:\n"
79 " -4 Only listen to IPv4 connections.\n"
80 " -6 Only listen to IPv6 connections.\n"
81 " -a ip-address[@port] Listen to the specified incoming IP address (and port)\n"
82 " May be specified multiple times).\n"
83 " -c configfile Read specified configfile instead of %s.\n"
84 " -d do not fork as a daemon process.\n"
85 #ifndef NDEBUG
86 " -F facilities Specify the debug facilities.\n"
87 #endif /* NDEBUG */
88 " -h Print this help information.\n"
89 , CONFIGFILE);
90 fprintf(stderr,
91 " -i identity Specify the identity when queried for id.server CHAOS TXT.\n"
92 " -I nsid Specify the NSID. This must be a hex string.\n"
93 #ifndef NDEBUG
94 " -L level Specify the debug level.\n"
95 #endif /* NDEBUG */
96 " -l filename Specify the log file.\n"
97 " -N server-count The number of servers to start.\n"
98 " -n tcp-count The maximum number of TCP connections per server.\n"
99 " -P pidfile Specify the PID file to write.\n"
100 " -p port Specify the port to listen to.\n"
101 " -s seconds Dump statistics every SECONDS seconds.\n"
102 " -t chrootdir Change root to specified directory on startup.\n"
103 );
104 fprintf(stderr,
105 " -u user Change effective uid to the specified user.\n"
106 " -V level Specify verbosity level.\n"
107 " -v Print version information.\n"
108 );
109 fprintf(stderr, "Version %s. Report bugs to <%s>.\n",
110 PACKAGE_VERSION, PACKAGE_BUGREPORT);
111 }
112
113 /*
114 * Print the version exit.
115 *
116 */
117 static void
version(void)118 version(void)
119 {
120 fprintf(stderr, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
121 fprintf(stderr, "Written by NLnet Labs.\n\n");
122 fprintf(stderr, "Configure line: %s\n", CONFCMDLINE);
123 #ifdef USE_MINI_EVENT
124 fprintf(stderr, "Event loop: internal (uses select)\n");
125 #else
126 # if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
127 fprintf(stderr, "Event loop: %s %s (uses %s)\n",
128 "libev",
129 nsd_event_vs(),
130 nsd_event_method());
131 # else
132 fprintf(stderr, "Event loop: %s %s (uses %s)\n",
133 "libevent",
134 nsd_event_vs(),
135 nsd_event_method());
136 # endif
137 #endif
138 #ifdef HAVE_SSL
139 fprintf(stderr, "Linked with %s\n\n",
140 # ifdef SSLEAY_VERSION
141 SSLeay_version(SSLEAY_VERSION)
142 # else
143 OpenSSL_version(OPENSSL_VERSION)
144 # endif
145 );
146 #endif
147 fprintf(stderr,
148 "Copyright (C) 2001-2020 NLnet Labs. This is free software.\n"
149 "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n"
150 "FOR A PARTICULAR PURPOSE.\n");
151 exit(0);
152 }
153
154 static void
setup_verifier_environment(void)155 setup_verifier_environment(void)
156 {
157 size_t i;
158 int ret, ip4, ip6;
159 char *buf, host[NI_MAXHOST], serv[NI_MAXSERV];
160 size_t size, cnt = 0;
161
162 /* allocate large enough buffer to hold a list of all ip addresses.
163 ((" " + INET6_ADDRSTRLEN + "@" + "65535") * n) + "\0" */
164 size = ((INET6_ADDRSTRLEN + 1 + 5 + 1) * nsd.verify_ifs) + 1;
165 buf = xalloc(size);
166
167 ip4 = ip6 = 0;
168 for(i = 0; i < nsd.verify_ifs; i++) {
169 ret = getnameinfo(
170 (struct sockaddr *)&nsd.verify_udp[i].addr.ai_addr,
171 nsd.verify_udp[i].addr.ai_addrlen,
172 host, sizeof(host), serv, sizeof(serv),
173 NI_NUMERICHOST | NI_NUMERICSERV);
174 if(ret != 0) {
175 log_msg(LOG_ERR, "error in getnameinfo: %s",
176 gai_strerror(ret));
177 continue;
178 }
179 buf[cnt++] = ' ';
180 cnt += strlcpy(&buf[cnt], host, size - cnt);
181 assert(cnt < size);
182 buf[cnt++] = '@';
183 cnt += strlcpy(&buf[cnt], serv, size - cnt);
184 assert(cnt < size);
185 #ifdef INET6
186 if (nsd.verify_udp[i].addr.ai_family == AF_INET6 && !ip6) {
187 setenv("VERIFY_IPV6_ADDRESS", host, 1);
188 setenv("VERIFY_IPV6_PORT", serv, 1);
189 setenv("VERIFY_IP_ADDRESS", host, 1);
190 setenv("VERIFY_PORT", serv, 1);
191 ip6 = 1;
192 } else
193 #endif
194 if (!ip4) {
195 assert(nsd.verify_udp[i].addr.ai_family == AF_INET);
196 setenv("VERIFY_IPV4_ADDRESS", host, 1);
197 setenv("VERIFY_IPV4_PORT", serv, 1);
198 if (!ip6) {
199 setenv("VERIFY_IP_ADDRESS", host, 1);
200 setenv("VERIFY_PORT", serv, 1);
201 }
202 ip4 = 1;
203 }
204 }
205
206 setenv("VERIFY_IP_ADDRESSES", &buf[1], 1);
207 free(buf);
208 }
209
210 static void
copyaddrinfo(struct nsd_addrinfo * dest,struct addrinfo * src)211 copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src)
212 {
213 dest->ai_flags = src->ai_flags;
214 dest->ai_family = src->ai_family;
215 dest->ai_socktype = src->ai_socktype;
216 dest->ai_addrlen = src->ai_addrlen;
217 memcpy(&dest->ai_addr, src->ai_addr, src->ai_addrlen);
218 }
219
220 static void
setup_socket(struct nsd_socket * sock,const char * node,const char * port,struct addrinfo * hints)221 setup_socket(
222 struct nsd_socket *sock, const char *node, const char *port,
223 struct addrinfo *hints)
224 {
225 int ret;
226 char *host;
227 char host_buf[sizeof("65535") + INET6_ADDRSTRLEN + 1 /* '\0' */];
228 const char *service;
229 struct addrinfo *addr = NULL;
230
231 sock->fib = -1;
232 if(node) {
233 char *sep;
234
235 if (strlcpy(host_buf, node, sizeof(host_buf)) >= sizeof(host_buf)) {
236 error("cannot parse address '%s': %s", node,
237 strerror(ENAMETOOLONG));
238 }
239
240 host = host_buf;
241 sep = strchr(host_buf, '@');
242 if(sep != NULL) {
243 *sep = '\0';
244 service = sep + 1;
245 } else {
246 service = port;
247 }
248 } else {
249 host = NULL;
250 service = port;
251 }
252
253 if((ret = getaddrinfo(host, service, hints, &addr)) == 0) {
254 copyaddrinfo(&sock->addr, addr);
255 freeaddrinfo(addr);
256 } else {
257 error("cannot parse address '%s': getaddrinfo: %s %s",
258 host ? host : "(null)",
259 gai_strerror(ret),
260 ret==EAI_SYSTEM ? strerror(errno) : "");
261 }
262 }
263
264 static void
figure_socket_servers(struct nsd_socket * sock,struct ip_address_option * ip)265 figure_socket_servers(
266 struct nsd_socket *sock, struct ip_address_option *ip)
267 {
268 int i;
269 struct range_option *server;
270
271 sock->servers = xalloc_zero(nsd_bitset_size(nsd.child_count));
272 region_add_cleanup(nsd.region, free, sock->servers);
273 nsd_bitset_init(sock->servers, nsd.child_count);
274
275 if(!ip || !ip->servers) {
276 /* every server must listen on this socket */
277 for(i = 0; i < (int)nsd.child_count; i++) {
278 nsd_bitset_set(sock->servers, i);
279 }
280 return;
281 }
282
283 /* only specific servers must listen on this socket */
284 for(server = ip->servers; server; server = server->next) {
285 if(server->first == server->last) {
286 if(server->first <= 0) {
287 error("server %d specified for ip-address %s "
288 "is invalid; server ranges are 1-based",
289 server->first, ip->address);
290 } else if(server->last > (int)nsd.child_count) {
291 error("server %d specified for ip-address %s "
292 "exceeds number of servers configured "
293 "in server-count",
294 server->first, ip->address);
295 }
296 } else {
297 /* parse_range must ensure range itself is valid */
298 assert(server->first < server->last);
299 if(server->first <= 0) {
300 error("server range %d-%d specified for "
301 "ip-address %s is invalid; server "
302 "ranges are 1-based",
303 server->first, server->last, ip->address);
304 } else if(server->last > (int)nsd.child_count) {
305 error("server range %d-%d specified for "
306 "ip-address %s exceeds number of servers "
307 "configured in server-count",
308 server->first, server->last, ip->address);
309 }
310 }
311 for(i = server->first - 1; i < server->last; i++) {
312 nsd_bitset_set(sock->servers, i);
313 }
314 }
315 }
316
317 static void
figure_default_sockets(struct nsd_socket ** udp,struct nsd_socket ** tcp,size_t * ifs,const char * node,const char * udp_port,const char * tcp_port,const struct addrinfo * hints)318 figure_default_sockets(
319 struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs,
320 const char *node, const char *udp_port, const char *tcp_port,
321 const struct addrinfo *hints)
322 {
323 size_t i = 0, n = 1;
324 struct addrinfo ai[2] = { *hints, *hints };
325
326 assert(udp != NULL);
327 assert(tcp != NULL);
328 assert(ifs != NULL);
329
330 ai[0].ai_socktype = SOCK_DGRAM;
331 ai[1].ai_socktype = SOCK_STREAM;
332
333 #ifdef INET6
334 #ifdef IPV6_V6ONLY
335 if (hints->ai_family == AF_UNSPEC) {
336 ai[0].ai_family = AF_INET6;
337 ai[1].ai_family = AF_INET6;
338 n++;
339 }
340 #endif /* IPV6_V6ONLY */
341 #endif /* INET6 */
342
343 *udp = xalloc_zero((n + 1) * sizeof(struct nsd_socket));
344 *tcp = xalloc_zero((n + 1) * sizeof(struct nsd_socket));
345 region_add_cleanup(nsd.region, free, *udp);
346 region_add_cleanup(nsd.region, free, *tcp);
347
348 #ifdef INET6
349 if(hints->ai_family == AF_UNSPEC) {
350 /*
351 * With IPv6 we'd like to open two separate sockets, one for
352 * IPv4 and one for IPv6, both listening to the wildcard
353 * address (unless the -4 or -6 flags are specified).
354 *
355 * However, this is only supported on platforms where we can
356 * turn the socket option IPV6_V6ONLY _on_. Otherwise we just
357 * listen to a single IPv6 socket and any incoming IPv4
358 * connections will be automatically mapped to our IPv6
359 * socket.
360 */
361 #ifdef IPV6_V6ONLY
362 int r;
363 struct addrinfo *addrs[2] = { NULL, NULL };
364
365 if((r = getaddrinfo(node, udp_port, &ai[0], &addrs[0])) == 0 &&
366 (r = getaddrinfo(node, tcp_port, &ai[1], &addrs[1])) == 0)
367 {
368 (*udp)[i].flags |= NSD_SOCKET_IS_OPTIONAL;
369 (*udp)[i].fib = -1;
370 copyaddrinfo(&(*udp)[i].addr, addrs[0]);
371 figure_socket_servers(&(*udp)[i], NULL);
372 (*tcp)[i].flags |= NSD_SOCKET_IS_OPTIONAL;
373 (*tcp)[i].fib = -1;
374 copyaddrinfo(&(*tcp)[i].addr, addrs[1]);
375 figure_socket_servers(&(*tcp)[i], NULL);
376 i++;
377 } else {
378 log_msg(LOG_WARNING, "No IPv6, fallback to IPv4. getaddrinfo: %s",
379 r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
380 }
381
382 if(addrs[0])
383 freeaddrinfo(addrs[0]);
384 if(addrs[1])
385 freeaddrinfo(addrs[1]);
386
387 ai[0].ai_family = AF_INET;
388 ai[1].ai_family = AF_INET;
389 #endif /* IPV6_V6ONLY */
390 }
391 #endif /* INET6 */
392
393 *ifs = i + 1;
394 setup_socket(&(*udp)[i], node, udp_port, &ai[0]);
395 figure_socket_servers(&(*udp)[i], NULL);
396 setup_socket(&(*tcp)[i], node, tcp_port, &ai[1]);
397 figure_socket_servers(&(*tcp)[i], NULL);
398 }
399
400 #ifdef HAVE_GETIFADDRS
401 static int
find_device(struct nsd_socket * sock,const struct ifaddrs * ifa)402 find_device(
403 struct nsd_socket *sock,
404 const struct ifaddrs *ifa)
405 {
406 for(; ifa != NULL; ifa = ifa->ifa_next) {
407 if((ifa->ifa_addr == NULL) ||
408 (ifa->ifa_addr->sa_family != sock->addr.ai_family) ||
409 ((ifa->ifa_flags & IFF_UP) == 0 ||
410 (ifa->ifa_flags & IFF_LOOPBACK) != 0 ||
411 (ifa->ifa_flags & IFF_RUNNING) == 0))
412 {
413 continue;
414 }
415
416 #ifdef INET6
417 if(ifa->ifa_addr->sa_family == AF_INET6) {
418 struct sockaddr_in6 *sa1, *sa2;
419 size_t sz = sizeof(struct in6_addr);
420 sa1 = (struct sockaddr_in6 *)ifa->ifa_addr;
421 sa2 = (struct sockaddr_in6 *)&sock->addr.ai_addr;
422 if(memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sz) == 0) {
423 break;
424 }
425 } else
426 #endif
427 if(ifa->ifa_addr->sa_family == AF_INET) {
428 struct sockaddr_in *sa1, *sa2;
429 sa1 = (struct sockaddr_in *)ifa->ifa_addr;
430 sa2 = (struct sockaddr_in *)&sock->addr.ai_addr;
431 if(sa1->sin_addr.s_addr == sa2->sin_addr.s_addr) {
432 break;
433 }
434 }
435 }
436
437 if(ifa != NULL) {
438 size_t len = strlcpy(sock->device, ifa->ifa_name, sizeof(sock->device));
439 if(len < sizeof(sock->device)) {
440 char *colon = strchr(sock->device, ':');
441 if(colon != NULL)
442 *colon = '\0';
443 return 1;
444 }
445 }
446
447 return 0;
448 }
449 #endif /* HAVE_GETIFADDRS */
450
451 static void
figure_sockets(struct nsd_socket ** udp,struct nsd_socket ** tcp,size_t * ifs,struct ip_address_option * ips,const char * node,const char * udp_port,const char * tcp_port,const struct addrinfo * hints)452 figure_sockets(
453 struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs,
454 struct ip_address_option *ips,
455 const char *node, const char *udp_port, const char *tcp_port,
456 const struct addrinfo *hints)
457 {
458 size_t i = 0;
459 struct addrinfo ai = *hints;
460 struct ip_address_option *ip;
461 #ifdef HAVE_GETIFADDRS
462 struct ifaddrs *ifa = NULL;
463 #endif
464 int bind_device = 0;
465
466 if(!ips) {
467 figure_default_sockets(
468 udp, tcp, ifs, node, udp_port, tcp_port, hints);
469 return;
470 }
471
472 *ifs = 0;
473 for(ip = ips; ip; ip = ip->next) {
474 (*ifs)++;
475 bind_device |= (ip->dev != 0);
476 }
477
478 #ifdef HAVE_GETIFADDRS
479 if(bind_device && getifaddrs(&ifa) == -1) {
480 error("getifaddrs failed: %s", strerror(errno));
481 }
482 #endif
483
484 *udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
485 *tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
486 region_add_cleanup(nsd.region, free, *udp);
487 region_add_cleanup(nsd.region, free, *tcp);
488
489 ai.ai_flags |= AI_NUMERICHOST;
490 for(ip = ips, i = 0; ip; ip = ip->next, i++) {
491 ai.ai_socktype = SOCK_DGRAM;
492 setup_socket(&(*udp)[i], ip->address, udp_port, &ai);
493 figure_socket_servers(&(*udp)[i], ip);
494 ai.ai_socktype = SOCK_STREAM;
495 setup_socket(&(*tcp)[i], ip->address, tcp_port, &ai);
496 figure_socket_servers(&(*tcp)[i], ip);
497 if(ip->fib != -1) {
498 (*udp)[i].fib = ip->fib;
499 (*tcp)[i].fib = ip->fib;
500 }
501 #ifdef HAVE_GETIFADDRS
502 if(ip->dev != 0) {
503 (*udp)[i].flags |= NSD_BIND_DEVICE;
504 (*tcp)[i].flags |= NSD_BIND_DEVICE;
505 if(ifa != NULL && (find_device(&(*udp)[i], ifa) == 0 ||
506 find_device(&(*tcp)[i], ifa) == 0))
507 {
508 error("cannot find device for ip-address %s",
509 ip->address);
510 }
511 }
512 #endif
513 }
514
515 assert(i == *ifs);
516
517 #ifdef HAVE_GETIFADDRS
518 if(ifa != NULL) {
519 freeifaddrs(ifa);
520 }
521 #endif
522 }
523
524 /* print server affinity for given socket. "*" if socket has no affinity with
525 any specific server, "x-y" if socket has affinity with more than two
526 consecutively numbered servers, "x" if socket has affinity with a specific
527 server number, which is not necessarily just one server. e.g. "1 3" is
528 printed if socket has affinity with servers number one and three, but not
529 server number two. */
530 static ssize_t
print_socket_servers(struct nsd_socket * sock,char * buf,size_t bufsz)531 print_socket_servers(struct nsd_socket *sock, char *buf, size_t bufsz)
532 {
533 int i, x, y, z, n = (int)(sock->servers->size);
534 char *sep = "";
535 size_t off, tot;
536 ssize_t cnt = 0;
537
538 assert(bufsz != 0);
539
540 off = tot = 0;
541 x = y = z = -1;
542 for (i = 0; i <= n; i++) {
543 if (i == n || !nsd_bitset_isset(sock->servers, i)) {
544 cnt = 0;
545 if (i == n && x == -1) {
546 assert(y == -1);
547 assert(z == -1);
548 cnt = snprintf(buf, bufsz, "-");
549 } else if (y > z) {
550 assert(x > z);
551 if (x == 0 && y == (n - 1)) {
552 assert(z == -1);
553 cnt = snprintf(buf+off, bufsz-off,
554 "*");
555 } else if (x == y) {
556 cnt = snprintf(buf+off, bufsz-off,
557 "%s%d", sep, x+1);
558 } else if (x == (y - 1)) {
559 cnt = snprintf(buf+off, bufsz-off,
560 "%s%d %d", sep, x+1, y+1);
561 } else {
562 assert(y > (x + 1));
563 cnt = snprintf(buf+off, bufsz-off,
564 "%s%d-%d", sep, x+1, y+1);
565 }
566 }
567 z = i;
568 if (cnt > 0) {
569 tot += (size_t)cnt;
570 off = (tot < bufsz) ? tot : bufsz - 1;
571 sep = " ";
572 } else if (cnt < 0) {
573 return -1;
574 }
575 } else if (x <= z) {
576 x = y = i;
577 } else {
578 assert(x > z);
579 y = i;
580 }
581 }
582
583 return tot;
584 }
585
586 static void
print_sockets(struct nsd_socket * udp,struct nsd_socket * tcp,size_t ifs)587 print_sockets(
588 struct nsd_socket *udp, struct nsd_socket *tcp, size_t ifs)
589 {
590 char sockbuf[INET6_ADDRSTRLEN + 6 + 1];
591 char *serverbuf;
592 size_t i, serverbufsz, servercnt;
593 const char *fmt = "listen on ip-address %s (%s) with server(s): %s";
594 struct nsd_bitset *servers;
595
596 if(ifs == 0) {
597 return;
598 }
599
600 assert(udp != NULL);
601 assert(tcp != NULL);
602
603 servercnt = udp[0].servers->size;
604 serverbufsz = (((servercnt / 10) * servercnt) + servercnt) + 1;
605 serverbuf = xalloc(serverbufsz);
606
607 /* warn user of unused servers */
608 servers = xalloc(nsd_bitset_size(servercnt));
609 nsd_bitset_init(servers, (size_t)servercnt);
610
611 for(i = 0; i < ifs; i++) {
612 assert(udp[i].servers->size == servercnt);
613 addrport2str((void*)&udp[i].addr.ai_addr, sockbuf, sizeof(sockbuf));
614 print_socket_servers(&udp[i], serverbuf, serverbufsz);
615 nsd_bitset_or(servers, servers, udp[i].servers);
616 VERBOSITY(3, (LOG_NOTICE, fmt, sockbuf, "udp", serverbuf));
617 assert(tcp[i].servers->size == servercnt);
618 addrport2str((void*)&tcp[i].addr.ai_addr, sockbuf, sizeof(sockbuf));
619 print_socket_servers(&tcp[i], serverbuf, serverbufsz);
620 nsd_bitset_or(servers, servers, tcp[i].servers);
621 VERBOSITY(3, (LOG_NOTICE, fmt, sockbuf, "tcp", serverbuf));
622 }
623
624
625 /* warn user of unused servers */
626 for(i = 0; i < servercnt; i++) {
627 if(!nsd_bitset_isset(servers, i)) {
628 log_msg(LOG_WARNING, "server %zu will not listen on "
629 "any specified ip-address", i+1);
630 }
631 }
632 free(serverbuf);
633 free(servers);
634 }
635
636 #ifdef HAVE_CPUSET_T
free_cpuset(void * ptr)637 static void free_cpuset(void *ptr)
638 {
639 cpuset_t *set = (cpuset_t *)ptr;
640 cpuset_destroy(set);
641 }
642 #endif
643
644 /*
645 * Fetch the nsd parent process id from the nsd pidfile
646 *
647 */
648 pid_t
readpid(const char * file)649 readpid(const char *file)
650 {
651 int fd;
652 pid_t pid;
653 char pidbuf[16];
654 char *t;
655 int l;
656
657 if ((fd = open(file, O_RDONLY)) == -1) {
658 return -1;
659 }
660
661 if (((l = read(fd, pidbuf, sizeof(pidbuf)))) == -1) {
662 close(fd);
663 return -1;
664 }
665
666 close(fd);
667
668 /* Empty pidfile means no pidfile... */
669 if (l == 0) {
670 errno = ENOENT;
671 return -1;
672 }
673
674 pid = (pid_t) strtol(pidbuf, &t, 10);
675
676 if (*t && *t != '\n') {
677 return -1;
678 }
679 return pid;
680 }
681
682 /*
683 * Store the nsd parent process id in the nsd pidfile
684 *
685 */
686 int
writepid(struct nsd * nsd)687 writepid(struct nsd *nsd)
688 {
689 int fd;
690 char pidbuf[32];
691 size_t count = 0;
692 if(!nsd->pidfile || !nsd->pidfile[0])
693 return 0;
694
695 snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) nsd->pid);
696
697 if((fd = open(nsd->pidfile, O_WRONLY | O_CREAT | O_TRUNC
698 #ifdef O_NOFOLLOW
699 | O_NOFOLLOW
700 #endif
701 , 0644)) == -1) {
702 log_msg(LOG_ERR, "cannot open pidfile %s: %s",
703 nsd->pidfile, strerror(errno));
704 return -1;
705 }
706
707 while(count < strlen(pidbuf)) {
708 ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
709 if(r == -1) {
710 if(errno == EAGAIN || errno == EINTR)
711 continue;
712 log_msg(LOG_ERR, "cannot write pidfile %s: %s",
713 nsd->pidfile, strerror(errno));
714 close(fd);
715 return -1;
716 } else if(r == 0) {
717 log_msg(LOG_ERR, "cannot write any bytes to "
718 "pidfile %s: write returns 0 bytes written",
719 nsd->pidfile);
720 close(fd);
721 return -1;
722 }
723 count += r;
724 }
725 close(fd);
726
727 if (chown(nsd->pidfile, nsd->uid, nsd->gid) == -1) {
728 log_msg(LOG_ERR, "cannot chown %u.%u %s: %s",
729 (unsigned) nsd->uid, (unsigned) nsd->gid,
730 nsd->pidfile, strerror(errno));
731 return -1;
732 }
733
734 return 0;
735 }
736
737 void
unlinkpid(const char * file)738 unlinkpid(const char* file)
739 {
740 int fd = -1;
741
742 if (file && file[0]) {
743 /* truncate pidfile */
744 fd = open(file, O_WRONLY | O_TRUNC, 0644);
745 if (fd == -1) {
746 /* Truncate the pid file. */
747 log_msg(LOG_ERR, "can not truncate the pid file %s: %s", file, strerror(errno));
748 } else {
749 close(fd);
750 }
751
752 /* unlink pidfile */
753 if (unlink(file) == -1) {
754 /* this unlink may not work if the pidfile is located
755 * outside of the chroot/workdir or we no longer
756 * have permissions */
757 VERBOSITY(3, (LOG_WARNING,
758 "failed to unlink pidfile %s: %s",
759 file, strerror(errno)));
760 }
761 }
762 }
763
764 /*
765 * Incoming signals, set appropriate actions.
766 *
767 */
768 void
sig_handler(int sig)769 sig_handler(int sig)
770 {
771 /* To avoid race cond. We really don't want to use log_msg() in this handler */
772
773 /* Are we a child server? */
774 if (nsd.server_kind != NSD_SERVER_MAIN) {
775 switch (sig) {
776 case SIGCHLD:
777 nsd.signal_hint_child = 1;
778 break;
779 case SIGALRM:
780 break;
781 case SIGINT:
782 case SIGTERM:
783 nsd.signal_hint_quit = 1;
784 break;
785 case SIGILL:
786 case SIGUSR1: /* Dump stats on SIGUSR1. */
787 nsd.signal_hint_statsusr = 1;
788 break;
789 default:
790 break;
791 }
792 return;
793 }
794
795 /* We are the main process */
796 switch (sig) {
797 case SIGCHLD:
798 nsd.signal_hint_child = 1;
799 return;
800 case SIGHUP:
801 nsd.signal_hint_reload_hup = 1;
802 return;
803 case SIGALRM:
804 nsd.signal_hint_stats = 1;
805 break;
806 case SIGILL:
807 /*
808 * For backwards compatibility with BIND 8 and older
809 * versions of NSD.
810 */
811 nsd.signal_hint_statsusr = 1;
812 break;
813 case SIGUSR1:
814 /* Dump statistics. */
815 nsd.signal_hint_statsusr = 1;
816 break;
817 case SIGINT:
818 case SIGTERM:
819 default:
820 nsd.signal_hint_shutdown = 1;
821 break;
822 }
823 }
824
825 /*
826 * Statistic output...
827 *
828 */
829 #ifdef BIND8_STATS
830 void
bind8_stats(struct nsd * nsd)831 bind8_stats (struct nsd *nsd)
832 {
833 char buf[MAXSYSLOGMSGLEN];
834 char *msg, *t;
835 int i, len;
836 struct nsdst st;
837
838 /* Current time... */
839 time_t now;
840 if(!nsd->st_period)
841 return;
842 time(&now);
843
844 memcpy(&st, nsd->st, sizeof(st));
845 stats_subtract(&st, &nsd->stat_proc);
846
847 /* NSTATS */
848 t = msg = buf + snprintf(buf, MAXSYSLOGMSGLEN, "NSTATS %lld %lu",
849 (long long) now, (unsigned long) st.boot);
850 for (i = 0; i <= 255; i++) {
851 /* How much space left? */
852 if ((len = buf + MAXSYSLOGMSGLEN - t) < 32) {
853 log_msg(LOG_INFO, "%s", buf);
854 t = msg;
855 len = buf + MAXSYSLOGMSGLEN - t;
856 }
857
858 if (st.qtype[i] != 0) {
859 t += snprintf(t, len, " %s=%lu", rrtype_to_string(i), st.qtype[i]);
860 }
861 }
862 if (t > msg)
863 log_msg(LOG_INFO, "%s", buf);
864
865 /* XSTATS */
866 /* Only print it if we're in the main daemon or have anything to report... */
867 if (nsd->server_kind == NSD_SERVER_MAIN
868 || st.dropped || st.raxfr || st.rixfr || (st.qudp + st.qudp6 - st.dropped)
869 || st.txerr || st.opcode[OPCODE_QUERY] || st.opcode[OPCODE_IQUERY]
870 || st.wrongzone || st.ctcp + st.ctcp6 || st.rcode[RCODE_SERVFAIL]
871 || st.rcode[RCODE_FORMAT] || st.nona || st.rcode[RCODE_NXDOMAIN]
872 || st.opcode[OPCODE_UPDATE]) {
873
874 log_msg(LOG_INFO, "XSTATS %lld %lu"
875 " RR=%lu RNXD=%lu RFwdR=%lu RDupR=%lu RFail=%lu RFErr=%lu RErr=%lu RAXFR=%lu RIXFR=%lu"
876 " RLame=%lu ROpts=%lu SSysQ=%lu SAns=%lu SFwdQ=%lu SDupQ=%lu SErr=%lu RQ=%lu"
877 " RIQ=%lu RFwdQ=%lu RDupQ=%lu RTCP=%lu SFwdR=%lu SFail=%lu SFErr=%lu SNaAns=%lu"
878 " SNXD=%lu RUQ=%lu RURQ=%lu RUXFR=%lu RUUpd=%lu",
879 (long long) now, (unsigned long) st.boot,
880 st.dropped, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0,
881 (unsigned long)0, (unsigned long)0, st.raxfr, st.rixfr, (unsigned long)0, (unsigned long)0,
882 (unsigned long)0, st.qudp + st.qudp6 - st.dropped, (unsigned long)0,
883 (unsigned long)0, st.txerr,
884 st.opcode[OPCODE_QUERY], st.opcode[OPCODE_IQUERY], st.wrongzone,
885 (unsigned long)0, st.ctcp + st.ctcp6,
886 (unsigned long)0, st.rcode[RCODE_SERVFAIL], st.rcode[RCODE_FORMAT],
887 st.nona, st.rcode[RCODE_NXDOMAIN],
888 (unsigned long)0, (unsigned long)0, (unsigned long)0, st.opcode[OPCODE_UPDATE]);
889 }
890
891 }
892 #endif /* BIND8_STATS */
893
894 static
cookie_secret_file_read(nsd_type * nsd)895 int cookie_secret_file_read(nsd_type* nsd) {
896 char secret[NSD_COOKIE_SECRET_SIZE * 2 + 2/*'\n' and '\0'*/];
897 char const* file = nsd->options->cookie_secret_file;
898 FILE* f;
899 int corrupt = 0;
900 size_t count;
901
902 assert( nsd->options->cookie_secret_file != NULL );
903 f = fopen(file, "r");
904 /* a non-existing cookie file is not an error */
905 if( f == NULL ) { return errno != EPERM; }
906 /* cookie secret file exists and is readable */
907 nsd->cookie_count = 0;
908 for( count = 0; count < NSD_COOKIE_HISTORY_SIZE; count++ ) {
909 size_t secret_len = 0;
910 ssize_t decoded_len = 0;
911 if( fgets(secret, sizeof(secret), f) == NULL ) { break; }
912 secret_len = strlen(secret);
913 if( secret_len == 0 ) { break; }
914 assert( secret_len <= sizeof(secret) );
915 secret_len = secret[secret_len - 1] == '\n' ? secret_len - 1 : secret_len;
916 if( secret_len != NSD_COOKIE_SECRET_SIZE * 2 ) { corrupt++; break; }
917 /* needed for `hex_pton`; stripping potential `\n` */
918 secret[secret_len] = '\0';
919 decoded_len = hex_pton(secret, nsd->cookie_secrets[count].cookie_secret,
920 NSD_COOKIE_SECRET_SIZE);
921 if( decoded_len != NSD_COOKIE_SECRET_SIZE ) { corrupt++; break; }
922 nsd->cookie_count++;
923 }
924 fclose(f);
925 return corrupt == 0;
926 }
927
928 extern char *optarg;
929 extern int optind;
930
931 int
main(int argc,char * argv[])932 main(int argc, char *argv[])
933 {
934 /* Scratch variables... */
935 int c;
936 pid_t oldpid;
937 size_t i;
938 struct sigaction action;
939 #ifdef HAVE_GETPWNAM
940 struct passwd *pwd = NULL;
941 #endif /* HAVE_GETPWNAM */
942
943 struct ip_address_option *ip;
944 struct addrinfo hints;
945 const char *udp_port = 0;
946 const char *tcp_port = 0;
947 const char *verify_port = 0;
948
949 const char *configfile = CONFIGFILE;
950
951 char* argv0 = (argv0 = strrchr(argv[0], '/')) ? argv0 + 1 : argv[0];
952
953 log_init(argv0);
954
955 /* Initialize the server handler... */
956 memset(&nsd, 0, sizeof(struct nsd));
957 nsd.region = region_create(xalloc, free);
958 nsd.pidfile = 0;
959 nsd.server_kind = NSD_SERVER_MAIN;
960 memset(&hints, 0, sizeof(hints));
961 hints.ai_family = DEFAULT_AI_FAMILY;
962 hints.ai_flags = AI_PASSIVE;
963 nsd.identity = 0;
964 nsd.version = VERSION;
965 nsd.username = 0;
966 nsd.chrootdir = 0;
967 nsd.nsid = NULL;
968 nsd.nsid_len = 0;
969 nsd.cookie_count = 0;
970
971 nsd.child_count = 0;
972 nsd.maximum_tcp_count = 0;
973 nsd.current_tcp_count = 0;
974 nsd.file_rotation_ok = 0;
975
976 nsd.do_answer_cookie = 1;
977
978 /* Set up our default identity to gethostname(2) */
979 if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
980 nsd.identity = hostname;
981 } else {
982 log_msg(LOG_ERR,
983 "failed to get the host name: %s - using default identity",
984 strerror(errno));
985 nsd.identity = IDENTITY;
986 }
987
988 /* Create region where options will be stored and set defaults */
989 nsd.options = nsd_options_create(region_create_custom(xalloc, free,
990 DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE,
991 DEFAULT_INITIAL_CLEANUP_SIZE, 1));
992
993 /* Parse the command line... */
994 while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v"
995 #ifndef NDEBUG /* <mattthijs> only when configured with --enable-checking */
996 "F:L:"
997 #endif /* NDEBUG */
998 )) != -1) {
999 switch (c) {
1000 case '4':
1001 hints.ai_family = AF_INET;
1002 break;
1003 case '6':
1004 #ifdef INET6
1005 hints.ai_family = AF_INET6;
1006 #else /* !INET6 */
1007 error("IPv6 support not enabled.");
1008 #endif /* INET6 */
1009 break;
1010 case 'a':
1011 ip = region_alloc_zero(
1012 nsd.options->region, sizeof(*ip));
1013 ip->address = region_strdup(
1014 nsd.options->region, optarg);
1015 ip->next = nsd.options->ip_addresses;
1016 nsd.options->ip_addresses = ip;
1017 break;
1018 case 'c':
1019 configfile = optarg;
1020 break;
1021 case 'd':
1022 nsd.debug = 1;
1023 break;
1024 case 'f':
1025 break;
1026 case 'h':
1027 usage();
1028 exit(0);
1029 case 'i':
1030 nsd.identity = optarg;
1031 break;
1032 case 'I':
1033 if (nsd.nsid_len != 0) {
1034 /* can only be given once */
1035 break;
1036 }
1037 if (strncasecmp(optarg, "ascii_", 6) == 0) {
1038 nsd.nsid = xalloc(strlen(optarg+6));
1039 nsd.nsid_len = strlen(optarg+6);
1040 memmove(nsd.nsid, optarg+6, nsd.nsid_len);
1041 } else {
1042 if (strlen(optarg) % 2 != 0) {
1043 error("the NSID must be a hex string of an even length.");
1044 }
1045 nsd.nsid = xalloc(strlen(optarg) / 2);
1046 nsd.nsid_len = strlen(optarg) / 2;
1047 if (hex_pton(optarg, nsd.nsid, nsd.nsid_len) == -1) {
1048 error("hex string cannot be parsed '%s' in NSID.", optarg);
1049 }
1050 }
1051 break;
1052 case 'l':
1053 nsd.log_filename = optarg;
1054 break;
1055 case 'N':
1056 i = atoi(optarg);
1057 if (i <= 0) {
1058 error("number of child servers must be greater than zero.");
1059 } else {
1060 nsd.child_count = i;
1061 }
1062 break;
1063 case 'n':
1064 i = atoi(optarg);
1065 if (i <= 0) {
1066 error("number of concurrent TCP connections must greater than zero.");
1067 } else {
1068 nsd.maximum_tcp_count = i;
1069 }
1070 break;
1071 case 'P':
1072 nsd.pidfile = optarg;
1073 break;
1074 case 'p':
1075 if (atoi(optarg) == 0) {
1076 error("port argument must be numeric.");
1077 }
1078 tcp_port = optarg;
1079 udp_port = optarg;
1080 break;
1081 case 's':
1082 #ifdef BIND8_STATS
1083 nsd.st_period = atoi(optarg);
1084 #else /* !BIND8_STATS */
1085 error("BIND 8 statistics not enabled.");
1086 #endif /* BIND8_STATS */
1087 break;
1088 case 't':
1089 #ifdef HAVE_CHROOT
1090 nsd.chrootdir = optarg;
1091 #else /* !HAVE_CHROOT */
1092 error("chroot not supported on this platform.");
1093 #endif /* HAVE_CHROOT */
1094 break;
1095 case 'u':
1096 nsd.username = optarg;
1097 break;
1098 case 'V':
1099 verbosity = atoi(optarg);
1100 break;
1101 case 'v':
1102 version();
1103 /* version exits */
1104 break;
1105 #ifndef NDEBUG
1106 case 'F':
1107 sscanf(optarg, "%x", &nsd_debug_facilities);
1108 break;
1109 case 'L':
1110 sscanf(optarg, "%d", &nsd_debug_level);
1111 break;
1112 #endif /* NDEBUG */
1113 case '?':
1114 default:
1115 usage();
1116 exit(1);
1117 }
1118 }
1119 argc -= optind;
1120 /* argv += optind; */
1121
1122 /* Commandline parse error */
1123 if (argc != 0) {
1124 usage();
1125 exit(1);
1126 }
1127
1128 if (strlen(nsd.identity) > UCHAR_MAX) {
1129 error("server identity too long (%u characters)",
1130 (unsigned) strlen(nsd.identity));
1131 }
1132 if(!tsig_init(nsd.region))
1133 error("init tsig failed");
1134 pp_init(&write_uint16, &write_uint32);
1135
1136 /* Read options */
1137 if(!parse_options_file(nsd.options, configfile, NULL, NULL, NULL)) {
1138 error("could not read config: %s\n", configfile);
1139 }
1140 if(!parse_zone_list_file(nsd.options)) {
1141 error("could not read zonelist file %s\n",
1142 nsd.options->zonelistfile);
1143 }
1144 if(nsd.options->do_ip4 && !nsd.options->do_ip6) {
1145 hints.ai_family = AF_INET;
1146 }
1147 #ifdef INET6
1148 if(nsd.options->do_ip6 && !nsd.options->do_ip4) {
1149 hints.ai_family = AF_INET6;
1150 }
1151 #endif /* INET6 */
1152 if (verbosity == 0)
1153 verbosity = nsd.options->verbosity;
1154 #ifndef NDEBUG
1155 if (nsd_debug_level > 0 && verbosity == 0)
1156 verbosity = nsd_debug_level;
1157 #endif /* NDEBUG */
1158 if(nsd.options->debug_mode) nsd.debug=1;
1159 if(!nsd.pidfile)
1160 {
1161 if(nsd.options->pidfile)
1162 nsd.pidfile = nsd.options->pidfile;
1163 else
1164 nsd.pidfile = PIDFILE;
1165 }
1166 if(strcmp(nsd.identity, hostname)==0 || strcmp(nsd.identity,IDENTITY)==0)
1167 {
1168 if(nsd.options->identity)
1169 nsd.identity = nsd.options->identity;
1170 }
1171 if(nsd.options->version) {
1172 nsd.version = nsd.options->version;
1173 }
1174 if (nsd.options->logfile && !nsd.log_filename) {
1175 nsd.log_filename = nsd.options->logfile;
1176 }
1177 if(nsd.child_count == 0) {
1178 nsd.child_count = nsd.options->server_count;
1179 }
1180
1181 #ifdef SO_REUSEPORT
1182 if(nsd.options->reuseport && nsd.child_count > 1) {
1183 nsd.reuseport = nsd.child_count;
1184 }
1185 #endif /* SO_REUSEPORT */
1186 if(nsd.maximum_tcp_count == 0) {
1187 nsd.maximum_tcp_count = nsd.options->tcp_count;
1188 }
1189 nsd.tcp_timeout = nsd.options->tcp_timeout;
1190 nsd.tcp_query_count = nsd.options->tcp_query_count;
1191 nsd.tcp_mss = nsd.options->tcp_mss;
1192 nsd.outgoing_tcp_mss = nsd.options->outgoing_tcp_mss;
1193 nsd.ipv4_edns_size = nsd.options->ipv4_edns_size;
1194 nsd.ipv6_edns_size = nsd.options->ipv6_edns_size;
1195 #ifdef HAVE_SSL
1196 nsd.tls_ctx = NULL;
1197 #endif
1198
1199 if(udp_port == 0)
1200 {
1201 if(nsd.options->port != 0) {
1202 udp_port = nsd.options->port;
1203 tcp_port = nsd.options->port;
1204 } else {
1205 udp_port = UDP_PORT;
1206 tcp_port = TCP_PORT;
1207 }
1208 }
1209 if(nsd.options->verify_port != 0) {
1210 verify_port = nsd.options->verify_port;
1211 } else {
1212 verify_port = VERIFY_PORT;
1213 }
1214 #ifdef BIND8_STATS
1215 if(nsd.st_period == 0) {
1216 nsd.st_period = nsd.options->statistics;
1217 }
1218 #endif /* BIND8_STATS */
1219 #ifdef HAVE_CHROOT
1220 if(nsd.chrootdir == 0) nsd.chrootdir = nsd.options->chroot;
1221 #ifdef CHROOTDIR
1222 /* if still no chrootdir, fallback to default */
1223 if(nsd.chrootdir == 0) nsd.chrootdir = CHROOTDIR;
1224 #endif /* CHROOTDIR */
1225 #endif /* HAVE_CHROOT */
1226 if(nsd.username == 0) {
1227 if(nsd.options->username) nsd.username = nsd.options->username;
1228 else nsd.username = USER;
1229 }
1230 if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
1231 if(chdir(nsd.options->zonesdir)) {
1232 error("cannot chdir to '%s': %s",
1233 nsd.options->zonesdir, strerror(errno));
1234 }
1235 DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
1236 nsd.options->zonesdir));
1237 }
1238
1239 /* EDNS0 */
1240 edns_init_data(&nsd.edns_ipv4, nsd.options->ipv4_edns_size);
1241 #if defined(INET6)
1242 #if defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU)
1243 edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
1244 #else /* no way to set IPV6 MTU, send no bigger than that. */
1245 if (nsd.options->ipv6_edns_size < IPV6_MIN_MTU)
1246 edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size);
1247 else
1248 edns_init_data(&nsd.edns_ipv6, IPV6_MIN_MTU);
1249 #endif /* IPV6 MTU) */
1250 #endif /* defined(INET6) */
1251
1252 nsd.do_answer_cookie = nsd.options->answer_cookie;
1253 if (nsd.cookie_count > 0)
1254 ; /* pass */
1255
1256 else if (nsd.options->cookie_secret) {
1257 ssize_t len = hex_pton(nsd.options->cookie_secret,
1258 nsd.cookie_secrets[0].cookie_secret, NSD_COOKIE_SECRET_SIZE);
1259 if (len != NSD_COOKIE_SECRET_SIZE ) {
1260 error("A cookie secret must be a "
1261 "128 bit hex string");
1262 }
1263 nsd.cookie_count = 1;
1264 } else {
1265 size_t j;
1266 size_t const cookie_secret_len = NSD_COOKIE_SECRET_SIZE;
1267 /* Calculate a new random secret */
1268 srandom(getpid() ^ time(NULL));
1269
1270 for( j = 0; j < NSD_COOKIE_HISTORY_SIZE; j++) {
1271 #if defined(HAVE_SSL)
1272 if (!RAND_status()
1273 || !RAND_bytes(nsd.cookie_secrets[j].cookie_secret, cookie_secret_len))
1274 #endif
1275 for (i = 0; i < cookie_secret_len; i++)
1276 nsd.cookie_secrets[j].cookie_secret[i] = random_generate(256);
1277 }
1278 // XXX: all we have is a random cookie, still pretend we have one
1279 nsd.cookie_count = 1;
1280 }
1281
1282 if (nsd.nsid_len == 0 && nsd.options->nsid) {
1283 if (strlen(nsd.options->nsid) % 2 != 0) {
1284 error("the NSID must be a hex string of an even length.");
1285 }
1286 nsd.nsid = xalloc(strlen(nsd.options->nsid) / 2);
1287 nsd.nsid_len = strlen(nsd.options->nsid) / 2;
1288 if (hex_pton(nsd.options->nsid, nsd.nsid, nsd.nsid_len) == -1) {
1289 error("hex string cannot be parsed '%s' in NSID.", nsd.options->nsid);
1290 }
1291 }
1292 edns_init_nsid(&nsd.edns_ipv4, nsd.nsid_len);
1293 #if defined(INET6)
1294 edns_init_nsid(&nsd.edns_ipv6, nsd.nsid_len);
1295 #endif /* defined(INET6) */
1296
1297 #ifdef HAVE_CPUSET_T
1298 nsd.use_cpu_affinity = (nsd.options->cpu_affinity != NULL);
1299 if(nsd.use_cpu_affinity) {
1300 int ncpus;
1301 struct cpu_option* opt = nsd.options->cpu_affinity;
1302
1303 if((ncpus = number_of_cpus()) == -1) {
1304 error("cannot retrieve number of cpus: %s",
1305 strerror(errno));
1306 }
1307 nsd.cpuset = cpuset_create();
1308 region_add_cleanup(nsd.region, free_cpuset, nsd.cpuset);
1309 for(; opt; opt = opt->next) {
1310 assert(opt->cpu >= 0);
1311 if(opt->cpu >= ncpus) {
1312 error("invalid cpu %d specified in "
1313 "cpu-affinity", opt->cpu);
1314 }
1315 cpuset_set((cpuid_t)opt->cpu, nsd.cpuset);
1316 }
1317 }
1318 if(nsd.use_cpu_affinity) {
1319 int cpu;
1320 struct cpu_map_option *opt
1321 = nsd.options->service_cpu_affinity;
1322
1323 cpu = -1;
1324 for(; opt && cpu == -1; opt = opt->next) {
1325 if(opt->service == -1) {
1326 cpu = opt->cpu;
1327 assert(cpu >= 0);
1328 }
1329 }
1330 nsd.xfrd_cpuset = cpuset_create();
1331 region_add_cleanup(nsd.region, free_cpuset, nsd.xfrd_cpuset);
1332 if(cpu == -1) {
1333 cpuset_or(nsd.xfrd_cpuset,
1334 nsd.cpuset);
1335 } else {
1336 if(!cpuset_isset(cpu, nsd.cpuset)) {
1337 error("cpu %d specified in xfrd-cpu-affinity "
1338 "is not specified in cpu-affinity", cpu);
1339 }
1340 cpuset_set((cpuid_t)cpu, nsd.xfrd_cpuset);
1341 }
1342 }
1343 #endif /* HAVE_CPUSET_T */
1344
1345 /* Number of child servers to fork. */
1346 nsd.children = (struct nsd_child *) region_alloc_array(
1347 nsd.region, nsd.child_count, sizeof(struct nsd_child));
1348 for (i = 0; i < nsd.child_count; ++i) {
1349 nsd.children[i].kind = NSD_SERVER_BOTH;
1350 nsd.children[i].pid = -1;
1351 nsd.children[i].child_fd = -1;
1352 nsd.children[i].parent_fd = -1;
1353 nsd.children[i].handler = NULL;
1354 nsd.children[i].need_to_send_STATS = 0;
1355 nsd.children[i].need_to_send_QUIT = 0;
1356 nsd.children[i].need_to_exit = 0;
1357 nsd.children[i].has_exited = 0;
1358 #ifdef BIND8_STATS
1359 nsd.children[i].query_count = 0;
1360 #endif
1361
1362 #ifdef HAVE_CPUSET_T
1363 if(nsd.use_cpu_affinity) {
1364 int cpu, server;
1365 struct cpu_map_option *opt
1366 = nsd.options->service_cpu_affinity;
1367
1368 cpu = -1;
1369 server = i+1;
1370 for(; opt && cpu == -1; opt = opt->next) {
1371 if(opt->service == server) {
1372 cpu = opt->cpu;
1373 assert(cpu >= 0);
1374 }
1375 }
1376 nsd.children[i].cpuset = cpuset_create();
1377 region_add_cleanup(nsd.region,
1378 free_cpuset,
1379 nsd.children[i].cpuset);
1380 if(cpu == -1) {
1381 cpuset_or(nsd.children[i].cpuset,
1382 nsd.cpuset);
1383 } else {
1384 if(!cpuset_isset((cpuid_t)cpu, nsd.cpuset)) {
1385 error("cpu %d specified in "
1386 "server-%d-cpu-affinity is not "
1387 "specified in cpu-affinity",
1388 cpu, server);
1389 }
1390 cpuset_set(
1391 (cpuid_t)cpu, nsd.children[i].cpuset);
1392 }
1393 }
1394 #endif /* HAVE_CPUSET_T */
1395 }
1396
1397 nsd.this_child = NULL;
1398
1399 resolve_interface_names(nsd.options);
1400 figure_sockets(&nsd.udp, &nsd.tcp, &nsd.ifs,
1401 nsd.options->ip_addresses, NULL, udp_port, tcp_port, &hints);
1402
1403 if(nsd.options->verify_enable) {
1404 figure_sockets(&nsd.verify_udp, &nsd.verify_tcp, &nsd.verify_ifs,
1405 nsd.options->verify_ip_addresses, "localhost", verify_port, verify_port, &hints);
1406 setup_verifier_environment();
1407 }
1408
1409 /* Parse the username into uid and gid */
1410 nsd.gid = getgid();
1411 nsd.uid = getuid();
1412 #ifdef HAVE_GETPWNAM
1413 /* Parse the username into uid and gid */
1414 if (*nsd.username) {
1415 if (isdigit((unsigned char)*nsd.username)) {
1416 char *t;
1417 nsd.uid = strtol(nsd.username, &t, 10);
1418 if (*t != 0) {
1419 if (*t != '.' || !isdigit((unsigned char)*++t)) {
1420 error("-u user or -u uid or -u uid.gid");
1421 }
1422 nsd.gid = strtol(t, &t, 10);
1423 } else {
1424 /* Lookup the group id in /etc/passwd */
1425 if ((pwd = getpwuid(nsd.uid)) == NULL) {
1426 error("user id %u does not exist.", (unsigned) nsd.uid);
1427 } else {
1428 nsd.gid = pwd->pw_gid;
1429 }
1430 }
1431 } else {
1432 /* Lookup the user id in /etc/passwd */
1433 if ((pwd = getpwnam(nsd.username)) == NULL) {
1434 error("user '%s' does not exist.", nsd.username);
1435 } else {
1436 nsd.uid = pwd->pw_uid;
1437 nsd.gid = pwd->pw_gid;
1438 }
1439 }
1440 }
1441 /* endpwent(); */
1442 #endif /* HAVE_GETPWNAM */
1443
1444 #if defined(HAVE_SSL)
1445 key_options_tsig_add(nsd.options);
1446 #endif
1447
1448 append_trailing_slash(&nsd.options->xfrdir, nsd.options->region);
1449 /* Check relativity of pathnames to chroot */
1450 if (nsd.chrootdir && nsd.chrootdir[0]) {
1451 /* existing chrootdir: append trailing slash for strncmp checking */
1452 append_trailing_slash(&nsd.chrootdir, nsd.region);
1453 append_trailing_slash(&nsd.options->zonesdir, nsd.options->region);
1454
1455 /* zonesdir must be absolute and within chroot,
1456 * all other pathnames may be relative to zonesdir */
1457 if (strncmp(nsd.options->zonesdir, nsd.chrootdir, strlen(nsd.chrootdir)) != 0) {
1458 error("zonesdir %s has to be an absolute path that starts with the chroot path %s",
1459 nsd.options->zonesdir, nsd.chrootdir);
1460 } else if (!file_inside_chroot(nsd.pidfile, nsd.chrootdir)) {
1461 error("pidfile %s is not relative to %s: chroot not possible",
1462 nsd.pidfile, nsd.chrootdir);
1463 } else if (!file_inside_chroot(nsd.options->xfrdfile, nsd.chrootdir)) {
1464 error("xfrdfile %s is not relative to %s: chroot not possible",
1465 nsd.options->xfrdfile, nsd.chrootdir);
1466 } else if (!file_inside_chroot(nsd.options->zonelistfile, nsd.chrootdir)) {
1467 error("zonelistfile %s is not relative to %s: chroot not possible",
1468 nsd.options->zonelistfile, nsd.chrootdir);
1469 } else if (!file_inside_chroot(nsd.options->xfrdir, nsd.chrootdir)) {
1470 error("xfrdir %s is not relative to %s: chroot not possible",
1471 nsd.options->xfrdir, nsd.chrootdir);
1472 }
1473 }
1474
1475 /* Set up the logging */
1476 log_open(LOG_PID, FACILITY, nsd.log_filename);
1477 if(nsd.options->log_only_syslog)
1478 log_set_log_function(log_only_syslog);
1479 else if (!nsd.log_filename)
1480 log_set_log_function(log_syslog);
1481 else if (nsd.uid && nsd.gid) {
1482 if(chown(nsd.log_filename, nsd.uid, nsd.gid) != 0)
1483 VERBOSITY(2, (LOG_WARNING, "chown %s failed: %s",
1484 nsd.log_filename, strerror(errno)));
1485 }
1486 log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING);
1487
1488 /* Do we have a running nsd? */
1489 if(nsd.pidfile && nsd.pidfile[0]) {
1490 if ((oldpid = readpid(nsd.pidfile)) == -1) {
1491 if (errno != ENOENT) {
1492 log_msg(LOG_ERR, "can't read pidfile %s: %s",
1493 nsd.pidfile, strerror(errno));
1494 }
1495 } else {
1496 if (kill(oldpid, 0) == 0 || errno == EPERM) {
1497 log_msg(LOG_WARNING,
1498 "%s is already running as %u, continuing",
1499 argv0, (unsigned) oldpid);
1500 } else {
1501 log_msg(LOG_ERR,
1502 "...stale pid file from process %u",
1503 (unsigned) oldpid);
1504 }
1505 }
1506 }
1507
1508 #ifdef HAVE_SETPROCTITLE
1509 setproctitle("main");
1510 #endif
1511 #ifdef HAVE_CPUSET_T
1512 if(nsd.use_cpu_affinity) {
1513 set_cpu_affinity(nsd.cpuset);
1514 }
1515 #endif
1516
1517 print_sockets(nsd.udp, nsd.tcp, nsd.ifs);
1518
1519 /* Setup the signal handling... */
1520 action.sa_handler = sig_handler;
1521 sigfillset(&action.sa_mask);
1522 action.sa_flags = 0;
1523 sigaction(SIGTERM, &action, NULL);
1524 sigaction(SIGHUP, &action, NULL);
1525 sigaction(SIGINT, &action, NULL);
1526 sigaction(SIGILL, &action, NULL);
1527 sigaction(SIGUSR1, &action, NULL);
1528 sigaction(SIGALRM, &action, NULL);
1529 sigaction(SIGCHLD, &action, NULL);
1530 action.sa_handler = SIG_IGN;
1531 sigaction(SIGPIPE, &action, NULL);
1532
1533 /* Initialize... */
1534 nsd.mode = NSD_RUN;
1535 nsd.signal_hint_child = 0;
1536 nsd.signal_hint_reload = 0;
1537 nsd.signal_hint_reload_hup = 0;
1538 nsd.signal_hint_quit = 0;
1539 nsd.signal_hint_shutdown = 0;
1540 nsd.signal_hint_stats = 0;
1541 nsd.signal_hint_statsusr = 0;
1542 nsd.quit_sync_done = 0;
1543
1544 /* Initialize the server... */
1545 if (server_init(&nsd) != 0) {
1546 error("server initialization failed, %s could "
1547 "not be started", argv0);
1548 }
1549 #if defined(HAVE_SSL)
1550 if(nsd.options->control_enable || (nsd.options->tls_service_key && nsd.options->tls_service_key[0])) {
1551 perform_openssl_init();
1552 }
1553 #endif /* HAVE_SSL */
1554 if(nsd.options->control_enable) {
1555 /* read ssl keys while superuser and outside chroot */
1556 if(!(nsd.rc = daemon_remote_create(nsd.options)))
1557 error("could not perform remote control setup");
1558 }
1559 #if defined(HAVE_SSL)
1560 if(nsd.options->tls_service_key && nsd.options->tls_service_key[0]
1561 && nsd.options->tls_service_pem && nsd.options->tls_service_pem[0]) {
1562 if(!(nsd.tls_ctx = server_tls_ctx_create(&nsd, NULL,
1563 nsd.options->tls_service_ocsp)))
1564 error("could not set up tls SSL_CTX");
1565 }
1566 #endif /* HAVE_SSL */
1567
1568 if(nsd.options->cookie_secret_file && nsd.options->cookie_secret_file[0]
1569 && !cookie_secret_file_read(&nsd) ) {
1570 log_msg(LOG_ERR, "cookie secret file corrupt or not readable");
1571 }
1572
1573 /* Unless we're debugging, fork... */
1574 if (!nsd.debug) {
1575 int fd;
1576
1577 /* Take off... */
1578 switch (fork()) {
1579 case 0:
1580 /* Child */
1581 break;
1582 case -1:
1583 error("fork() failed: %s", strerror(errno));
1584 break;
1585 default:
1586 /* Parent is done */
1587 server_close_all_sockets(nsd.udp, nsd.ifs);
1588 server_close_all_sockets(nsd.tcp, nsd.ifs);
1589 exit(0);
1590 }
1591
1592 /* Detach ourselves... */
1593 if (setsid() == -1) {
1594 error("setsid() failed: %s", strerror(errno));
1595 }
1596
1597 if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
1598 (void)dup2(fd, STDIN_FILENO);
1599 (void)dup2(fd, STDOUT_FILENO);
1600 (void)dup2(fd, STDERR_FILENO);
1601 if (fd > 2)
1602 (void)close(fd);
1603 }
1604 }
1605
1606 /* Get our process id */
1607 nsd.pid = getpid();
1608
1609 /* Set user context */
1610 #ifdef HAVE_GETPWNAM
1611 if (*nsd.username) {
1612 #ifdef HAVE_SETUSERCONTEXT
1613 /* setusercontext does initgroups, setuid, setgid, and
1614 * also resource limits from login config, but we
1615 * still call setresuid, setresgid to be sure to set all uid */
1616 if (setusercontext(NULL, pwd, nsd.uid,
1617 LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
1618 log_msg(LOG_WARNING, "unable to setusercontext %s: %s",
1619 nsd.username, strerror(errno));
1620 #endif /* HAVE_SETUSERCONTEXT */
1621 }
1622 #endif /* HAVE_GETPWNAM */
1623
1624 /* Chroot */
1625 #ifdef HAVE_CHROOT
1626 if (nsd.chrootdir && nsd.chrootdir[0]) {
1627 int l = strlen(nsd.chrootdir)-1; /* ends in trailing slash */
1628
1629 if (file_inside_chroot(nsd.log_filename, nsd.chrootdir))
1630 nsd.file_rotation_ok = 1;
1631
1632 /* strip chroot from pathnames if they're absolute */
1633 nsd.options->zonesdir += l;
1634 if (nsd.log_filename){
1635 if (nsd.log_filename[0] == '/')
1636 nsd.log_filename += l;
1637 }
1638 if (nsd.pidfile && nsd.pidfile[0] == '/')
1639 nsd.pidfile += l;
1640 if (nsd.options->xfrdfile[0] == '/')
1641 nsd.options->xfrdfile += l;
1642 if (nsd.options->zonelistfile[0] == '/')
1643 nsd.options->zonelistfile += l;
1644 if (nsd.options->xfrdir[0] == '/')
1645 nsd.options->xfrdir += l;
1646
1647 /* strip chroot from pathnames of "include:" statements
1648 * on subsequent repattern commands */
1649 cfg_parser->chroot = nsd.chrootdir;
1650
1651 #ifdef HAVE_TZSET
1652 /* set timezone whilst not yet in chroot */
1653 tzset();
1654 #endif
1655 if (chroot(nsd.chrootdir)) {
1656 error("unable to chroot: %s", strerror(errno));
1657 }
1658 if (chdir("/")) {
1659 error("unable to chdir to chroot: %s", strerror(errno));
1660 }
1661 DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed root directory to %s",
1662 nsd.chrootdir));
1663 /* chdir to zonesdir again after chroot */
1664 if(nsd.options->zonesdir && nsd.options->zonesdir[0]) {
1665 if(chdir(nsd.options->zonesdir)) {
1666 error("unable to chdir to '%s': %s",
1667 nsd.options->zonesdir, strerror(errno));
1668 }
1669 DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s",
1670 nsd.options->zonesdir));
1671 }
1672 }
1673 else
1674 #endif /* HAVE_CHROOT */
1675 nsd.file_rotation_ok = 1;
1676
1677 DEBUG(DEBUG_IPC,1, (LOG_INFO, "file rotation on %s %sabled",
1678 nsd.log_filename, nsd.file_rotation_ok?"en":"dis"));
1679
1680 /* Write pidfile */
1681 if (writepid(&nsd) == -1) {
1682 log_msg(LOG_ERR, "cannot overwrite the pidfile %s: %s",
1683 nsd.pidfile, strerror(errno));
1684 }
1685
1686 /* Drop the permissions */
1687 #ifdef HAVE_GETPWNAM
1688 if (*nsd.username) {
1689 #ifdef HAVE_INITGROUPS
1690 if(initgroups(nsd.username, nsd.gid) != 0)
1691 log_msg(LOG_WARNING, "unable to initgroups %s: %s",
1692 nsd.username, strerror(errno));
1693 #endif /* HAVE_INITGROUPS */
1694 endpwent();
1695
1696 #ifdef HAVE_SETRESGID
1697 if(setresgid(nsd.gid,nsd.gid,nsd.gid) != 0)
1698 #elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
1699 if(setregid(nsd.gid,nsd.gid) != 0)
1700 #else /* use setgid */
1701 if(setgid(nsd.gid) != 0)
1702 #endif /* HAVE_SETRESGID */
1703 error("unable to set group id of %s: %s",
1704 nsd.username, strerror(errno));
1705
1706 #ifdef HAVE_SETRESUID
1707 if(setresuid(nsd.uid,nsd.uid,nsd.uid) != 0)
1708 #elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
1709 if(setreuid(nsd.uid,nsd.uid) != 0)
1710 #else /* use setuid */
1711 if(setuid(nsd.uid) != 0)
1712 #endif /* HAVE_SETRESUID */
1713 error("unable to set user id of %s: %s",
1714 nsd.username, strerror(errno));
1715
1716 DEBUG(DEBUG_IPC,1, (LOG_INFO, "dropped user privileges, run as %s",
1717 nsd.username));
1718 }
1719 #endif /* HAVE_GETPWNAM */
1720
1721 if (pledge("stdio rpath wpath cpath dns inet proc", NULL) == -1)
1722 error("pledge");
1723
1724 xfrd_make_tempdir(&nsd);
1725 #ifdef USE_ZONE_STATS
1726 options_zonestatnames_create(nsd.options);
1727 server_zonestat_alloc(&nsd);
1728 #endif /* USE_ZONE_STATS */
1729 #ifdef BIND8_STATS
1730 server_stat_alloc(&nsd);
1731 #endif /* BIND8_STATS */
1732 if(nsd.server_kind == NSD_SERVER_MAIN) {
1733 server_prepare_xfrd(&nsd);
1734 /* xfrd forks this before reading database, so it does not get
1735 * the memory size of the database */
1736 server_start_xfrd(&nsd, 0, 0);
1737 /* close zonelistfile in non-xfrd processes */
1738 zone_list_close(nsd.options);
1739 #ifdef USE_DNSTAP
1740 if(nsd.options->dnstap_enable) {
1741 nsd.dt_collector = dt_collector_create(&nsd);
1742 dt_collector_start(nsd.dt_collector, &nsd);
1743 }
1744 #endif /* USE_DNSTAP */
1745 }
1746 if (server_prepare(&nsd) != 0) {
1747 unlinkpid(nsd.pidfile);
1748 error("server preparation failed, %s could "
1749 "not be started", argv0);
1750 }
1751 if(nsd.server_kind == NSD_SERVER_MAIN) {
1752 server_send_soa_xfrd(&nsd, 0);
1753 }
1754
1755 /* Really take off */
1756 log_msg(LOG_NOTICE, "%s started (%s), pid %d",
1757 argv0, PACKAGE_STRING, (int) nsd.pid);
1758
1759 if (nsd.server_kind == NSD_SERVER_MAIN) {
1760 server_main(&nsd);
1761 } else {
1762 server_child(&nsd);
1763 }
1764
1765 /* NOTREACH */
1766 exit(0);
1767 }
1768