Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / ntpd / ntpd.c
blob13a8c433aa0916a31495861055054073d721fd0c
1 /* $NetBSD: ntpd.c,v 1.1.1.1 2009/12/13 16:56:15 kardel Exp $ */
3 /*
4 * ntpd.c - main program for the fixed point NTP daemon
5 */
7 #ifdef HAVE_CONFIG_H
8 # include <config.h>
9 #endif
11 #include "ntp_machine.h"
12 #include "ntpd.h"
13 #include "ntp_io.h"
14 #include "ntp_stdlib.h"
15 #include <ntp_random.h>
17 #include "ntp_syslog.h"
18 #include "isc/assertions.h"
19 #include "isc/error.h"
20 #include "isc/strerror.h"
21 #include "isc/formatcheck.h"
23 #ifdef SIM
24 # include "ntpsim.h"
25 #endif
27 #include "ntpd-opts.h"
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32 #ifdef HAVE_SYS_STAT_H
33 # include <sys/stat.h>
34 #endif
35 #include <stdio.h>
36 #if !defined(VMS) /*wjm*/
37 # ifdef HAVE_SYS_PARAM_H
38 # include <sys/param.h>
39 # endif
40 #endif /* VMS */
41 #ifdef HAVE_SYS_SIGNAL_H
42 # include <sys/signal.h>
43 #else
44 # include <signal.h>
45 #endif
46 #ifdef HAVE_SYS_IOCTL_H
47 # include <sys/ioctl.h>
48 #endif /* HAVE_SYS_IOCTL_H */
49 #ifdef HAVE_SYS_RESOURCE_H
50 # include <sys/resource.h>
51 #endif /* HAVE_SYS_RESOURCE_H */
52 #if defined(HAVE_RTPRIO)
53 # ifdef HAVE_SYS_RESOURCE_H
54 # include <sys/resource.h>
55 # endif
56 # ifdef HAVE_SYS_LOCK_H
57 # include <sys/lock.h>
58 # endif
59 # include <sys/rtprio.h>
60 #else
61 # ifdef HAVE_PLOCK
62 # ifdef HAVE_SYS_LOCK_H
63 # include <sys/lock.h>
64 # endif
65 # endif
66 #endif
67 #if defined(HAVE_SCHED_SETSCHEDULER)
68 # ifdef HAVE_SCHED_H
69 # include <sched.h>
70 # else
71 # ifdef HAVE_SYS_SCHED_H
72 # include <sys/sched.h>
73 # endif
74 # endif
75 #endif
76 #if defined(HAVE_SYS_MMAN_H)
77 # include <sys/mman.h>
78 #endif
80 #ifdef HAVE_TERMIOS_H
81 # include <termios.h>
82 #endif
84 #ifdef SYS_DOMAINOS
85 # include <apollo/base.h>
86 #endif /* SYS_DOMAINOS */
88 #include "recvbuff.h"
89 #include "ntp_cmdargs.h"
91 #if 0 /* HMS: I don't think we need this. 961223 */
92 #ifdef LOCK_PROCESS
93 # ifdef SYS_SOLARIS
94 # include <sys/mman.h>
95 # else
96 # include <sys/lock.h>
97 # endif
98 #endif
99 #endif
101 #ifdef _AIX
102 # include <ulimit.h>
103 #endif /* _AIX */
105 #ifdef SCO5_CLOCK
106 # include <sys/ci/ciioctl.h>
107 #endif
109 #ifdef HAVE_DROPROOT
110 # include <ctype.h>
111 # include <grp.h>
112 # include <pwd.h>
113 #ifdef HAVE_LINUX_CAPABILITIES
114 # include <sys/capability.h>
115 # include <sys/prctl.h>
116 #endif
117 #endif
120 * Signals we catch for debugging. If not debugging we ignore them.
122 #define MOREDEBUGSIG SIGUSR1
123 #define LESSDEBUGSIG SIGUSR2
126 * Signals which terminate us gracefully.
128 #ifndef SYS_WINNT
129 # define SIGDIE1 SIGHUP
130 # define SIGDIE3 SIGQUIT
131 # define SIGDIE2 SIGINT
132 # define SIGDIE4 SIGTERM
133 #endif /* SYS_WINNT */
135 #ifdef HAVE_DNSREGISTRATION
136 #include <dns_sd.h>
137 DNSServiceRef mdns;
138 #endif
141 * Scheduling priority we run at
143 #define NTPD_PRIO (-12)
145 int priority_done = 2; /* 0 - Set priority */
146 /* 1 - priority is OK where it is */
147 /* 2 - Don't set priority */
148 /* 1 and 2 are pretty much the same */
150 #ifdef DEBUG
152 * Debugging flag
154 volatile int debug = 0; /* No debugging by default */
155 #endif
157 int listen_to_virtual_ips = 1;
158 const char *specific_interface = NULL; /* interface name or IP address to bind to */
161 * No-fork flag. If set, we do not become a background daemon.
163 int nofork = 0; /* Fork by default */
165 #ifdef HAVE_DNSREGISTRATION
167 * mDNS registration flag. If set, we attempt to register with the mDNS system, but only
168 * after we have synched the first time. If the attempt fails, then try again once per
169 * minute for up to 5 times. After all, we may be starting before mDNS.
171 int mdnsreg = 1;
172 int mdnstries = 5;
173 #endif /* HAVE_DNSREGISTRATION */
175 #ifdef HAVE_DROPROOT
176 int droproot = 0;
177 char *user = NULL; /* User to switch to */
178 char *group = NULL; /* group to switch to */
179 const char *chrootdir = NULL; /* directory to chroot to */
180 uid_t sw_uid;
181 gid_t sw_gid;
182 char *endp;
183 struct group *gr;
184 struct passwd *pw;
185 #endif /* HAVE_DROPROOT */
188 * Initializing flag. All async routines watch this and only do their
189 * thing when it is clear.
191 int initializing;
194 * Version declaration
196 extern const char *Version;
198 char const *progname;
200 int was_alarmed;
202 #ifdef DECL_SYSCALL
204 * We put this here, since the argument profile is syscall-specific
206 extern int syscall (int, ...);
207 #endif /* DECL_SYSCALL */
210 #ifdef SIGDIE2
211 static RETSIGTYPE finish (int);
212 #endif /* SIGDIE2 */
214 #ifdef DEBUG
215 #ifndef SYS_WINNT
216 static RETSIGTYPE moredebug (int);
217 static RETSIGTYPE lessdebug (int);
218 #endif
219 #else /* not DEBUG */
220 static RETSIGTYPE no_debug (int);
221 #endif /* not DEBUG */
223 int ntpdmain (int, char **);
224 static void set_process_priority (void);
225 void init_logging (char const *, int);
226 void setup_logfile (void);
227 static void process_commandline_opts(int *, char ***);
229 static void assertion_failed (const char *file, int line,
230 isc_assertiontype_t type, const char *cond);
231 static void library_fatal_error (const char *file, int line,
232 const char *format, va_list args) ISC_FORMAT_PRINTF(3, 0);
233 static void library_unexpected_error(const char *file, int line,
234 const char *format, va_list args) ISC_FORMAT_PRINTF(3, 0);
238 * Initialize the logging
240 void
241 init_logging(
242 char const *name,
243 int log_version
246 const char *cp;
249 * Logging. This may actually work on the gizmo board. Find a name
250 * to log with by using the basename
252 cp = strrchr(name, '/');
253 if (cp == 0)
254 cp = name;
255 else
256 cp++;
258 #if !defined(VMS)
260 # ifndef LOG_DAEMON
261 openlog(cp, LOG_PID);
262 # else /* LOG_DAEMON */
264 # ifndef LOG_NTP
265 # define LOG_NTP LOG_DAEMON
266 # endif
267 openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP);
268 # ifdef DEBUG
269 if (debug)
270 setlogmask(LOG_UPTO(LOG_DEBUG));
271 else
272 # endif /* DEBUG */
273 setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
274 # endif /* LOG_DAEMON */
275 #endif /* !VMS */
277 if (log_version)
278 NLOG(NLOG_SYSINFO) /* 'if' clause for syslog */
279 msyslog(LOG_NOTICE, "%s", Version);
284 * Redirect logging to a file if requested with -l.
285 * The ntp.conf logfile directive does not use this code, see
286 * config_vars() in ntp_config.c.
288 void
289 setup_logfile(
290 void
293 if (HAVE_OPT( LOGFILE )) {
294 const char *my_optarg = OPT_ARG( LOGFILE );
295 FILE *new_file;
297 if(strcmp(my_optarg, "stderr") == 0)
298 new_file = stderr;
299 else if(strcmp(my_optarg, "stdout") == 0)
300 new_file = stdout;
301 else
302 new_file = fopen(my_optarg, "a");
303 if (new_file != NULL) {
304 NLOG(NLOG_SYSINFO)
305 msyslog(LOG_NOTICE, "logging to file %s", my_optarg);
306 if (syslog_file != NULL &&
307 fileno(syslog_file) != fileno(new_file))
308 (void)fclose(syslog_file);
310 syslog_file = new_file;
311 syslogit = 0;
313 else
314 msyslog(LOG_ERR,
315 "Cannot open log file %s",
316 my_optarg);
321 static void
322 process_commandline_opts(
323 int *pargc,
324 char ***pargv
327 int optct;
329 optct = optionProcess(&ntpdOptions, *pargc, *pargv);
330 *pargc -= optct;
331 *pargv += optct;
335 #ifdef SIM
337 main(
338 int argc,
339 char *argv[]
342 process_commandline_opts(&argc, &argv);
344 return ntpsim(argc, argv);
346 #else /* SIM */
347 #ifdef NO_MAIN_ALLOWED
348 CALL(ntpd,"ntpd",ntpdmain);
349 #else
350 #ifndef SYS_WINNT
352 main(
353 int argc,
354 char *argv[]
357 return ntpdmain(argc, argv);
359 #endif /* SYS_WINNT */
360 #endif /* NO_MAIN_ALLOWED */
361 #endif /* SIM */
363 #ifdef _AIX
365 * OK. AIX is different than solaris in how it implements plock().
366 * If you do NOT adjust the stack limit, you will get the MAXIMUM
367 * stack size allocated and PINNED with you program. To check the
368 * value, use ulimit -a.
370 * To fix this, we create an automatic variable and set our stack limit
371 * to that PLUS 32KB of extra space (we need some headroom).
373 * This subroutine gets the stack address.
375 * Grover Davidson and Matt Ladendorf
378 static char *
379 get_aix_stack(void)
381 char ch;
382 return (&ch);
386 * Signal handler for SIGDANGER.
388 static void
389 catch_danger(int signo)
391 msyslog(LOG_INFO, "ntpd: setpgid(): %m");
392 /* Make the system believe we'll free something, but don't do it! */
393 return;
395 #endif /* _AIX */
398 * Set the process priority
400 static void
401 set_process_priority(void)
404 #ifdef DEBUG
405 if (debug > 1)
406 msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
407 ((priority_done)
408 ? "Leave priority alone"
409 : "Attempt to set priority"
411 priority_done);
412 #endif /* DEBUG */
414 #if defined(HAVE_SCHED_SETSCHEDULER)
415 if (!priority_done) {
416 extern int config_priority_override, config_priority;
417 int pmax, pmin;
418 struct sched_param sched;
420 pmax = sched_get_priority_max(SCHED_FIFO);
421 sched.sched_priority = pmax;
422 if ( config_priority_override ) {
423 pmin = sched_get_priority_min(SCHED_FIFO);
424 if ( config_priority > pmax )
425 sched.sched_priority = pmax;
426 else if ( config_priority < pmin )
427 sched.sched_priority = pmin;
428 else
429 sched.sched_priority = config_priority;
431 if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
432 msyslog(LOG_ERR, "sched_setscheduler(): %m");
433 else
434 ++priority_done;
436 #endif /* HAVE_SCHED_SETSCHEDULER */
437 #if defined(HAVE_RTPRIO)
438 # ifdef RTP_SET
439 if (!priority_done) {
440 struct rtprio srtp;
442 srtp.type = RTP_PRIO_REALTIME; /* was: RTP_PRIO_NORMAL */
443 srtp.prio = 0; /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
445 if (rtprio(RTP_SET, getpid(), &srtp) < 0)
446 msyslog(LOG_ERR, "rtprio() error: %m");
447 else
448 ++priority_done;
450 # else /* not RTP_SET */
451 if (!priority_done) {
452 if (rtprio(0, 120) < 0)
453 msyslog(LOG_ERR, "rtprio() error: %m");
454 else
455 ++priority_done;
457 # endif /* not RTP_SET */
458 #endif /* HAVE_RTPRIO */
459 #if defined(NTPD_PRIO) && NTPD_PRIO != 0
460 # ifdef HAVE_ATT_NICE
461 if (!priority_done) {
462 errno = 0;
463 if (-1 == nice (NTPD_PRIO) && errno != 0)
464 msyslog(LOG_ERR, "nice() error: %m");
465 else
466 ++priority_done;
468 # endif /* HAVE_ATT_NICE */
469 # ifdef HAVE_BSD_NICE
470 if (!priority_done) {
471 if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
472 msyslog(LOG_ERR, "setpriority() error: %m");
473 else
474 ++priority_done;
476 # endif /* HAVE_BSD_NICE */
477 #endif /* NTPD_PRIO && NTPD_PRIO != 0 */
478 if (!priority_done)
479 msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
484 * Main program. Initialize us, disconnect us from the tty if necessary,
485 * and loop waiting for I/O and/or timer expiries.
488 ntpdmain(
489 int argc,
490 char *argv[]
493 l_fp now;
494 struct recvbuf *rbuf;
495 #ifdef _AIX /* HMS: ifdef SIGDANGER? */
496 struct sigaction sa;
497 #endif
499 progname = argv[0];
500 initializing = 1; /* mark that we are initializing */
501 process_commandline_opts(&argc, &argv);
502 init_logging(progname, 1); /* Open the log file */
504 #ifdef HAVE_UMASK
506 mode_t uv;
508 uv = umask(0);
509 if(uv)
510 (void) umask(uv);
511 else
512 (void) umask(022);
514 #endif
516 #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
518 uid_t uid;
520 uid = getuid();
521 if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
522 msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid);
523 printf("must be run as root, not uid %ld\n", (long)uid);
524 exit(1);
527 #endif
529 /* getstartup(argc, argv); / * startup configuration, may set debug */
531 #ifdef DEBUG
532 debug = DESC(DEBUG_LEVEL).optOccCt;
533 DPRINTF(1, ("%s\n", Version));
534 #endif
536 /* honor -l/--logfile option to log to a file */
537 setup_logfile();
540 * Enable the Multi-Media Timer for Windows?
542 #ifdef SYS_WINNT
543 if (HAVE_OPT( MODIFYMMTIMER ))
544 set_mm_timer(MM_TIMER_HIRES);
545 #endif
547 if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT )
548 #ifdef DEBUG
549 || debug
550 #endif
551 || HAVE_OPT( SAVECONFIGQUIT ))
552 nofork = 1;
554 if (HAVE_OPT( NOVIRTUALIPS ))
555 listen_to_virtual_ips = 0;
558 * --interface, listen on specified interfaces
560 if (HAVE_OPT( INTERFACE )) {
561 int ifacect = STACKCT_OPT( INTERFACE );
562 const char** ifaces = STACKLST_OPT( INTERFACE );
563 isc_netaddr_t netaddr;
565 while (ifacect-- > 0) {
566 add_nic_rule(
567 is_ip_address(*ifaces, &netaddr)
568 ? MATCH_IFADDR
569 : MATCH_IFNAME,
570 *ifaces, -1, ACTION_LISTEN);
571 ifaces++;
575 if (HAVE_OPT( NICE ))
576 priority_done = 0;
578 #if defined(HAVE_SCHED_SETSCHEDULER)
579 if (HAVE_OPT( PRIORITY )) {
580 config_priority = OPT_VALUE_PRIORITY;
581 config_priority_override = 1;
582 priority_done = 0;
584 #endif
586 #ifdef SYS_WINNT
588 * Start interpolation thread, must occur before first
589 * get_systime()
591 init_winnt_time();
592 #endif
594 * Initialize random generator and public key pair
596 get_systime(&now);
598 ntp_srandom((int)(now.l_i * now.l_uf));
600 #if !defined(VMS)
601 # ifndef NODETACH
603 * Detach us from the terminal. May need an #ifndef GIZMO.
605 if (!nofork) {
608 * Install trap handlers to log errors and assertion
609 * failures. Default handlers print to stderr which
610 * doesn't work if detached.
612 isc_assertion_setcallback(assertion_failed);
613 isc_error_setfatal(library_fatal_error);
614 isc_error_setunexpected(library_unexpected_error);
616 # ifndef SYS_WINNT
617 # ifdef HAVE_DAEMON
618 daemon(0, 0);
619 # else /* not HAVE_DAEMON */
620 if (fork()) /* HMS: What about a -1? */
621 exit(0);
624 #if !defined(F_CLOSEM)
625 u_long s;
626 int max_fd;
627 #endif /* !FCLOSEM */
628 if (syslog_file != NULL) {
629 fclose(syslog_file);
630 syslog_file = NULL;
632 #if defined(F_CLOSEM)
634 * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
635 * by Eric Agar (saves us from doing 32767 system
636 * calls)
638 if (fcntl(0, F_CLOSEM, 0) == -1)
639 msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");
640 #else /* not F_CLOSEM */
642 # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
643 max_fd = sysconf(_SC_OPEN_MAX);
644 # else /* HAVE_SYSCONF && _SC_OPEN_MAX */
645 max_fd = getdtablesize();
646 # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
647 for (s = 0; s < max_fd; s++)
648 (void) close((int)s);
649 #endif /* not F_CLOSEM */
650 (void) open("/", 0);
651 (void) dup2(0, 1);
652 (void) dup2(0, 2);
654 init_logging(progname, 0);
655 /* we lost our logfile (if any) daemonizing */
656 setup_logfile();
658 #ifdef SYS_DOMAINOS
660 uid_$t puid;
661 status_$t st;
663 proc2_$who_am_i(&puid);
664 proc2_$make_server(&puid, &st);
666 #endif /* SYS_DOMAINOS */
667 #if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
668 # ifdef HAVE_SETSID
669 if (setsid() == (pid_t)-1)
670 msyslog(LOG_ERR, "ntpd: setsid(): %m");
671 # else
672 if (setpgid(0, 0) == -1)
673 msyslog(LOG_ERR, "ntpd: setpgid(): %m");
674 # endif
675 #else /* HAVE_SETPGID || HAVE_SETSID */
677 # if defined(TIOCNOTTY)
678 int fid;
680 fid = open("/dev/tty", 2);
681 if (fid >= 0)
683 (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
684 (void) close(fid);
686 # endif /* defined(TIOCNOTTY) */
687 # ifdef HAVE_SETPGRP_0
688 (void) setpgrp();
689 # else /* HAVE_SETPGRP_0 */
690 (void) setpgrp(0, getpid());
691 # endif /* HAVE_SETPGRP_0 */
693 #endif /* HAVE_SETPGID || HAVE_SETSID */
694 #ifdef _AIX
695 /* Don't get killed by low-on-memory signal. */
696 sa.sa_handler = catch_danger;
697 sigemptyset(&sa.sa_mask);
698 sa.sa_flags = SA_RESTART;
700 (void) sigaction(SIGDANGER, &sa, NULL);
701 #endif /* _AIX */
703 # endif /* not HAVE_DAEMON */
704 # endif /* SYS_WINNT */
706 # endif /* NODETACH */
707 #endif /* VMS */
709 #ifdef SCO5_CLOCK
711 * SCO OpenServer's system clock offers much more precise timekeeping
712 * on the base CPU than the other CPUs (for multiprocessor systems),
713 * so we must lock to the base CPU.
716 int fd = open("/dev/at1", O_RDONLY);
717 if (fd >= 0) {
718 int zero = 0;
719 if (ioctl(fd, ACPU_LOCK, &zero) < 0)
720 msyslog(LOG_ERR, "cannot lock to base CPU: %m");
721 close( fd );
722 } /* else ...
723 * If we can't open the device, this probably just isn't
724 * a multiprocessor system, so we're A-OK.
727 #endif
729 #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
730 # ifdef HAVE_SETRLIMIT
732 * Set the stack limit to something smaller, so that we don't lock a lot
733 * of unused stack memory.
736 struct rlimit rl;
738 /* HMS: must make the rlim_cur amount configurable */
739 if (getrlimit(RLIMIT_STACK, &rl) != -1
740 && (rl.rlim_cur = 50 * 4096) < rl.rlim_max)
742 if (setrlimit(RLIMIT_STACK, &rl) == -1)
744 msyslog(LOG_ERR,
745 "Cannot adjust stack limit for mlockall: %m");
748 # ifdef RLIMIT_MEMLOCK
750 * The default RLIMIT_MEMLOCK is very low on Linux systems.
751 * Unless we increase this limit malloc calls are likely to
752 * fail if we drop root privlege. To be useful the value
753 * has to be larger than the largest ntpd resident set size.
755 rl.rlim_cur = rl.rlim_max = 32*1024*1024;
756 if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) {
757 msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
759 # endif /* RLIMIT_MEMLOCK */
761 # endif /* HAVE_SETRLIMIT */
763 * lock the process into memory
765 if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
766 msyslog(LOG_ERR, "mlockall(): %m");
767 #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
768 # ifdef HAVE_PLOCK
769 # ifdef PROCLOCK
770 # ifdef _AIX
772 * set the stack limit for AIX for plock().
773 * see get_aix_stack() for more info.
775 if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0)
777 msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m");
779 # endif /* _AIX */
781 * lock the process into memory
783 if (plock(PROCLOCK) < 0)
784 msyslog(LOG_ERR, "plock(PROCLOCK): %m");
785 # else /* not PROCLOCK */
786 # ifdef TXTLOCK
788 * Lock text into ram
790 if (plock(TXTLOCK) < 0)
791 msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
792 # else /* not TXTLOCK */
793 msyslog(LOG_ERR, "plock() - don't know what to lock!");
794 # endif /* not TXTLOCK */
795 # endif /* not PROCLOCK */
796 # endif /* HAVE_PLOCK */
797 #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
800 * Set up signals we pay attention to locally.
802 #ifdef SIGDIE1
803 (void) signal_no_reset(SIGDIE1, finish);
804 #endif /* SIGDIE1 */
805 #ifdef SIGDIE2
806 (void) signal_no_reset(SIGDIE2, finish);
807 #endif /* SIGDIE2 */
808 #ifdef SIGDIE3
809 (void) signal_no_reset(SIGDIE3, finish);
810 #endif /* SIGDIE3 */
811 #ifdef SIGDIE4
812 (void) signal_no_reset(SIGDIE4, finish);
813 #endif /* SIGDIE4 */
815 #ifdef SIGBUS
816 (void) signal_no_reset(SIGBUS, finish);
817 #endif /* SIGBUS */
819 #if !defined(SYS_WINNT) && !defined(VMS)
820 # ifdef DEBUG
821 (void) signal_no_reset(MOREDEBUGSIG, moredebug);
822 (void) signal_no_reset(LESSDEBUGSIG, lessdebug);
823 # else
824 (void) signal_no_reset(MOREDEBUGSIG, no_debug);
825 (void) signal_no_reset(LESSDEBUGSIG, no_debug);
826 # endif /* DEBUG */
827 #endif /* !SYS_WINNT && !VMS */
830 * Set up signals we should never pay attention to.
832 #if defined SIGPIPE
833 (void) signal_no_reset(SIGPIPE, SIG_IGN);
834 #endif /* SIGPIPE */
837 * Call the init_ routines to initialize the data structures.
839 * Exactly what command-line options are we expecting here?
841 init_auth();
842 init_util();
843 init_restrict();
844 init_mon();
845 init_timer();
846 init_lib();
847 init_request();
848 init_control();
849 init_peer();
850 #ifdef REFCLOCK
851 init_refclock();
852 #endif
853 set_process_priority();
854 init_proto(); /* Call at high priority */
855 init_io();
856 init_loopfilter();
857 mon_start(MON_ON); /* monitor on by default now */
858 /* turn off in config if unwanted */
861 * Get the configuration. This is done in a separate module
862 * since this will definitely be different for the gizmo board.
864 getconfig(argc, argv);
865 report_event(EVNT_SYSRESTART, NULL, NULL);
866 loop_config(LOOP_DRIFTCOMP, old_drift);
867 initializing = 0;
869 #ifdef HAVE_DROPROOT
870 if( droproot ) {
871 /* Drop super-user privileges and chroot now if the OS supports this */
873 #ifdef HAVE_LINUX_CAPABILITIES
874 /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
875 if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
876 msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
877 exit(-1);
879 #else
880 /* we need a user to switch to */
881 if (user == NULL) {
882 msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
883 exit(-1);
885 #endif /* HAVE_LINUX_CAPABILITIES */
887 if (user != NULL) {
888 if (isdigit((unsigned char)*user)) {
889 sw_uid = (uid_t)strtoul(user, &endp, 0);
890 if (*endp != '\0')
891 goto getuser;
893 if ((pw = getpwuid(sw_uid)) != NULL) {
894 user = strdup(pw->pw_name);
895 if (NULL == user) {
896 msyslog(LOG_ERR, "strdup() failed: %m");
897 exit (-1);
899 sw_gid = pw->pw_gid;
900 } else {
901 errno = 0;
902 msyslog(LOG_ERR, "Cannot find user ID %s", user);
903 exit (-1);
906 } else {
907 getuser:
908 errno = 0;
909 if ((pw = getpwnam(user)) != NULL) {
910 sw_uid = pw->pw_uid;
911 sw_gid = pw->pw_gid;
912 } else {
913 if (errno)
914 msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
915 else
916 msyslog(LOG_ERR, "Cannot find user `%s'", user);
917 exit (-1);
921 if (group != NULL) {
922 if (isdigit((unsigned char)*group)) {
923 sw_gid = (gid_t)strtoul(group, &endp, 0);
924 if (*endp != '\0')
925 goto getgroup;
926 } else {
927 getgroup:
928 if ((gr = getgrnam(group)) != NULL) {
929 sw_gid = gr->gr_gid;
930 } else {
931 errno = 0;
932 msyslog(LOG_ERR, "Cannot find group `%s'", group);
933 exit (-1);
938 if (chrootdir ) {
939 /* make sure cwd is inside the jail: */
940 if (chdir(chrootdir)) {
941 msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
942 exit (-1);
944 if (chroot(chrootdir)) {
945 msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
946 exit (-1);
948 if (chdir("/")) {
949 msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
950 exit (-1);
953 if (user && initgroups(user, sw_gid)) {
954 msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
955 exit (-1);
957 if (group && setgid(sw_gid)) {
958 msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
959 exit (-1);
961 if (group && setegid(sw_gid)) {
962 msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
963 exit (-1);
965 if (group)
966 setgroups(1, &sw_gid);
967 else
968 initgroups(pw->pw_name, pw->pw_gid);
969 if (user && setuid(sw_uid)) {
970 msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
971 exit (-1);
973 if (user && seteuid(sw_uid)) {
974 msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
975 exit (-1);
978 #ifndef HAVE_LINUX_CAPABILITIES
980 * for now assume that the privilege to bind to privileged ports
981 * is associated with running with uid 0 - should be refined on
982 * ports that allow binding to NTP_PORT with uid != 0
984 disable_dynamic_updates |= (sw_uid != 0); /* also notifies routing message listener */
985 #endif
987 if (disable_dynamic_updates && interface_interval) {
988 interface_interval = 0;
989 msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking");
992 #ifdef HAVE_LINUX_CAPABILITIES
993 do {
995 * We may be running under non-root uid now, but we still hold full root privileges!
996 * We drop all of them, except for the crucial one or two: cap_sys_time and
997 * cap_net_bind_service if doing dynamic interface tracking.
999 cap_t caps;
1000 char *captext = (interface_interval)
1001 ? "cap_sys_time,cap_net_bind_service=ipe"
1002 : "cap_sys_time=ipe";
1003 if( ! ( caps = cap_from_text( captext ) ) ) {
1004 msyslog( LOG_ERR, "cap_from_text() failed: %m" );
1005 exit(-1);
1007 if( cap_set_proc( caps ) == -1 ) {
1008 msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" );
1009 exit(-1);
1011 cap_free( caps );
1012 } while(0);
1013 #endif /* HAVE_LINUX_CAPABILITIES */
1015 } /* if( droproot ) */
1016 #endif /* HAVE_DROPROOT */
1019 * Use select() on all on all input fd's for unlimited
1020 * time. select() will terminate on SIGALARM or on the
1021 * reception of input. Using select() means we can't do
1022 * robust signal handling and we get a potential race
1023 * between checking for alarms and doing the select().
1024 * Mostly harmless, I think.
1026 /* On VMS, I suspect that select() can't be interrupted
1027 * by a "signal" either, so I take the easy way out and
1028 * have select() time out after one second.
1029 * System clock updates really aren't time-critical,
1030 * and - lacking a hardware reference clock - I have
1031 * yet to learn about anything else that is.
1033 #if defined(HAVE_IO_COMPLETION_PORT)
1035 for (;;) {
1036 GetReceivedBuffers();
1037 #else /* normal I/O */
1039 BLOCK_IO_AND_ALARM();
1040 was_alarmed = 0;
1041 for (;;)
1043 # if !defined(HAVE_SIGNALED_IO)
1044 extern fd_set activefds;
1045 extern int maxactivefd;
1047 fd_set rdfdes;
1048 int nfound;
1049 # endif
1051 if (alarm_flag) /* alarmed? */
1053 was_alarmed = 1;
1054 alarm_flag = 0;
1057 if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE)
1060 * Nothing to do. Wait for something.
1062 # ifndef HAVE_SIGNALED_IO
1063 rdfdes = activefds;
1064 # if defined(VMS) || defined(SYS_VXWORKS)
1065 /* make select() wake up after one second */
1067 struct timeval t1;
1069 t1.tv_sec = 1; t1.tv_usec = 0;
1070 nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
1071 (fd_set *)0, &t1);
1073 # else
1074 nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
1075 (fd_set *)0, (struct timeval *)0);
1076 # endif /* VMS */
1077 if (nfound > 0)
1079 l_fp ts;
1081 get_systime(&ts);
1083 (void)input_handler(&ts);
1085 else if (nfound == -1 && errno != EINTR)
1086 msyslog(LOG_ERR, "select() error: %m");
1087 # ifdef DEBUG
1088 else if (debug > 5)
1089 msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
1090 # endif /* DEBUG */
1091 # else /* HAVE_SIGNALED_IO */
1093 wait_for_signal();
1094 # endif /* HAVE_SIGNALED_IO */
1095 if (alarm_flag) /* alarmed? */
1097 was_alarmed = 1;
1098 alarm_flag = 0;
1102 if (was_alarmed)
1104 UNBLOCK_IO_AND_ALARM();
1106 * Out here, signals are unblocked. Call timer routine
1107 * to process expiry.
1109 timer();
1110 was_alarmed = 0;
1111 BLOCK_IO_AND_ALARM();
1114 #endif /* ! HAVE_IO_COMPLETION_PORT */
1116 #ifdef DEBUG_TIMING
1118 l_fp pts;
1119 l_fp tsa, tsb;
1120 int bufcount = 0;
1122 get_systime(&pts);
1123 tsa = pts;
1124 #endif
1125 rbuf = get_full_recv_buffer();
1126 while (rbuf != NULL)
1128 if (alarm_flag)
1130 was_alarmed = 1;
1131 alarm_flag = 0;
1133 UNBLOCK_IO_AND_ALARM();
1135 if (was_alarmed)
1136 { /* avoid timer starvation during lengthy I/O handling */
1137 timer();
1138 was_alarmed = 0;
1142 * Call the data procedure to handle each received
1143 * packet.
1145 if (rbuf->receiver != NULL) /* This should always be true */
1147 #ifdef DEBUG_TIMING
1148 l_fp dts = pts;
1150 L_SUB(&dts, &rbuf->recv_time);
1151 DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
1152 collect_timing(rbuf, "buffer processing delay", 1, &dts);
1153 bufcount++;
1154 #endif
1155 (rbuf->receiver)(rbuf);
1156 } else {
1157 msyslog(LOG_ERR, "receive buffer corruption - receiver found to be NULL - ABORTING");
1158 abort();
1161 BLOCK_IO_AND_ALARM();
1162 freerecvbuf(rbuf);
1163 rbuf = get_full_recv_buffer();
1165 #ifdef DEBUG_TIMING
1166 get_systime(&tsb);
1167 L_SUB(&tsb, &tsa);
1168 if (bufcount) {
1169 collect_timing(NULL, "processing", bufcount, &tsb);
1170 DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
1173 #endif
1176 * Go around again
1179 #ifdef HAVE_DNSREGISTRATION
1180 if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
1181 mdnsreg = current_time;
1182 msyslog(LOG_INFO, "Attemping to register mDNS");
1183 if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL,
1184 htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
1185 if (!--mdnstries) {
1186 msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
1187 } else {
1188 msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
1190 } else {
1191 msyslog(LOG_INFO, "mDNS service registered.");
1192 mdnsreg = 0;
1195 #endif /* HAVE_DNSREGISTRATION */
1198 UNBLOCK_IO_AND_ALARM();
1199 return 1;
1203 #ifdef SIGDIE2
1205 * finish - exit gracefully
1207 static RETSIGTYPE
1208 finish(
1209 int sig
1212 msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);
1213 #ifdef HAVE_DNSREGISTRATION
1214 if (mdns != NULL)
1215 DNSServiceRefDeallocate(mdns);
1216 #endif
1217 switch (sig) {
1218 # ifdef SIGBUS
1219 case SIGBUS:
1220 printf("\nfinish(SIGBUS)\n");
1221 exit(0);
1222 # endif
1223 case 0: /* Should never happen... */
1224 return;
1226 default:
1227 exit(0);
1230 #endif /* SIGDIE2 */
1233 /* assertion_failed
1234 * Redirect trap messages from ISC libraries to syslog.
1235 * This code was cloned and simplified from BIND.
1239 * assertion_failed - Handle assertion failures.
1242 static void
1243 assertion_failed(const char *file, int line, isc_assertiontype_t type,
1244 const char *cond)
1246 isc_assertion_setcallback(NULL); /* Avoid recursion */
1248 msyslog(LOG_ERR, "%s:%d: %s(%s) failed",
1249 file, line, isc_assertion_typetotext(type), cond);
1250 msyslog(LOG_ERR, "exiting (due to assertion failure)");
1252 abort();
1256 * library_fatal_error - Handle fatal errors from our libraries.
1259 static void
1260 library_fatal_error(const char *file, int line, const char *format,
1261 va_list args)
1263 char errbuf[256];
1265 isc_error_setfatal(NULL); /* Avoid recursion */
1267 msyslog(LOG_ERR, "%s:%d: fatal error:", file, line);
1268 vsnprintf(errbuf, sizeof(errbuf), format, args);
1269 msyslog(LOG_ERR, errbuf);
1270 msyslog(LOG_ERR, "exiting (due to fatal error in library)");
1272 abort();
1276 * library_unexpected_error - Handle non fatal errors from our libraries.
1278 #define MAX_UNEXPECTED_ERRORS 100
1279 int unexpected_error_cnt = 0;
1280 static void
1281 library_unexpected_error(const char *file, int line, const char *format,
1282 va_list args)
1284 char errbuf[256];
1286 if (unexpected_error_cnt >= MAX_UNEXPECTED_ERRORS)
1287 return; /* avoid clutter in log */
1289 msyslog(LOG_ERR, "%s:%d: unexpected error:", file, line);
1290 vsnprintf(errbuf, sizeof(errbuf), format, args);
1291 msyslog(LOG_ERR, errbuf);
1293 if (++unexpected_error_cnt == MAX_UNEXPECTED_ERRORS)
1295 msyslog(LOG_ERR, "Too many errors. Shutting up.");
1301 #ifdef DEBUG
1302 #ifndef SYS_WINNT
1304 * moredebug - increase debugging verbosity
1306 static RETSIGTYPE
1307 moredebug(
1308 int sig
1311 int saved_errno = errno;
1313 if (debug < 255)
1315 debug++;
1316 msyslog(LOG_DEBUG, "debug raised to %d", debug);
1318 errno = saved_errno;
1322 * lessdebug - decrease debugging verbosity
1324 static RETSIGTYPE
1325 lessdebug(
1326 int sig
1329 int saved_errno = errno;
1331 if (debug > 0)
1333 debug--;
1334 msyslog(LOG_DEBUG, "debug lowered to %d", debug);
1336 errno = saved_errno;
1338 #endif
1339 #else /* not DEBUG */
1340 #ifndef SYS_WINNT
1342 * no_debug - We don't do the debug here.
1344 static RETSIGTYPE
1345 no_debug(
1346 int sig
1349 int saved_errno = errno;
1351 msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
1352 errno = saved_errno;
1354 #endif /* not SYS_WINNT */
1355 #endif /* not DEBUG */