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_syslog.h"
16#include "isc/assertions.h"
17#include "isc/error.h"
18#include "isc/strerror.h"
19#include "isc/formatcheck.h"
20
21#ifdef SIM
22# include "ntpsim.h"
23#endif
24
25#include "ntpd-opts.h"
26
27#ifdef HAVE_UNISTD_H
28# include <unistd.h>
29#endif
30#ifdef HAVE_SYS_STAT_H
31# include <sys/stat.h>
32#endif
33#include <stdio.h>
34#if !defined(VMS)	/*wjm*/
35# ifdef HAVE_SYS_PARAM_H
36#  include <sys/param.h>
37# endif
38#endif /* VMS */
39#ifdef HAVE_SYS_SIGNAL_H
40# include <sys/signal.h>
41#else
42# include <signal.h>
43#endif
44#ifdef HAVE_SYS_IOCTL_H
45# include <sys/ioctl.h>
46#endif /* HAVE_SYS_IOCTL_H */
47#ifdef HAVE_SYS_RESOURCE_H
48# include <sys/resource.h>
49#endif /* HAVE_SYS_RESOURCE_H */
50#if defined(HAVE_RTPRIO)
51# ifdef HAVE_SYS_RESOURCE_H
52#  include <sys/resource.h>
53# endif
54# ifdef HAVE_SYS_LOCK_H
55#  include <sys/lock.h>
56# endif
57# include <sys/rtprio.h>
58#else
59# ifdef HAVE_PLOCK
60#  ifdef HAVE_SYS_LOCK_H
61#	include <sys/lock.h>
62#  endif
63# endif
64#endif
65#if defined(HAVE_SCHED_SETSCHEDULER)
66# ifdef HAVE_SCHED_H
67#  include <sched.h>
68# else
69#  ifdef HAVE_SYS_SCHED_H
70#   include <sys/sched.h>
71#  endif
72# endif
73#endif
74#if defined(HAVE_SYS_MMAN_H)
75# include <sys/mman.h>
76#endif
77
78#ifdef HAVE_TERMIOS_H
79# include <termios.h>
80#endif
81
82#ifdef SYS_DOMAINOS
83# include <apollo/base.h>
84#endif /* SYS_DOMAINOS */
85
86#include "recvbuff.h"
87#include "ntp_cmdargs.h"
88
89#if 0				/* HMS: I don't think we need this. 961223 */
90#ifdef LOCK_PROCESS
91# ifdef SYS_SOLARIS
92#  include <sys/mman.h>
93# else
94#  include <sys/lock.h>
95# endif
96#endif
97#endif
98
99#ifdef _AIX
100# include <ulimit.h>
101#endif /* _AIX */
102
103#ifdef SCO5_CLOCK
104# include <sys/ci/ciioctl.h>
105#endif
106
107#ifdef HAVE_DROPROOT
108# include <ctype.h>
109# include <grp.h>
110# include <pwd.h>
111#ifdef HAVE_LINUX_CAPABILITIES
112# include <sys/capability.h>
113# include <sys/prctl.h>
114#endif
115#endif
116
117#include <sandbox.h>
118
119/*
120 * Signals we catch for debugging.	If not debugging we ignore them.
121 */
122#define MOREDEBUGSIG	SIGUSR1
123#define LESSDEBUGSIG	SIGUSR2
124
125/*
126 * Signals which terminate us gracefully.
127 */
128#ifndef SYS_WINNT
129# define SIGDIE1	SIGHUP
130# define SIGDIE3	SIGQUIT
131# define SIGDIE2	SIGINT
132# define SIGDIE4	SIGTERM
133#endif /* SYS_WINNT */
134
135#ifdef HAVE_DNSREGISTRATION
136#include <dns_sd.h>
137DNSServiceRef mdns;
138#endif
139
140/*
141 * Scheduling priority we run at
142 */
143#define NTPD_PRIO	(-12)
144
145int 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 */
149
150#ifdef DEBUG
151/*
152 * Debugging flag
153 */
154volatile int debug = 0;		/* No debugging by default */
155#endif
156
157int	listen_to_virtual_ips = 1;
158const char *specific_interface = NULL;        /* interface name or IP address to bind to */
159
160/*
161 * No-fork flag.  If set, we do not become a background daemon.
162 */
163int nofork = 0;			/* Fork by default */
164
165#ifdef HAVE_DNSREGISTRATION
166/*
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.
170 */
171int mdnsreg = 1;
172int mdnstries = 5;
173#endif  /* HAVE_DNSREGISTRATION */
174
175#ifdef HAVE_DROPROOT
176int droproot = 0;
177char *user = NULL;		/* User to switch to */
178char *group = NULL;		/* group to switch to */
179const char *chrootdir = NULL;	/* directory to chroot to */
180int sw_uid;
181int sw_gid;
182char *endp;
183struct group *gr;
184struct passwd *pw;
185#endif /* HAVE_DROPROOT */
186
187/*
188 * Initializing flag.  All async routines watch this and only do their
189 * thing when it is clear.
190 */
191int initializing;
192
193/*
194 * Version declaration
195 */
196extern const char *Version;
197
198char const *progname;
199
200int was_alarmed;
201
202#ifdef DECL_SYSCALL
203/*
204 * We put this here, since the argument profile is syscall-specific
205 */
206extern int syscall	(int, ...);
207#endif /* DECL_SYSCALL */
208
209
210#ifdef	SIGDIE2
211static	RETSIGTYPE	finish		(int);
212#endif	/* SIGDIE2 */
213
214#ifdef	DEBUG
215#ifndef SYS_WINNT
216static	RETSIGTYPE	moredebug	(int);
217static	RETSIGTYPE	lessdebug	(int);
218#endif
219#else /* not DEBUG */
220static	RETSIGTYPE	no_debug	(int);
221#endif	/* not DEBUG */
222
223int		ntpdmain		(int, char **);
224static void	set_process_priority	(void);
225void		init_logging		(char const *, int);
226void		setup_logfile		(void);
227static void	process_commandline_opts(int *, char ***);
228
229static void	assertion_failed	(const char *file, int line,
230	isc_assertiontype_t type, const char *cond);
231static void	library_fatal_error	(const char *file, int line,
232	const char *format, va_list args) ISC_FORMAT_PRINTF(3, 0);
233static void	library_unexpected_error(const char *file, int line,
234	const char *format, va_list args) ISC_FORMAT_PRINTF(3, 0);
235
236
237/*
238 * Initialize the logging
239 */
240void
241init_logging(
242	char const *name,
243	int log_version
244	)
245{
246	const char *cp;
247
248	/*
249	 * Logging.  This may actually work on the gizmo board.  Find a name
250	 * to log with by using the basename
251	 */
252	cp = strrchr(name, '/');
253	if (cp == 0)
254		cp = name;
255	else
256		cp++;
257
258#if !defined(VMS)
259
260# ifndef LOG_DAEMON
261	openlog(cp, LOG_PID);
262# else /* LOG_DAEMON */
263
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 */
276
277}
278
279
280/*
281 * Redirect logging to a file if requested with -l.
282 * The ntp.conf logfile directive does not use this code, see
283 * config_vars() in ntp_config.c.
284 */
285void
286setup_logfile(
287	void
288	)
289{
290	if (HAVE_OPT( LOGFILE )) {
291		const char *my_optarg = OPT_ARG( LOGFILE );
292		FILE *new_file;
293
294		if(strcmp(my_optarg, "stderr") == 0)
295			new_file = stderr;
296		else if(strcmp(my_optarg, "stdout") == 0)
297			new_file = stdout;
298		else
299			new_file = fopen(my_optarg, "a");
300		if (new_file != NULL) {
301			NLOG(NLOG_SYSINFO)
302				msyslog(LOG_NOTICE, "logging to file %s", my_optarg);
303			if (syslog_file != NULL &&
304				fileno(syslog_file) != fileno(new_file))
305				(void)fclose(syslog_file);
306
307			syslog_file = new_file;
308			syslogit = 0;
309		}
310		else
311			msyslog(LOG_ERR,
312				"Cannot open log file %s",
313				my_optarg);
314	}
315}
316
317
318static void
319process_commandline_opts(
320	int *pargc,
321	char ***pargv
322	)
323{
324	int optct;
325
326	optct = optionProcess(&ntpdOptions, *pargc, *pargv);
327	*pargc -= optct;
328	*pargv += optct;
329}
330
331
332#ifdef SIM
333int
334main(
335	int argc,
336	char *argv[]
337	)
338{
339	process_commandline_opts(&argc, &argv);
340
341	return ntpsim(argc, argv);
342}
343#else /* SIM */
344#ifdef NO_MAIN_ALLOWED
345CALL(ntpd,"ntpd",ntpdmain);
346#else
347#ifndef SYS_WINNT
348int
349main(
350	int argc,
351	char *argv[]
352	)
353{
354	return ntpdmain(argc, argv);
355}
356#endif /* SYS_WINNT */
357#endif /* NO_MAIN_ALLOWED */
358#endif /* SIM */
359
360#ifdef _AIX
361/*
362 * OK. AIX is different than solaris in how it implements plock().
363 * If you do NOT adjust the stack limit, you will get the MAXIMUM
364 * stack size allocated and PINNED with you program. To check the
365 * value, use ulimit -a.
366 *
367 * To fix this, we create an automatic variable and set our stack limit
368 * to that PLUS 32KB of extra space (we need some headroom).
369 *
370 * This subroutine gets the stack address.
371 *
372 * Grover Davidson and Matt Ladendorf
373 *
374 */
375static char *
376get_aix_stack(void)
377{
378	char ch;
379	return (&ch);
380}
381
382/*
383 * Signal handler for SIGDANGER.
384 */
385static void
386catch_danger(int signo)
387{
388	msyslog(LOG_INFO, "ntpd: setpgid(): %m");
389	/* Make the system believe we'll free something, but don't do it! */
390	return;
391}
392#endif /* _AIX */
393
394/*
395 * Set the process priority
396 */
397static void
398set_process_priority(void)
399{
400
401#ifdef DEBUG
402	if (debug > 1)
403		msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
404			((priority_done)
405			 ? "Leave priority alone"
406			 : "Attempt to set priority"
407				),
408			priority_done);
409#endif /* DEBUG */
410
411#if defined(HAVE_SCHED_SETSCHEDULER)
412	if (!priority_done) {
413		extern int config_priority_override, config_priority;
414		int pmax, pmin;
415		struct sched_param sched;
416
417		pmax = sched_get_priority_max(SCHED_FIFO);
418		sched.sched_priority = pmax;
419		if ( config_priority_override ) {
420			pmin = sched_get_priority_min(SCHED_FIFO);
421			if ( config_priority > pmax )
422				sched.sched_priority = pmax;
423			else if ( config_priority < pmin )
424				sched.sched_priority = pmin;
425			else
426				sched.sched_priority = config_priority;
427		}
428		if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
429			msyslog(LOG_ERR, "sched_setscheduler(): %m");
430		else
431			++priority_done;
432	}
433#endif /* HAVE_SCHED_SETSCHEDULER */
434#if defined(HAVE_RTPRIO)
435# ifdef RTP_SET
436	if (!priority_done) {
437		struct rtprio srtp;
438
439		srtp.type = RTP_PRIO_REALTIME;	/* was: RTP_PRIO_NORMAL */
440		srtp.prio = 0;		/* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
441
442		if (rtprio(RTP_SET, getpid(), &srtp) < 0)
443			msyslog(LOG_ERR, "rtprio() error: %m");
444		else
445			++priority_done;
446	}
447# else /* not RTP_SET */
448	if (!priority_done) {
449		if (rtprio(0, 120) < 0)
450			msyslog(LOG_ERR, "rtprio() error: %m");
451		else
452			++priority_done;
453	}
454# endif /* not RTP_SET */
455#endif  /* HAVE_RTPRIO */
456#if defined(NTPD_PRIO) && NTPD_PRIO != 0
457# ifdef HAVE_ATT_NICE
458	if (!priority_done) {
459		errno = 0;
460		if (-1 == nice (NTPD_PRIO) && errno != 0)
461			msyslog(LOG_ERR, "nice() error: %m");
462		else
463			++priority_done;
464	}
465# endif /* HAVE_ATT_NICE */
466# ifdef HAVE_BSD_NICE
467	if (!priority_done) {
468		if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
469			msyslog(LOG_ERR, "setpriority() error: %m");
470		else
471			++priority_done;
472	}
473# endif /* HAVE_BSD_NICE */
474#endif /* NTPD_PRIO && NTPD_PRIO != 0 */
475	if (!priority_done)
476		msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
477}
478
479
480/*
481 * Main program.  Initialize us, disconnect us from the tty if necessary,
482 * and loop waiting for I/O and/or timer expiries.
483 */
484int
485ntpdmain(
486	int argc,
487	char *argv[]
488	)
489{
490	l_fp now;
491	struct recvbuf *rbuf;
492#ifdef _AIX			/* HMS: ifdef SIGDANGER? */
493	struct sigaction sa;
494#endif
495
496	progname = argv[0];
497	initializing = 1;		/* mark that we are initializing */
498	process_commandline_opts(&argc, &argv);
499	init_logging(progname, 1);	/* Open the log file */
500
501	char *error = NULL;
502	if (sandbox_init("ntpd", SANDBOX_NAMED, &error) == -1) {
503		msyslog(LOG_ERR, "sandbox_init(ntpd, SANDBOX_NAMED) failed: %s", error);
504		sandbox_free_error(error);
505	}
506#ifdef HAVE_UMASK
507	{
508		mode_t uv;
509
510		uv = umask(0);
511		if(uv)
512			(void) umask(uv);
513		else
514			(void) umask(022);
515	}
516#endif
517
518#if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
519	{
520		uid_t uid;
521
522		uid = getuid();
523		if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
524			msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid);
525			printf("must be run as root, not uid %ld\n", (long)uid);
526			exit(1);
527		}
528	}
529#endif
530
531	/* getstartup(argc, argv); / * startup configuration, may set debug */
532
533#ifdef DEBUG
534	debug = DESC(DEBUG_LEVEL).optOccCt;
535	DPRINTF(1, ("%s\n", Version));
536#endif
537
538	/* honor -l/--logfile option to log to a file */
539	setup_logfile();
540
541/*
542 * Enable the Multi-Media Timer for Windows?
543 */
544#ifdef SYS_WINNT
545	if (HAVE_OPT( MODIFYMMTIMER ))
546		set_mm_timer(MM_TIMER_HIRES);
547#endif
548
549	if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT )
550#ifdef DEBUG
551	    || debug
552#endif
553	    || HAVE_OPT( SAVECONFIGQUIT ))
554		nofork = 1;
555
556	if (HAVE_OPT( NOVIRTUALIPS ))
557		listen_to_virtual_ips = 0;
558
559	/*
560	 * --interface, listen on specified interfaces
561	 */
562	if (HAVE_OPT( INTERFACE )) {
563		int	ifacect = STACKCT_OPT( INTERFACE );
564		const char**	ifaces  = STACKLST_OPT( INTERFACE );
565		isc_netaddr_t	netaddr;
566
567		while (ifacect-- > 0) {
568			add_nic_rule(
569				is_ip_address(*ifaces, &netaddr)
570					? MATCH_IFADDR
571					: MATCH_IFNAME,
572				*ifaces, -1, ACTION_LISTEN);
573			ifaces++;
574		}
575	}
576
577	if (HAVE_OPT( NICE ))
578		priority_done = 0;
579
580#if defined(HAVE_SCHED_SETSCHEDULER)
581	if (HAVE_OPT( PRIORITY )) {
582		config_priority = OPT_VALUE_PRIORITY;
583		config_priority_override = 1;
584		priority_done = 0;
585	}
586#endif
587
588#ifdef SYS_WINNT
589	/*
590	 * Start interpolation thread, must occur before first
591	 * get_systime()
592	 */
593	init_winnt_time();
594#endif
595	/*
596	 * Initialize random generator and public key pair
597	 */
598	get_systime(&now);
599
600	ntp_srandom((int)(now.l_i * now.l_uf));
601
602#if !defined(VMS)
603# ifndef NODETACH
604	/*
605	 * Detach us from the terminal.  May need an #ifndef GIZMO.
606	 */
607	if (!nofork) {
608
609		/*
610		 * Install trap handlers to log errors and assertion
611		 * failures.  Default handlers print to stderr which
612		 * doesn't work if detached.
613		 */
614		isc_assertion_setcallback(assertion_failed);
615		isc_error_setfatal(library_fatal_error);
616		isc_error_setunexpected(library_unexpected_error);
617
618#  ifndef SYS_WINNT
619#   ifdef HAVE_DAEMON
620		daemon(0, 0);
621#   else /* not HAVE_DAEMON */
622		if (fork())	/* HMS: What about a -1? */
623			exit(0);
624
625		{
626#if !defined(F_CLOSEM)
627			u_long s;
628			int max_fd;
629#endif /* !FCLOSEM */
630			if (syslog_file != NULL) {
631				fclose(syslog_file);
632				syslog_file = NULL;
633			}
634#if defined(F_CLOSEM)
635			/*
636			 * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
637			 * by Eric Agar (saves us from doing 32767 system
638			 * calls)
639			 */
640			if (fcntl(0, F_CLOSEM, 0) == -1)
641			    msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");
642#else  /* not F_CLOSEM */
643
644# if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
645			max_fd = sysconf(_SC_OPEN_MAX);
646# else /* HAVE_SYSCONF && _SC_OPEN_MAX */
647			max_fd = getdtablesize();
648# endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
649			for (s = 0; s < max_fd; s++)
650				(void) close((int)s);
651#endif /* not F_CLOSEM */
652			(void) open("/", 0);
653			(void) dup2(0, 1);
654			(void) dup2(0, 2);
655
656			init_logging(progname, 0);
657			/* we lost our logfile (if any) daemonizing */
658			setup_logfile();
659
660#ifdef SYS_DOMAINOS
661			{
662				uid_$t puid;
663				status_$t st;
664
665				proc2_$who_am_i(&puid);
666				proc2_$make_server(&puid, &st);
667			}
668#endif /* SYS_DOMAINOS */
669#if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
670# ifdef HAVE_SETSID
671			if (setsid() == (pid_t)-1)
672				msyslog(LOG_ERR, "ntpd: setsid(): %m");
673# else
674			if (setpgid(0, 0) == -1)
675				msyslog(LOG_ERR, "ntpd: setpgid(): %m");
676# endif
677#else /* HAVE_SETPGID || HAVE_SETSID */
678			{
679# if defined(TIOCNOTTY)
680				int fid;
681
682				fid = open("/dev/tty", 2);
683				if (fid >= 0)
684				{
685					(void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
686					(void) close(fid);
687				}
688# endif /* defined(TIOCNOTTY) */
689# ifdef HAVE_SETPGRP_0
690				(void) setpgrp();
691# else /* HAVE_SETPGRP_0 */
692				(void) setpgrp(0, getpid());
693# endif /* HAVE_SETPGRP_0 */
694			}
695#endif /* HAVE_SETPGID || HAVE_SETSID */
696#ifdef _AIX
697			/* Don't get killed by low-on-memory signal. */
698			sa.sa_handler = catch_danger;
699			sigemptyset(&sa.sa_mask);
700			sa.sa_flags = SA_RESTART;
701
702			(void) sigaction(SIGDANGER, &sa, NULL);
703#endif /* _AIX */
704		}
705#   endif /* not HAVE_DAEMON */
706#  endif /* SYS_WINNT */
707	}
708# endif /* NODETACH */
709#endif /* VMS */
710
711#ifdef SCO5_CLOCK
712	/*
713	 * SCO OpenServer's system clock offers much more precise timekeeping
714	 * on the base CPU than the other CPUs (for multiprocessor systems),
715	 * so we must lock to the base CPU.
716	 */
717	{
718	    int fd = open("/dev/at1", O_RDONLY);
719	    if (fd >= 0) {
720		int zero = 0;
721		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
722		    msyslog(LOG_ERR, "cannot lock to base CPU: %m");
723		close( fd );
724	    } /* else ...
725	       *   If we can't open the device, this probably just isn't
726	       *   a multiprocessor system, so we're A-OK.
727	       */
728	}
729#endif
730
731#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
732# ifdef HAVE_SETRLIMIT
733	/*
734	 * Set the stack limit to something smaller, so that we don't lock a lot
735	 * of unused stack memory.
736	 */
737	{
738	    struct rlimit rl;
739
740	    /* HMS: must make the rlim_cur amount configurable */
741	    if (getrlimit(RLIMIT_STACK, &rl) != -1
742		&& (rl.rlim_cur = 50 * 4096) < rl.rlim_max)
743	    {
744		    if (setrlimit(RLIMIT_STACK, &rl) == -1)
745		    {
746			    msyslog(LOG_ERR,
747				"Cannot adjust stack limit for mlockall: %m");
748		    }
749	    }
750#  ifdef RLIMIT_MEMLOCK
751	    /*
752	     * The default RLIMIT_MEMLOCK is very low on Linux systems.
753	     * Unless we increase this limit malloc calls are likely to
754	     * fail if we drop root privlege.  To be useful the value
755	     * has to be larger than the largest ntpd resident set size.
756	     */
757	    rl.rlim_cur = rl.rlim_max = 32*1024*1024;
758	    if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) {
759		msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
760	    }
761#  endif /* RLIMIT_MEMLOCK */
762	}
763# endif /* HAVE_SETRLIMIT */
764	/*
765	 * lock the process into memory
766	 */
767	if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
768		msyslog(LOG_ERR, "mlockall(): %m");
769#else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
770# ifdef HAVE_PLOCK
771#  ifdef PROCLOCK
772#   ifdef _AIX
773	/*
774	 * set the stack limit for AIX for plock().
775	 * see get_aix_stack() for more info.
776	 */
777	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0)
778	{
779		msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m");
780	}
781#   endif /* _AIX */
782	/*
783	 * lock the process into memory
784	 */
785	if (plock(PROCLOCK) < 0)
786		msyslog(LOG_ERR, "plock(PROCLOCK): %m");
787#  else /* not PROCLOCK */
788#   ifdef TXTLOCK
789	/*
790	 * Lock text into ram
791	 */
792	if (plock(TXTLOCK) < 0)
793		msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
794#   else /* not TXTLOCK */
795	msyslog(LOG_ERR, "plock() - don't know what to lock!");
796#   endif /* not TXTLOCK */
797#  endif /* not PROCLOCK */
798# endif /* HAVE_PLOCK */
799#endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
800
801	/*
802	 * Set up signals we pay attention to locally.
803	 */
804#ifdef SIGDIE1
805	(void) signal_no_reset(SIGDIE1, finish);
806#endif	/* SIGDIE1 */
807#ifdef SIGDIE2
808	(void) signal_no_reset(SIGDIE2, finish);
809#endif	/* SIGDIE2 */
810#ifdef SIGDIE3
811	(void) signal_no_reset(SIGDIE3, finish);
812#endif	/* SIGDIE3 */
813#ifdef SIGDIE4
814	(void) signal_no_reset(SIGDIE4, finish);
815#endif	/* SIGDIE4 */
816
817#ifdef SIGBUS
818	(void) signal_no_reset(SIGBUS, finish);
819#endif /* SIGBUS */
820
821#if !defined(SYS_WINNT) && !defined(VMS)
822# ifdef DEBUG
823	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
824	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
825# else
826	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
827	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
828# endif /* DEBUG */
829#endif /* !SYS_WINNT && !VMS */
830
831	/*
832	 * Set up signals we should never pay attention to.
833	 */
834#if defined SIGPIPE
835	(void) signal_no_reset(SIGPIPE, SIG_IGN);
836#endif	/* SIGPIPE */
837
838	/*
839	 * Call the init_ routines to initialize the data structures.
840	 *
841	 * Exactly what command-line options are we expecting here?
842	 */
843	init_auth();
844	init_util();
845	init_restrict();
846	init_mon();
847	init_timer();
848	init_lib();
849	init_request();
850	init_control();
851	init_peer();
852#ifdef REFCLOCK
853	init_refclock();
854#endif
855	set_process_priority();
856	init_proto();		/* Call at high priority */
857	init_io();
858	init_loopfilter();
859	mon_start(MON_ON);	/* monitor on by default now	  */
860				/* turn off in config if unwanted */
861
862	/*
863	 * Get the configuration.  This is done in a separate module
864	 * since this will definitely be different for the gizmo board.
865	 */
866	getconfig(argc, argv);
867	NLOG(NLOG_SYSINFO) /* 'if' clause for syslog */
868	msyslog(LOG_NOTICE, "%s", Version);
869	report_event(EVNT_SYSRESTART, NULL, NULL);
870	loop_config(LOOP_DRIFTCOMP, old_drift);
871	initializing = 0;
872
873#ifdef HAVE_DROPROOT
874	if( droproot ) {
875		/* Drop super-user privileges and chroot now if the OS supports this */
876
877#ifdef HAVE_LINUX_CAPABILITIES
878		/* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
879		if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
880			msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
881			exit(-1);
882		}
883#else
884		/* we need a user to switch to */
885		if (user == NULL) {
886			msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
887			exit(-1);
888		}
889#endif /* HAVE_LINUX_CAPABILITIES */
890
891		if (user != NULL) {
892			if (isdigit((unsigned char)*user)) {
893				sw_uid = (uid_t)strtoul(user, &endp, 0);
894				if (*endp != '\0')
895					goto getuser;
896
897				if ((pw = getpwuid(sw_uid)) != NULL) {
898					user = strdup(pw->pw_name);
899					if (NULL == user) {
900						msyslog(LOG_ERR, "strdup() failed: %m");
901						exit (-1);
902					}
903					sw_gid = pw->pw_gid;
904				} else {
905					errno = 0;
906					msyslog(LOG_ERR, "Cannot find user ID %s", user);
907					exit (-1);
908				}
909
910			} else {
911getuser:
912				errno = 0;
913				if ((pw = getpwnam(user)) != NULL) {
914					sw_uid = pw->pw_uid;
915					sw_gid = pw->pw_gid;
916				} else {
917					if (errno)
918					    msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
919					else
920					    msyslog(LOG_ERR, "Cannot find user `%s'", user);
921					exit (-1);
922				}
923			}
924		}
925		if (group != NULL) {
926			if (isdigit((unsigned char)*group)) {
927				sw_gid = (gid_t)strtoul(group, &endp, 0);
928				if (*endp != '\0')
929					goto getgroup;
930			} else {
931getgroup:
932				if ((gr = getgrnam(group)) != NULL) {
933					sw_gid = gr->gr_gid;
934				} else {
935					errno = 0;
936					msyslog(LOG_ERR, "Cannot find group `%s'", group);
937					exit (-1);
938				}
939			}
940		}
941
942		if (chrootdir ) {
943			/* make sure cwd is inside the jail: */
944			if (chdir(chrootdir)) {
945				msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
946				exit (-1);
947			}
948			if (chroot(chrootdir)) {
949				msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
950				exit (-1);
951			}
952			if (chdir("/")) {
953				msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
954				exit (-1);
955			}
956		}
957		if (user && initgroups(user, sw_gid)) {
958			msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
959			exit (-1);
960		}
961		if (group && setgid(sw_gid)) {
962			msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
963			exit (-1);
964		}
965		if (group && setegid(sw_gid)) {
966			msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
967			exit (-1);
968		}
969		if (user && setuid(sw_uid)) {
970			msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
971			exit (-1);
972		}
973		if (user && seteuid(sw_uid)) {
974			msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
975			exit (-1);
976		}
977
978#ifndef HAVE_LINUX_CAPABILITIES
979		/*
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
983		 */
984		disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
985#endif
986
987		if (disable_dynamic_updates && interface_interval) {
988			interface_interval = 0;
989			msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking");
990		}
991
992#ifdef HAVE_LINUX_CAPABILITIES
993		do {
994			/*
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.
998			 */
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);
1006			}
1007			if( cap_set_proc( caps ) == -1 ) {
1008				msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" );
1009				exit(-1);
1010			}
1011			cap_free( caps );
1012		} while(0);
1013#endif /* HAVE_LINUX_CAPABILITIES */
1014
1015	}    /* if( droproot ) */
1016#endif /* HAVE_DROPROOT */
1017
1018	/*
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.
1025	 */
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.
1032	 */
1033#if defined(HAVE_IO_COMPLETION_PORT)
1034
1035	for (;;) {
1036		GetReceivedBuffers();
1037#else /* normal I/O */
1038
1039	BLOCK_IO_AND_ALARM();
1040	was_alarmed = 0;
1041	for (;;)
1042	{
1043# if !defined(HAVE_SIGNALED_IO)
1044		extern fd_set activefds;
1045		extern int maxactivefd;
1046
1047		fd_set rdfdes;
1048		int nfound;
1049# endif
1050
1051		if (alarm_flag)		/* alarmed? */
1052		{
1053			was_alarmed = 1;
1054			alarm_flag = 0;
1055		}
1056
1057		if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE)
1058		{
1059			/*
1060			 * Nothing to do.  Wait for something.
1061			 */
1062# ifndef HAVE_SIGNALED_IO
1063			rdfdes = activefds;
1064#  if defined(VMS) || defined(SYS_VXWORKS)
1065			/* make select() wake up after one second */
1066			{
1067				struct timeval t1;
1068
1069				t1.tv_sec = 1; t1.tv_usec = 0;
1070				nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
1071						(fd_set *)0, &t1);
1072			}
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)
1078			{
1079				l_fp ts;
1080
1081				get_systime(&ts);
1082
1083				(void)input_handler(&ts);
1084			}
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 */
1092
1093			wait_for_signal();
1094# endif /* HAVE_SIGNALED_IO */
1095			if (alarm_flag)		/* alarmed? */
1096			{
1097				was_alarmed = 1;
1098				alarm_flag = 0;
1099			}
1100		}
1101
1102		if (was_alarmed)
1103		{
1104			UNBLOCK_IO_AND_ALARM();
1105			/*
1106			 * Out here, signals are unblocked.  Call timer routine
1107			 * to process expiry.
1108			 */
1109			timer();
1110			was_alarmed = 0;
1111			BLOCK_IO_AND_ALARM();
1112		}
1113
1114#endif /* ! HAVE_IO_COMPLETION_PORT */
1115
1116#ifdef DEBUG_TIMING
1117		{
1118			l_fp pts;
1119			l_fp tsa, tsb;
1120			int bufcount = 0;
1121
1122			get_systime(&pts);
1123			tsa = pts;
1124#endif
1125			rbuf = get_full_recv_buffer();
1126			while (rbuf != NULL)
1127			{
1128				if (alarm_flag)
1129				{
1130					was_alarmed = 1;
1131					alarm_flag = 0;
1132				}
1133				UNBLOCK_IO_AND_ALARM();
1134
1135				if (was_alarmed)
1136				{	/* avoid timer starvation during lengthy I/O handling */
1137					timer();
1138					was_alarmed = 0;
1139				}
1140
1141				/*
1142				 * Call the data procedure to handle each received
1143				 * packet.
1144				 */
1145				if (rbuf->receiver != NULL)	/* This should always be true */
1146				{
1147#ifdef DEBUG_TIMING
1148					l_fp dts = pts;
1149
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();
1159				}
1160
1161				BLOCK_IO_AND_ALARM();
1162				freerecvbuf(rbuf);
1163				rbuf = get_full_recv_buffer();
1164			}
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)));
1171			}
1172		}
1173#endif
1174
1175		/*
1176		 * Go around again
1177		 */
1178
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.");
1189				}
1190			} else {
1191				msyslog(LOG_INFO, "mDNS service registered.");
1192				mdnsreg = 0;
1193			}
1194		}
1195#endif /* HAVE_DNSREGISTRATION */
1196
1197	}
1198	UNBLOCK_IO_AND_ALARM();
1199	return 1;
1200}
1201
1202
1203#ifdef SIGDIE2
1204/*
1205 * finish - exit gracefully
1206 */
1207static RETSIGTYPE
1208finish(
1209	int sig
1210	)
1211{
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;
1225
1226	default:
1227		exit(0);
1228	}
1229}
1230#endif	/* SIGDIE2 */
1231
1232
1233/* assertion_failed
1234 * Redirect trap messages from ISC libraries to syslog.
1235 * This code was cloned and simplified from BIND.
1236 */
1237
1238/*
1239 * assertion_failed - Handle assertion failures.
1240 */
1241
1242static void
1243assertion_failed(const char *file, int line, isc_assertiontype_t type,
1244                 const char *cond)
1245{
1246	isc_assertion_setcallback(NULL);    /* Avoid recursion */
1247
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)");
1251
1252	abort();
1253}
1254
1255/*
1256 * library_fatal_error - Handle fatal errors from our libraries.
1257 */
1258
1259static void
1260library_fatal_error(const char *file, int line, const char *format,
1261                    va_list args)
1262{
1263	char errbuf[256];
1264
1265	isc_error_setfatal(NULL);  /* Avoid recursion */
1266
1267	msyslog(LOG_ERR, "%s:%d: fatal error:", file, line);
1268	vsnprintf(errbuf, sizeof(errbuf), format, args);
1269	msyslog(LOG_ERR, "%s", errbuf);
1270	msyslog(LOG_ERR, "exiting (due to fatal error in library)");
1271
1272	abort();
1273}
1274
1275/*
1276 * library_unexpected_error - Handle non fatal errors from our libraries.
1277 */
1278#define MAX_UNEXPECTED_ERRORS 100
1279int unexpected_error_cnt = 0;
1280static void
1281library_unexpected_error(const char *file, int line, const char *format,
1282                         va_list args)
1283{
1284	char errbuf[256];
1285
1286	if (unexpected_error_cnt >= MAX_UNEXPECTED_ERRORS)
1287		return;	/* avoid clutter in log */
1288
1289	msyslog(LOG_ERR, "%s:%d: unexpected error:", file, line);
1290	vsnprintf(errbuf, sizeof(errbuf), format, args);
1291	msyslog(LOG_ERR, "%s", errbuf);
1292
1293	if (++unexpected_error_cnt == MAX_UNEXPECTED_ERRORS)
1294	{
1295		msyslog(LOG_ERR, "Too many errors.  Shutting up.");
1296	}
1297
1298}
1299
1300
1301#ifdef DEBUG
1302#ifndef SYS_WINNT
1303/*
1304 * moredebug - increase debugging verbosity
1305 */
1306static RETSIGTYPE
1307moredebug(
1308	int sig
1309	)
1310{
1311	int saved_errno = errno;
1312
1313	if (debug < 255)
1314	{
1315		debug++;
1316		msyslog(LOG_DEBUG, "debug raised to %d", debug);
1317	}
1318	errno = saved_errno;
1319}
1320
1321/*
1322 * lessdebug - decrease debugging verbosity
1323 */
1324static RETSIGTYPE
1325lessdebug(
1326	int sig
1327	)
1328{
1329	int saved_errno = errno;
1330
1331	if (debug > 0)
1332	{
1333		debug--;
1334		msyslog(LOG_DEBUG, "debug lowered to %d", debug);
1335	}
1336	errno = saved_errno;
1337}
1338#endif
1339#else /* not DEBUG */
1340#ifndef SYS_WINNT
1341/*
1342 * no_debug - We don't do the debug here.
1343 */
1344static RETSIGTYPE
1345no_debug(
1346	int sig
1347	)
1348{
1349	int saved_errno = errno;
1350
1351	msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
1352	errno = saved_errno;
1353}
1354#endif  /* not SYS_WINNT */
1355#endif	/* not DEBUG */
1356