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