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