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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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