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