1/* 2 * ntpd.c - main program for the fixed point NTP daemon 3 */ 4 5#ifdef HAVE_CONFIG_H 6# include <config.h> 7#endif 8 9#include "ntp_machine.h" 10#include "ntpd.h" 11#include "ntp_io.h" 12#include "ntp_stdlib.h" 13#include <ntp_random.h> 14 15#include "ntp_config.h" 16#include "ntp_syslog.h" 17#include "ntp_assert.h" 18#include "isc/error.h" 19#include "isc/strerror.h" 20#include "isc/formatcheck.h" 21#include "iosignal.h" 22 23#ifdef SIM 24# include "ntpsim.h" 25#endif 26 27#include "ntp_libopts.h" 28#include "ntpd-opts.h" 29 30/* there's a short treatise below what the thread stuff is for. 31 * [Bug 2954] enable the threading warm-up only for Linux. 32 */ 33#if defined(HAVE_PTHREADS) && HAVE_PTHREADS && !defined(NO_THREADS) 34# ifdef HAVE_PTHREAD_H 35# include <pthread.h> 36# endif 37# if defined(linux) 38# define NEED_PTHREAD_WARMUP 39# endif 40#endif 41 42#ifdef HAVE_UNISTD_H 43# include <unistd.h> 44#endif 45#ifdef HAVE_SYS_STAT_H 46# include <sys/stat.h> 47#endif 48#include <stdio.h> 49#ifdef HAVE_SYS_PARAM_H 50# include <sys/param.h> 51#endif 52#ifdef HAVE_SYS_SIGNAL_H 53# include <sys/signal.h> 54#else 55# include <signal.h> 56#endif 57#ifdef HAVE_SYS_IOCTL_H 58# include <sys/ioctl.h> 59#endif /* HAVE_SYS_IOCTL_H */ 60#if defined(HAVE_RTPRIO) 61# ifdef HAVE_SYS_LOCK_H 62# include <sys/lock.h> 63# endif 64# include <sys/rtprio.h> 65#else 66# ifdef HAVE_PLOCK 67# ifdef HAVE_SYS_LOCK_H 68# include <sys/lock.h> 69# endif 70# endif 71#endif 72#if defined(HAVE_SCHED_SETSCHEDULER) 73# ifdef HAVE_SCHED_H 74# include <sched.h> 75# else 76# ifdef HAVE_SYS_SCHED_H 77# include <sys/sched.h> 78# endif 79# endif 80#endif 81#if defined(HAVE_SYS_MMAN_H) 82# include <sys/mman.h> 83#endif 84 85#ifdef HAVE_TERMIOS_H 86# include <termios.h> 87#endif 88 89#ifdef SYS_DOMAINOS 90# include <apollo/base.h> 91#endif /* SYS_DOMAINOS */ 92 93 94#include "recvbuff.h" 95#include "ntp_cmdargs.h" 96 97#if 0 /* HMS: I don't think we need this. 961223 */ 98#ifdef LOCK_PROCESS 99# ifdef SYS_SOLARIS 100# include <sys/mman.h> 101# else 102# include <sys/lock.h> 103# endif 104#endif 105#endif 106 107#ifdef SYS_WINNT 108# include "ntservice.h" 109#endif 110 111#ifdef _AIX 112# include <ulimit.h> 113#endif /* _AIX */ 114 115#ifdef SCO5_CLOCK 116# include <sys/ci/ciioctl.h> 117#endif 118 119#ifdef HAVE_DROPROOT 120# include <ctype.h> 121# include <grp.h> 122# include <pwd.h> 123#ifdef HAVE_LINUX_CAPABILITIES 124# include <sys/capability.h> 125# include <sys/prctl.h> 126#endif /* HAVE_LINUX_CAPABILITIES */ 127#if defined(HAVE_PRIV_H) && defined(HAVE_SOLARIS_PRIVS) 128# include <priv.h> 129#endif /* HAVE_PRIV_H */ 130#endif /* HAVE_DROPROOT */ 131 132#if defined (LIBSECCOMP) && (KERN_SECCOMP) 133/* # include <sys/types.h> */ 134# include <sys/resource.h> 135# include <seccomp.h> 136#endif /* LIBSECCOMP and KERN_SECCOMP */ 137 138#ifdef HAVE_DNSREGISTRATION 139# include <dns_sd.h> 140DNSServiceRef mdns; 141#endif 142 143#ifdef HAVE_SETPGRP_0 144# define ntp_setpgrp(x, y) setpgrp() 145#else 146# define ntp_setpgrp(x, y) setpgrp(x, y) 147#endif 148 149#ifdef HAVE_SOLARIS_PRIVS 150# define LOWPRIVS "basic,sys_time,net_privaddr,proc_setid,!proc_info,!proc_session,!proc_exec" 151static priv_set_t *lowprivs = NULL; 152static priv_set_t *highprivs = NULL; 153#endif /* HAVE_SOLARIS_PRIVS */ 154/* 155 * Scheduling priority we run at 156 */ 157#define NTPD_PRIO (-12) 158 159int priority_done = 2; /* 0 - Set priority */ 160 /* 1 - priority is OK where it is */ 161 /* 2 - Don't set priority */ 162 /* 1 and 2 are pretty much the same */ 163 164int listen_to_virtual_ips = TRUE; 165 166/* 167 * No-fork flag. If set, we do not become a background daemon. 168 */ 169int nofork; /* Fork by default */ 170 171#ifdef HAVE_DNSREGISTRATION 172/* 173 * mDNS registration flag. If set, we attempt to register with the mDNS system, but only 174 * after we have synched the first time. If the attempt fails, then try again once per 175 * minute for up to 5 times. After all, we may be starting before mDNS. 176 */ 177int mdnsreg = FALSE; 178int mdnstries = 5; 179#endif /* HAVE_DNSREGISTRATION */ 180 181#ifdef HAVE_DROPROOT 182int droproot; 183int root_dropped; 184char *user; /* User to switch to */ 185char *group; /* group to switch to */ 186const char *chrootdir; /* directory to chroot to */ 187uid_t sw_uid; 188gid_t sw_gid; 189struct group *gr; 190struct passwd *pw; 191#endif /* HAVE_DROPROOT */ 192 193#ifdef HAVE_WORKING_FORK 194int waitsync_fd_to_close = -1; /* -w/--wait-sync */ 195#endif 196 197/* 198 * Version declaration 199 */ 200extern const char *Version; 201 202char const *progname; 203 204int was_alarmed; 205 206#ifdef DECL_SYSCALL 207/* 208 * We put this here, since the argument profile is syscall-specific 209 */ 210extern int syscall (int, ...); 211#endif /* DECL_SYSCALL */ 212 213 214#if !defined(SIM) && defined(SIGDIE1) 215static volatile int signalled = 0; 216static volatile int signo = 0; 217 218/* In an ideal world, 'finish_safe()' would declared as noreturn... */ 219static void finish_safe (int); 220static RETSIGTYPE finish (int); 221#endif 222 223#if !defined(SIM) && defined(HAVE_WORKING_FORK) 224static int wait_child_sync_if (int, long); 225#endif 226 227#if !defined(SIM) && !defined(SYS_WINNT) 228# ifdef DEBUG 229static RETSIGTYPE moredebug (int); 230static RETSIGTYPE lessdebug (int); 231# else /* !DEBUG follows */ 232static RETSIGTYPE no_debug (int); 233# endif /* !DEBUG */ 234#endif /* !SIM && !SYS_WINNT */ 235 236#ifndef WORK_FORK 237int saved_argc; 238char ** saved_argv; 239#endif 240 241#ifndef SIM 242int ntpdmain (int, char **); 243static void set_process_priority (void); 244static void assertion_failed (const char *, int, 245 isc_assertiontype_t, 246 const char *) 247 __attribute__ ((__noreturn__)); 248static void library_fatal_error (const char *, int, 249 const char *, va_list) 250 ISC_FORMAT_PRINTF(3, 0); 251static void library_unexpected_error(const char *, int, 252 const char *, va_list) 253 ISC_FORMAT_PRINTF(3, 0); 254#endif /* !SIM */ 255 256 257/* Bug2332 unearthed a problem in the interaction of reduced user 258 * privileges, the limits on memory usage and some versions of the 259 * pthread library on Linux systems. The 'pthread_cancel()' function and 260 * likely some others need to track the stack of the thread involved, 261 * and uses a function that comes from GCC (--> libgcc_s.so) to do 262 * this. Unfortunately the developers of glibc decided to load the 263 * library on demand, which speeds up program start but can cause 264 * trouble here: Due to all the things NTPD does to limit its resource 265 * usage, this deferred load of libgcc_s does not always work once the 266 * restrictions are in effect. 267 * 268 * One way out of this was attempting a forced link against libgcc_s 269 * when possible because it makes the library available immediately 270 * without deferred load. (The symbol resolution would still be dynamic 271 * and on demand, but the code would already be in the process image.) 272 * 273 * This is a tricky thing to do, since it's not necessary everywhere, 274 * not possible everywhere, has shown to break the build of other 275 * programs in the NTP suite and is now generally frowned upon. 276 * 277 * So we take a different approach here: We creat a worker thread that does 278 * actually nothing except waiting for cancellation and cancel it. If 279 * this is done before all the limitations are put in place, the 280 * machinery is pre-heated and all the runtime stuff should be in place 281 * and useable when needed. 282 * 283 * This uses only the standard pthread API and should work with all 284 * implementations of pthreads. It is not necessary everywhere, but it's 285 * cheap enough to go on nearly unnoticed. 286 * 287 * Addendum: Bug 2954 showed that the assumption that this should work 288 * with all OS is wrong -- at least FreeBSD bombs heavily. 289 */ 290#ifdef NEED_PTHREAD_WARMUP 291 292/* simple thread function: sleep until cancelled, just to exercise 293 * thread cancellation. 294 */ 295static void* 296my_pthread_warmup_worker( 297 void *thread_args) 298{ 299 (void)thread_args; 300 for (;;) 301 sleep(10); 302 return NULL; 303} 304 305/* pre-heat threading: create a thread and cancel it, just to exercise 306 * thread cancellation. 307 */ 308static void 309my_pthread_warmup(void) 310{ 311 pthread_t thread; 312 pthread_attr_t thr_attr; 313 int rc; 314 315 pthread_attr_init(&thr_attr); 316#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ 317 defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && \ 318 defined(PTHREAD_STACK_MIN) 319 { 320 size_t ssmin = 32*1024; /* 32kB should be minimum */ 321 if (ssmin < PTHREAD_STACK_MIN) 322 ssmin = PTHREAD_STACK_MIN; 323 rc = pthread_attr_setstacksize(&thr_attr, ssmin); 324 if (0 != rc) 325 msyslog(LOG_ERR, 326 "my_pthread_warmup: pthread_attr_setstacksize() -> %s", 327 strerror(rc)); 328 } 329#endif 330 rc = pthread_create( 331 &thread, &thr_attr, my_pthread_warmup_worker, NULL); 332 pthread_attr_destroy(&thr_attr); 333 if (0 != rc) { 334 msyslog(LOG_ERR, 335 "my_pthread_warmup: pthread_create() -> %s", 336 strerror(rc)); 337 } else { 338 pthread_cancel(thread); 339 pthread_join(thread, NULL); 340 } 341} 342 343#endif /*defined(NEED_PTHREAD_WARMUP)*/ 344 345#ifdef NEED_EARLY_FORK 346static void 347dummy_callback(void) { return; } 348 349static void 350fork_nonchroot_worker(void) { 351 getaddrinfo_sometime("localhost", "ntp", NULL, INITIAL_DNS_RETRY, 352 (gai_sometime_callback)&dummy_callback, NULL); 353} 354#endif /* NEED_EARLY_FORK */ 355 356void 357parse_cmdline_opts( 358 int * pargc, 359 char ***pargv 360 ) 361{ 362 static int parsed; 363 static int optct; 364 365 if (!parsed) 366 optct = ntpOptionProcess(&ntpdOptions, *pargc, *pargv); 367 368 parsed = 1; 369 370 *pargc -= optct; 371 *pargv += optct; 372} 373 374 375#ifdef SIM 376int 377main( 378 int argc, 379 char *argv[] 380 ) 381{ 382 progname = argv[0]; 383 parse_cmdline_opts(&argc, &argv); 384#ifdef DEBUG 385 debug = OPT_VALUE_SET_DEBUG_LEVEL; 386 DPRINTF(1, ("%s\n", Version)); 387#endif 388 389 return ntpsim(argc, argv); 390} 391#else /* !SIM follows */ 392#ifdef NO_MAIN_ALLOWED 393CALL(ntpd,"ntpd",ntpdmain); 394#else /* !NO_MAIN_ALLOWED follows */ 395#ifndef SYS_WINNT 396int 397main( 398 int argc, 399 char *argv[] 400 ) 401{ 402 return ntpdmain(argc, argv); 403} 404#endif /* !SYS_WINNT */ 405#endif /* !NO_MAIN_ALLOWED */ 406#endif /* !SIM */ 407 408#ifdef _AIX 409/* 410 * OK. AIX is different than solaris in how it implements plock(). 411 * If you do NOT adjust the stack limit, you will get the MAXIMUM 412 * stack size allocated and PINNED with you program. To check the 413 * value, use ulimit -a. 414 * 415 * To fix this, we create an automatic variable and set our stack limit 416 * to that PLUS 32KB of extra space (we need some headroom). 417 * 418 * This subroutine gets the stack address. 419 * 420 * Grover Davidson and Matt Ladendorf 421 * 422 */ 423static char * 424get_aix_stack(void) 425{ 426 char ch; 427 return (&ch); 428} 429 430/* 431 * Signal handler for SIGDANGER. 432 */ 433static void 434catch_danger(int signo) 435{ 436 msyslog(LOG_INFO, "ntpd: setpgid(): %m"); 437 /* Make the system believe we'll free something, but don't do it! */ 438 return; 439} 440#endif /* _AIX */ 441 442/* 443 * Set the process priority 444 */ 445#ifndef SIM 446static void 447set_process_priority(void) 448{ 449 450# ifdef DEBUG 451 if (debug > 1) 452 msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>", 453 ((priority_done) 454 ? "Leave priority alone" 455 : "Attempt to set priority" 456 ), 457 priority_done); 458# endif /* DEBUG */ 459 460# if defined(HAVE_SCHED_SETSCHEDULER) 461 if (!priority_done) { 462 extern int config_priority_override, config_priority; 463 int pmax, pmin; 464 struct sched_param sched; 465 466 pmax = sched_get_priority_max(SCHED_FIFO); 467 sched.sched_priority = pmax; 468 if ( config_priority_override ) { 469 pmin = sched_get_priority_min(SCHED_FIFO); 470 if ( config_priority > pmax ) 471 sched.sched_priority = pmax; 472 else if ( config_priority < pmin ) 473 sched.sched_priority = pmin; 474 else 475 sched.sched_priority = config_priority; 476 } 477 if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 ) 478 msyslog(LOG_ERR, "sched_setscheduler(): %m"); 479 else 480 ++priority_done; 481 } 482# endif /* HAVE_SCHED_SETSCHEDULER */ 483# ifdef HAVE_RTPRIO 484# ifdef RTP_SET 485 if (!priority_done) { 486 struct rtprio srtp; 487 488 srtp.type = RTP_PRIO_REALTIME; /* was: RTP_PRIO_NORMAL */ 489 srtp.prio = 0; /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */ 490 491 if (rtprio(RTP_SET, getpid(), &srtp) < 0) 492 msyslog(LOG_ERR, "rtprio() error: %m"); 493 else 494 ++priority_done; 495 } 496# else /* !RTP_SET follows */ 497 if (!priority_done) { 498 if (rtprio(0, 120) < 0) 499 msyslog(LOG_ERR, "rtprio() error: %m"); 500 else 501 ++priority_done; 502 } 503# endif /* !RTP_SET */ 504# endif /* HAVE_RTPRIO */ 505# if defined(NTPD_PRIO) && NTPD_PRIO != 0 506# ifdef HAVE_ATT_NICE 507 if (!priority_done) { 508 errno = 0; 509 if (-1 == nice (NTPD_PRIO) && errno != 0) 510 msyslog(LOG_ERR, "nice() error: %m"); 511 else 512 ++priority_done; 513 } 514# endif /* HAVE_ATT_NICE */ 515# ifdef HAVE_BSD_NICE 516 if (!priority_done) { 517 if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO)) 518 msyslog(LOG_ERR, "setpriority() error: %m"); 519 else 520 ++priority_done; 521 } 522# endif /* HAVE_BSD_NICE */ 523# endif /* NTPD_PRIO && NTPD_PRIO != 0 */ 524 if (!priority_done) 525 msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority"); 526} 527#endif /* !SIM */ 528 529#if !defined(SIM) && !defined(SYS_WINNT) 530/* 531 * Detach from terminal (much like daemon()) 532 * Nothe that this function calls exit() 533 */ 534static void 535detach_from_terminal( 536 int pipe_fds[2], 537 long wait_sync, 538 const char *logfilename 539 ) 540{ 541 int rc; 542 int exit_code; 543# if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY) 544 int fid; 545# endif 546# ifdef _AIX 547 struct sigaction sa; 548# endif 549 550 rc = fork(); 551 if (-1 == rc) { 552 exit_code = (errno) ? errno : -1; 553 msyslog(LOG_ERR, "fork: %m"); 554 exit(exit_code); 555 } 556 if (rc > 0) { 557 /* parent */ 558 exit_code = wait_child_sync_if(pipe_fds[0], 559 wait_sync); 560 exit(exit_code); 561 } 562 563 /* 564 * child/daemon 565 * close all open files excepting waitsync_fd_to_close. 566 * msyslog() unreliable until after init_logging(). 567 */ 568 closelog(); 569 if (syslog_file != NULL) { 570 fclose(syslog_file); 571 syslog_file = NULL; 572 syslogit = TRUE; 573 } 574 close_all_except(waitsync_fd_to_close); 575 INSIST(0 == open("/dev/null", 0) && 1 == dup2(0, 1) \ 576 && 2 == dup2(0, 2)); 577 578 init_logging(progname, 0, TRUE); 579 /* we lost our logfile (if any) daemonizing */ 580 setup_logfile(logfilename); 581 582# ifdef SYS_DOMAINOS 583 { 584 uid_$t puid; 585 status_$t st; 586 587 proc2_$who_am_i(&puid); 588 proc2_$make_server(&puid, &st); 589 } 590# endif /* SYS_DOMAINOS */ 591# ifdef HAVE_SETSID 592 if (setsid() == (pid_t)-1) 593 msyslog(LOG_ERR, "setsid(): %m"); 594# elif defined(HAVE_SETPGID) 595 if (setpgid(0, 0) == -1) 596 msyslog(LOG_ERR, "setpgid(): %m"); 597# else /* !HAVE_SETSID && !HAVE_SETPGID follows */ 598# ifdef TIOCNOTTY 599 fid = open("/dev/tty", 2); 600 if (fid >= 0) { 601 ioctl(fid, (u_long)TIOCNOTTY, NULL); 602 close(fid); 603 } 604# endif /* TIOCNOTTY */ 605 ntp_setpgrp(0, getpid()); 606# endif /* !HAVE_SETSID && !HAVE_SETPGID */ 607# ifdef _AIX 608 /* Don't get killed by low-on-memory signal. */ 609 sa.sa_handler = catch_danger; 610 sigemptyset(&sa.sa_mask); 611 sa.sa_flags = SA_RESTART; 612 sigaction(SIGDANGER, &sa, NULL); 613# endif /* _AIX */ 614 615 return; 616} 617 618#ifdef HAVE_DROPROOT 619/* 620 * Map user name/number to user ID 621*/ 622static int 623map_user( 624 ) 625{ 626 char *endp; 627 628 if (isdigit((unsigned char)*user)) { 629 sw_uid = (uid_t)strtoul(user, &endp, 0); 630 if (*endp != '\0') 631 goto getuser; 632 633 if ((pw = getpwuid(sw_uid)) != NULL) { 634 free(user); 635 user = estrdup(pw->pw_name); 636 sw_gid = pw->pw_gid; 637 } else { 638 errno = 0; 639 msyslog(LOG_ERR, "Cannot find user ID %s", user); 640 return 0; 641 } 642 643 } else { 644getuser: 645 errno = 0; 646 if ((pw = getpwnam(user)) != NULL) { 647 sw_uid = pw->pw_uid; 648 sw_gid = pw->pw_gid; 649 } else { 650 if (errno) 651 msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user); 652 else 653 msyslog(LOG_ERR, "Cannot find user `%s'", user); 654 return 0; 655 } 656 } 657 658 return 1; 659} 660 661/* 662 * Map group name/number to group ID 663*/ 664static int 665map_group( 666 ) 667{ 668 char *endp; 669 670 if (isdigit((unsigned char)*group)) { 671 sw_gid = (gid_t)strtoul(group, &endp, 0); 672 if (*endp != '\0') 673 goto getgroup; 674 } else { 675getgroup: 676 if ((gr = getgrnam(group)) != NULL) { 677 sw_gid = gr->gr_gid; 678 } else { 679 errno = 0; 680 msyslog(LOG_ERR, "Cannot find group `%s'", group); 681 return 0; 682 } 683 } 684 685 return 1; 686} 687 688/* 689 * Change (effective) user and group IDs, also initialize the supplementary group access list 690 */ 691int 692set_user_group_ids( 693 ) 694{ 695 /* If the the user was already mapped, no need to map it again */ 696 if ((NULL != user) && (0 == sw_uid)) { 697 if (0 == map_user()) 698 exit (-1); 699 } 700 /* same applies for the group */ 701 if ((NULL != group) && (0 == sw_gid)) { 702 if (0 == map_group()) 703 exit (-1); 704 } 705 706 if (user && initgroups(user, sw_gid)) { 707 msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user); 708 return 0; 709 } 710 if (group && setgid(sw_gid)) { 711 msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group); 712 return 0; 713 } 714 if (group && setegid(sw_gid)) { 715 msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group); 716 return 0; 717 } 718 if (group) { 719 if (0 != setgroups(1, &sw_gid)) { 720 msyslog(LOG_ERR, "setgroups(1, %d) failed: %m", sw_gid); 721 return 0; 722 } 723 } 724 else if (pw) 725 if (0 != initgroups(pw->pw_name, pw->pw_gid)) { 726 msyslog(LOG_ERR, "initgroups(<%s>, %d) filed: %m", pw->pw_name, pw->pw_gid); 727 return 0; 728 } 729 if (user && setuid(sw_uid)) { 730 msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user); 731 return 0; 732 } 733 if (user && seteuid(sw_uid)) { 734 msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user); 735 return 0; 736 } 737 738 return 1; 739} 740#endif /* HAVE_DROPROOT */ 741#endif /* !SIM */ 742 743/* 744 * Main program. Initialize us, disconnect us from the tty if necessary, 745 * and loop waiting for I/O and/or timer expiries. 746 */ 747#ifndef SIM 748int 749ntpdmain( 750 int argc, 751 char *argv[] 752 ) 753{ 754 l_fp now; 755 struct recvbuf *rbuf; 756 const char * logfilename; 757# ifdef HAVE_UMASK 758 mode_t uv; 759# endif 760# if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ 761 uid_t uid; 762# endif 763# if defined(HAVE_WORKING_FORK) 764 long wait_sync = 0; 765 int pipe_fds[2]; 766 int rc; 767 int exit_code; 768# endif /* HAVE_WORKING_FORK*/ 769# ifdef SCO5_CLOCK 770 int fd; 771 int zero; 772# endif 773 774# ifdef NEED_PTHREAD_WARMUP 775 my_pthread_warmup(); 776# endif 777 778# ifdef HAVE_UMASK 779 uv = umask(0); 780 if (uv) 781 umask(uv); 782 else 783 umask(022); 784# endif 785 saved_argc = argc; 786 saved_argv = argv; 787 progname = argv[0]; 788 initializing = TRUE; /* mark that we are initializing */ 789 parse_cmdline_opts(&argc, &argv); 790# ifdef DEBUG 791 debug = OPT_VALUE_SET_DEBUG_LEVEL; 792# ifdef HAVE_SETLINEBUF 793 setlinebuf(stdout); 794# endif 795# endif 796 797 if (HAVE_OPT(NOFORK) || HAVE_OPT(QUIT) 798# ifdef DEBUG 799 || debug 800# endif 801 || HAVE_OPT(SAVECONFIGQUIT)) 802 nofork = TRUE; 803 804 init_logging(progname, NLOG_SYNCMASK, TRUE); 805 /* honor -l/--logfile option to log to a file */ 806 if (HAVE_OPT(LOGFILE)) { 807 logfilename = OPT_ARG(LOGFILE); 808 syslogit = FALSE; 809 change_logfile(logfilename, FALSE); 810 } else { 811 logfilename = NULL; 812 if (nofork) 813 msyslog_term = TRUE; 814 if (HAVE_OPT(SAVECONFIGQUIT)) 815 syslogit = FALSE; 816 } 817 msyslog(LOG_NOTICE, "%s: Starting", Version); 818 819 { 820 int i; 821 char buf[1024]; /* Secret knowledge of msyslog buf length */ 822 char *cp = buf; 823 824 /* Note that every arg has an initial space character */ 825 snprintf(cp, sizeof(buf), "Command line:"); 826 cp += strlen(cp); 827 828 for (i = 0; i < saved_argc ; ++i) { 829 snprintf(cp, sizeof(buf) - (cp - buf), 830 " %s", saved_argv[i]); 831 cp += strlen(cp); 832 } 833 msyslog(LOG_INFO, "%s", buf); 834 } 835 836 /* 837 * Install trap handlers to log errors and assertion failures. 838 * Default handlers print to stderr which doesn't work if detached. 839 */ 840 isc_assertion_setcallback(assertion_failed); 841 isc_error_setfatal(library_fatal_error); 842 isc_error_setunexpected(library_unexpected_error); 843 844 /* MPE lacks the concept of root */ 845# if defined(HAVE_GETUID) && !defined(MPE) 846 uid = getuid(); 847 if (uid && !HAVE_OPT( SAVECONFIGQUIT )) { 848 msyslog_term = TRUE; 849 msyslog(LOG_ERR, 850 "must be run as root, not uid %ld", (long)uid); 851 exit(1); 852 } 853# endif 854 855/* 856 * Enable the Multi-Media Timer for Windows? 857 */ 858# ifdef SYS_WINNT 859 if (HAVE_OPT( MODIFYMMTIMER )) 860 set_mm_timer(MM_TIMER_HIRES); 861# endif 862 863#ifdef HAVE_DNSREGISTRATION 864/* 865 * Enable mDNS registrations? 866 */ 867 if (HAVE_OPT( MDNS )) { 868 mdnsreg = TRUE; 869 } 870#endif /* HAVE_DNSREGISTRATION */ 871 872 if (HAVE_OPT( NOVIRTUALIPS )) 873 listen_to_virtual_ips = 0; 874 875 /* 876 * --interface, listen on specified interfaces 877 */ 878 if (HAVE_OPT( INTERFACE )) { 879 int ifacect = STACKCT_OPT( INTERFACE ); 880 const char** ifaces = STACKLST_OPT( INTERFACE ); 881 sockaddr_u addr; 882 883 while (ifacect-- > 0) { 884 add_nic_rule( 885 is_ip_address(*ifaces, AF_UNSPEC, &addr) 886 ? MATCH_IFADDR 887 : MATCH_IFNAME, 888 *ifaces, -1, ACTION_LISTEN); 889 ifaces++; 890 } 891 } 892 893 if (HAVE_OPT( NICE )) 894 priority_done = 0; 895 896# ifdef HAVE_SCHED_SETSCHEDULER 897 if (HAVE_OPT( PRIORITY )) { 898 config_priority = OPT_VALUE_PRIORITY; 899 config_priority_override = 1; 900 priority_done = 0; 901 } 902# endif 903 904# ifdef HAVE_WORKING_FORK 905 /* make sure the FDs are initialised */ 906 pipe_fds[0] = -1; 907 pipe_fds[1] = -1; 908 do { /* 'loop' once */ 909 if (!HAVE_OPT( WAIT_SYNC )) 910 break; 911 wait_sync = OPT_VALUE_WAIT_SYNC; 912 if (wait_sync <= 0) { 913 wait_sync = 0; 914 break; 915 } 916 /* -w requires a fork() even with debug > 0 */ 917 nofork = FALSE; 918 if (pipe(pipe_fds)) { 919 exit_code = (errno) ? errno : -1; 920 msyslog(LOG_ERR, 921 "Pipe creation failed for --wait-sync: %m"); 922 exit(exit_code); 923 } 924 waitsync_fd_to_close = pipe_fds[1]; 925 } while (0); /* 'loop' once */ 926# endif /* HAVE_WORKING_FORK */ 927 928 init_lib(); 929# ifdef SYS_WINNT 930 /* 931 * Make sure the service is initialized before we do anything else 932 */ 933 ntservice_init(); 934 935 /* 936 * Start interpolation thread, must occur before first 937 * get_systime() 938 */ 939 init_winnt_time(); 940# endif 941 /* 942 * Initialize random generator and public key pair 943 */ 944 get_systime(&now); 945 946 ntp_srandom((int)(now.l_i * now.l_uf)); 947 948 /* 949 * Detach us from the terminal. May need an #ifndef GIZMO. 950 */ 951 if (!nofork) { 952 953# ifdef HAVE_WORKING_FORK 954 detach_from_terminal(pipe_fds, wait_sync, logfilename); 955# endif /* HAVE_WORKING_FORK */ 956 } 957 958# ifdef SCO5_CLOCK 959 /* 960 * SCO OpenServer's system clock offers much more precise timekeeping 961 * on the base CPU than the other CPUs (for multiprocessor systems), 962 * so we must lock to the base CPU. 963 */ 964 fd = open("/dev/at1", O_RDONLY); 965 if (fd >= 0) { 966 zero = 0; 967 if (ioctl(fd, ACPU_LOCK, &zero) < 0) 968 msyslog(LOG_ERR, "cannot lock to base CPU: %m"); 969 close(fd); 970 } 971# endif 972 973 /* Setup stack size in preparation for locking pages in memory. */ 974# if defined(HAVE_MLOCKALL) 975# ifdef HAVE_SETRLIMIT 976 ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k"); 977# ifdef RLIMIT_MEMLOCK 978 /* 979 * The default RLIMIT_MEMLOCK is very low on Linux systems. 980 * Unless we increase this limit malloc calls are likely to 981 * fail if we drop root privilege. To be useful the value 982 * has to be larger than the largest ntpd resident set size. 983 */ 984 ntp_rlimit(RLIMIT_MEMLOCK, DFLT_RLIMIT_MEMLOCK * 1024 * 1024, 1024 * 1024, "MB"); 985# endif /* RLIMIT_MEMLOCK */ 986# endif /* HAVE_SETRLIMIT */ 987# else /* !HAVE_MLOCKALL follows */ 988# ifdef HAVE_PLOCK 989# ifdef PROCLOCK 990# ifdef _AIX 991 /* 992 * set the stack limit for AIX for plock(). 993 * see get_aix_stack() for more info. 994 */ 995 if (ulimit(SET_STACKLIM, (get_aix_stack() - 8 * 4096)) < 0) 996 msyslog(LOG_ERR, 997 "Cannot adjust stack limit for plock: %m"); 998# endif /* _AIX */ 999# endif /* PROCLOCK */ 1000# endif /* HAVE_PLOCK */ 1001# endif /* !HAVE_MLOCKALL */ 1002 1003 /* 1004 * Set up signals we pay attention to locally. 1005 */ 1006# ifdef SIGDIE1 1007 signal_no_reset(SIGDIE1, finish); 1008 signal_no_reset(SIGDIE2, finish); 1009 signal_no_reset(SIGDIE3, finish); 1010 signal_no_reset(SIGDIE4, finish); 1011# endif 1012# ifdef SIGBUS 1013 signal_no_reset(SIGBUS, finish); 1014# endif 1015 1016# if !defined(SYS_WINNT) && !defined(VMS) 1017# ifdef DEBUG 1018 (void) signal_no_reset(MOREDEBUGSIG, moredebug); 1019 (void) signal_no_reset(LESSDEBUGSIG, lessdebug); 1020# else 1021 (void) signal_no_reset(MOREDEBUGSIG, no_debug); 1022 (void) signal_no_reset(LESSDEBUGSIG, no_debug); 1023# endif /* DEBUG */ 1024# endif /* !SYS_WINNT && !VMS */ 1025 1026 /* 1027 * Set up signals we should never pay attention to. 1028 */ 1029# ifdef SIGPIPE 1030 signal_no_reset(SIGPIPE, SIG_IGN); 1031# endif 1032 1033 /* 1034 * Call the init_ routines to initialize the data structures. 1035 * 1036 * Exactly what command-line options are we expecting here? 1037 */ 1038 INIT_SSL(); 1039 init_auth(); 1040 init_util(); 1041 init_restrict(); 1042 init_mon(); 1043 init_timer(); 1044 init_request(); 1045 init_control(); 1046 init_peer(); 1047# ifdef REFCLOCK 1048 init_refclock(); 1049# endif 1050 set_process_priority(); 1051 init_proto(); /* Call at high priority */ 1052 init_io(); 1053 init_loopfilter(); 1054 mon_start(MON_ON); /* monitor on by default now */ 1055 /* turn off in config if unwanted */ 1056 1057 /* 1058 * Get the configuration. This is done in a separate module 1059 * since this will definitely be different for the gizmo board. 1060 */ 1061 getconfig(argc, argv); 1062 1063 if (-1 == cur_memlock) { 1064# if defined(HAVE_MLOCKALL) 1065 /* 1066 * lock the process into memory 1067 */ 1068 if ( !HAVE_OPT(SAVECONFIGQUIT) 1069# ifdef RLIMIT_MEMLOCK 1070 && -1 != DFLT_RLIMIT_MEMLOCK 1071# endif 1072 && 0 != mlockall(MCL_CURRENT|MCL_FUTURE)) 1073 msyslog(LOG_ERR, "mlockall(): %m"); 1074# else /* !HAVE_MLOCKALL follows */ 1075# ifdef HAVE_PLOCK 1076# ifdef PROCLOCK 1077 /* 1078 * lock the process into memory 1079 */ 1080 if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(PROCLOCK)) 1081 msyslog(LOG_ERR, "plock(PROCLOCK): %m"); 1082# else /* !PROCLOCK follows */ 1083# ifdef TXTLOCK 1084 /* 1085 * Lock text into ram 1086 */ 1087 if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(TXTLOCK)) 1088 msyslog(LOG_ERR, "plock(TXTLOCK) error: %m"); 1089# else /* !TXTLOCK follows */ 1090 msyslog(LOG_ERR, "plock() - don't know what to lock!"); 1091# endif /* !TXTLOCK */ 1092# endif /* !PROCLOCK */ 1093# endif /* HAVE_PLOCK */ 1094# endif /* !HAVE_MLOCKALL */ 1095 } 1096 1097 loop_config(LOOP_DRIFTINIT, 0); 1098 report_event(EVNT_SYSRESTART, NULL, NULL); 1099 initializing = FALSE; 1100 1101# ifdef HAVE_DROPROOT 1102 if (droproot) { 1103 1104#ifdef NEED_EARLY_FORK 1105 fork_nonchroot_worker(); 1106#endif 1107 1108 /* Drop super-user privileges and chroot now if the OS supports this */ 1109 1110# ifdef HAVE_LINUX_CAPABILITIES 1111 /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */ 1112 if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) { 1113 msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" ); 1114 exit(-1); 1115 } 1116# elif HAVE_SOLARIS_PRIVS 1117 /* Nothing to do here */ 1118# else 1119 /* we need a user to switch to */ 1120 if (user == NULL) { 1121 msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" ); 1122 exit(-1); 1123 } 1124# endif /* HAVE_LINUX_CAPABILITIES || HAVE_SOLARIS_PRIVS */ 1125 1126 if (user != NULL) { 1127 if (0 == map_user()) 1128 exit (-1); 1129 } 1130 if (group != NULL) { 1131 if (0 == map_group()) 1132 exit (-1); 1133 } 1134 1135 if (chrootdir ) { 1136 /* make sure cwd is inside the jail: */ 1137 if (chdir(chrootdir)) { 1138 msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir); 1139 exit (-1); 1140 } 1141 if (chroot(chrootdir)) { 1142 msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir); 1143 exit (-1); 1144 } 1145 if (chdir("/")) { 1146 msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m"); 1147 exit (-1); 1148 } 1149 } 1150# ifdef HAVE_SOLARIS_PRIVS 1151 if ((lowprivs = priv_str_to_set(LOWPRIVS, ",", NULL)) == NULL) { 1152 msyslog(LOG_ERR, "priv_str_to_set() failed:%m"); 1153 exit(-1); 1154 } 1155 if ((highprivs = priv_allocset()) == NULL) { 1156 msyslog(LOG_ERR, "priv_allocset() failed:%m"); 1157 exit(-1); 1158 } 1159 (void) getppriv(PRIV_PERMITTED, highprivs); 1160 (void) priv_intersect(highprivs, lowprivs); 1161 if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) { 1162 msyslog(LOG_ERR, "setppriv() failed:%m"); 1163 exit(-1); 1164 } 1165# endif /* HAVE_SOLARIS_PRIVS */ 1166 if (0 == set_user_group_ids()) 1167 exit(-1); 1168 1169# if !defined(HAVE_LINUX_CAPABILITIES) && !defined(HAVE_SOLARIS_PRIVS) 1170 /* 1171 * for now assume that the privilege to bind to privileged ports 1172 * is associated with running with uid 0 - should be refined on 1173 * ports that allow binding to NTP_PORT with uid != 0 1174 */ 1175 disable_dynamic_updates |= (sw_uid != 0); /* also notifies routing message listener */ 1176# endif /* !HAVE_LINUX_CAPABILITIES && !HAVE_SOLARIS_PRIVS */ 1177 1178 if (disable_dynamic_updates && interface_interval) { 1179 interface_interval = 0; 1180 msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking"); 1181 } 1182 1183# ifdef HAVE_LINUX_CAPABILITIES 1184 { 1185 /* 1186 * We may be running under non-root uid now, but we still hold full root privileges! 1187 * We drop all of them, except for the crucial one or two: cap_sys_time and 1188 * cap_net_bind_service if doing dynamic interface tracking. 1189 */ 1190 cap_t caps; 1191 char *captext; 1192 1193 captext = (0 != interface_interval) 1194 ? "cap_sys_time,cap_net_bind_service=pe" 1195 : "cap_sys_time=pe"; 1196 caps = cap_from_text(captext); 1197 if (!caps) { 1198 msyslog(LOG_ERR, 1199 "cap_from_text(%s) failed: %m", 1200 captext); 1201 exit(-1); 1202 } 1203 if (-1 == cap_set_proc(caps)) { 1204 msyslog(LOG_ERR, 1205 "cap_set_proc() failed to drop root privs: %m"); 1206 exit(-1); 1207 } 1208 cap_free(caps); 1209 } 1210# endif /* HAVE_LINUX_CAPABILITIES */ 1211# ifdef HAVE_SOLARIS_PRIVS 1212 if (priv_delset(lowprivs, "proc_setid") == -1) { 1213 msyslog(LOG_ERR, "priv_delset() failed:%m"); 1214 exit(-1); 1215 } 1216 if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) { 1217 msyslog(LOG_ERR, "setppriv() failed:%m"); 1218 exit(-1); 1219 } 1220 priv_freeset(lowprivs); 1221 priv_freeset(highprivs); 1222# endif /* HAVE_SOLARIS_PRIVS */ 1223 root_dropped = TRUE; 1224 fork_deferred_worker(); 1225 } /* if (droproot) */ 1226# endif /* HAVE_DROPROOT */ 1227 1228/* libssecomp sandboxing */ 1229#if defined (LIBSECCOMP) && (KERN_SECCOMP) 1230 scmp_filter_ctx ctx; 1231 1232 if ((ctx = seccomp_init(SCMP_ACT_KILL)) < 0) 1233 msyslog(LOG_ERR, "%s: seccomp_init(SCMP_ACT_KILL) failed: %m", __func__); 1234 else { 1235 msyslog(LOG_DEBUG, "%s: seccomp_init(SCMP_ACT_KILL) succeeded", __func__); 1236 } 1237 1238#ifdef __x86_64__ 1239int scmp_sc[] = { 1240 SCMP_SYS(adjtimex), 1241 SCMP_SYS(bind), 1242 SCMP_SYS(brk), 1243 SCMP_SYS(chdir), 1244 SCMP_SYS(clock_gettime), 1245 SCMP_SYS(clock_settime), 1246 SCMP_SYS(close), 1247 SCMP_SYS(connect), 1248 SCMP_SYS(exit_group), 1249 SCMP_SYS(fstat), 1250 SCMP_SYS(fsync), 1251 SCMP_SYS(futex), 1252 SCMP_SYS(getitimer), 1253 SCMP_SYS(getsockname), 1254 SCMP_SYS(ioctl), 1255 SCMP_SYS(lseek), 1256 SCMP_SYS(madvise), 1257 SCMP_SYS(mmap), 1258 SCMP_SYS(munmap), 1259 SCMP_SYS(open), 1260 SCMP_SYS(poll), 1261 SCMP_SYS(read), 1262 SCMP_SYS(recvmsg), 1263 SCMP_SYS(rename), 1264 SCMP_SYS(rt_sigaction), 1265 SCMP_SYS(rt_sigprocmask), 1266 SCMP_SYS(rt_sigreturn), 1267 SCMP_SYS(select), 1268 SCMP_SYS(sendto), 1269 SCMP_SYS(setitimer), 1270 SCMP_SYS(setsid), 1271 SCMP_SYS(socket), 1272 SCMP_SYS(stat), 1273 SCMP_SYS(time), 1274 SCMP_SYS(write), 1275}; 1276#endif 1277#ifdef __i386__ 1278int scmp_sc[] = { 1279 SCMP_SYS(_newselect), 1280 SCMP_SYS(adjtimex), 1281 SCMP_SYS(brk), 1282 SCMP_SYS(chdir), 1283 SCMP_SYS(clock_gettime), 1284 SCMP_SYS(clock_settime), 1285 SCMP_SYS(close), 1286 SCMP_SYS(exit_group), 1287 SCMP_SYS(fsync), 1288 SCMP_SYS(futex), 1289 SCMP_SYS(getitimer), 1290 SCMP_SYS(madvise), 1291 SCMP_SYS(mmap), 1292 SCMP_SYS(mmap2), 1293 SCMP_SYS(munmap), 1294 SCMP_SYS(open), 1295 SCMP_SYS(poll), 1296 SCMP_SYS(read), 1297 SCMP_SYS(rename), 1298 SCMP_SYS(rt_sigaction), 1299 SCMP_SYS(rt_sigprocmask), 1300 SCMP_SYS(select), 1301 SCMP_SYS(setitimer), 1302 SCMP_SYS(setsid), 1303 SCMP_SYS(sigprocmask), 1304 SCMP_SYS(sigreturn), 1305 SCMP_SYS(socketcall), 1306 SCMP_SYS(stat64), 1307 SCMP_SYS(time), 1308 SCMP_SYS(write), 1309}; 1310#endif 1311 { 1312 int i; 1313 1314 for (i = 0; i < COUNTOF(scmp_sc); i++) { 1315 if (seccomp_rule_add(ctx, 1316 SCMP_ACT_ALLOW, scmp_sc[i], 0) < 0) { 1317 msyslog(LOG_ERR, 1318 "%s: seccomp_rule_add() failed: %m", 1319 __func__); 1320 } 1321 } 1322 } 1323 1324 if (seccomp_load(ctx) < 0) 1325 msyslog(LOG_ERR, "%s: seccomp_load() failed: %m", 1326 __func__); 1327 else { 1328 msyslog(LOG_DEBUG, "%s: seccomp_load() succeeded", __func__); 1329 } 1330#endif /* LIBSECCOMP and KERN_SECCOMP */ 1331 1332#ifdef SYS_WINNT 1333 ntservice_isup(); 1334#endif 1335 1336# ifdef HAVE_IO_COMPLETION_PORT 1337 1338 for (;;) { 1339#if !defined(SIM) && defined(SIGDIE1) 1340 if (signalled) 1341 finish_safe(signo); 1342#endif 1343 GetReceivedBuffers(); 1344# else /* normal I/O */ 1345 1346 BLOCK_IO_AND_ALARM(); 1347 was_alarmed = FALSE; 1348 1349 for (;;) { 1350#if !defined(SIM) && defined(SIGDIE1) 1351 if (signalled) 1352 finish_safe(signo); 1353#endif 1354 if (alarm_flag) { /* alarmed? */ 1355 was_alarmed = TRUE; 1356 alarm_flag = FALSE; 1357 } 1358 1359 /* collect async name/addr results */ 1360 if (!was_alarmed) 1361 harvest_blocking_responses(); 1362 1363 if (!was_alarmed && !has_full_recv_buffer()) { 1364 /* 1365 * Nothing to do. Wait for something. 1366 */ 1367 io_handler(); 1368 } 1369 1370 if (alarm_flag) { /* alarmed? */ 1371 was_alarmed = TRUE; 1372 alarm_flag = FALSE; 1373 } 1374 1375 if (was_alarmed) { 1376 UNBLOCK_IO_AND_ALARM(); 1377 /* 1378 * Out here, signals are unblocked. Call timer routine 1379 * to process expiry. 1380 */ 1381 timer(); 1382 was_alarmed = FALSE; 1383 BLOCK_IO_AND_ALARM(); 1384 } 1385 1386# endif /* !HAVE_IO_COMPLETION_PORT */ 1387 1388# ifdef DEBUG_TIMING 1389 { 1390 l_fp pts; 1391 l_fp tsa, tsb; 1392 int bufcount = 0; 1393 1394 get_systime(&pts); 1395 tsa = pts; 1396# endif 1397 rbuf = get_full_recv_buffer(); 1398 while (rbuf != NULL) { 1399 if (alarm_flag) { 1400 was_alarmed = TRUE; 1401 alarm_flag = FALSE; 1402 } 1403 UNBLOCK_IO_AND_ALARM(); 1404 1405 if (was_alarmed) { 1406 /* avoid timer starvation during lengthy I/O handling */ 1407 timer(); 1408 was_alarmed = FALSE; 1409 } 1410 1411 /* 1412 * Call the data procedure to handle each received 1413 * packet. 1414 */ 1415 if (rbuf->receiver != NULL) { 1416# ifdef DEBUG_TIMING 1417 l_fp dts = pts; 1418 1419 L_SUB(&dts, &rbuf->recv_time); 1420 DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9))); 1421 collect_timing(rbuf, "buffer processing delay", 1, &dts); 1422 bufcount++; 1423# endif 1424 (*rbuf->receiver)(rbuf); 1425 } else { 1426 msyslog(LOG_ERR, "fatal: receive buffer callback NULL"); 1427 abort(); 1428 } 1429 1430 BLOCK_IO_AND_ALARM(); 1431 freerecvbuf(rbuf); 1432 rbuf = get_full_recv_buffer(); 1433 } 1434# ifdef DEBUG_TIMING 1435 get_systime(&tsb); 1436 L_SUB(&tsb, &tsa); 1437 if (bufcount) { 1438 collect_timing(NULL, "processing", bufcount, &tsb); 1439 DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9))); 1440 } 1441 } 1442# endif 1443 1444 /* 1445 * Go around again 1446 */ 1447 1448# ifdef HAVE_DNSREGISTRATION 1449 if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) { 1450 mdnsreg = current_time; 1451 msyslog(LOG_INFO, "Attempting to register mDNS"); 1452 if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, 1453 htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) { 1454 if (!--mdnstries) { 1455 msyslog(LOG_ERR, "Unable to register mDNS, giving up."); 1456 } else { 1457 msyslog(LOG_INFO, "Unable to register mDNS, will try later."); 1458 } 1459 } else { 1460 msyslog(LOG_INFO, "mDNS service registered."); 1461 mdnsreg = FALSE; 1462 } 1463 } 1464# endif /* HAVE_DNSREGISTRATION */ 1465 1466 } 1467 UNBLOCK_IO_AND_ALARM(); 1468 return 1; 1469} 1470#endif /* !SIM */ 1471 1472 1473#if !defined(SIM) && defined(SIGDIE1) 1474/* 1475 * finish - exit gracefully 1476 */ 1477static void 1478finish_safe( 1479 int sig 1480 ) 1481{ 1482 const char *sig_desc; 1483 1484 sig_desc = NULL; 1485#ifdef HAVE_STRSIGNAL 1486 sig_desc = strsignal(sig); 1487#endif 1488 if (sig_desc == NULL) 1489 sig_desc = ""; 1490 msyslog(LOG_NOTICE, "%s exiting on signal %d (%s)", progname, 1491 sig, sig_desc); 1492 /* See Bug 2513 and Bug 2522 re the unlink of PIDFILE */ 1493# ifdef HAVE_DNSREGISTRATION 1494 if (mdns != NULL) 1495 DNSServiceRefDeallocate(mdns); 1496# endif 1497 peer_cleanup(); 1498 exit(0); 1499} 1500 1501static RETSIGTYPE 1502finish( 1503 int sig 1504 ) 1505{ 1506 signalled = 1; 1507 signo = sig; 1508} 1509 1510#endif /* !SIM && SIGDIE1 */ 1511 1512 1513#ifndef SIM 1514/* 1515 * wait_child_sync_if - implements parent side of -w/--wait-sync 1516 */ 1517# ifdef HAVE_WORKING_FORK 1518static int 1519wait_child_sync_if( 1520 int pipe_read_fd, 1521 long wait_sync 1522 ) 1523{ 1524 int rc; 1525 int exit_code; 1526 time_t wait_end_time; 1527 time_t cur_time; 1528 time_t wait_rem; 1529 fd_set readset; 1530 struct timeval wtimeout; 1531 1532 if (0 == wait_sync) 1533 return 0; 1534 1535 /* waitsync_fd_to_close used solely by child */ 1536 close(waitsync_fd_to_close); 1537 wait_end_time = time(NULL) + wait_sync; 1538 do { 1539 cur_time = time(NULL); 1540 wait_rem = (wait_end_time > cur_time) 1541 ? (wait_end_time - cur_time) 1542 : 0; 1543 wtimeout.tv_sec = wait_rem; 1544 wtimeout.tv_usec = 0; 1545 FD_ZERO(&readset); 1546 FD_SET(pipe_read_fd, &readset); 1547 rc = select(pipe_read_fd + 1, &readset, NULL, NULL, 1548 &wtimeout); 1549 if (-1 == rc) { 1550 if (EINTR == errno) 1551 continue; 1552 exit_code = (errno) ? errno : -1; 1553 msyslog(LOG_ERR, 1554 "--wait-sync select failed: %m"); 1555 return exit_code; 1556 } 1557 if (0 == rc) { 1558 /* 1559 * select() indicated a timeout, but in case 1560 * its timeouts are affected by a step of the 1561 * system clock, select() again with a zero 1562 * timeout to confirm. 1563 */ 1564 FD_ZERO(&readset); 1565 FD_SET(pipe_read_fd, &readset); 1566 wtimeout.tv_sec = 0; 1567 wtimeout.tv_usec = 0; 1568 rc = select(pipe_read_fd + 1, &readset, NULL, 1569 NULL, &wtimeout); 1570 if (0 == rc) /* select() timeout */ 1571 break; 1572 else /* readable */ 1573 return 0; 1574 } else /* readable */ 1575 return 0; 1576 } while (wait_rem > 0); 1577 1578 fprintf(stderr, "%s: -w/--wait-sync %ld timed out.\n", 1579 progname, wait_sync); 1580 return ETIMEDOUT; 1581} 1582# endif /* HAVE_WORKING_FORK */ 1583 1584 1585/* 1586 * assertion_failed - Redirect assertion failures to msyslog(). 1587 */ 1588static void 1589assertion_failed( 1590 const char *file, 1591 int line, 1592 isc_assertiontype_t type, 1593 const char *cond 1594 ) 1595{ 1596 isc_assertion_setcallback(NULL); /* Avoid recursion */ 1597 1598 msyslog(LOG_ERR, "%s:%d: %s(%s) failed", 1599 file, line, isc_assertion_typetotext(type), cond); 1600 msyslog(LOG_ERR, "exiting (due to assertion failure)"); 1601 1602#if defined(DEBUG) && defined(SYS_WINNT) 1603 if (debug) 1604 DebugBreak(); 1605#endif 1606 1607 abort(); 1608} 1609 1610 1611/* 1612 * library_fatal_error - Handle fatal errors from our libraries. 1613 */ 1614static void 1615library_fatal_error( 1616 const char *file, 1617 int line, 1618 const char *format, 1619 va_list args 1620 ) 1621{ 1622 char errbuf[256]; 1623 1624 isc_error_setfatal(NULL); /* Avoid recursion */ 1625 1626 msyslog(LOG_ERR, "%s:%d: fatal error:", file, line); 1627 vsnprintf(errbuf, sizeof(errbuf), format, args); 1628 msyslog(LOG_ERR, "%s", errbuf); 1629 msyslog(LOG_ERR, "exiting (due to fatal error in library)"); 1630 1631#if defined(DEBUG) && defined(SYS_WINNT) 1632 if (debug) 1633 DebugBreak(); 1634#endif 1635 1636 abort(); 1637} 1638 1639 1640/* 1641 * library_unexpected_error - Handle non fatal errors from our libraries. 1642 */ 1643# define MAX_UNEXPECTED_ERRORS 100 1644int unexpected_error_cnt = 0; 1645static void 1646library_unexpected_error( 1647 const char *file, 1648 int line, 1649 const char *format, 1650 va_list args 1651 ) 1652{ 1653 char errbuf[256]; 1654 1655 if (unexpected_error_cnt >= MAX_UNEXPECTED_ERRORS) 1656 return; /* avoid clutter in log */ 1657 1658 msyslog(LOG_ERR, "%s:%d: unexpected error:", file, line); 1659 vsnprintf(errbuf, sizeof(errbuf), format, args); 1660 msyslog(LOG_ERR, "%s", errbuf); 1661 1662 if (++unexpected_error_cnt == MAX_UNEXPECTED_ERRORS) 1663 msyslog(LOG_ERR, "Too many errors. Shutting up."); 1664 1665} 1666#endif /* !SIM */ 1667 1668#if !defined(SIM) && !defined(SYS_WINNT) 1669# ifdef DEBUG 1670 1671/* 1672 * moredebug - increase debugging verbosity 1673 */ 1674static RETSIGTYPE 1675moredebug( 1676 int sig 1677 ) 1678{ 1679 int saved_errno = errno; 1680 1681 if (debug < 255) 1682 { 1683 debug++; 1684 msyslog(LOG_DEBUG, "debug raised to %d", debug); 1685 } 1686 errno = saved_errno; 1687} 1688 1689 1690/* 1691 * lessdebug - decrease debugging verbosity 1692 */ 1693static RETSIGTYPE 1694lessdebug( 1695 int sig 1696 ) 1697{ 1698 int saved_errno = errno; 1699 1700 if (debug > 0) 1701 { 1702 debug--; 1703 msyslog(LOG_DEBUG, "debug lowered to %d", debug); 1704 } 1705 errno = saved_errno; 1706} 1707 1708# else /* !DEBUG follows */ 1709 1710 1711/* 1712 * no_debug - We don't do the debug here. 1713 */ 1714static RETSIGTYPE 1715no_debug( 1716 int sig 1717 ) 1718{ 1719 int saved_errno = errno; 1720 1721 msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig); 1722 errno = saved_errno; 1723} 1724# endif /* !DEBUG */ 1725#endif /* !SIM && !SYS_WINNT */ 1726