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 14 #ifdef SIM 15 #include "ntpsim.h" 16 #endif 17 18 #ifdef HAVE_UNISTD_H 19 # include <unistd.h> 20 #endif 21 #ifdef HAVE_SYS_STAT_H 22 # include <sys/stat.h> 23 #endif 24 #include <stdio.h> 25 #ifndef SYS_WINNT 26 # if !defined(VMS) /*wjm*/ 27 # ifdef HAVE_SYS_PARAM_H 28 # include <sys/param.h> 29 # endif 30 # endif /* VMS */ 31 # ifdef HAVE_SYS_SIGNAL_H 32 # include <sys/signal.h> 33 # else 34 # include <signal.h> 35 # endif 36 # ifdef HAVE_SYS_IOCTL_H 37 # include <sys/ioctl.h> 38 # endif /* HAVE_SYS_IOCTL_H */ 39 # ifdef HAVE_SYS_RESOURCE_H 40 # include <sys/resource.h> 41 # endif /* HAVE_SYS_RESOURCE_H */ 42 #else 43 # include <signal.h> 44 # include <process.h> 45 # include <io.h> 46 # include "../libntp/log.h" 47 # include <clockstuff.h> 48 # include <crtdbg.h> 49 #endif /* SYS_WINNT */ 50 #if defined(HAVE_RTPRIO) 51 # ifdef HAVE_SYS_RESOURCE_H 52 # include <sys/resource.h> 53 # endif 54 # ifdef HAVE_SYS_LOCK_H 55 # include <sys/lock.h> 56 # endif 57 # include <sys/rtprio.h> 58 #else 59 # ifdef HAVE_PLOCK 60 # ifdef HAVE_SYS_LOCK_H 61 # include <sys/lock.h> 62 # endif 63 # endif 64 #endif 65 #if defined(HAVE_SCHED_SETSCHEDULER) 66 # ifdef HAVE_SCHED_H 67 # include <sched.h> 68 # else 69 # ifdef HAVE_SYS_SCHED_H 70 # include <sys/sched.h> 71 # endif 72 # endif 73 #endif 74 #if defined(HAVE_SYS_MMAN_H) 75 # include <sys/mman.h> 76 #endif 77 78 #ifdef HAVE_TERMIOS_H 79 # include <termios.h> 80 #endif 81 82 #ifdef SYS_DOMAINOS 83 # include <apollo/base.h> 84 #endif /* SYS_DOMAINOS */ 85 86 #include "recvbuff.h" 87 #include "ntp_cmdargs.h" 88 89 #if 0 /* HMS: I don't think we need this. 961223 */ 90 #ifdef LOCK_PROCESS 91 # ifdef SYS_SOLARIS 92 # include <sys/mman.h> 93 # else 94 # include <sys/lock.h> 95 # endif 96 #endif 97 #endif 98 99 #ifdef _AIX 100 # include <ulimit.h> 101 #endif /* _AIX */ 102 103 #ifdef SCO5_CLOCK 104 # include <sys/ci/ciioctl.h> 105 #endif 106 107 #ifdef HAVE_CLOCKCTL 108 # include <ctype.h> 109 # include <grp.h> 110 # include <pwd.h> 111 #endif 112 113 /* 114 * Signals we catch for debugging. If not debugging we ignore them. 115 */ 116 #define MOREDEBUGSIG SIGUSR1 117 #define LESSDEBUGSIG SIGUSR2 118 119 /* 120 * Signals which terminate us gracefully. 121 */ 122 #ifndef SYS_WINNT 123 # define SIGDIE1 SIGHUP 124 # define SIGDIE3 SIGQUIT 125 # define SIGDIE2 SIGINT 126 # define SIGDIE4 SIGTERM 127 #endif /* SYS_WINNT */ 128 129 #if defined SYS_WINNT 130 /* handles for various threads, process, and objects */ 131 HANDLE ResolverThreadHandle = NULL; 132 /* variables used to inform the Service Control Manager of our current state */ 133 BOOL NoWinService = FALSE; 134 SERVICE_STATUS ssStatus; 135 SERVICE_STATUS_HANDLE sshStatusHandle; 136 HANDLE WaitHandles[3] = { NULL, NULL, NULL }; 137 char szMsgPath[255]; 138 static BOOL WINAPI OnConsoleEvent(DWORD dwCtrlType); 139 BOOL init_randfile(); 140 #endif /* SYS_WINNT */ 141 142 /* 143 * Scheduling priority we run at 144 */ 145 #define NTPD_PRIO (-12) 146 147 int priority_done = 2; /* 0 - Set priority */ 148 /* 1 - priority is OK where it is */ 149 /* 2 - Don't set priority */ 150 /* 1 and 2 are pretty much the same */ 151 152 /* 153 * Debugging flag 154 */ 155 volatile int debug; 156 157 /* 158 * Set the processing not to be in the forground 159 */ 160 int forground_process = FALSE; 161 162 /* 163 * No-fork flag. If set, we do not become a background daemon. 164 */ 165 int nofork; 166 167 #ifdef HAVE_CLOCKCTL 168 char *user = NULL; /* User to switch to */ 169 char *group = NULL; /* group to switch to */ 170 char *chrootdir = NULL; /* directory to chroot to */ 171 int sw_uid; 172 int sw_gid; 173 char *endp; 174 struct group *gr; 175 struct passwd *pw; 176 #endif /* HAVE_CLOCKCTL */ 177 178 /* 179 * Initializing flag. All async routines watch this and only do their 180 * thing when it is clear. 181 */ 182 int initializing; 183 184 /* 185 * Version declaration 186 */ 187 extern const char *Version; 188 189 int was_alarmed; 190 191 #ifdef DECL_SYSCALL 192 /* 193 * We put this here, since the argument profile is syscall-specific 194 */ 195 extern int syscall P((int, ...)); 196 #endif /* DECL_SYSCALL */ 197 198 199 #ifdef SIGDIE2 200 static RETSIGTYPE finish P((int)); 201 #endif /* SIGDIE2 */ 202 203 #ifdef DEBUG 204 #ifndef SYS_WINNT 205 static RETSIGTYPE moredebug P((int)); 206 static RETSIGTYPE lessdebug P((int)); 207 #endif 208 #else /* not DEBUG */ 209 static RETSIGTYPE no_debug P((int)); 210 #endif /* not DEBUG */ 211 212 int ntpdmain P((int, char **)); 213 static void set_process_priority P((void)); 214 215 #ifdef SIM 216 int 217 main( 218 int argc, 219 char *argv[] 220 ) 221 { 222 return ntpsim(argc, argv); 223 } 224 #else /* SIM */ 225 #ifdef NO_MAIN_ALLOWED 226 CALL(ntpd,"ntpd",ntpdmain); 227 #else 228 int 229 main( 230 int argc, 231 char *argv[] 232 ) 233 { 234 return ntpdmain(argc, argv); 235 } 236 #endif 237 #endif /* SIM */ 238 239 #ifdef _AIX 240 /* 241 * OK. AIX is different than solaris in how it implements plock(). 242 * If you do NOT adjust the stack limit, you will get the MAXIMUM 243 * stack size allocated and PINNED with you program. To check the 244 * value, use ulimit -a. 245 * 246 * To fix this, we create an automatic variable and set our stack limit 247 * to that PLUS 32KB of extra space (we need some headroom). 248 * 249 * This subroutine gets the stack address. 250 * 251 * Grover Davidson and Matt Ladendorf 252 * 253 */ 254 static char * 255 get_aix_stack(void) 256 { 257 char ch; 258 return (&ch); 259 } 260 261 /* 262 * Signal handler for SIGDANGER. 263 */ 264 static void 265 catch_danger(int signo) 266 { 267 msyslog(LOG_INFO, "ntpd: setpgid(): %m"); 268 /* Make the system believe we'll free something, but don't do it! */ 269 return; 270 } 271 #endif /* _AIX */ 272 273 /* 274 * Set the process priority 275 */ 276 static void 277 set_process_priority(void) 278 { 279 280 #ifdef DEBUG 281 if (debug > 1) 282 msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>", 283 ((priority_done) 284 ? "Leave priority alone" 285 : "Attempt to set priority" 286 ), 287 priority_done); 288 #endif /* DEBUG */ 289 290 #ifdef SYS_WINNT 291 priority_done += NT_set_process_priority(); 292 #endif 293 294 #if defined(HAVE_SCHED_SETSCHEDULER) 295 if (!priority_done) { 296 extern int config_priority_override, config_priority; 297 int pmax, pmin; 298 struct sched_param sched; 299 300 pmax = sched_get_priority_max(SCHED_FIFO); 301 sched.sched_priority = pmax; 302 if ( config_priority_override ) { 303 pmin = sched_get_priority_min(SCHED_FIFO); 304 if ( config_priority > pmax ) 305 sched.sched_priority = pmax; 306 else if ( config_priority < pmin ) 307 sched.sched_priority = pmin; 308 else 309 sched.sched_priority = config_priority; 310 } 311 if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 ) 312 msyslog(LOG_ERR, "sched_setscheduler(): %m"); 313 else 314 ++priority_done; 315 } 316 #endif /* HAVE_SCHED_SETSCHEDULER */ 317 #if defined(HAVE_RTPRIO) 318 # ifdef RTP_SET 319 if (!priority_done) { 320 struct rtprio srtp; 321 322 srtp.type = RTP_PRIO_REALTIME; /* was: RTP_PRIO_NORMAL */ 323 srtp.prio = 0; /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */ 324 325 if (rtprio(RTP_SET, getpid(), &srtp) < 0) 326 msyslog(LOG_ERR, "rtprio() error: %m"); 327 else 328 ++priority_done; 329 } 330 # else /* not RTP_SET */ 331 if (!priority_done) { 332 if (rtprio(0, 120) < 0) 333 msyslog(LOG_ERR, "rtprio() error: %m"); 334 else 335 ++priority_done; 336 } 337 # endif /* not RTP_SET */ 338 #endif /* HAVE_RTPRIO */ 339 #if defined(NTPD_PRIO) && NTPD_PRIO != 0 340 # ifdef HAVE_ATT_NICE 341 if (!priority_done) { 342 errno = 0; 343 if (-1 == nice (NTPD_PRIO) && errno != 0) 344 msyslog(LOG_ERR, "nice() error: %m"); 345 else 346 ++priority_done; 347 } 348 # endif /* HAVE_ATT_NICE */ 349 # ifdef HAVE_BSD_NICE 350 if (!priority_done) { 351 if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO)) 352 msyslog(LOG_ERR, "setpriority() error: %m"); 353 else 354 ++priority_done; 355 } 356 # endif /* HAVE_BSD_NICE */ 357 #endif /* NTPD_PRIO && NTPD_PRIO != 0 */ 358 if (!priority_done) 359 msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority"); 360 } 361 362 363 /* 364 * Main program. Initialize us, disconnect us from the tty if necessary, 365 * and loop waiting for I/O and/or timer expiries. 366 */ 367 int 368 ntpdmain( 369 int argc, 370 char *argv[] 371 ) 372 { 373 l_fp now; 374 char *cp; 375 struct recvbuf *rbuflist; 376 struct recvbuf *rbuf; 377 #ifdef _AIX /* HMS: ifdef SIGDANGER? */ 378 struct sigaction sa; 379 #endif 380 381 initializing = 1; /* mark that we are initializing */ 382 debug = 0; /* no debugging by default */ 383 nofork = 0; /* will fork by default */ 384 385 #ifdef HAVE_UMASK 386 { 387 mode_t uv; 388 389 uv = umask(0); 390 if(uv) 391 (void) umask(uv); 392 else 393 (void) umask(022); 394 } 395 #endif 396 397 #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ 398 { 399 uid_t uid; 400 401 uid = getuid(); 402 if (uid) 403 { 404 msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid); 405 exit(1); 406 } 407 } 408 #endif 409 410 #ifdef SYS_WINNT 411 /* Set the Event-ID message-file name. */ 412 if (!GetModuleFileName(NULL, szMsgPath, sizeof(szMsgPath))) { 413 msyslog(LOG_ERR, "GetModuleFileName(PGM_EXE_FILE) failed: %m\n"); 414 exit(1); 415 } 416 addSourceToRegistry("NTP", szMsgPath); 417 #endif 418 getstartup(argc, argv); /* startup configuration, may set debug */ 419 420 if (debug) 421 printf("%s\n", Version); 422 423 /* 424 * Initialize random generator and public key pair 425 */ 426 #ifdef SYS_WINNT 427 /* Initialize random file before OpenSSL checks */ 428 if(!init_randfile()) 429 msyslog(LOG_ERR, "Unable to initialize .rnd file\n"); 430 #endif 431 get_systime(&now); 432 SRANDOM((int)(now.l_i * now.l_uf)); 433 434 #if !defined(VMS) 435 # ifndef NODETACH 436 /* 437 * Detach us from the terminal. May need an #ifndef GIZMO. 438 */ 439 # ifdef DEBUG 440 if (!debug && !nofork) 441 # else /* DEBUG */ 442 if (!nofork) 443 # endif /* DEBUG */ 444 { 445 # ifndef SYS_WINNT 446 # ifdef HAVE_DAEMON 447 daemon(0, 0); 448 # else /* not HAVE_DAEMON */ 449 if (fork()) /* HMS: What about a -1? */ 450 exit(0); 451 452 { 453 #if !defined(F_CLOSEM) 454 u_long s; 455 int max_fd; 456 #endif /* not F_CLOSEM */ 457 458 #if defined(F_CLOSEM) 459 /* 460 * From 'Writing Reliable AIX Daemons,' SG24-4946-00, 461 * by Eric Agar (saves us from doing 32767 system 462 * calls) 463 */ 464 if (fcntl(0, F_CLOSEM, 0) == -1) 465 msyslog(LOG_ERR, "ntpd: failed to close open files(): %m"); 466 #else /* not F_CLOSEM */ 467 468 # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) 469 max_fd = sysconf(_SC_OPEN_MAX); 470 # else /* HAVE_SYSCONF && _SC_OPEN_MAX */ 471 max_fd = getdtablesize(); 472 # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */ 473 for (s = 0; s < max_fd; s++) 474 (void) close((int)s); 475 #endif /* not F_CLOSEM */ 476 (void) open("/", 0); 477 (void) dup2(0, 1); 478 (void) dup2(0, 2); 479 #ifdef SYS_DOMAINOS 480 { 481 uid_$t puid; 482 status_$t st; 483 484 proc2_$who_am_i(&puid); 485 proc2_$make_server(&puid, &st); 486 } 487 #endif /* SYS_DOMAINOS */ 488 #if defined(HAVE_SETPGID) || defined(HAVE_SETSID) 489 # ifdef HAVE_SETSID 490 if (setsid() == (pid_t)-1) 491 msyslog(LOG_ERR, "ntpd: setsid(): %m"); 492 # else 493 if (setpgid(0, 0) == -1) 494 msyslog(LOG_ERR, "ntpd: setpgid(): %m"); 495 # endif 496 #else /* HAVE_SETPGID || HAVE_SETSID */ 497 { 498 # if defined(TIOCNOTTY) 499 int fid; 500 501 fid = open("/dev/tty", 2); 502 if (fid >= 0) 503 { 504 (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0); 505 (void) close(fid); 506 } 507 # endif /* defined(TIOCNOTTY) */ 508 # ifdef HAVE_SETPGRP_0 509 (void) setpgrp(); 510 # else /* HAVE_SETPGRP_0 */ 511 (void) setpgrp(0, getpid()); 512 # endif /* HAVE_SETPGRP_0 */ 513 } 514 #endif /* HAVE_SETPGID || HAVE_SETSID */ 515 #ifdef _AIX 516 /* Don't get killed by low-on-memory signal. */ 517 sa.sa_handler = catch_danger; 518 sigemptyset(&sa.sa_mask); 519 sa.sa_flags = SA_RESTART; 520 521 (void) sigaction(SIGDANGER, &sa, NULL); 522 #endif /* _AIX */ 523 } 524 # endif /* not HAVE_DAEMON */ 525 # else /* SYS_WINNT */ 526 527 { 528 if (NoWinService == FALSE) { 529 SERVICE_TABLE_ENTRY dispatchTable[] = { 530 { TEXT("NetworkTimeProtocol"), (LPSERVICE_MAIN_FUNCTION)service_main }, 531 { NULL, NULL } 532 }; 533 534 /* daemonize */ 535 if (!StartServiceCtrlDispatcher(dispatchTable)) 536 { 537 msyslog(LOG_ERR, "StartServiceCtrlDispatcher: %m"); 538 ExitProcess(2); 539 } 540 } 541 else { 542 service_main(argc, argv); 543 return 0; 544 } 545 } 546 # endif /* SYS_WINNT */ 547 } 548 # endif /* NODETACH */ 549 # if defined(SYS_WINNT) && !defined(NODETACH) 550 else 551 service_main(argc, argv); 552 return 0; /* must return a value */ 553 } /* end main */ 554 555 /* 556 * If this runs as a service under NT, the main thread will block at 557 * StartServiceCtrlDispatcher() and another thread will be started by the 558 * Service Control Dispatcher which will begin execution at the routine 559 * specified in that call (viz. service_main) 560 */ 561 void 562 service_main( 563 DWORD argc, 564 LPTSTR *argv 565 ) 566 { 567 char *cp; 568 struct recvbuf *rbuflist; 569 struct recvbuf *rbuf; 570 571 if(!debug && NoWinService == FALSE) 572 { 573 /* register our service control handler */ 574 sshStatusHandle = RegisterServiceCtrlHandler( TEXT("NetworkTimeProtocol"), 575 (LPHANDLER_FUNCTION)service_ctrl); 576 if(sshStatusHandle == 0) 577 { 578 msyslog(LOG_ERR, "RegisterServiceCtrlHandler failed: %m"); 579 return; 580 } 581 582 /* report pending status to Service Control Manager */ 583 ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 584 ssStatus.dwCurrentState = SERVICE_START_PENDING; 585 ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; 586 ssStatus.dwWin32ExitCode = NO_ERROR; 587 ssStatus.dwServiceSpecificExitCode = 0; 588 ssStatus.dwCheckPoint = 1; 589 ssStatus.dwWaitHint = 5000; 590 if (!SetServiceStatus(sshStatusHandle, &ssStatus)) 591 { 592 msyslog(LOG_ERR, "SetServiceStatus: %m"); 593 ssStatus.dwCurrentState = SERVICE_STOPPED; 594 SetServiceStatus(sshStatusHandle, &ssStatus); 595 return; 596 } 597 598 } /* debug */ 599 # endif /* defined(SYS_WINNT) && !defined(NODETACH) */ 600 #endif /* VMS */ 601 602 /* 603 * Logging. This may actually work on the gizmo board. Find a name 604 * to log with by using the basename of argv[0] 605 */ 606 cp = strrchr(argv[0], '/'); 607 if (cp == 0) 608 cp = argv[0]; 609 else 610 cp++; 611 612 debug = 0; /* will be immediately re-initialized 8-( */ 613 getstartup(argc, argv); /* startup configuration, catch logfile this time */ 614 615 #if !defined(VMS) 616 617 # ifndef LOG_DAEMON 618 openlog(cp, LOG_PID); 619 # else /* LOG_DAEMON */ 620 621 # ifndef LOG_NTP 622 # define LOG_NTP LOG_DAEMON 623 # endif 624 openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP); 625 # ifdef DEBUG 626 if (debug) 627 setlogmask(LOG_UPTO(LOG_DEBUG)); 628 else 629 # endif /* DEBUG */ 630 setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ 631 # endif /* LOG_DAEMON */ 632 #endif /* !SYS_WINNT && !VMS */ 633 634 NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */ 635 msyslog(LOG_NOTICE, "%s", Version); 636 637 #ifdef SYS_WINNT 638 /* GMS 1/18/1997 639 * TODO: lock the process in memory using SetProcessWorkingSetSize() and VirtualLock() functions 640 * 641 process_handle = GetCurrentProcess(); 642 if (SetProcessWorkingSetSize(process_handle, 2097152 , 4194304 ) == TRUE) { 643 if (VirtualLock(0 , 4194304) == FALSE) 644 msyslog(LOG_ERR, "VirtualLock() failed: %m"); 645 } else { 646 msyslog(LOG_ERR, "SetProcessWorkingSetSize() failed: %m"); 647 } 648 */ 649 #endif /* SYS_WINNT */ 650 651 #ifdef SCO5_CLOCK 652 /* 653 * SCO OpenServer's system clock offers much more precise timekeeping 654 * on the base CPU than the other CPUs (for multiprocessor systems), 655 * so we must lock to the base CPU. 656 */ 657 { 658 int fd = open("/dev/at1", O_RDONLY); 659 if (fd >= 0) { 660 int zero = 0; 661 if (ioctl(fd, ACPU_LOCK, &zero) < 0) 662 msyslog(LOG_ERR, "cannot lock to base CPU: %m\n"); 663 close( fd ); 664 } /* else ... 665 * If we can't open the device, this probably just isn't 666 * a multiprocessor system, so we're A-OK. 667 */ 668 } 669 #endif 670 671 #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE) 672 # ifdef HAVE_SETRLIMIT 673 /* 674 * Set the stack limit to something smaller, so that we don't lock a lot 675 * of unused stack memory. 676 */ 677 { 678 struct rlimit rl; 679 680 if (getrlimit(RLIMIT_STACK, &rl) != -1 681 && (rl.rlim_cur = 20 * 4096) < rl.rlim_max) 682 { 683 if (setrlimit(RLIMIT_STACK, &rl) == -1) 684 { 685 msyslog(LOG_ERR, 686 "Cannot adjust stack limit for mlockall: %m"); 687 } 688 } 689 } 690 # endif /* HAVE_SETRLIMIT */ 691 /* 692 * lock the process into memory 693 */ 694 if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) 695 msyslog(LOG_ERR, "mlockall(): %m"); 696 #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */ 697 # ifdef HAVE_PLOCK 698 # ifdef PROCLOCK 699 # ifdef _AIX 700 /* 701 * set the stack limit for AIX for plock(). 702 * see get_aix_stack for more info. 703 */ 704 if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0) 705 { 706 msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m"); 707 } 708 # endif /* _AIX */ 709 /* 710 * lock the process into memory 711 */ 712 if (plock(PROCLOCK) < 0) 713 msyslog(LOG_ERR, "plock(PROCLOCK): %m"); 714 # else /* not PROCLOCK */ 715 # ifdef TXTLOCK 716 /* 717 * Lock text into ram 718 */ 719 if (plock(TXTLOCK) < 0) 720 msyslog(LOG_ERR, "plock(TXTLOCK) error: %m"); 721 # else /* not TXTLOCK */ 722 msyslog(LOG_ERR, "plock() - don't know what to lock!"); 723 # endif /* not TXTLOCK */ 724 # endif /* not PROCLOCK */ 725 # endif /* HAVE_PLOCK */ 726 #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */ 727 728 /* 729 * Set up signals we pay attention to locally. 730 */ 731 #ifdef SIGDIE1 732 (void) signal_no_reset(SIGDIE1, finish); 733 #endif /* SIGDIE1 */ 734 #ifdef SIGDIE2 735 (void) signal_no_reset(SIGDIE2, finish); 736 #endif /* SIGDIE2 */ 737 #ifdef SIGDIE3 738 (void) signal_no_reset(SIGDIE3, finish); 739 #endif /* SIGDIE3 */ 740 #ifdef SIGDIE4 741 (void) signal_no_reset(SIGDIE4, finish); 742 #endif /* SIGDIE4 */ 743 744 #ifdef SIGBUS 745 (void) signal_no_reset(SIGBUS, finish); 746 #endif /* SIGBUS */ 747 748 #if !defined(SYS_WINNT) && !defined(VMS) 749 # ifdef DEBUG 750 (void) signal_no_reset(MOREDEBUGSIG, moredebug); 751 (void) signal_no_reset(LESSDEBUGSIG, lessdebug); 752 # else 753 (void) signal_no_reset(MOREDEBUGSIG, no_debug); 754 (void) signal_no_reset(LESSDEBUGSIG, no_debug); 755 # endif /* DEBUG */ 756 #endif /* !SYS_WINNT && !VMS */ 757 758 /* 759 * Set up signals we should never pay attention to. 760 */ 761 #if defined SIGPIPE 762 (void) signal_no_reset(SIGPIPE, SIG_IGN); 763 #endif /* SIGPIPE */ 764 765 #if defined SYS_WINNT 766 if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE)) { 767 msyslog(LOG_ERR, "Can't set console control handler: %m"); 768 } 769 #endif 770 771 /* 772 * Call the init_ routines to initialize the data structures. 773 */ 774 #if defined (HAVE_IO_COMPLETION_PORT) 775 init_io_completion_port(); 776 init_winnt_time(); 777 #endif 778 init_auth(); 779 init_util(); 780 init_restrict(); 781 init_mon(); 782 init_timer(); 783 init_lib(); 784 init_random(); 785 init_request(); 786 init_control(); 787 init_peer(); 788 #ifdef REFCLOCK 789 init_refclock(); 790 #endif 791 set_process_priority(); 792 init_proto(); /* Call at high priority */ 793 init_io(); 794 init_loopfilter(); 795 mon_start(MON_ON); /* monitor on by default now */ 796 /* turn off in config if unwanted */ 797 798 /* 799 * Get configuration. This (including argument list parsing) is 800 * done in a separate module since this will definitely be different 801 * for the gizmo board. While at it, save the host name for later 802 * along with the length. The crypto needs this. 803 */ 804 #ifdef DEBUG 805 debug = 0; 806 #endif 807 getconfig(argc, argv); 808 #ifdef OPENSSL 809 crypto_setup(); 810 #endif /* OPENSSL */ 811 initializing = 0; 812 813 #if defined(SYS_WINNT) && !defined(NODETACH) 814 # if defined(DEBUG) 815 if(!debug) 816 { 817 # endif 818 if (NoWinService == FALSE) { 819 /* report to the service control manager that the service is running */ 820 ssStatus.dwCurrentState = SERVICE_RUNNING; 821 ssStatus.dwWin32ExitCode = NO_ERROR; 822 if (!SetServiceStatus(sshStatusHandle, &ssStatus)) 823 { 824 msyslog(LOG_ERR, "SetServiceStatus: %m"); 825 if (ResolverThreadHandle != NULL) 826 CloseHandle(ResolverThreadHandle); 827 ssStatus.dwCurrentState = SERVICE_STOPPED; 828 SetServiceStatus(sshStatusHandle, &ssStatus); 829 return; 830 } 831 } 832 # if defined(DEBUG) 833 } 834 # endif 835 #endif 836 837 #ifdef HAVE_CLOCKCTL 838 /* 839 * Drop super-user privileges and chroot now if the OS supports 840 * non root clock control (only NetBSD for now). 841 */ 842 if (user != NULL) { 843 if (isdigit((unsigned char)*user)) { 844 sw_uid = (uid_t)strtoul(user, &endp, 0); 845 if (*endp != '\0') 846 goto getuser; 847 } else { 848 getuser: 849 if ((pw = getpwnam(user)) != NULL) { 850 sw_uid = pw->pw_uid; 851 } else { 852 errno = 0; 853 msyslog(LOG_ERR, "Cannot find user `%s'", user); 854 exit (-1); 855 } 856 } 857 } 858 if (group != NULL) { 859 if (isdigit((unsigned char)*group)) { 860 sw_gid = (gid_t)strtoul(group, &endp, 0); 861 if (*endp != '\0') 862 goto getgroup; 863 } else { 864 getgroup: 865 if ((gr = getgrnam(group)) != NULL) { 866 sw_gid = pw->pw_gid; 867 } else { 868 errno = 0; 869 msyslog(LOG_ERR, "Cannot find group `%s'", group); 870 exit (-1); 871 } 872 } 873 } 874 if (chrootdir && chroot(chrootdir)) { 875 msyslog(LOG_ERR, "Cannot chroot to `%s': %m", chrootdir); 876 exit (-1); 877 } 878 if (group && setgid(sw_gid)) { 879 msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group); 880 exit (-1); 881 } 882 if (group && setegid(sw_gid)) { 883 msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group); 884 exit (-1); 885 } 886 if (user && setuid(sw_uid)) { 887 msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user); 888 exit (-1); 889 } 890 if (user && seteuid(sw_uid)) { 891 msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user); 892 exit (-1); 893 } 894 #endif 895 /* 896 * Report that we're up to any trappers 897 */ 898 report_event(EVNT_SYSRESTART, (struct peer *)0); 899 900 /* 901 * Use select() on all on all input fd's for unlimited 902 * time. select() will terminate on SIGALARM or on the 903 * reception of input. Using select() means we can't do 904 * robust signal handling and we get a potential race 905 * between checking for alarms and doing the select(). 906 * Mostly harmless, I think. 907 */ 908 /* On VMS, I suspect that select() can't be interrupted 909 * by a "signal" either, so I take the easy way out and 910 * have select() time out after one second. 911 * System clock updates really aren't time-critical, 912 * and - lacking a hardware reference clock - I have 913 * yet to learn about anything else that is. 914 */ 915 #if defined(HAVE_IO_COMPLETION_PORT) 916 WaitHandles[0] = CreateEvent(NULL, FALSE, FALSE, NULL); /* exit reques */ 917 WaitHandles[1] = get_timer_handle(); 918 WaitHandles[2] = get_io_event(); 919 920 for (;;) { 921 DWORD Index = WaitForMultipleObjectsEx(sizeof(WaitHandles)/sizeof(WaitHandles[0]), WaitHandles, FALSE, 1000, TRUE); 922 switch (Index) { 923 case WAIT_OBJECT_0 + 0 : /* exit request */ 924 exit(0); 925 break; 926 927 case WAIT_OBJECT_0 + 1 : /* timer */ 928 timer(); 929 break; 930 931 case WAIT_OBJECT_0 + 2 : /* Io event */ 932 # ifdef DEBUG 933 if ( debug > 3 ) 934 { 935 printf( "IoEvent occurred\n" ); 936 } 937 # endif 938 break; 939 940 case WAIT_IO_COMPLETION : /* loop */ 941 case WAIT_TIMEOUT : 942 break; 943 case WAIT_FAILED: 944 msyslog(LOG_ERR, "ntpdc: WaitForMultipleObjectsEx Failed: Error: %m"); 945 break; 946 947 /* For now do nothing if not expected */ 948 default: 949 break; 950 951 } /* switch */ 952 rbuflist = getrecvbufs(); /* get received buffers */ 953 954 #else /* normal I/O */ 955 956 was_alarmed = 0; 957 rbuflist = (struct recvbuf *)0; 958 for (;;) 959 { 960 # if !defined(HAVE_SIGNALED_IO) 961 extern fd_set activefds; 962 extern int maxactivefd; 963 964 fd_set rdfdes; 965 int nfound; 966 # elif defined(HAVE_SIGNALED_IO) 967 block_io_and_alarm(); 968 # endif 969 970 rbuflist = getrecvbufs(); /* get received buffers */ 971 if (alarm_flag) /* alarmed? */ 972 { 973 was_alarmed = 1; 974 alarm_flag = 0; 975 } 976 977 if (!was_alarmed && rbuflist == (struct recvbuf *)0) 978 { 979 /* 980 * Nothing to do. Wait for something. 981 */ 982 # ifndef HAVE_SIGNALED_IO 983 rdfdes = activefds; 984 # if defined(VMS) || defined(SYS_VXWORKS) 985 /* make select() wake up after one second */ 986 { 987 struct timeval t1; 988 989 t1.tv_sec = 1; t1.tv_usec = 0; 990 nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, 991 (fd_set *)0, &t1); 992 } 993 # else 994 nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0, 995 (fd_set *)0, (struct timeval *)0); 996 # endif /* VMS */ 997 if (nfound > 0) 998 { 999 l_fp ts; 1000 1001 get_systime(&ts); 1002 1003 (void)input_handler(&ts); 1004 } 1005 else if (nfound == -1 && errno != EINTR) 1006 msyslog(LOG_ERR, "select() error: %m"); 1007 # ifdef DEBUG 1008 else if (debug > 2) 1009 msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound); 1010 # endif /* DEBUG */ 1011 # else /* HAVE_SIGNALED_IO */ 1012 1013 wait_for_signal(); 1014 # endif /* HAVE_SIGNALED_IO */ 1015 if (alarm_flag) /* alarmed? */ 1016 { 1017 was_alarmed = 1; 1018 alarm_flag = 0; 1019 } 1020 rbuflist = getrecvbufs(); /* get received buffers */ 1021 } 1022 # ifdef HAVE_SIGNALED_IO 1023 unblock_io_and_alarm(); 1024 # endif /* HAVE_SIGNALED_IO */ 1025 1026 /* 1027 * Out here, signals are unblocked. Call timer routine 1028 * to process expiry. 1029 */ 1030 if (was_alarmed) 1031 { 1032 timer(); 1033 was_alarmed = 0; 1034 } 1035 1036 #endif /* HAVE_IO_COMPLETION_PORT */ 1037 /* 1038 * Call the data procedure to handle each received 1039 * packet. 1040 */ 1041 while (rbuflist != (struct recvbuf *)0) 1042 { 1043 rbuf = rbuflist; 1044 rbuflist = rbuf->next; 1045 (rbuf->receiver)(rbuf); 1046 freerecvbuf(rbuf); 1047 } 1048 #if defined DEBUG && defined SYS_WINNT 1049 if (debug > 4) 1050 printf("getrecvbufs: %ld handler interrupts, %ld frames\n", 1051 handler_calls, handler_pkts); 1052 #endif 1053 1054 /* 1055 * Go around again 1056 */ 1057 } 1058 #ifndef SYS_WINNT 1059 exit(1); /* unreachable */ 1060 #endif 1061 #ifndef SYS_WINNT 1062 return 1; /* DEC OSF cc braindamage */ 1063 #endif 1064 } 1065 1066 1067 #ifdef SIGDIE2 1068 /* 1069 * finish - exit gracefully 1070 */ 1071 static RETSIGTYPE 1072 finish( 1073 int sig 1074 ) 1075 { 1076 1077 msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig); 1078 1079 switch (sig) 1080 { 1081 # ifdef SIGBUS 1082 case SIGBUS: 1083 printf("\nfinish(SIGBUS)\n"); 1084 exit(0); 1085 # endif 1086 case 0: /* Should never happen... */ 1087 return; 1088 default: 1089 exit(0); 1090 } 1091 } 1092 #endif /* SIGDIE2 */ 1093 1094 1095 #ifdef DEBUG 1096 #ifndef SYS_WINNT 1097 /* 1098 * moredebug - increase debugging verbosity 1099 */ 1100 static RETSIGTYPE 1101 moredebug( 1102 int sig 1103 ) 1104 { 1105 int saved_errno = errno; 1106 1107 if (debug < 255) 1108 { 1109 debug++; 1110 msyslog(LOG_DEBUG, "debug raised to %d", debug); 1111 } 1112 errno = saved_errno; 1113 } 1114 1115 /* 1116 * lessdebug - decrease debugging verbosity 1117 */ 1118 static RETSIGTYPE 1119 lessdebug( 1120 int sig 1121 ) 1122 { 1123 int saved_errno = errno; 1124 1125 if (debug > 0) 1126 { 1127 debug--; 1128 msyslog(LOG_DEBUG, "debug lowered to %d", debug); 1129 } 1130 errno = saved_errno; 1131 } 1132 #endif 1133 #else /* not DEBUG */ 1134 #ifndef SYS_WINNT/* 1135 * no_debug - We don't do the debug here. 1136 */ 1137 static RETSIGTYPE 1138 no_debug( 1139 int sig 1140 ) 1141 { 1142 int saved_errno = errno; 1143 1144 msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig); 1145 errno = saved_errno; 1146 } 1147 #endif /* not SYS_WINNT */ 1148 #endif /* not DEBUG */ 1149 1150 #ifdef SYS_WINNT 1151 /* service_ctrl - control handler for NTP service 1152 * signals the service_main routine of start/stop requests 1153 * from the control panel or other applications making 1154 * win32API calls 1155 */ 1156 void 1157 service_ctrl( 1158 DWORD dwCtrlCode 1159 ) 1160 { 1161 DWORD dwState = SERVICE_RUNNING; 1162 1163 /* Handle the requested control code */ 1164 switch(dwCtrlCode) 1165 { 1166 case SERVICE_CONTROL_PAUSE: 1167 /* see no reason to support this */ 1168 break; 1169 1170 case SERVICE_CONTROL_CONTINUE: 1171 /* see no reason to support this */ 1172 break; 1173 1174 case SERVICE_CONTROL_STOP: 1175 dwState = SERVICE_STOP_PENDING; 1176 /* 1177 * Report the status, specifying the checkpoint and waithint, 1178 * before setting the termination event. 1179 */ 1180 ssStatus.dwCurrentState = dwState; 1181 ssStatus.dwWin32ExitCode = NO_ERROR; 1182 ssStatus.dwWaitHint = 3000; 1183 if (!SetServiceStatus(sshStatusHandle, &ssStatus)) 1184 { 1185 msyslog(LOG_ERR, "SetServiceStatus: %m"); 1186 } 1187 if (WaitHandles[0] != NULL) { 1188 SetEvent(WaitHandles[0]); 1189 } 1190 return; 1191 1192 case SERVICE_CONTROL_INTERROGATE: 1193 /* Update the service status */ 1194 break; 1195 1196 default: 1197 /* invalid control code */ 1198 break; 1199 1200 } 1201 1202 ssStatus.dwCurrentState = dwState; 1203 ssStatus.dwWin32ExitCode = NO_ERROR; 1204 if (!SetServiceStatus(sshStatusHandle, &ssStatus)) 1205 { 1206 msyslog(LOG_ERR, "SetServiceStatus: %m"); 1207 } 1208 } 1209 1210 static BOOL WINAPI 1211 OnConsoleEvent( 1212 DWORD dwCtrlType 1213 ) 1214 { 1215 switch (dwCtrlType) { 1216 case CTRL_BREAK_EVENT : 1217 if (debug > 0) { 1218 debug <<= 1; 1219 } 1220 else { 1221 debug = 1; 1222 } 1223 if (debug > 8) { 1224 debug = 0; 1225 } 1226 printf("debug level %d\n", debug); 1227 break ; 1228 1229 case CTRL_C_EVENT : 1230 case CTRL_CLOSE_EVENT : 1231 case CTRL_SHUTDOWN_EVENT : 1232 if (WaitHandles[0] != NULL) { 1233 SetEvent(WaitHandles[0]); 1234 } 1235 break; 1236 1237 default : 1238 return FALSE; 1239 1240 1241 } 1242 return TRUE;; 1243 } 1244 1245 1246 /* 1247 * NT version of exit() - all calls to exit() should be routed to 1248 * this function. 1249 */ 1250 void 1251 service_exit( 1252 int status 1253 ) 1254 { 1255 if (!debug) { /* did not become a service, simply exit */ 1256 /* service mode, need to have the service_main routine 1257 * register with the service control manager that the 1258 * service has stopped running, before exiting 1259 */ 1260 ssStatus.dwCurrentState = SERVICE_STOPPED; 1261 SetServiceStatus(sshStatusHandle, &ssStatus); 1262 1263 } 1264 uninit_io_completion_port(); 1265 reset_winnt_time(); 1266 1267 # if defined _MSC_VER 1268 _CrtDumpMemoryLeaks(); 1269 # endif 1270 #undef exit 1271 exit(status); 1272 } 1273 1274 #endif /* SYS_WINNT */ 1275