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 45 #include "nsd.h" 46 #include "options.h" 47 #include "tsig.h" 48 #include "remote.h" 49 #include "xfrd-disk.h" 50 #ifdef USE_DNSTAP 51 #include "dnstap/dnstap_collector.h" 52 #endif 53 54 /* The server handler... */ 55 struct nsd nsd; 56 static char hostname[MAXHOSTNAMELEN]; 57 extern config_parser_state_type* cfg_parser; 58 static void version(void) ATTR_NORETURN; 59 60 /* 61 * Print the help text. 62 * 63 */ 64 static void 65 usage (void) 66 { 67 fprintf(stderr, "Usage: nsd [OPTION]...\n"); 68 fprintf(stderr, "Name Server Daemon.\n\n"); 69 fprintf(stderr, 70 "Supported options:\n" 71 " -4 Only listen to IPv4 connections.\n" 72 " -6 Only listen to IPv6 connections.\n" 73 " -a ip-address[@port] Listen to the specified incoming IP address (and port)\n" 74 " May be specified multiple times).\n" 75 " -c configfile Read specified configfile instead of %s.\n" 76 " -d do not fork as a daemon process.\n" 77 #ifndef NDEBUG 78 " -F facilities Specify the debug facilities.\n" 79 #endif /* NDEBUG */ 80 " -f database Specify the database to load.\n" 81 " -h Print this help information.\n" 82 , CONFIGFILE); 83 fprintf(stderr, 84 " -i identity Specify the identity when queried for id.server CHAOS TXT.\n" 85 " -I nsid Specify the NSID. This must be a hex string.\n" 86 #ifndef NDEBUG 87 " -L level Specify the debug level.\n" 88 #endif /* NDEBUG */ 89 " -l filename Specify the log file.\n" 90 " -N server-count The number of servers to start.\n" 91 " -n tcp-count The maximum number of TCP connections per server.\n" 92 " -P pidfile Specify the PID file to write.\n" 93 " -p port Specify the port to listen to.\n" 94 " -s seconds Dump statistics every SECONDS seconds.\n" 95 " -t chrootdir Change root to specified directory on startup.\n" 96 ); 97 fprintf(stderr, 98 " -u user Change effective uid to the specified user.\n" 99 " -V level Specify verbosity level.\n" 100 " -v Print version information.\n" 101 ); 102 fprintf(stderr, "Version %s. Report bugs to <%s>.\n", 103 PACKAGE_VERSION, PACKAGE_BUGREPORT); 104 } 105 106 /* 107 * Print the version exit. 108 * 109 */ 110 static void 111 version(void) 112 { 113 fprintf(stderr, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); 114 fprintf(stderr, "Written by NLnet Labs.\n\n"); 115 fprintf(stderr, 116 "Copyright (C) 2001-2006 NLnet Labs. This is free software.\n" 117 "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n" 118 "FOR A PARTICULAR PURPOSE.\n"); 119 exit(0); 120 } 121 122 static void 123 copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src) 124 { 125 dest->ai_flags = src->ai_flags; 126 dest->ai_family = src->ai_family; 127 dest->ai_socktype = src->ai_socktype; 128 dest->ai_addrlen = src->ai_addrlen; 129 memcpy(&dest->ai_addr, src->ai_addr, src->ai_addrlen); 130 } 131 132 static void 133 setup_socket(struct nsd_socket *sock, const char *node, const char *port, struct addrinfo *hints) 134 { 135 int ret; 136 char *sep = NULL; 137 char *host, host_buf[INET6_ADDRSTRLEN + 1 /* '\0' */]; 138 const char *service; 139 char service_buf[6 + 1 /* '\0' */]; /* 65535 */ 140 struct addrinfo *addr = NULL; 141 142 if(node) { 143 host = host_buf; 144 sep = strchr(node, '@'); 145 if(sep) { 146 size_t len = (sep - node) + 1; 147 if (len > sizeof(host_buf)) { 148 len = sizeof(host_buf); 149 } 150 strlcpy(host_buf, node, len); 151 strlcpy(service_buf, sep + 1, sizeof(service_buf)); 152 service = service_buf; 153 } else { 154 strlcpy(host_buf, node, sizeof(host_buf)); 155 service = port; 156 } 157 } else { 158 host = NULL; 159 service = port; 160 } 161 162 if((ret = getaddrinfo(host, service, hints, &addr)) == 0) { 163 copyaddrinfo(&sock->addr, addr); 164 freeaddrinfo(addr); 165 } else { 166 error("cannot parse address '%s': getaddrinfo: %s %s", 167 host ? host : "(null)", 168 gai_strerror(ret), 169 ret==EAI_SYSTEM ? strerror(errno) : ""); 170 } 171 } 172 173 static void 174 figure_default_sockets( 175 struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs, 176 const char *udp_port, const char *tcp_port, 177 const struct addrinfo *hints) 178 { 179 int r; 180 size_t i = 0, n = 1; 181 struct addrinfo ai[2] = { *hints, *hints }; 182 183 assert(udp != NULL); 184 assert(tcp != NULL); 185 assert(ifs != NULL); 186 187 ai[0].ai_socktype = SOCK_DGRAM; 188 ai[1].ai_socktype = SOCK_STREAM; 189 190 #ifdef INET6 191 #ifdef IPV6_V6ONLY 192 if (hints->ai_family == AF_UNSPEC) { 193 ai[0].ai_family = AF_INET6; 194 ai[1].ai_family = AF_INET6; 195 n++; 196 } 197 #endif /* IPV6_V6ONLY */ 198 #endif /* INET6 */ 199 200 *udp = xalloc_zero((n + 1) * sizeof(struct nsd_socket)); 201 *tcp = xalloc_zero((n + 1) * sizeof(struct nsd_socket)); 202 region_add_cleanup(nsd.region, free, *udp); 203 region_add_cleanup(nsd.region, free, *tcp); 204 205 #ifdef INET6 206 if(hints->ai_family == AF_UNSPEC) { 207 /* 208 * With IPv6 we'd like to open two separate sockets, 209 * one for IPv4 and one for IPv6, both listening to 210 * the wildcard address (unless the -4 or -6 flags are 211 * specified). 212 * 213 * However, this is only supported on platforms where 214 * we can turn the socket option IPV6_V6ONLY _on_. 215 * Otherwise we just listen to a single IPv6 socket 216 * and any incoming IPv4 connections will be 217 * automatically mapped to our IPv6 socket. 218 */ 219 #ifdef IPV6_V6ONLY 220 struct addrinfo *addrs[2] = { NULL, NULL }; 221 222 if((r = getaddrinfo(NULL, udp_port, &ai[0], &addrs[0])) == 0 && 223 (r = getaddrinfo(NULL, tcp_port, &ai[1], &addrs[1])) == 0) 224 { 225 (*udp)[i].flags |= NSD_SOCKET_IS_OPTIONAL; 226 copyaddrinfo(&(*udp)[i].addr, addrs[0]); 227 (*tcp)[i].flags |= NSD_SOCKET_IS_OPTIONAL; 228 copyaddrinfo(&(*tcp)[i].addr, addrs[1]); 229 i++; 230 } else { 231 log_msg(LOG_WARNING, "No IPv6, fallback to IPv4. getaddrinfo: %s", 232 r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); 233 } 234 235 if(addrs[0]) 236 freeaddrinfo(addrs[0]); 237 if(addrs[1]) 238 freeaddrinfo(addrs[1]); 239 240 ai[0].ai_family = AF_INET; 241 ai[1].ai_family = AF_INET; 242 #endif /* IPV6_V6ONLY */ 243 } 244 #endif /* INET6 */ 245 246 *ifs = i + 1; 247 setup_socket(&(*udp)[i], NULL, udp_port, &ai[0]); 248 setup_socket(&(*tcp)[i], NULL, tcp_port, &ai[1]); 249 } 250 251 static void 252 figure_sockets( 253 struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs, 254 struct ip_address_option *ips, 255 const char *udp_port, const char *tcp_port, 256 const struct addrinfo *hints) 257 { 258 size_t i = 0; 259 struct addrinfo ai = *hints; 260 struct ip_address_option *ip; 261 262 if(!ips) { 263 figure_default_sockets(udp, tcp, ifs, udp_port, tcp_port, hints); 264 return; 265 } 266 267 *ifs = 0; 268 for(ip = ips; ip; ip = ip->next) { 269 (*ifs)++; 270 } 271 272 *udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket)); 273 *tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket)); 274 region_add_cleanup(nsd.region, free, *udp); 275 region_add_cleanup(nsd.region, free, *tcp); 276 277 ai.ai_flags |= AI_NUMERICHOST; 278 for(ip = ips, i = 0; ip; ip = ip->next, i++) { 279 ai.ai_socktype = SOCK_DGRAM; 280 setup_socket(&(*udp)[i], ip->address, udp_port, &ai); 281 ai.ai_socktype = SOCK_STREAM; 282 setup_socket(&(*tcp)[i], ip->address, tcp_port, &ai); 283 } 284 285 assert(i == *ifs); 286 } 287 288 /* 289 * Fetch the nsd parent process id from the nsd pidfile 290 * 291 */ 292 pid_t 293 readpid(const char *file) 294 { 295 int fd; 296 pid_t pid; 297 char pidbuf[16]; 298 char *t; 299 int l; 300 301 if ((fd = open(file, O_RDONLY)) == -1) { 302 return -1; 303 } 304 305 if (((l = read(fd, pidbuf, sizeof(pidbuf)))) == -1) { 306 close(fd); 307 return -1; 308 } 309 310 close(fd); 311 312 /* Empty pidfile means no pidfile... */ 313 if (l == 0) { 314 errno = ENOENT; 315 return -1; 316 } 317 318 pid = (pid_t) strtol(pidbuf, &t, 10); 319 320 if (*t && *t != '\n') { 321 return -1; 322 } 323 return pid; 324 } 325 326 /* 327 * Store the nsd parent process id in the nsd pidfile 328 * 329 */ 330 int 331 writepid(struct nsd *nsd) 332 { 333 FILE * fd; 334 char pidbuf[32]; 335 if(!nsd->pidfile || !nsd->pidfile[0]) 336 return 0; 337 338 snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) nsd->pid); 339 340 if ((fd = fopen(nsd->pidfile, "w")) == NULL ) { 341 log_msg(LOG_ERR, "cannot open pidfile %s: %s", 342 nsd->pidfile, strerror(errno)); 343 return -1; 344 } 345 346 if (!write_data(fd, pidbuf, strlen(pidbuf))) { 347 log_msg(LOG_ERR, "cannot write pidfile %s: %s", 348 nsd->pidfile, strerror(errno)); 349 fclose(fd); 350 return -1; 351 } 352 fclose(fd); 353 354 if (chown(nsd->pidfile, nsd->uid, nsd->gid) == -1) { 355 log_msg(LOG_ERR, "cannot chown %u.%u %s: %s", 356 (unsigned) nsd->uid, (unsigned) nsd->gid, 357 nsd->pidfile, strerror(errno)); 358 return -1; 359 } 360 361 return 0; 362 } 363 364 void 365 unlinkpid(const char* file) 366 { 367 int fd = -1; 368 369 if (file && file[0]) { 370 /* truncate pidfile */ 371 fd = open(file, O_WRONLY | O_TRUNC, 0644); 372 if (fd == -1) { 373 /* Truncate the pid file. */ 374 log_msg(LOG_ERR, "can not truncate the pid file %s: %s", file, strerror(errno)); 375 } else 376 close(fd); 377 378 /* unlink pidfile */ 379 if (unlink(file) == -1) 380 log_msg(LOG_WARNING, "failed to unlink pidfile %s: %s", 381 file, strerror(errno)); 382 } 383 } 384 385 /* 386 * Incoming signals, set appropriate actions. 387 * 388 */ 389 void 390 sig_handler(int sig) 391 { 392 /* To avoid race cond. We really don't want to use log_msg() in this handler */ 393 394 /* Are we a child server? */ 395 if (nsd.server_kind != NSD_SERVER_MAIN) { 396 switch (sig) { 397 case SIGCHLD: 398 nsd.signal_hint_child = 1; 399 break; 400 case SIGALRM: 401 break; 402 case SIGINT: 403 case SIGTERM: 404 nsd.signal_hint_quit = 1; 405 break; 406 case SIGILL: 407 case SIGUSR1: /* Dump stats on SIGUSR1. */ 408 nsd.signal_hint_statsusr = 1; 409 break; 410 default: 411 break; 412 } 413 return; 414 } 415 416 /* We are the main process */ 417 switch (sig) { 418 case SIGCHLD: 419 nsd.signal_hint_child = 1; 420 return; 421 case SIGHUP: 422 nsd.signal_hint_reload_hup = 1; 423 return; 424 case SIGALRM: 425 nsd.signal_hint_stats = 1; 426 break; 427 case SIGILL: 428 /* 429 * For backwards compatibility with BIND 8 and older 430 * versions of NSD. 431 */ 432 nsd.signal_hint_statsusr = 1; 433 break; 434 case SIGUSR1: 435 /* Dump statistics. */ 436 nsd.signal_hint_statsusr = 1; 437 break; 438 case SIGINT: 439 case SIGTERM: 440 default: 441 nsd.signal_hint_shutdown = 1; 442 break; 443 } 444 } 445 446 /* 447 * Statistic output... 448 * 449 */ 450 #ifdef BIND8_STATS 451 void 452 bind8_stats (struct nsd *nsd) 453 { 454 char buf[MAXSYSLOGMSGLEN]; 455 char *msg, *t; 456 int i, len; 457 458 /* Current time... */ 459 time_t now; 460 if(!nsd->st.period) 461 return; 462 time(&now); 463 464 /* NSTATS */ 465 t = msg = buf + snprintf(buf, MAXSYSLOGMSGLEN, "NSTATS %lld %lu", 466 (long long) now, (unsigned long) nsd->st.boot); 467 for (i = 0; i <= 255; i++) { 468 /* How much space left? */ 469 if ((len = buf + MAXSYSLOGMSGLEN - t) < 32) { 470 log_msg(LOG_INFO, "%s", buf); 471 t = msg; 472 len = buf + MAXSYSLOGMSGLEN - t; 473 } 474 475 if (nsd->st.qtype[i] != 0) { 476 t += snprintf(t, len, " %s=%lu", rrtype_to_string(i), nsd->st.qtype[i]); 477 } 478 } 479 if (t > msg) 480 log_msg(LOG_INFO, "%s", buf); 481 482 /* XSTATS */ 483 /* Only print it if we're in the main daemon or have anything to report... */ 484 if (nsd->server_kind == NSD_SERVER_MAIN 485 || nsd->st.dropped || nsd->st.raxfr || (nsd->st.qudp + nsd->st.qudp6 - nsd->st.dropped) 486 || nsd->st.txerr || nsd->st.opcode[OPCODE_QUERY] || nsd->st.opcode[OPCODE_IQUERY] 487 || nsd->st.wrongzone || nsd->st.ctcp + nsd->st.ctcp6 || nsd->st.rcode[RCODE_SERVFAIL] 488 || nsd->st.rcode[RCODE_FORMAT] || nsd->st.nona || nsd->st.rcode[RCODE_NXDOMAIN] 489 || nsd->st.opcode[OPCODE_UPDATE]) { 490 491 log_msg(LOG_INFO, "XSTATS %lld %lu" 492 " RR=%lu RNXD=%lu RFwdR=%lu RDupR=%lu RFail=%lu RFErr=%lu RErr=%lu RAXFR=%lu" 493 " RLame=%lu ROpts=%lu SSysQ=%lu SAns=%lu SFwdQ=%lu SDupQ=%lu SErr=%lu RQ=%lu" 494 " RIQ=%lu RFwdQ=%lu RDupQ=%lu RTCP=%lu SFwdR=%lu SFail=%lu SFErr=%lu SNaAns=%lu" 495 " SNXD=%lu RUQ=%lu RURQ=%lu RUXFR=%lu RUUpd=%lu", 496 (long long) now, (unsigned long) nsd->st.boot, 497 nsd->st.dropped, (unsigned long)0, (unsigned long)0, (unsigned long)0, (unsigned long)0, 498 (unsigned long)0, (unsigned long)0, nsd->st.raxfr, (unsigned long)0, (unsigned long)0, 499 (unsigned long)0, nsd->st.qudp + nsd->st.qudp6 - nsd->st.dropped, (unsigned long)0, 500 (unsigned long)0, nsd->st.txerr, 501 nsd->st.opcode[OPCODE_QUERY], nsd->st.opcode[OPCODE_IQUERY], nsd->st.wrongzone, 502 (unsigned long)0, nsd->st.ctcp + nsd->st.ctcp6, 503 (unsigned long)0, nsd->st.rcode[RCODE_SERVFAIL], nsd->st.rcode[RCODE_FORMAT], 504 nsd->st.nona, nsd->st.rcode[RCODE_NXDOMAIN], 505 (unsigned long)0, (unsigned long)0, (unsigned long)0, nsd->st.opcode[OPCODE_UPDATE]); 506 } 507 508 } 509 #endif /* BIND8_STATS */ 510 511 extern char *optarg; 512 extern int optind; 513 514 int 515 main(int argc, char *argv[]) 516 { 517 /* Scratch variables... */ 518 int c; 519 pid_t oldpid; 520 size_t i; 521 struct sigaction action; 522 #ifdef HAVE_GETPWNAM 523 struct passwd *pwd = NULL; 524 #endif /* HAVE_GETPWNAM */ 525 526 struct ip_address_option *ip; 527 struct addrinfo hints; 528 const char *udp_port = 0; 529 const char *tcp_port = 0; 530 531 const char *configfile = CONFIGFILE; 532 533 char* argv0 = (argv0 = strrchr(argv[0], '/')) ? argv0 + 1 : argv[0]; 534 535 log_init(argv0); 536 537 /* Initialize the server handler... */ 538 memset(&nsd, 0, sizeof(struct nsd)); 539 nsd.region = region_create(xalloc, free); 540 nsd.dbfile = 0; 541 nsd.pidfile = 0; 542 nsd.server_kind = NSD_SERVER_MAIN; 543 memset(&hints, 0, sizeof(hints)); 544 hints.ai_family = DEFAULT_AI_FAMILY; 545 hints.ai_flags = AI_PASSIVE; 546 nsd.identity = 0; 547 nsd.version = VERSION; 548 nsd.username = 0; 549 nsd.chrootdir = 0; 550 nsd.nsid = NULL; 551 nsd.nsid_len = 0; 552 553 nsd.child_count = 0; 554 nsd.maximum_tcp_count = 0; 555 nsd.current_tcp_count = 0; 556 nsd.file_rotation_ok = 0; 557 558 /* Set up our default identity to gethostname(2) */ 559 if (gethostname(hostname, MAXHOSTNAMELEN) == 0) { 560 nsd.identity = hostname; 561 } else { 562 log_msg(LOG_ERR, 563 "failed to get the host name: %s - using default identity", 564 strerror(errno)); 565 nsd.identity = IDENTITY; 566 } 567 568 /* Create region where options will be stored and set defaults */ 569 nsd.options = nsd_options_create(region_create_custom(xalloc, free, 570 DEFAULT_CHUNK_SIZE, DEFAULT_LARGE_OBJECT_SIZE, 571 DEFAULT_INITIAL_CLEANUP_SIZE, 1)); 572 573 /* Parse the command line... */ 574 while ((c = getopt(argc, argv, "46a:c:df:hi:I:l:N:n:P:p:s:u:t:X:V:v" 575 #ifndef NDEBUG /* <mattthijs> only when configured with --enable-checking */ 576 "F:L:" 577 #endif /* NDEBUG */ 578 )) != -1) { 579 switch (c) { 580 case '4': 581 hints.ai_family = AF_INET; 582 break; 583 case '6': 584 #ifdef INET6 585 hints.ai_family = AF_INET6; 586 #else /* !INET6 */ 587 error("IPv6 support not enabled."); 588 #endif /* INET6 */ 589 break; 590 case 'a': 591 ip = region_alloc_zero( 592 nsd.options->region, sizeof(*ip)); 593 ip->address = region_strdup( 594 nsd.options->region, optarg); 595 ip->next = nsd.options->ip_addresses; 596 nsd.options->ip_addresses = ip; 597 break; 598 case 'c': 599 configfile = optarg; 600 break; 601 case 'd': 602 nsd.debug = 1; 603 break; 604 case 'f': 605 nsd.dbfile = optarg; 606 break; 607 case 'h': 608 usage(); 609 exit(0); 610 case 'i': 611 nsd.identity = optarg; 612 break; 613 case 'I': 614 if (nsd.nsid_len != 0) { 615 /* can only be given once */ 616 break; 617 } 618 if (strncasecmp(optarg, "ascii_", 6) == 0) { 619 nsd.nsid = xalloc(strlen(optarg+6)); 620 nsd.nsid_len = strlen(optarg+6); 621 memmove(nsd.nsid, optarg+6, nsd.nsid_len); 622 } else { 623 if (strlen(optarg) % 2 != 0) { 624 error("the NSID must be a hex string of an even length."); 625 } 626 nsd.nsid = xalloc(strlen(optarg) / 2); 627 nsd.nsid_len = strlen(optarg) / 2; 628 if (hex_pton(optarg, nsd.nsid, nsd.nsid_len) == -1) { 629 error("hex string cannot be parsed '%s' in NSID.", optarg); 630 } 631 } 632 break; 633 case 'l': 634 nsd.log_filename = optarg; 635 break; 636 case 'N': 637 i = atoi(optarg); 638 if (i <= 0) { 639 error("number of child servers must be greater than zero."); 640 } else { 641 nsd.child_count = i; 642 } 643 break; 644 case 'n': 645 i = atoi(optarg); 646 if (i <= 0) { 647 error("number of concurrent TCP connections must greater than zero."); 648 } else { 649 nsd.maximum_tcp_count = i; 650 } 651 break; 652 case 'P': 653 nsd.pidfile = optarg; 654 break; 655 case 'p': 656 if (atoi(optarg) == 0) { 657 error("port argument must be numeric."); 658 } 659 tcp_port = optarg; 660 udp_port = optarg; 661 break; 662 case 's': 663 #ifdef BIND8_STATS 664 nsd.st.period = atoi(optarg); 665 #else /* !BIND8_STATS */ 666 error("BIND 8 statistics not enabled."); 667 #endif /* BIND8_STATS */ 668 break; 669 case 't': 670 #ifdef HAVE_CHROOT 671 nsd.chrootdir = optarg; 672 #else /* !HAVE_CHROOT */ 673 error("chroot not supported on this platform."); 674 #endif /* HAVE_CHROOT */ 675 break; 676 case 'u': 677 nsd.username = optarg; 678 break; 679 case 'V': 680 verbosity = atoi(optarg); 681 break; 682 case 'v': 683 version(); 684 /* version exits */ 685 break; 686 #ifndef NDEBUG 687 case 'F': 688 sscanf(optarg, "%x", &nsd_debug_facilities); 689 break; 690 case 'L': 691 sscanf(optarg, "%d", &nsd_debug_level); 692 break; 693 #endif /* NDEBUG */ 694 case '?': 695 default: 696 usage(); 697 exit(1); 698 } 699 } 700 argc -= optind; 701 /* argv += optind; */ 702 703 /* Commandline parse error */ 704 if (argc != 0) { 705 usage(); 706 exit(1); 707 } 708 709 if (strlen(nsd.identity) > UCHAR_MAX) { 710 error("server identity too long (%u characters)", 711 (unsigned) strlen(nsd.identity)); 712 } 713 if(!tsig_init(nsd.region)) 714 error("init tsig failed"); 715 716 /* Read options */ 717 if(!parse_options_file(nsd.options, configfile, NULL, NULL)) { 718 error("could not read config: %s\n", configfile); 719 } 720 if(!parse_zone_list_file(nsd.options)) { 721 error("could not read zonelist file %s\n", 722 nsd.options->zonelistfile); 723 } 724 if(nsd.options->do_ip4 && !nsd.options->do_ip6) { 725 hints.ai_family = AF_INET; 726 } 727 #ifdef INET6 728 if(nsd.options->do_ip6 && !nsd.options->do_ip4) { 729 hints.ai_family = AF_INET6; 730 } 731 #endif /* INET6 */ 732 if (verbosity == 0) 733 verbosity = nsd.options->verbosity; 734 #ifndef NDEBUG 735 if (nsd_debug_level > 0 && verbosity == 0) 736 verbosity = nsd_debug_level; 737 #endif /* NDEBUG */ 738 if(nsd.options->debug_mode) nsd.debug=1; 739 if(!nsd.dbfile) 740 { 741 if(nsd.options->database) 742 nsd.dbfile = nsd.options->database; 743 else 744 nsd.dbfile = DBFILE; 745 } 746 if(!nsd.pidfile) 747 { 748 if(nsd.options->pidfile) 749 nsd.pidfile = nsd.options->pidfile; 750 else 751 nsd.pidfile = PIDFILE; 752 } 753 if(strcmp(nsd.identity, hostname)==0 || strcmp(nsd.identity,IDENTITY)==0) 754 { 755 if(nsd.options->identity) 756 nsd.identity = nsd.options->identity; 757 } 758 if(nsd.options->version) { 759 nsd.version = nsd.options->version; 760 } 761 if (nsd.options->logfile && !nsd.log_filename) { 762 nsd.log_filename = nsd.options->logfile; 763 } 764 if(nsd.child_count == 0) { 765 nsd.child_count = nsd.options->server_count; 766 } 767 #ifdef SO_REUSEPORT 768 if(nsd.options->reuseport && nsd.child_count > 1) { 769 nsd.reuseport = nsd.child_count; 770 } 771 #endif /* SO_REUSEPORT */ 772 if(nsd.maximum_tcp_count == 0) { 773 nsd.maximum_tcp_count = nsd.options->tcp_count; 774 } 775 nsd.tcp_timeout = nsd.options->tcp_timeout; 776 nsd.tcp_query_count = nsd.options->tcp_query_count; 777 nsd.tcp_mss = nsd.options->tcp_mss; 778 nsd.outgoing_tcp_mss = nsd.options->outgoing_tcp_mss; 779 nsd.ipv4_edns_size = nsd.options->ipv4_edns_size; 780 nsd.ipv6_edns_size = nsd.options->ipv6_edns_size; 781 #ifdef HAVE_SSL 782 nsd.tls_ctx = NULL; 783 #endif 784 785 if(udp_port == 0) 786 { 787 if(nsd.options->port != 0) { 788 udp_port = nsd.options->port; 789 tcp_port = nsd.options->port; 790 } else { 791 udp_port = UDP_PORT; 792 tcp_port = TCP_PORT; 793 } 794 } 795 #ifdef BIND8_STATS 796 if(nsd.st.period == 0) { 797 nsd.st.period = nsd.options->statistics; 798 } 799 #endif /* BIND8_STATS */ 800 #ifdef HAVE_CHROOT 801 if(nsd.chrootdir == 0) nsd.chrootdir = nsd.options->chroot; 802 #ifdef CHROOTDIR 803 /* if still no chrootdir, fallback to default */ 804 if(nsd.chrootdir == 0) nsd.chrootdir = CHROOTDIR; 805 #endif /* CHROOTDIR */ 806 #endif /* HAVE_CHROOT */ 807 if(nsd.username == 0) { 808 if(nsd.options->username) nsd.username = nsd.options->username; 809 else nsd.username = USER; 810 } 811 if(nsd.options->zonesdir && nsd.options->zonesdir[0]) { 812 if(chdir(nsd.options->zonesdir)) { 813 error("cannot chdir to '%s': %s", 814 nsd.options->zonesdir, strerror(errno)); 815 } 816 DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s", 817 nsd.options->zonesdir)); 818 } 819 820 /* EDNS0 */ 821 edns_init_data(&nsd.edns_ipv4, nsd.options->ipv4_edns_size); 822 #if defined(INET6) 823 #if defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU) 824 edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size); 825 #else /* no way to set IPV6 MTU, send no bigger than that. */ 826 if (nsd.options->ipv6_edns_size < IPV6_MIN_MTU) 827 edns_init_data(&nsd.edns_ipv6, nsd.options->ipv6_edns_size); 828 else 829 edns_init_data(&nsd.edns_ipv6, IPV6_MIN_MTU); 830 #endif /* IPV6 MTU) */ 831 #endif /* defined(INET6) */ 832 833 if (nsd.nsid_len == 0 && nsd.options->nsid) { 834 if (strlen(nsd.options->nsid) % 2 != 0) { 835 error("the NSID must be a hex string of an even length."); 836 } 837 nsd.nsid = xalloc(strlen(nsd.options->nsid) / 2); 838 nsd.nsid_len = strlen(nsd.options->nsid) / 2; 839 if (hex_pton(nsd.options->nsid, nsd.nsid, nsd.nsid_len) == -1) { 840 error("hex string cannot be parsed '%s' in NSID.", nsd.options->nsid); 841 } 842 } 843 edns_init_nsid(&nsd.edns_ipv4, nsd.nsid_len); 844 #if defined(INET6) 845 edns_init_nsid(&nsd.edns_ipv6, nsd.nsid_len); 846 #endif /* defined(INET6) */ 847 848 /* Number of child servers to fork. */ 849 nsd.children = (struct nsd_child *) region_alloc_array( 850 nsd.region, nsd.child_count, sizeof(struct nsd_child)); 851 for (i = 0; i < nsd.child_count; ++i) { 852 nsd.children[i].kind = NSD_SERVER_BOTH; 853 nsd.children[i].pid = -1; 854 nsd.children[i].child_fd = -1; 855 nsd.children[i].parent_fd = -1; 856 nsd.children[i].handler = NULL; 857 nsd.children[i].need_to_send_STATS = 0; 858 nsd.children[i].need_to_send_QUIT = 0; 859 nsd.children[i].need_to_exit = 0; 860 nsd.children[i].has_exited = 0; 861 #ifdef BIND8_STATS 862 nsd.children[i].query_count = 0; 863 #endif 864 } 865 866 nsd.this_child = NULL; 867 868 figure_sockets(&nsd.udp, &nsd.tcp, &nsd.ifs, 869 nsd.options->ip_addresses, udp_port, tcp_port, &hints); 870 871 /* Parse the username into uid and gid */ 872 nsd.gid = getgid(); 873 nsd.uid = getuid(); 874 #ifdef HAVE_GETPWNAM 875 /* Parse the username into uid and gid */ 876 if (*nsd.username) { 877 if (isdigit((unsigned char)*nsd.username)) { 878 char *t; 879 nsd.uid = strtol(nsd.username, &t, 10); 880 if (*t != 0) { 881 if (*t != '.' || !isdigit((unsigned char)*++t)) { 882 error("-u user or -u uid or -u uid.gid"); 883 } 884 nsd.gid = strtol(t, &t, 10); 885 } else { 886 /* Lookup the group id in /etc/passwd */ 887 if ((pwd = getpwuid(nsd.uid)) == NULL) { 888 error("user id %u does not exist.", (unsigned) nsd.uid); 889 } else { 890 nsd.gid = pwd->pw_gid; 891 } 892 } 893 } else { 894 /* Lookup the user id in /etc/passwd */ 895 if ((pwd = getpwnam(nsd.username)) == NULL) { 896 error("user '%s' does not exist.", nsd.username); 897 } else { 898 nsd.uid = pwd->pw_uid; 899 nsd.gid = pwd->pw_gid; 900 } 901 } 902 } 903 /* endpwent(); */ 904 #endif /* HAVE_GETPWNAM */ 905 906 #if defined(HAVE_SSL) 907 key_options_tsig_add(nsd.options); 908 #endif 909 910 append_trailing_slash(&nsd.options->xfrdir, nsd.options->region); 911 /* Check relativity of pathnames to chroot */ 912 if (nsd.chrootdir && nsd.chrootdir[0]) { 913 /* existing chrootdir: append trailing slash for strncmp checking */ 914 append_trailing_slash(&nsd.chrootdir, nsd.region); 915 append_trailing_slash(&nsd.options->zonesdir, nsd.options->region); 916 917 /* zonesdir must be absolute and within chroot, 918 * all other pathnames may be relative to zonesdir */ 919 if (strncmp(nsd.options->zonesdir, nsd.chrootdir, strlen(nsd.chrootdir)) != 0) { 920 error("zonesdir %s has to be an absolute path that starts with the chroot path %s", 921 nsd.options->zonesdir, nsd.chrootdir); 922 } else if (!file_inside_chroot(nsd.pidfile, nsd.chrootdir)) { 923 error("pidfile %s is not relative to %s: chroot not possible", 924 nsd.pidfile, nsd.chrootdir); 925 } else if (!file_inside_chroot(nsd.dbfile, nsd.chrootdir)) { 926 error("database %s is not relative to %s: chroot not possible", 927 nsd.dbfile, nsd.chrootdir); 928 } else if (!file_inside_chroot(nsd.options->xfrdfile, nsd.chrootdir)) { 929 error("xfrdfile %s is not relative to %s: chroot not possible", 930 nsd.options->xfrdfile, nsd.chrootdir); 931 } else if (!file_inside_chroot(nsd.options->zonelistfile, nsd.chrootdir)) { 932 error("zonelistfile %s is not relative to %s: chroot not possible", 933 nsd.options->zonelistfile, nsd.chrootdir); 934 } else if (!file_inside_chroot(nsd.options->xfrdir, nsd.chrootdir)) { 935 error("xfrdir %s is not relative to %s: chroot not possible", 936 nsd.options->xfrdir, nsd.chrootdir); 937 } 938 } 939 940 /* Set up the logging */ 941 log_open(LOG_PID, FACILITY, nsd.log_filename); 942 if (!nsd.log_filename) 943 log_set_log_function(log_syslog); 944 else if (nsd.uid && nsd.gid) { 945 if(chown(nsd.log_filename, nsd.uid, nsd.gid) != 0) 946 VERBOSITY(2, (LOG_WARNING, "chown %s failed: %s", 947 nsd.log_filename, strerror(errno))); 948 } 949 log_msg(LOG_NOTICE, "%s starting (%s)", argv0, PACKAGE_STRING); 950 951 /* Do we have a running nsd? */ 952 if(nsd.pidfile && nsd.pidfile[0]) { 953 if ((oldpid = readpid(nsd.pidfile)) == -1) { 954 if (errno != ENOENT) { 955 log_msg(LOG_ERR, "can't read pidfile %s: %s", 956 nsd.pidfile, strerror(errno)); 957 } 958 } else { 959 if (kill(oldpid, 0) == 0 || errno == EPERM) { 960 log_msg(LOG_WARNING, 961 "%s is already running as %u, continuing", 962 argv0, (unsigned) oldpid); 963 } else { 964 log_msg(LOG_ERR, 965 "...stale pid file from process %u", 966 (unsigned) oldpid); 967 } 968 } 969 } 970 971 /* Setup the signal handling... */ 972 action.sa_handler = sig_handler; 973 sigfillset(&action.sa_mask); 974 action.sa_flags = 0; 975 sigaction(SIGTERM, &action, NULL); 976 sigaction(SIGHUP, &action, NULL); 977 sigaction(SIGINT, &action, NULL); 978 sigaction(SIGILL, &action, NULL); 979 sigaction(SIGUSR1, &action, NULL); 980 sigaction(SIGALRM, &action, NULL); 981 sigaction(SIGCHLD, &action, NULL); 982 action.sa_handler = SIG_IGN; 983 sigaction(SIGPIPE, &action, NULL); 984 985 /* Initialize... */ 986 nsd.mode = NSD_RUN; 987 nsd.signal_hint_child = 0; 988 nsd.signal_hint_reload = 0; 989 nsd.signal_hint_reload_hup = 0; 990 nsd.signal_hint_quit = 0; 991 nsd.signal_hint_shutdown = 0; 992 nsd.signal_hint_stats = 0; 993 nsd.signal_hint_statsusr = 0; 994 nsd.quit_sync_done = 0; 995 996 /* Initialize the server... */ 997 if (server_init(&nsd) != 0) { 998 error("server initialization failed, %s could " 999 "not be started", argv0); 1000 } 1001 #if defined(HAVE_SSL) 1002 if(nsd.options->control_enable || (nsd.options->tls_service_key && nsd.options->tls_service_key[0])) { 1003 perform_openssl_init(); 1004 } 1005 if(nsd.options->control_enable) { 1006 /* read ssl keys while superuser and outside chroot */ 1007 if(!(nsd.rc = daemon_remote_create(nsd.options))) 1008 error("could not perform remote control setup"); 1009 } 1010 if(nsd.options->tls_service_key && nsd.options->tls_service_key[0] 1011 && nsd.options->tls_service_pem && nsd.options->tls_service_pem[0]) { 1012 if(!(nsd.tls_ctx = server_tls_ctx_create(&nsd, NULL, 1013 nsd.options->tls_service_ocsp))) 1014 error("could not set up tls SSL_CTX"); 1015 } 1016 #endif /* HAVE_SSL */ 1017 1018 /* Unless we're debugging, fork... */ 1019 if (!nsd.debug) { 1020 int fd; 1021 1022 /* Take off... */ 1023 switch (fork()) { 1024 case 0: 1025 /* Child */ 1026 break; 1027 case -1: 1028 error("fork() failed: %s", strerror(errno)); 1029 break; 1030 default: 1031 /* Parent is done */ 1032 server_close_all_sockets(nsd.udp, nsd.ifs); 1033 server_close_all_sockets(nsd.tcp, nsd.ifs); 1034 exit(0); 1035 } 1036 1037 /* Detach ourselves... */ 1038 if (setsid() == -1) { 1039 error("setsid() failed: %s", strerror(errno)); 1040 } 1041 1042 if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { 1043 (void)dup2(fd, STDIN_FILENO); 1044 (void)dup2(fd, STDOUT_FILENO); 1045 (void)dup2(fd, STDERR_FILENO); 1046 if (fd > 2) 1047 (void)close(fd); 1048 } 1049 } 1050 1051 /* Get our process id */ 1052 nsd.pid = getpid(); 1053 1054 /* Set user context */ 1055 #ifdef HAVE_GETPWNAM 1056 if (*nsd.username) { 1057 #ifdef HAVE_SETUSERCONTEXT 1058 /* setusercontext does initgroups, setuid, setgid, and 1059 * also resource limits from login config, but we 1060 * still call setresuid, setresgid to be sure to set all uid */ 1061 if (setusercontext(NULL, pwd, nsd.uid, 1062 LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0) 1063 log_msg(LOG_WARNING, "unable to setusercontext %s: %s", 1064 nsd.username, strerror(errno)); 1065 #endif /* HAVE_SETUSERCONTEXT */ 1066 } 1067 #endif /* HAVE_GETPWNAM */ 1068 1069 /* Chroot */ 1070 #ifdef HAVE_CHROOT 1071 if (nsd.chrootdir && nsd.chrootdir[0]) { 1072 int l = strlen(nsd.chrootdir)-1; /* ends in trailing slash */ 1073 1074 if (file_inside_chroot(nsd.log_filename, nsd.chrootdir)) 1075 nsd.file_rotation_ok = 1; 1076 1077 /* strip chroot from pathnames if they're absolute */ 1078 nsd.options->zonesdir += l; 1079 if (nsd.log_filename){ 1080 if (nsd.log_filename[0] == '/') 1081 nsd.log_filename += l; 1082 } 1083 if (nsd.pidfile && nsd.pidfile[0] == '/') 1084 nsd.pidfile += l; 1085 if (nsd.dbfile[0] == '/') 1086 nsd.dbfile += l; 1087 if (nsd.options->xfrdfile[0] == '/') 1088 nsd.options->xfrdfile += l; 1089 if (nsd.options->zonelistfile[0] == '/') 1090 nsd.options->zonelistfile += l; 1091 if (nsd.options->xfrdir[0] == '/') 1092 nsd.options->xfrdir += l; 1093 1094 /* strip chroot from pathnames of "include:" statements 1095 * on subsequent repattern commands */ 1096 cfg_parser->chroot = nsd.chrootdir; 1097 1098 #ifdef HAVE_TZSET 1099 /* set timezone whilst not yet in chroot */ 1100 tzset(); 1101 #endif 1102 if (chroot(nsd.chrootdir)) { 1103 error("unable to chroot: %s", strerror(errno)); 1104 } 1105 if (chdir("/")) { 1106 error("unable to chdir to chroot: %s", strerror(errno)); 1107 } 1108 DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed root directory to %s", 1109 nsd.chrootdir)); 1110 /* chdir to zonesdir again after chroot */ 1111 if(nsd.options->zonesdir && nsd.options->zonesdir[0]) { 1112 if(chdir(nsd.options->zonesdir)) { 1113 error("unable to chdir to '%s': %s", 1114 nsd.options->zonesdir, strerror(errno)); 1115 } 1116 DEBUG(DEBUG_IPC,1, (LOG_INFO, "changed directory to %s", 1117 nsd.options->zonesdir)); 1118 } 1119 } 1120 else 1121 #endif /* HAVE_CHROOT */ 1122 nsd.file_rotation_ok = 1; 1123 1124 DEBUG(DEBUG_IPC,1, (LOG_INFO, "file rotation on %s %sabled", 1125 nsd.log_filename, nsd.file_rotation_ok?"en":"dis")); 1126 1127 /* Write pidfile */ 1128 if (writepid(&nsd) == -1) { 1129 log_msg(LOG_ERR, "cannot overwrite the pidfile %s: %s", 1130 nsd.pidfile, strerror(errno)); 1131 } 1132 1133 /* Drop the permissions */ 1134 #ifdef HAVE_GETPWNAM 1135 if (*nsd.username) { 1136 #ifdef HAVE_INITGROUPS 1137 if(initgroups(nsd.username, nsd.gid) != 0) 1138 log_msg(LOG_WARNING, "unable to initgroups %s: %s", 1139 nsd.username, strerror(errno)); 1140 #endif /* HAVE_INITGROUPS */ 1141 endpwent(); 1142 1143 #ifdef HAVE_SETRESGID 1144 if(setresgid(nsd.gid,nsd.gid,nsd.gid) != 0) 1145 #elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID) 1146 if(setregid(nsd.gid,nsd.gid) != 0) 1147 #else /* use setgid */ 1148 if(setgid(nsd.gid) != 0) 1149 #endif /* HAVE_SETRESGID */ 1150 error("unable to set group id of %s: %s", 1151 nsd.username, strerror(errno)); 1152 1153 #ifdef HAVE_SETRESUID 1154 if(setresuid(nsd.uid,nsd.uid,nsd.uid) != 0) 1155 #elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID) 1156 if(setreuid(nsd.uid,nsd.uid) != 0) 1157 #else /* use setuid */ 1158 if(setuid(nsd.uid) != 0) 1159 #endif /* HAVE_SETRESUID */ 1160 error("unable to set user id of %s: %s", 1161 nsd.username, strerror(errno)); 1162 1163 DEBUG(DEBUG_IPC,1, (LOG_INFO, "dropped user privileges, run as %s", 1164 nsd.username)); 1165 } 1166 #endif /* HAVE_GETPWNAM */ 1167 1168 if (pledge("stdio rpath wpath cpath dns inet proc", NULL) == -1) 1169 error("pledge"); 1170 1171 xfrd_make_tempdir(&nsd); 1172 #ifdef USE_ZONE_STATS 1173 options_zonestatnames_create(nsd.options); 1174 server_zonestat_alloc(&nsd); 1175 #endif /* USE_ZONE_STATS */ 1176 #ifdef USE_DNSTAP 1177 if(nsd.options->dnstap_enable) { 1178 nsd.dt_collector = dt_collector_create(&nsd); 1179 dt_collector_start(nsd.dt_collector, &nsd); 1180 } 1181 #endif /* USE_DNSTAP */ 1182 1183 if(nsd.server_kind == NSD_SERVER_MAIN) { 1184 server_prepare_xfrd(&nsd); 1185 /* xfrd forks this before reading database, so it does not get 1186 * the memory size of the database */ 1187 server_start_xfrd(&nsd, 0, 0); 1188 /* close zonelistfile in non-xfrd processes */ 1189 zone_list_close(nsd.options); 1190 } 1191 if (server_prepare(&nsd) != 0) { 1192 unlinkpid(nsd.pidfile); 1193 error("server preparation failed, %s could " 1194 "not be started", argv0); 1195 } 1196 if(nsd.server_kind == NSD_SERVER_MAIN) { 1197 server_send_soa_xfrd(&nsd, 0); 1198 } 1199 1200 /* Really take off */ 1201 log_msg(LOG_NOTICE, "%s started (%s), pid %d", 1202 argv0, PACKAGE_STRING, (int) nsd.pid); 1203 1204 if (nsd.server_kind == NSD_SERVER_MAIN) { 1205 server_main(&nsd); 1206 } else { 1207 server_child(&nsd); 1208 } 1209 1210 /* NOTREACH */ 1211 exit(0); 1212 } 1213