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