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