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