]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ntp/ntpd/ntpd.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ntp / ntpd / ntpd.c
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 #ifdef SIM
16 # include "ntpsim.h"
17 # include "ntpdsim-opts.h"
18 #else
19 # include "ntpd-opts.h"
20 #endif
21
22 #ifdef HAVE_UNISTD_H
23 # include <unistd.h>
24 #endif
25 #ifdef HAVE_SYS_STAT_H
26 # include <sys/stat.h>
27 #endif
28 #include <stdio.h>
29 #if !defined(VMS)       /*wjm*/
30 # ifdef HAVE_SYS_PARAM_H
31 #  include <sys/param.h>
32 # endif
33 #endif /* VMS */
34 #ifdef HAVE_SYS_SIGNAL_H
35 # include <sys/signal.h>
36 #else
37 # include <signal.h>
38 #endif
39 #ifdef HAVE_SYS_IOCTL_H
40 # include <sys/ioctl.h>
41 #endif /* HAVE_SYS_IOCTL_H */
42 #ifdef HAVE_SYS_RESOURCE_H
43 # include <sys/resource.h>
44 #endif /* HAVE_SYS_RESOURCE_H */
45 #if defined(HAVE_RTPRIO)
46 # ifdef HAVE_SYS_RESOURCE_H
47 #  include <sys/resource.h>
48 # endif
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 #include "recvbuff.h"  
82 #include "ntp_cmdargs.h"  
83
84 #if 0                           /* HMS: I don't think we need this. 961223 */
85 #ifdef LOCK_PROCESS
86 # ifdef SYS_SOLARIS
87 #  include <sys/mman.h>
88 # else
89 #  include <sys/lock.h>
90 # endif
91 #endif
92 #endif
93
94 #ifdef _AIX
95 # include <ulimit.h>
96 #endif /* _AIX */
97
98 #ifdef SCO5_CLOCK
99 # include <sys/ci/ciioctl.h>
100 #endif
101
102 #ifdef HAVE_DROPROOT
103 # include <ctype.h>
104 # include <grp.h>
105 # include <pwd.h>
106 #ifdef HAVE_LINUX_CAPABILITIES
107 # include <sys/capability.h>
108 # include <sys/prctl.h>
109 #endif
110 #endif
111
112 /*
113  * Signals we catch for debugging.      If not debugging we ignore them.
114  */
115 #define MOREDEBUGSIG    SIGUSR1
116 #define LESSDEBUGSIG    SIGUSR2
117
118 /*
119  * Signals which terminate us gracefully.
120  */
121 #ifndef SYS_WINNT
122 # define SIGDIE1        SIGHUP
123 # define SIGDIE3        SIGQUIT
124 # define SIGDIE2        SIGINT
125 # define SIGDIE4        SIGTERM
126 #endif /* SYS_WINNT */
127
128 #ifdef HAVE_DNSREGISTRATION
129 #include <dns_sd.h>
130 DNSServiceRef mdns;
131 #endif
132
133 /*
134  * Scheduling priority we run at
135  */
136 #define NTPD_PRIO       (-12)
137
138 int priority_done = 2;          /* 0 - Set priority */
139                                 /* 1 - priority is OK where it is */
140                                 /* 2 - Don't set priority */
141                                 /* 1 and 2 are pretty much the same */
142
143 #ifdef DEBUG
144 /*
145  * Debugging flag
146  */
147 volatile int debug = 0;         /* No debugging by default */
148 #endif
149
150 int     listen_to_virtual_ips = 1;
151 const char *specific_interface = NULL;        /* interface name or IP address to bind to */
152
153 /*
154  * No-fork flag.  If set, we do not become a background daemon.
155  */
156 int nofork = 0;                 /* Fork by default */
157
158 #ifdef HAVE_DROPROOT
159 int droproot = 0;
160 char *user = NULL;              /* User to switch to */
161 char *group = NULL;             /* group to switch to */
162 char *chrootdir = NULL;         /* directory to chroot to */
163 int sw_uid;
164 int sw_gid;
165 char *endp;  
166 struct group *gr;
167 struct passwd *pw; 
168 #endif /* HAVE_DROPROOT */
169
170 /*
171  * Initializing flag.  All async routines watch this and only do their
172  * thing when it is clear.
173  */
174 int initializing;
175
176 /*
177  * Version declaration
178  */
179 extern const char *Version;
180
181 char const *progname;
182
183 int was_alarmed;
184
185 #ifdef DECL_SYSCALL
186 /*
187  * We put this here, since the argument profile is syscall-specific
188  */
189 extern int syscall      P((int, ...));
190 #endif /* DECL_SYSCALL */
191
192
193 #ifdef  SIGDIE2
194 static  RETSIGTYPE      finish          P((int));
195 #endif  /* SIGDIE2 */
196
197 #ifdef  DEBUG
198 #ifndef SYS_WINNT
199 static  RETSIGTYPE      moredebug       P((int));
200 static  RETSIGTYPE      lessdebug       P((int));
201 #endif
202 #else /* not DEBUG */
203 static  RETSIGTYPE      no_debug        P((int));
204 #endif  /* not DEBUG */
205
206 int             ntpdmain                P((int, char **));
207 static void     set_process_priority    P((void));
208 static void     init_logging            P((char const *));
209 static void     setup_logfile           P((void));
210
211 /*
212  * Initialize the logging
213  */
214 void
215 init_logging(char const *name)
216 {
217         const char *cp;
218
219         /*
220          * Logging.  This may actually work on the gizmo board.  Find a name
221          * to log with by using the basename
222          */
223         cp = strrchr(name, '/');
224         if (cp == 0)
225                 cp = name;
226         else
227                 cp++;
228
229 #if !defined(VMS)
230
231 # ifndef LOG_DAEMON
232         openlog(cp, LOG_PID);
233 # else /* LOG_DAEMON */
234
235 #  ifndef LOG_NTP
236 #       define  LOG_NTP LOG_DAEMON
237 #  endif
238         openlog(cp, LOG_PID | LOG_NDELAY, LOG_NTP);
239 #  ifdef DEBUG
240         if (debug)
241                 setlogmask(LOG_UPTO(LOG_DEBUG));
242         else
243 #  endif /* DEBUG */
244                 setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */
245 # endif /* LOG_DAEMON */
246 #endif  /* !SYS_WINNT && !VMS */
247
248         NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */
249                 msyslog(LOG_NOTICE, "%s", Version);
250 }
251
252
253 /*
254  * See if we should redirect the logfile
255  */
256
257 void
258 setup_logfile(
259         void
260         )
261 {
262         if (HAVE_OPT( LOGFILE )) {
263                 const char *my_optarg = OPT_ARG( LOGFILE );
264                 FILE *new_file;
265
266                 if(strcmp(my_optarg, "stderr") == 0)
267                         new_file = stderr;
268                 else if(strcmp(my_optarg, "stdout") == 0)
269                         new_file = stdout;
270                 else
271                         new_file = fopen(my_optarg, "a");
272                 if (new_file != NULL) {
273                         NLOG(NLOG_SYSINFO)
274                                 msyslog(LOG_NOTICE, "logging to file %s", my_optarg);
275                         if (syslog_file != NULL &&
276                                 fileno(syslog_file) != fileno(new_file))
277                                 (void)fclose(syslog_file);
278
279                         syslog_file = new_file;
280                         syslogit = 0;
281                 }
282                 else
283                         msyslog(LOG_ERR,
284                                 "Cannot open log file %s",
285                                 my_optarg);
286         }
287 }
288
289 #ifdef SIM
290 int
291 main(
292         int argc,
293         char *argv[]
294         )
295 {
296         return ntpsim(argc, argv);
297 }
298 #else /* SIM */
299 #ifdef NO_MAIN_ALLOWED
300 CALL(ntpd,"ntpd",ntpdmain);
301 #else
302 #ifndef SYS_WINNT
303 int
304 main(
305         int argc,
306         char *argv[]
307         )
308 {
309         return ntpdmain(argc, argv);
310 }
311 #endif /* SYS_WINNT */
312 #endif /* NO_MAIN_ALLOWED */
313 #endif /* SIM */
314
315 #ifdef _AIX
316 /*
317  * OK. AIX is different than solaris in how it implements plock().
318  * If you do NOT adjust the stack limit, you will get the MAXIMUM
319  * stack size allocated and PINNED with you program. To check the 
320  * value, use ulimit -a. 
321  *
322  * To fix this, we create an automatic variable and set our stack limit 
323  * to that PLUS 32KB of extra space (we need some headroom).
324  *
325  * This subroutine gets the stack address.
326  *
327  * Grover Davidson and Matt Ladendorf
328  *
329  */
330 static char *
331 get_aix_stack(void)
332 {
333         char ch;
334         return (&ch);
335 }
336
337 /*
338  * Signal handler for SIGDANGER.
339  */
340 static void
341 catch_danger(int signo)
342 {
343         msyslog(LOG_INFO, "ntpd: setpgid(): %m");
344         /* Make the system believe we'll free something, but don't do it! */
345         return;
346 }
347 #endif /* _AIX */
348
349 /*
350  * Set the process priority
351  */
352 static void
353 set_process_priority(void)
354 {
355
356 #ifdef DEBUG
357         if (debug > 1)
358                 msyslog(LOG_DEBUG, "set_process_priority: %s: priority_done is <%d>",
359                         ((priority_done)
360                          ? "Leave priority alone"
361                          : "Attempt to set priority"
362                                 ),
363                         priority_done);
364 #endif /* DEBUG */
365
366 #ifdef SYS_WINNT
367         priority_done += NT_set_process_priority();
368 #endif
369
370 #if defined(HAVE_SCHED_SETSCHEDULER)
371         if (!priority_done) {
372                 extern int config_priority_override, config_priority;
373                 int pmax, pmin;
374                 struct sched_param sched;
375
376                 pmax = sched_get_priority_max(SCHED_FIFO);
377                 sched.sched_priority = pmax;
378                 if ( config_priority_override ) {
379                         pmin = sched_get_priority_min(SCHED_FIFO);
380                         if ( config_priority > pmax )
381                                 sched.sched_priority = pmax;
382                         else if ( config_priority < pmin )
383                                 sched.sched_priority = pmin;
384                         else
385                                 sched.sched_priority = config_priority;
386                 }
387                 if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 )
388                         msyslog(LOG_ERR, "sched_setscheduler(): %m");
389                 else
390                         ++priority_done;
391         }
392 #endif /* HAVE_SCHED_SETSCHEDULER */
393 #if defined(HAVE_RTPRIO)
394 # ifdef RTP_SET
395         if (!priority_done) {
396                 struct rtprio srtp;
397
398                 srtp.type = RTP_PRIO_REALTIME;  /* was: RTP_PRIO_NORMAL */
399                 srtp.prio = 0;          /* 0 (hi) -> RTP_PRIO_MAX (31,lo) */
400
401                 if (rtprio(RTP_SET, getpid(), &srtp) < 0)
402                         msyslog(LOG_ERR, "rtprio() error: %m");
403                 else
404                         ++priority_done;
405         }
406 # else /* not RTP_SET */
407         if (!priority_done) {
408                 if (rtprio(0, 120) < 0)
409                         msyslog(LOG_ERR, "rtprio() error: %m");
410                 else
411                         ++priority_done;
412         }
413 # endif /* not RTP_SET */
414 #endif  /* HAVE_RTPRIO */
415 #if defined(NTPD_PRIO) && NTPD_PRIO != 0
416 # ifdef HAVE_ATT_NICE
417         if (!priority_done) {
418                 errno = 0;
419                 if (-1 == nice (NTPD_PRIO) && errno != 0)
420                         msyslog(LOG_ERR, "nice() error: %m");
421                 else
422                         ++priority_done;
423         }
424 # endif /* HAVE_ATT_NICE */
425 # ifdef HAVE_BSD_NICE
426         if (!priority_done) {
427                 if (-1 == setpriority(PRIO_PROCESS, 0, NTPD_PRIO))
428                         msyslog(LOG_ERR, "setpriority() error: %m");
429                 else
430                         ++priority_done;
431         }
432 # endif /* HAVE_BSD_NICE */
433 #endif /* NTPD_PRIO && NTPD_PRIO != 0 */
434         if (!priority_done)
435                 msyslog(LOG_ERR, "set_process_priority: No way found to improve our priority");
436 }
437
438
439 /*
440  * Main program.  Initialize us, disconnect us from the tty if necessary,
441  * and loop waiting for I/O and/or timer expiries.
442  */
443 int
444 ntpdmain(
445         int argc,
446         char *argv[]
447         )
448 {
449         l_fp now;
450         struct recvbuf *rbuf;
451 #ifdef _AIX                     /* HMS: ifdef SIGDANGER? */
452         struct sigaction sa;
453 #endif
454
455         progname = argv[0];
456
457         initializing = 1;               /* mark that we are initializing */
458
459         {
460                 int optct = optionProcess(
461 #ifdef SIM
462                                           &ntpdsimOptions
463 #else
464                                           &ntpdOptions
465 #endif
466                                           , argc, argv);
467                 argc -= optct;
468                 argv += optct;
469         }
470
471         /* HMS: is this lame? Should we process -l first? */
472
473         init_logging(progname);         /* Open the log file */
474
475 #ifdef HAVE_UMASK
476         {
477                 mode_t uv;
478
479                 uv = umask(0);
480                 if(uv)
481                         (void) umask(uv);
482                 else
483                         (void) umask(022);
484         }
485 #endif
486
487 #if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
488         {
489                 uid_t uid;
490
491                 uid = getuid();
492                 if (uid)
493                 {
494                         msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid);
495                         printf("must be run as root, not uid %ld", (long)uid);
496                         exit(1);
497                 }
498         }
499 #endif
500
501 #ifdef OPENSSL
502         if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) {
503                 msyslog(LOG_ERR,
504                     "ntpd: OpenSSL version mismatch. Built against %lx, you have %lx\n",
505                     OPENSSL_VERSION_NUMBER, SSLeay());
506                 exit(1);
507         }
508 #endif
509
510         /* getstartup(argc, argv); / * startup configuration, may set debug */
511
512 #ifdef DEBUG
513         debug = DESC(DEBUG_LEVEL).optOccCt;
514         if (debug)
515             printf("%s\n", Version);
516 #endif
517
518 /*
519  * Enable the Multi-Media Timer for Windows?
520  */
521 #ifdef SYS_WINNT
522         if (HAVE_OPT( MODIFYMMTIMER ))
523                 set_mm_timer(MM_TIMER_HIRES);
524 #endif
525
526         if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT ))
527                 nofork = 1;
528
529         if (HAVE_OPT( NOVIRTUALIPS ))
530                 listen_to_virtual_ips = 0;
531
532         if (HAVE_OPT( INTERFACE )) {
533 #if 0
534                 int     ifacect = STACKCT_OPT( INTERFACE );
535                 char**  ifaces  = STACKLST_OPT( INTERFACE );
536
537                 /* malloc space for the array of names */
538                 while (ifacect-- > 0) {
539                         next_iface = *ifaces++;
540                 }
541 #else
542                 specific_interface = OPT_ARG( INTERFACE );
543 #endif
544         }
545
546         if (HAVE_OPT( NICE ))
547                 priority_done = 0;
548
549 #if defined(HAVE_SCHED_SETSCHEDULER)
550         if (HAVE_OPT( PRIORITY )) {
551                 config_priority = OPT_VALUE_PRIORITY;
552                 config_priority_override = 1;
553                 priority_done = 0;
554         }
555 #endif
556
557 #ifdef SYS_WINNT
558         /*
559          * Initialize the time structures and variables
560          */
561         init_winnt_time();
562 #endif
563
564         setup_logfile();
565
566         /*
567          * Initialize random generator and public key pair
568          */
569         get_systime(&now);
570
571         ntp_srandom((int)(now.l_i * now.l_uf));
572
573 #ifdef HAVE_DNSREGISTRATION
574         /* HMS: does this have to happen this early? */
575         msyslog(LOG_INFO, "Attemping to register mDNS");
576         if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
577                 msyslog(LOG_ERR, "Unable to register mDNS");
578         }
579 #endif
580
581 #if !defined(VMS)
582 # ifndef NODETACH
583         /*
584          * Detach us from the terminal.  May need an #ifndef GIZMO.
585          */
586         if (
587 #  ifdef DEBUG
588             !debug &&
589 #  endif /* DEBUG */
590             !nofork)
591         {
592 #  ifndef SYS_WINNT
593 #   ifdef HAVE_DAEMON
594                 daemon(0, 0);
595 #   else /* not HAVE_DAEMON */
596                 if (fork())     /* HMS: What about a -1? */
597                         exit(0);
598
599                 {
600 #if !defined(F_CLOSEM)
601                         u_long s;
602                         int max_fd;
603 #endif /* not F_CLOSEM */
604
605 #if defined(F_CLOSEM)
606                         /*
607                          * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
608                          * by Eric Agar (saves us from doing 32767 system
609                          * calls)
610                          */
611                         if (fcntl(0, F_CLOSEM, 0) == -1)
612                             msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");
613 #else  /* not F_CLOSEM */
614
615 # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
616                         max_fd = sysconf(_SC_OPEN_MAX);
617 # else /* HAVE_SYSCONF && _SC_OPEN_MAX */
618                         max_fd = getdtablesize();
619 # endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
620                         for (s = 0; s < max_fd; s++)
621                                 (void) close((int)s);
622 #endif /* not F_CLOSEM */
623                         (void) open("/", 0);
624                         (void) dup2(0, 1);
625                         (void) dup2(0, 2);
626 #ifdef SYS_DOMAINOS
627                         {
628                                 uid_$t puid;
629                                 status_$t st;
630
631                                 proc2_$who_am_i(&puid);
632                                 proc2_$make_server(&puid, &st);
633                         }
634 #endif /* SYS_DOMAINOS */
635 #if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
636 # ifdef HAVE_SETSID
637                         if (setsid() == (pid_t)-1)
638                                 msyslog(LOG_ERR, "ntpd: setsid(): %m");
639 # else
640                         if (setpgid(0, 0) == -1)
641                                 msyslog(LOG_ERR, "ntpd: setpgid(): %m");
642 # endif
643 #else /* HAVE_SETPGID || HAVE_SETSID */
644                         {
645 # if defined(TIOCNOTTY)
646                                 int fid;
647
648                                 fid = open("/dev/tty", 2);
649                                 if (fid >= 0)
650                                 {
651                                         (void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
652                                         (void) close(fid);
653                                 }
654 # endif /* defined(TIOCNOTTY) */
655 # ifdef HAVE_SETPGRP_0
656                                 (void) setpgrp();
657 # else /* HAVE_SETPGRP_0 */
658                                 (void) setpgrp(0, getpid());
659 # endif /* HAVE_SETPGRP_0 */
660                         }
661 #endif /* HAVE_SETPGID || HAVE_SETSID */
662 #ifdef _AIX
663                         /* Don't get killed by low-on-memory signal. */
664                         sa.sa_handler = catch_danger;
665                         sigemptyset(&sa.sa_mask);
666                         sa.sa_flags = SA_RESTART;
667
668                         (void) sigaction(SIGDANGER, &sa, NULL);
669 #endif /* _AIX */
670                 }
671 #   endif /* not HAVE_DAEMON */
672 #  endif /* SYS_WINNT */
673         }
674 # endif /* NODETACH */
675 #endif /* VMS */
676
677         setup_logfile();        /* We lost any redirect when we daemonized */
678
679 #ifdef SCO5_CLOCK
680         /*
681          * SCO OpenServer's system clock offers much more precise timekeeping
682          * on the base CPU than the other CPUs (for multiprocessor systems),
683          * so we must lock to the base CPU.
684          */
685         {
686             int fd = open("/dev/at1", O_RDONLY);
687             if (fd >= 0) {
688                 int zero = 0;
689                 if (ioctl(fd, ACPU_LOCK, &zero) < 0)
690                     msyslog(LOG_ERR, "cannot lock to base CPU: %m");
691                 close( fd );
692             } /* else ...
693                *   If we can't open the device, this probably just isn't
694                *   a multiprocessor system, so we're A-OK.
695                */
696         }
697 #endif
698
699 #if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
700 # ifdef HAVE_SETRLIMIT
701         /*
702          * Set the stack limit to something smaller, so that we don't lock a lot
703          * of unused stack memory.
704          */
705         {
706             struct rlimit rl;
707
708             /* HMS: must make the rlim_cur amount configurable */
709             if (getrlimit(RLIMIT_STACK, &rl) != -1
710                 && (rl.rlim_cur = 50 * 4096) < rl.rlim_max)
711             {
712                     if (setrlimit(RLIMIT_STACK, &rl) == -1)
713                     {
714                             msyslog(LOG_ERR,
715                                 "Cannot adjust stack limit for mlockall: %m");
716                     }
717             }
718 #  ifdef RLIMIT_MEMLOCK
719             /*
720              * The default RLIMIT_MEMLOCK is very low on Linux systems.
721              * Unless we increase this limit malloc calls are likely to
722              * fail if we drop root privlege.  To be useful the value
723              * has to be larger than the largest ntpd resident set size.
724              */
725             rl.rlim_cur = rl.rlim_max = 32*1024*1024;
726             if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) {
727                 msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
728             }
729 #  endif /* RLIMIT_MEMLOCK */
730         }
731 # endif /* HAVE_SETRLIMIT */
732         /*
733          * lock the process into memory
734          */
735         if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
736                 msyslog(LOG_ERR, "mlockall(): %m");
737 #else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
738 # ifdef HAVE_PLOCK
739 #  ifdef PROCLOCK
740 #   ifdef _AIX
741         /* 
742          * set the stack limit for AIX for plock().
743          * see get_aix_stack() for more info.
744          */
745         if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0)
746         {
747                 msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m");
748         }
749 #   endif /* _AIX */
750         /*
751          * lock the process into memory
752          */
753         if (plock(PROCLOCK) < 0)
754                 msyslog(LOG_ERR, "plock(PROCLOCK): %m");
755 #  else /* not PROCLOCK */
756 #   ifdef TXTLOCK
757         /*
758          * Lock text into ram
759          */
760         if (plock(TXTLOCK) < 0)
761                 msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
762 #   else /* not TXTLOCK */
763         msyslog(LOG_ERR, "plock() - don't know what to lock!");
764 #   endif /* not TXTLOCK */
765 #  endif /* not PROCLOCK */
766 # endif /* HAVE_PLOCK */
767 #endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
768
769         /*
770          * Set up signals we pay attention to locally.
771          */
772 #ifdef SIGDIE1
773         (void) signal_no_reset(SIGDIE1, finish);
774 #endif  /* SIGDIE1 */
775 #ifdef SIGDIE2
776         (void) signal_no_reset(SIGDIE2, finish);
777 #endif  /* SIGDIE2 */
778 #ifdef SIGDIE3
779         (void) signal_no_reset(SIGDIE3, finish);
780 #endif  /* SIGDIE3 */
781 #ifdef SIGDIE4
782         (void) signal_no_reset(SIGDIE4, finish);
783 #endif  /* SIGDIE4 */
784
785 #ifdef SIGBUS
786         (void) signal_no_reset(SIGBUS, finish);
787 #endif /* SIGBUS */
788
789 #if !defined(SYS_WINNT) && !defined(VMS)
790 # ifdef DEBUG
791         (void) signal_no_reset(MOREDEBUGSIG, moredebug);
792         (void) signal_no_reset(LESSDEBUGSIG, lessdebug);
793 # else
794         (void) signal_no_reset(MOREDEBUGSIG, no_debug);
795         (void) signal_no_reset(LESSDEBUGSIG, no_debug);
796 # endif /* DEBUG */
797 #endif /* !SYS_WINNT && !VMS */
798
799         /*
800          * Set up signals we should never pay attention to.
801          */
802 #if defined SIGPIPE
803         (void) signal_no_reset(SIGPIPE, SIG_IGN);
804 #endif  /* SIGPIPE */
805
806         /*
807          * Call the init_ routines to initialize the data structures.
808          *
809          * Exactly what command-line options are we expecting here?
810          */
811         init_auth();
812         init_util();
813         init_restrict();
814         init_mon();
815         init_timer();
816         init_lib();
817         init_request();
818         init_control();
819         init_peer();
820 #ifdef REFCLOCK
821         init_refclock();
822 #endif
823         set_process_priority();
824         init_proto();           /* Call at high priority */
825         init_io();
826         init_loopfilter();
827         mon_start(MON_ON);      /* monitor on by default now      */
828                                 /* turn off in config if unwanted */
829
830         /*
831          * Get the configuration.  This is done in a separate module
832          * since this will definitely be different for the gizmo board.
833          */
834
835         getconfig(argc, argv);
836
837         loop_config(LOOP_DRIFTCOMP, old_drift / 1e6);
838 #ifdef OPENSSL
839         crypto_setup();
840 #endif /* OPENSSL */
841         initializing = 0;
842
843 #ifdef HAVE_DROPROOT
844         if( droproot ) {
845                 /* Drop super-user privileges and chroot now if the OS supports this */
846
847 #ifdef HAVE_LINUX_CAPABILITIES
848                 /* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
849                 if( prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1 ) {
850                         msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
851                         exit(-1);
852                 }
853 #else
854                 /* we need a user to switch to */
855                 if( user == NULL ) {
856                         msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
857                         exit(-1);
858                 }
859 #endif /* HAVE_LINUX_CAPABILITIES */
860         
861                 if (user != NULL) {
862                         if (isdigit((unsigned char)*user)) {
863                                 sw_uid = (uid_t)strtoul(user, &endp, 0);
864                                 if (*endp != '\0') 
865                                         goto getuser;
866                         } else {
867 getuser:        
868                                 if ((pw = getpwnam(user)) != NULL) {
869                                         sw_uid = pw->pw_uid;
870                                 } else {
871                                         errno = 0;
872                                         msyslog(LOG_ERR, "Cannot find user `%s'", user);
873                                         exit (-1);
874                                 }
875                         }
876                 }
877                 if (group != NULL) {
878                         if (isdigit((unsigned char)*group)) {
879                                 sw_gid = (gid_t)strtoul(group, &endp, 0);
880                                 if (*endp != '\0') 
881                                         goto getgroup;
882                         } else {
883 getgroup:       
884                                 if ((gr = getgrnam(group)) != NULL) {
885                                         sw_gid = gr->gr_gid;
886                                 } else {
887                                         errno = 0;
888                                         msyslog(LOG_ERR, "Cannot find group `%s'", group);
889                                         exit (-1);
890                                 }
891                         }
892                 }
893                 
894                 if( chrootdir ) {
895                         /* make sure cwd is inside the jail: */
896                         if( chdir(chrootdir) ) {
897                                 msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
898                                 exit (-1);
899                         }
900                         if( chroot(chrootdir) ) {
901                                 msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
902                                 exit (-1);
903                         }
904                 }
905                 if (group && setgid(sw_gid)) {
906                         msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
907                         exit (-1);
908                 }
909                 if (group && setegid(sw_gid)) {
910                         msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
911                         exit (-1);
912                 }
913                 if (user && setuid(sw_uid)) {
914                         msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
915                         exit (-1);
916                 }
917                 if (user && seteuid(sw_uid)) {
918                         msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
919                         exit (-1);
920                 }
921         
922 #ifndef HAVE_LINUX_CAPABILITIES
923                 /*
924                  * for now assume that the privilege to bind to privileged ports
925                  * is associated with running with uid 0 - should be refined on
926                  * ports that allow binding to NTP_PORT with uid != 0
927                  */
928                 disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
929 #endif
930
931                 if (disable_dynamic_updates && interface_interval) {
932                         interface_interval = 0;
933                         msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking");
934                 }
935
936 #ifdef HAVE_LINUX_CAPABILITIES
937                 do {
938                         /*
939                          *  We may be running under non-root uid now, but we still hold full root privileges!
940                          *  We drop all of them, except for the crucial one or two: cap_sys_time and
941                          *  cap_net_bind_service if doing dynamic interface tracking.
942                          */
943                         cap_t caps;
944                         char *captext = interface_interval ?
945                                 "cap_sys_time,cap_net_bind_service=ipe" :
946                                 "cap_sys_time=ipe";
947                         if( ! ( caps = cap_from_text( captext ) ) ) {
948                                 msyslog( LOG_ERR, "cap_from_text() failed: %m" );
949                                 exit(-1);
950                         }
951                         if( cap_set_proc( caps ) == -1 ) {
952                                 msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" );
953                                 exit(-1);
954                         }
955                         cap_free( caps );
956                 } while(0);
957 #endif /* HAVE_LINUX_CAPABILITIES */
958
959         }    /* if( droproot ) */
960 #endif /* HAVE_DROPROOT */
961         
962         /*
963          * Report that we're up to any trappers
964          */
965         report_event(EVNT_SYSRESTART, (struct peer *)0);
966
967         /*
968          * Use select() on all on all input fd's for unlimited
969          * time.  select() will terminate on SIGALARM or on the
970          * reception of input.  Using select() means we can't do
971          * robust signal handling and we get a potential race
972          * between checking for alarms and doing the select().
973          * Mostly harmless, I think.
974          */
975         /* On VMS, I suspect that select() can't be interrupted
976          * by a "signal" either, so I take the easy way out and
977          * have select() time out after one second.
978          * System clock updates really aren't time-critical,
979          * and - lacking a hardware reference clock - I have
980          * yet to learn about anything else that is.
981          */
982 #if defined(HAVE_IO_COMPLETION_PORT)
983
984         for (;;) {
985                 GetReceivedBuffers();
986 #else /* normal I/O */
987
988         BLOCK_IO_AND_ALARM();
989         was_alarmed = 0;
990         for (;;)
991         {
992 # if !defined(HAVE_SIGNALED_IO) 
993                 extern fd_set activefds;
994                 extern int maxactivefd;
995
996                 fd_set rdfdes;
997                 int nfound;
998 # endif
999
1000                 if (alarm_flag)         /* alarmed? */
1001                 {
1002                         was_alarmed = 1;
1003                         alarm_flag = 0;
1004                 }
1005
1006                 if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE)
1007                 {
1008                         /*
1009                          * Nothing to do.  Wait for something.
1010                          */
1011 # ifndef HAVE_SIGNALED_IO
1012                         rdfdes = activefds;
1013 #  if defined(VMS) || defined(SYS_VXWORKS)
1014                         /* make select() wake up after one second */
1015                         {
1016                                 struct timeval t1;
1017
1018                                 t1.tv_sec = 1; t1.tv_usec = 0;
1019                                 nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
1020                                                 (fd_set *)0, &t1);
1021                         }
1022 #  else
1023                         nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
1024                                         (fd_set *)0, (struct timeval *)0);
1025 #  endif /* VMS */
1026                         if (nfound > 0)
1027                         {
1028                                 l_fp ts;
1029
1030                                 get_systime(&ts);
1031
1032                                 (void)input_handler(&ts);
1033                         }
1034                         else if (nfound == -1 && errno != EINTR)
1035                                 netsyslog(LOG_ERR, "select() error: %m");
1036 #  ifdef DEBUG
1037                         else if (debug > 5)
1038                                 netsyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
1039 #  endif /* DEBUG */
1040 # else /* HAVE_SIGNALED_IO */
1041                         
1042                         wait_for_signal();
1043 # endif /* HAVE_SIGNALED_IO */
1044                         if (alarm_flag)         /* alarmed? */
1045                         {
1046                                 was_alarmed = 1;
1047                                 alarm_flag = 0;
1048                         }
1049                 }
1050
1051                 if (was_alarmed)
1052                 {
1053                         UNBLOCK_IO_AND_ALARM();
1054                         /*
1055                          * Out here, signals are unblocked.  Call timer routine
1056                          * to process expiry.
1057                          */
1058                         timer();
1059                         was_alarmed = 0;
1060                         BLOCK_IO_AND_ALARM();
1061                 }
1062
1063 #endif /* HAVE_IO_COMPLETION_PORT */
1064
1065 #ifdef DEBUG_TIMING
1066                 {
1067                         l_fp pts;
1068                         l_fp tsa, tsb;
1069                         int bufcount = 0;
1070                         
1071                         get_systime(&pts);
1072                         tsa = pts;
1073 #endif
1074                         rbuf = get_full_recv_buffer();
1075                         while (rbuf != NULL)
1076                         {
1077                                 if (alarm_flag)
1078                                 {
1079                                         was_alarmed = 1;
1080                                         alarm_flag = 0;
1081                                 }
1082                                 UNBLOCK_IO_AND_ALARM();
1083
1084                                 if (was_alarmed)
1085                                 {       /* avoid timer starvation during lengthy I/O handling */
1086                                         timer();
1087                                         was_alarmed = 0;
1088                                 }
1089
1090                                 /*
1091                                  * Call the data procedure to handle each received
1092                                  * packet.
1093                                  */
1094                                 if (rbuf->receiver != NULL)     /* This should always be true */
1095                                 {
1096 #ifdef DEBUG_TIMING
1097                                         l_fp dts = pts;
1098
1099                                         L_SUB(&dts, &rbuf->recv_time);
1100                                         DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
1101                                         collect_timing(rbuf, "buffer processing delay", 1, &dts);
1102                                         bufcount++;
1103 #endif
1104                                         (rbuf->receiver)(rbuf);
1105                                 } else {
1106                                         msyslog(LOG_ERR, "receive buffer corruption - receiver found to be NULL - ABORTING");
1107                                         abort();
1108                                 }
1109
1110                                 BLOCK_IO_AND_ALARM();
1111                                 freerecvbuf(rbuf);
1112                                 rbuf = get_full_recv_buffer();
1113                         }
1114 #ifdef DEBUG_TIMING
1115                         get_systime(&tsb);
1116                         L_SUB(&tsb, &tsa);
1117                         if (bufcount) {
1118                                 collect_timing(NULL, "processing", bufcount, &tsb);
1119                                 DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
1120                         }
1121                 }
1122 #endif
1123
1124                 /*
1125                  * Go around again
1126                  */
1127         }
1128         UNBLOCK_IO_AND_ALARM();
1129         return 1;
1130 }
1131
1132
1133 #ifdef SIGDIE2
1134 /*
1135  * finish - exit gracefully
1136  */
1137 static RETSIGTYPE
1138 finish(
1139         int sig
1140         )
1141 {
1142
1143         msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);
1144         write_stats();
1145 #ifdef HAVE_DNSREGISTRATION
1146         if (mdns != NULL)
1147         DNSServiceRefDeallocate(mdns);
1148 #endif
1149
1150         switch (sig)
1151         {
1152 # ifdef SIGBUS
1153                 case SIGBUS:
1154                 printf("\nfinish(SIGBUS)\n");
1155                 exit(0);
1156 # endif
1157                 case 0:                 /* Should never happen... */
1158                 return;
1159                 default:
1160                 exit(0);
1161         }
1162 }
1163 #endif  /* SIGDIE2 */
1164
1165
1166 #ifdef DEBUG
1167 #ifndef SYS_WINNT
1168 /*
1169  * moredebug - increase debugging verbosity
1170  */
1171 static RETSIGTYPE
1172 moredebug(
1173         int sig
1174         )
1175 {
1176         int saved_errno = errno;
1177
1178         if (debug < 255)
1179         {
1180                 debug++;
1181                 msyslog(LOG_DEBUG, "debug raised to %d", debug);
1182         }
1183         errno = saved_errno;
1184 }
1185
1186 /*
1187  * lessdebug - decrease debugging verbosity
1188  */
1189 static RETSIGTYPE
1190 lessdebug(
1191         int sig
1192         )
1193 {
1194         int saved_errno = errno;
1195
1196         if (debug > 0)
1197         {
1198                 debug--;
1199                 msyslog(LOG_DEBUG, "debug lowered to %d", debug);
1200         }
1201         errno = saved_errno;
1202 }
1203 #endif
1204 #else /* not DEBUG */
1205 #ifndef SYS_WINNT
1206 /*
1207  * no_debug - We don't do the debug here.
1208  */
1209 static RETSIGTYPE
1210 no_debug(
1211         int sig
1212         )
1213 {
1214         int saved_errno = errno;
1215
1216         msyslog(LOG_DEBUG, "ntpd not compiled for debugging (signal %d)", sig);
1217         errno = saved_errno;
1218 }
1219 #endif  /* not SYS_WINNT */
1220 #endif  /* not DEBUG */