1 /* ntp_config.c
2 *
3 * This file contains the ntpd configuration code.
4 *
5 * Written By: Sachin Kamboj
6 * University of Delaware
7 * Newark, DE 19711
8 * Some parts borrowed from the older ntp_config.c
9 * Copyright Sachin Kamboj
10 * Copyright the NTPsec project contributors
11 * SPDX-License-Identifier: BSD-2-Clause
12 */
13
14 #include "config.h"
15
16 #include <stdio.h>
17 #include <ctype.h>
18 #include <signal.h>
19 #include <sys/wait.h>
20
21 #include "isc_netaddr.h"
22
23 #include "ntp.h"
24 #include "ntpd.h"
25 #include "ntp_io.h"
26 #include "ntp_refclock.h"
27 #include "ntp_filegen.h"
28 #include "ntp_stdlib.h"
29 #include "lib_strbuf.h"
30 #include "ntp_assert.h"
31 #include "ntp_dns.h"
32 #include "ntp_auth.h"
33
34 /*
35 * [Classic Bug 467]: Some linux headers collide with CONFIG_PHONE and
36 * CONFIG_KEYS so #include these later.
37 */
38 #include "ntp_config.h"
39 #include "ntp_scanner.h"
40 #include "ntp_parser.tab.h"
41
42 /* Hack to dance around bug in older Bison. See Classic Issue 287 */
43 /* Similar for yydebug below */
44 #ifndef yyparse
45 int yyparse (void);
46 #endif
47
48 /*
49 * Selection algorithm tuning parameters
50 */
51
52 /*
53 * In the past, we told reference clocks from network peers by giving
54 * the reference clocks magic address of a particular special form
55 * ntpd itself, the filtering that used to be done based on this magic
56 * address prefix is now done using a flag set on incoming packets.
57 * In ntpq, the filtering is replaced by asking the server how a
58 * peer's name should be displayed.
59 *
60 * Address filtering is still done in this file so we can tell which old-style
61 * config declarations refer to clocks. When that syntax is retired, drop these.
62 */
63 #define REFCLOCK_ADDR 0x7f7f0000 /* 127.127.0.0 */
64 #define REFCLOCK_MASK 0xffff0000 /* 255.255.0.0 */
65
66 #define ISREFCLOCKADR(srcadr) \
67 (IS_IPV4(srcadr) && \
68 (SRCADR(srcadr) & REFCLOCK_MASK) == REFCLOCK_ADDR)
69
70 /*
71 * Macros to determine the clock type and unit numbers from a
72 * refclock magic address
73 */
74 #define REFCLOCKTYPE(srcadr) ((SRCADR(srcadr) >> 8) & 0xff)
75 #define REFCLOCKUNIT(srcadr) (SRCADR(srcadr) & 0xff)
76
77
78 /* count of parsing errors - for log file */
79 int parsing_errors = 0;
80
81 /* list of servers from command line for config_peers() */
82 int cmdline_server_count = 0;
83 char ** cmdline_servers;
84
85 /*
86 * FIXME: ugly globals, only created to avoid wiring in option-parsing cruft.
87 * These are symptoms of deeper factoring issues; the things they're
88 * controlling, deep down inside that configuration parsing, should
89 * not be happening where they are.
90 */
91 bool have_interface_option;
92
93 /*
94 * "logconfig" building blocks
95 */
96 struct masks {
97 const char * const name;
98 const uint32_t mask;
99 };
100
101 static struct masks logcfg_class[] = {
102 { "clock", NLOG_OCLOCK },
103 { "peer", NLOG_OPEER },
104 { "sync", NLOG_OSYNC },
105 { "sys", NLOG_OSYS },
106 { NULL, 0 }
107 };
108
109 /* logcfg_noclass_items[] masks are complete and must not be shifted */
110 static struct masks logcfg_noclass_items[] = {
111 { "allall", NLOG_SYSMASK | NLOG_PEERMASK | NLOG_CLOCKMASK | NLOG_SYNCMASK },
112 { "allinfo", NLOG_SYSINFO | NLOG_PEERINFO | NLOG_CLOCKINFO | NLOG_SYNCINFO },
113 { "allevents", NLOG_SYSEVENT | NLOG_PEEREVENT | NLOG_CLOCKEVENT | NLOG_SYNCEVENT },
114 { "allstatus", NLOG_SYSSTATUS | NLOG_PEERSTATUS | NLOG_CLOCKSTATUS | NLOG_SYNCSTATUS },
115 { "allstatistics", NLOG_SYSSTATIST | NLOG_PEERSTATIST | NLOG_CLOCKSTATIST | NLOG_SYNCSTATIST },
116 /* the remainder are misspellings of clockall, peerall, sysall, and syncall. */
117 { "allclock", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OCLOCK },
118 { "allpeer", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OPEER },
119 { "allsys", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYS },
120 { "allsync", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYNC },
121 { NULL, 0 }
122 };
123
124 /* logcfg_class_items[] masks are shiftable by NLOG_O* counts */
125 static struct masks logcfg_class_items[] = {
126 { "all", NLOG_INFO | NLOG_EVENT | NLOG_STATUS | NLOG_STATIST },
127 { "info", NLOG_INFO },
128 { "events", NLOG_EVENT },
129 { "status", NLOG_STATUS },
130 { "statistics", NLOG_STATIST },
131 { NULL, 0 }
132 };
133
134 /* Limits */
135 #define MAXPHONE 10 /* maximum number of phone strings */
136 /* #define MAXPPS 20 * maximum length of PPS device string UNUSED */
137
138 /*
139 * Miscellaneous macros
140 */
141 #define _UC(str) ((char *)(intptr_t)(str))
142
143 /*
144 * Definitions of things either imported from or exported to outside
145 */
146 config_tree cfgt; /* Parser output stored here */
147 static struct config_tree_tag *cfg_tree_history; /* History of configs */
148 char *sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */
149
150 static char default_ntp_signd_socket[] =
151 #ifdef MSSNTP_PATH
152 MSSNTP_PATH;
153 #else
154 "";
155 #endif
156 char *ntp_signd_socket = default_ntp_signd_socket;
157
158 struct REMOTE_CONFIG_INFO remote_config; /* Remote configuration buffer and
159 pointer info */
160 /* FUNCTION PROTOTYPES */
161
162 static void init_syntax_tree(config_tree *);
163 static void apply_enable_disable(attr_val_fifo *q, int enable);
164
165 static void free_auth_node(config_tree *);
166 static void free_all_config_trees(void);
167
168 static struct peer *peer_config(sockaddr_u *, const char *,
169 endpt *, int, struct peer_ctl *);
170
171 static void free_config_access(config_tree *);
172 static void free_config_auth(config_tree *);
173 static void free_config_fudge(config_tree *);
174 static void free_config_logconfig(config_tree *);
175 static void free_config_monitor(config_tree *);
176 static void free_config_nic_rules(config_tree *);
177 static void free_config_peers(config_tree *);
178 static void free_config_phone(config_tree *);
179 static void free_config_reset_counters(config_tree *);
180 static void free_config_rlimit(config_tree *);
181 static void free_config_setvar(config_tree *);
182 static void free_config_system_opts(config_tree *);
183 static void free_config_tinker(config_tree *);
184 static void free_config_nts(config_tree *);
185 static void free_config_tos(config_tree *);
186 static void free_config_unpeers(config_tree *);
187 static void free_config_vars(config_tree *);
188
189 static void free_config_tree(config_tree *ptree);
190
191 static void destroy_restrict_node(restrict_node *my_node);
192 static bool is_sane_resolved_address(sockaddr_u *peeraddr, int hmode);
193 static void save_and_apply_config_tree(bool from_file);
194 static void destroy_int_fifo(int_fifo *);
195 #define FREE_INT_FIFO(pf) \
196 do { \
197 destroy_int_fifo(pf); \
198 (pf) = NULL; \
199 } while (0)
200 static void destroy_string_fifo(string_fifo *);
201 #define FREE_STRING_FIFO(pf) \
202 do { \
203 destroy_string_fifo(pf); \
204 (pf) = NULL; \
205 } while (0)
206 static void destroy_attr_val_fifo(attr_val_fifo *);
207 #define FREE_ATTR_VAL_FIFO(pf) \
208 do { \
209 destroy_attr_val_fifo(pf); \
210 (pf) = NULL; \
211 } while (0)
212 static void destroy_filegen_fifo(filegen_fifo *);
213 #define FREE_FILEGEN_FIFO(pf) \
214 do { \
215 destroy_filegen_fifo(pf); \
216 (pf) = NULL; \
217 } while (0)
218 static void destroy_restrict_fifo(restrict_fifo *);
219 #define FREE_RESTRICT_FIFO(pf) \
220 do { \
221 destroy_restrict_fifo(pf); \
222 (pf) = NULL; \
223 } while (0)
224 static void destroy_setvar_fifo(setvar_fifo *);
225 #define FREE_SETVAR_FIFO(pf) \
226 do { \
227 destroy_setvar_fifo(pf); \
228 (pf) = NULL; \
229 } while (0)
230 static void destroy_addr_opts_fifo(addr_opts_fifo *);
231 #define FREE_ADDR_OPTS_FIFO(pf) \
232 do { \
233 destroy_addr_opts_fifo(pf); \
234 (pf) = NULL; \
235 } while (0)
236
237 static void config_logconfig(config_tree *);
238 static void config_monitor(config_tree *);
239 static void config_rlimit(config_tree *);
240 static void config_system_opts(config_tree *);
241 static void config_tinker(config_tree *);
242 static void config_nts(config_tree *);
243 static void config_tos(config_tree *);
244 static void config_logfile(config_tree *);
245 static void config_vars(config_tree *);
246
247 static void config_ntpd(config_tree *, bool input_from_file);
248 static void config_auth(config_tree *);
249 static void config_access(config_tree *);
250 static void config_mdnstries(config_tree *);
251 static void config_phone(config_tree *);
252 static void config_setvar(config_tree *);
253 static void config_fudge(config_tree *);
254 static void config_peers(config_tree *);
255 static void config_unpeers(config_tree *);
256 static void config_nic_rules(config_tree *, bool input_from_file);
257 static void config_reset_counters(config_tree *);
258
259 enum gnn_type {
260 t_UNK, /* Unknown */
261 t_REF, /* Refclock */
262 t_MSK /* Network Mask */
263 };
264
265 static uint32_t get_pfxmatch(const char **, struct masks *);
266 static uint32_t get_match(const char *, struct masks *);
267 static uint32_t get_logmask(const char *);
268 static int getnetnum(const char *num, sockaddr_u *addr);
269 static void fix_node_cidr(restrict_node *my_node);
270
271
272 /* FUNCTIONS FOR INITIALIZATION
273 * ----------------------------
274 */
275
276 static void
free_auth_node(config_tree * ptree)277 free_auth_node(
278 config_tree *ptree
279 )
280 {
281 if (ptree->auth.keys) {
282 free(ptree->auth.keys);
283 ptree->auth.keys = NULL;
284 }
285
286 if (ptree->auth.ntp_signd_socket) {
287 free(ptree->auth.ntp_signd_socket);
288 ptree->auth.ntp_signd_socket = NULL;
289 }
290 }
291
292
293 static void
init_syntax_tree(config_tree * ptree)294 init_syntax_tree(
295 config_tree *ptree
296 )
297 {
298 ZERO(*ptree);
299 ptree->mdnstries = 5;
300 }
301
302
303 static void
free_all_config_trees(void)304 free_all_config_trees(void)
305 {
306 config_tree *ptree;
307 config_tree *pnext;
308
309 ptree = cfg_tree_history;
310
311 while (ptree != NULL) {
312 pnext = ptree->link;
313 free_config_tree(ptree);
314 ptree = pnext;
315 }
316 }
317
318
319 static void
free_config_tree(config_tree * ptree)320 free_config_tree(
321 config_tree *ptree
322 )
323 {
324 if (ptree->source.value.s != NULL)
325 free(ptree->source.value.s);
326
327 free_config_auth(ptree);
328 free_config_tos(ptree);
329 free_config_monitor(ptree);
330 free_config_access(ptree);
331 free_config_tinker(ptree);
332 free_config_nts(ptree);
333 free_config_rlimit(ptree);
334 free_config_system_opts(ptree);
335 free_config_logconfig(ptree);
336 free_config_phone(ptree);
337 free_config_setvar(ptree);
338 free_config_fudge(ptree);
339 free_config_vars(ptree);
340 free_config_peers(ptree);
341 free_config_unpeers(ptree);
342 free_config_nic_rules(ptree);
343 free_config_reset_counters(ptree);
344 free_auth_node(ptree);
345
346 free(ptree);
347 }
348
349 /* generic fifo routines for structs linked by 1st member */
350 void *
append_gen_fifo(void * fifo,void * entry)351 append_gen_fifo(
352 void *fifo,
353 void *entry
354 )
355 {
356 gen_fifo *pf;
357 gen_node *pe;
358
359 pf = fifo;
360 pe = entry;
361 if (NULL == pf)
362 pf = emalloc_zero(sizeof(*pf));
363 else
364 CHECK_FIFO_CONSISTENCY(*pf);
365 if (pe != NULL)
366 LINK_FIFO(*pf, pe, link);
367 CHECK_FIFO_CONSISTENCY(*pf);
368
369 return pf;
370 }
371
372
373 void *
concat_gen_fifos(void * first,void * second)374 concat_gen_fifos(
375 void *first,
376 void *second
377 )
378 {
379 gen_fifo *pf1;
380 gen_fifo *pf2;
381
382 pf1 = first;
383 pf2 = second;
384 if (NULL == pf1)
385 return pf2;
386 if (NULL == pf2)
387 return pf1;
388
389 CONCAT_FIFO(*pf1, *pf2, link);
390 free(pf2);
391
392 return pf1;
393 }
394
395
396 /* FUNCTIONS FOR CREATING NODES ON THE SYNTAX TREE
397 * -----------------------------------------------
398 */
399
400 attr_val *
create_attr_dval(int attr,double value)401 create_attr_dval(
402 int attr,
403 double value
404 )
405 {
406 attr_val *my_val;
407
408 my_val = emalloc_zero(sizeof(*my_val));
409 my_val->attr = attr;
410 my_val->value.d = value;
411 my_val->type = T_Double;
412
413 return my_val;
414 }
415
416
417 attr_val *
create_attr_ival(int attr,int value)418 create_attr_ival(
419 int attr,
420 int value
421 )
422 {
423 attr_val *my_val;
424
425 my_val = emalloc_zero(sizeof(*my_val));
426 my_val->attr = attr;
427 my_val->value.i = value;
428 my_val->type = T_Integer;
429
430 return my_val;
431 }
432
433
434 attr_val *
create_attr_uval(int attr,unsigned int value)435 create_attr_uval(
436 int attr,
437 unsigned int value
438 )
439 {
440 attr_val *my_val;
441
442 my_val = emalloc_zero(sizeof(*my_val));
443 my_val->attr = attr;
444 my_val->value.u = value;
445 my_val->type = T_U_int;
446
447 return my_val;
448 }
449
450
451 attr_val *
create_attr_rangeval(int attr,int first,int last)452 create_attr_rangeval(
453 int attr,
454 int first,
455 int last
456 )
457 {
458 attr_val *my_val;
459
460 my_val = emalloc_zero(sizeof(*my_val));
461 my_val->attr = attr;
462 my_val->value.r.first = first;
463 my_val->value.r.last = last;
464 my_val->type = T_Intrange;
465
466 return my_val;
467 }
468
469
470 attr_val *
create_attr_sval(int attr,const char * s)471 create_attr_sval(
472 int attr,
473 const char *s
474 )
475 {
476 attr_val *my_val;
477
478 my_val = emalloc_zero(sizeof(*my_val));
479 my_val->attr = attr;
480 if (NULL == s) { /* free() hates NULL */
481 s = estrdup("");
482 }
483 my_val->value.s = _UC(s);
484 my_val->type = T_String;
485
486 return my_val;
487 }
488
489
490 int_node *
create_int_node(int val)491 create_int_node(
492 int val
493 )
494 {
495 int_node *i_n;
496
497 i_n = emalloc_zero(sizeof(*i_n));
498 i_n->i = val;
499
500 return i_n;
501 }
502
503
504 string_node *
create_string_node(char * str)505 create_string_node(
506 char *str
507 )
508 {
509 string_node *sn;
510
511 sn = emalloc_zero(sizeof(*sn));
512 sn->s = str;
513
514 return sn;
515 }
516
517
518 address_node *
create_address_node(char * addr,int type)519 create_address_node(
520 char * addr,
521 int type
522 )
523 {
524 address_node *my_node;
525
526 REQUIRE(NULL != addr);
527 REQUIRE(AF_INET == type ||
528 AF_INET6 == type || AF_UNSPEC == type);
529 my_node = emalloc_zero(sizeof(*my_node));
530 my_node->address = addr;
531 my_node->type = (unsigned short)type;
532
533 return my_node;
534 }
535
536
537 void
destroy_address_node(address_node * my_node)538 destroy_address_node(
539 address_node *my_node
540 )
541 {
542 if (NULL == my_node)
543 return;
544 REQUIRE(NULL != my_node->address);
545
546 free(my_node->address);
547 free(my_node);
548 }
549
550
551 peer_node *
create_peer_node(int hmode,address_node * addr,attr_val_fifo * options)552 create_peer_node(
553 int hmode,
554 address_node * addr,
555 attr_val_fifo * options
556 )
557 {
558 peer_node *my_node;
559 attr_val *option;
560 int errflag = false;
561
562 my_node = emalloc_zero(sizeof(*my_node));
563
564 /* Initialize node values to default */
565
566 my_node->ctl.version = NTP_VERSION;
567 my_node->ctl.minpoll = NTP_MINDPOLL;
568 /* can not set maxpoll default yet, it may be NTP_MAXDPOLL or minpoll */
569 my_node->ctl.maxpoll = NTP_MAXPOLL_UNK;
570 my_node->ctl.bias = 0;
571
572 /* Now set the node to the read values */
573 my_node->host_mode = hmode;
574 my_node->addr = addr;
575
576 /* The options FIFO is consumed and reclaimed here */
577 if (options != NULL)
578 CHECK_FIFO_CONSISTENCY(*options);
579 while (options != NULL) {
580 UNLINK_FIFO(option, *options, link);
581 if (NULL == option) {
582 free(options);
583 break;
584 }
585
586 /* Check the kind of option being set */
587 switch (option->attr) {
588
589 case T_Flag:
590 switch (option->value.i) {
591 default:
592 INSIST(0);
593 break;
594
595 case T_Burst:
596 my_node->ctl.flags |= FLAG_BURST;
597 break;
598
599 case T_Iburst:
600 my_node->ctl.flags |= FLAG_IBURST;
601 break;
602
603 case T_Noselect:
604 my_node->ctl.flags |= FLAG_NOSELECT;
605 break;
606
607 case T_Noval:
608 my_node->ctl.flags |= FLAG_NTS_NOVAL;
609 break;
610
611 case T_Nts:
612 #ifdef DISABLE_NTS
613 msyslog(LOG_ERR, "CONFIG: nts not supported");
614 exit(1);
615 #else
616 my_node->ctl.flags |= (FLAG_NTS | FLAG_LOOKUP);
617 break;
618 #endif
619
620 case T_Prefer:
621 my_node->ctl.flags |= FLAG_PREFER;
622 break;
623
624 case T_True:
625 my_node->ctl.flags |= FLAG_TRUE;
626 break;
627 }
628 break;
629
630 case T_Aead:
631 my_node->ctl.nts_cfg.aead = option->value.s;
632 break;
633
634 case T_Ca:
635 my_node->ctl.nts_cfg.ca = option->value.s;
636 break;
637
638 case T_Minpoll:
639 if (option->value.i < NTP_MINPOLL ) {
640 msyslog(LOG_INFO,
641 "CONFIG: minpoll: provided value (%d) is too small [%d-%d])",
642 option->value.i, NTP_MINPOLL,
643 NTP_MAXPOLL);
644 my_node->ctl.minpoll = NTP_MINPOLL;
645 } else if (option->value.i > NTP_MAXPOLL) {
646 msyslog(LOG_INFO,
647 "CONFIG: minpoll: provided value (%d) is too large [%d-%d])",
648 option->value.i, NTP_MINPOLL,
649 NTP_MAXPOLL);
650 my_node->ctl.minpoll = NTP_MAXPOLL;
651 } else {
652 my_node->ctl.minpoll =
653 (uint8_t)option->value.u;
654 }
655 break;
656
657 case T_Maxpoll:
658 if (option->value.i < NTP_MINPOLL ) {
659 msyslog(LOG_INFO,
660 "CONFIG: maxpoll: value (%d) is too small [%d-%d])",
661 option->value.i, NTP_MINPOLL,
662 NTP_MAXPOLL);
663 my_node->ctl.maxpoll = NTP_MINPOLL;
664 } else if ( option->value.i > NTP_MAXPOLL) {
665 msyslog(LOG_INFO,
666 "CONFIG: maxpoll: value (%d) is too large [%d-%d])",
667 option->value.i, NTP_MINPOLL,
668 NTP_MAXPOLL);
669 my_node->ctl.maxpoll = NTP_MAXPOLL;
670 } else {
671 my_node->ctl.maxpoll =
672 (uint8_t)option->value.u;
673 }
674 break;
675
676 case T_Subtype:
677 case T_Mode:
678 my_node->ctl.mode = option->value.u;
679 break;
680
681 case T_Key:
682 if (option->value.u >= NTP_MAXKEY) {
683 msyslog(LOG_ERR, "CONFIG: key: invalid argument");
684 errflag = true;
685 } else {
686 my_node->ctl.peerkey =
687 (keyid_t)option->value.u;
688 }
689 break;
690
691 case T_Version:
692 if (option->value.u >= UCHAR_MAX) {
693 msyslog(LOG_ERR, "CONFIG: version: invalid argument");
694 errflag = true;
695 } else {
696 my_node->ctl.version =
697 (uint8_t)option->value.u;
698 }
699 break;
700
701 case T_Bias:
702 my_node->ctl.bias = option->value.d;
703 break;
704
705 #ifdef REFCLOCK
706 case T_Path:
707 my_node->ctl.path = estrdup(option->value.s);
708 break;
709
710 case T_Ppspath:
711 my_node->ctl.ppspath = estrdup(option->value.s);
712 break;
713
714 case T_Baud:
715 my_node->ctl.baud = option->value.u;
716 break;
717
718 /*
719 * Past this point are options the old syntax
720 * handled in fudge processing. They're parsed
721 * here to avoid ordering constraints.
722 */
723
724 case T_Time1:
725 my_node->clock_stat.haveflags |= CLK_HAVETIME1;
726 my_node->clock_stat.fudgetime1 = option->value.d;
727 break;
728
729 case T_Time2:
730 my_node->clock_stat.haveflags |= CLK_HAVETIME2;
731 my_node->clock_stat.fudgetime2 = option->value.d;
732 break;
733
734 case T_Stratum:
735 my_node->clock_stat.haveflags |= CLK_HAVEVAL1;
736 my_node->clock_stat.fudgeval1 = option->value.i;
737 break;
738
739 case T_Refid:
740 my_node->clock_stat.haveflags |= CLK_HAVEVAL2;
741 my_node->clock_stat.fudgeval2 = 0;
742 memcpy(&my_node->clock_stat.fudgeval2,
743 option->value.s,
744 min(strlen(option->value.s), REFIDLEN));
745 break;
746
747 case T_Flag1:
748 my_node->clock_stat.haveflags |= CLK_HAVEFLAG1;
749 if (option->value.i)
750 my_node->clock_stat.flags |= CLK_FLAG1;
751 else
752 my_node->clock_stat.flags &= ~CLK_FLAG1;
753 break;
754
755 case T_Flag2:
756 my_node->clock_stat.haveflags |= CLK_HAVEFLAG2;
757 if (option->value.i)
758 my_node->clock_stat.flags |= CLK_FLAG2;
759 else
760 my_node->clock_stat.flags &= ~CLK_FLAG2;
761 break;
762
763 case T_Flag3:
764 my_node->clock_stat.haveflags |= CLK_HAVEFLAG3;
765 if (option->value.i)
766 my_node->clock_stat.flags |= CLK_FLAG3;
767 else
768 my_node->clock_stat.flags &= ~CLK_FLAG3;
769 break;
770
771 case T_Flag4:
772 my_node->clock_stat.haveflags |= CLK_HAVEFLAG4;
773 if (option->value.i)
774 my_node->clock_stat.flags |= CLK_FLAG4;
775 else
776 my_node->clock_stat.flags &= ~CLK_FLAG4;
777 break;
778
779 case T_Holdover:
780 my_node->clock_stat.flags |= CLK_HOLDOVER;
781 break;
782 #endif /* REFCLOCK */
783
784 default:
785 msyslog(LOG_ERR,
786 "CONFIG: Unknown peer/server option token %s",
787 token_name(option->attr));
788 errflag = true;
789 }
790 free(option);
791 }
792
793 /* Check if errors were reported. If yes, ignore the node */
794 if (errflag) {
795 free(my_node);
796 my_node = NULL;
797 }
798
799 return my_node;
800 }
801
802
803 unpeer_node *
create_unpeer_node(address_node * addr)804 create_unpeer_node(
805 address_node *addr
806 )
807 {
808 unpeer_node * my_node;
809 unsigned int u;
810 char * pch;
811
812 my_node = emalloc_zero(sizeof(*my_node));
813
814 /*
815 * From the parser's perspective an association ID fits into
816 * its generic T_String definition of a name/address "address".
817 * We treat all valid 16-bit numbers as association IDs.
818 */
819 pch = addr->address;
820 while (*pch && isdigit((unsigned char)*pch)) {
821 pch++;
822 }
823
824 if (!*pch
825 && 1 == sscanf(addr->address, "%u", &u)
826 && u <= ASSOCID_MAX) {
827 my_node->assocID = (associd_t)u;
828 destroy_address_node(addr);
829 my_node->addr = NULL;
830 } else {
831 my_node->assocID = 0;
832 my_node->addr = addr;
833 }
834
835 return my_node;
836 }
837
838 filegen_node *
create_filegen_node(int filegen_token,attr_val_fifo * options)839 create_filegen_node(
840 int filegen_token,
841 attr_val_fifo * options
842 )
843 {
844 filegen_node *my_node;
845
846 my_node = emalloc_zero(sizeof(*my_node));
847 my_node->filegen_token = filegen_token;
848 my_node->options = options;
849
850 return my_node;
851 }
852
853
854 restrict_node *
create_restrict_node(const int mode,address_node * addr,address_node * mask,int_fifo * flags,int line_no)855 create_restrict_node(
856 const int mode,
857 address_node * addr,
858 address_node * mask,
859 int_fifo * flags,
860 int line_no
861 )
862 {
863 restrict_node *my_node;
864
865 my_node = emalloc_zero(sizeof(*my_node));
866 my_node->mode = mode;
867 my_node->addr = addr;
868 my_node->mask = mask;
869 my_node->flags = flags;
870 my_node->line_no = line_no;
871
872 return my_node;
873 }
874
875
876 static void
destroy_restrict_node(restrict_node * my_node)877 destroy_restrict_node(
878 restrict_node *my_node
879 )
880 {
881 /* With great care, free all the memory occupied by
882 * the restrict node
883 */
884 destroy_address_node(my_node->addr);
885 destroy_address_node(my_node->mask);
886 destroy_int_fifo(my_node->flags);
887 free(my_node);
888 }
889
890
891 static void
destroy_int_fifo(int_fifo * fifo)892 destroy_int_fifo(
893 int_fifo * fifo
894 )
895 {
896 int_node * i_n;
897
898 if (fifo != NULL) {
899 for (;;) {
900 UNLINK_FIFO(i_n, *fifo, link);
901 if (i_n == NULL)
902 break;
903 free(i_n);
904 }
905 free(fifo);
906 }
907 }
908
909
910 static void
destroy_string_fifo(string_fifo * fifo)911 destroy_string_fifo(
912 string_fifo * fifo
913 )
914 {
915 string_node * sn;
916
917 if (fifo != NULL) {
918 for (;;) {
919 UNLINK_FIFO(sn, *fifo, link);
920 if (sn == NULL)
921 break;
922 free(sn->s);
923 free(sn);
924 }
925 free(fifo);
926 }
927 }
928
929
930 static void
destroy_attr_val_fifo(attr_val_fifo * av_fifo)931 destroy_attr_val_fifo(
932 attr_val_fifo * av_fifo
933 )
934 {
935 attr_val * av;
936
937 if (av_fifo != NULL) {
938 for (;;) {
939 UNLINK_FIFO(av, *av_fifo, link);
940 if (av == NULL)
941 break;
942 if (T_String == av->type)
943 free(av->value.s);
944 free(av);
945 }
946 free(av_fifo);
947 }
948 }
949
950
951 static void
destroy_filegen_fifo(filegen_fifo * fifo)952 destroy_filegen_fifo(
953 filegen_fifo * fifo
954 )
955 {
956 filegen_node * fg;
957
958 if (fifo != NULL) {
959 for (;;) {
960 UNLINK_FIFO(fg, *fifo, link);
961 if (fg == NULL)
962 break;
963 destroy_attr_val_fifo(fg->options);
964 free(fg);
965 }
966 free(fifo);
967 }
968 }
969
970
971 static void
destroy_restrict_fifo(restrict_fifo * fifo)972 destroy_restrict_fifo(
973 restrict_fifo * fifo
974 )
975 {
976 restrict_node * rn;
977
978 if (fifo != NULL) {
979 for (;;) {
980 UNLINK_FIFO(rn, *fifo, link);
981 if (rn == NULL)
982 break;
983 destroy_restrict_node(rn);
984 }
985 free(fifo);
986 }
987 }
988
989
990 static void
destroy_setvar_fifo(setvar_fifo * fifo)991 destroy_setvar_fifo(
992 setvar_fifo * fifo
993 )
994 {
995 setvar_node * sv;
996
997 if (fifo != NULL) {
998 for (;;) {
999 UNLINK_FIFO(sv, *fifo, link);
1000 if (sv == NULL)
1001 break;
1002 free(sv->var);
1003 free(sv->val);
1004 free(sv);
1005 }
1006 free(fifo);
1007 }
1008 }
1009
1010
1011 static void
destroy_addr_opts_fifo(addr_opts_fifo * fifo)1012 destroy_addr_opts_fifo(
1013 addr_opts_fifo * fifo
1014 )
1015 {
1016 addr_opts_node * aon;
1017
1018 if (fifo != NULL) {
1019 for (;;) {
1020 UNLINK_FIFO(aon, *fifo, link);
1021 if (aon == NULL)
1022 break;
1023 destroy_address_node(aon->addr);
1024 destroy_attr_val_fifo(aon->options);
1025 free(aon);
1026 }
1027 free(fifo);
1028 }
1029 }
1030
1031
1032 setvar_node *
create_setvar_node(char * var,char * val,int isdefault)1033 create_setvar_node(
1034 char * var,
1035 char * val,
1036 int isdefault
1037 )
1038 {
1039 setvar_node * my_node;
1040 char * pch;
1041
1042 /* do not allow = in the variable name */
1043 pch = strchr(var, '=');
1044 if (NULL != pch) {
1045 *pch = '\0';
1046 }
1047
1048 /* Now store the string into a setvar_node */
1049 my_node = emalloc_zero(sizeof(*my_node));
1050 my_node->var = var;
1051 my_node->val = val;
1052 my_node->isdefault = isdefault;
1053
1054 return my_node;
1055 }
1056
1057
1058 nic_rule_node *
create_nic_rule_node(int match_class,char * if_name,int action)1059 create_nic_rule_node(
1060 int match_class,
1061 char *if_name, /* interface name or numeric address */
1062 int action
1063 )
1064 {
1065 nic_rule_node *my_node;
1066
1067 REQUIRE(match_class != 0 || if_name != NULL);
1068
1069 my_node = emalloc_zero(sizeof(*my_node));
1070 my_node->match_class = match_class;
1071 my_node->if_name = if_name;
1072 my_node->action = action;
1073
1074 return my_node;
1075 }
1076
1077
1078 addr_opts_node *
create_addr_opts_node(address_node * addr,attr_val_fifo * options)1079 create_addr_opts_node(
1080 address_node * addr,
1081 attr_val_fifo * options
1082 )
1083 {
1084 addr_opts_node *my_node;
1085
1086 my_node = emalloc_zero(sizeof(*my_node));
1087 my_node->addr = addr;
1088 my_node->options = options;
1089
1090 return my_node;
1091 }
1092
1093 /* FUNCTIONS FOR PERFORMING THE CONFIGURATION
1094 * ------------------------------------------
1095 */
1096
1097 static void
config_auth(config_tree * ptree)1098 config_auth(
1099 config_tree *ptree
1100 )
1101 {
1102 attr_val * my_val;
1103 int first;
1104 int last;
1105 int i;
1106 int count;
1107
1108 /* ntp_signd_socket Command */
1109 if (ptree->auth.ntp_signd_socket) {
1110 if (ntp_signd_socket != default_ntp_signd_socket) {
1111 free(ntp_signd_socket);
1112 }
1113 ntp_signd_socket = estrdup(ptree->auth.ntp_signd_socket);
1114 }
1115
1116 /*
1117 * Count the number of trusted keys to preallocate storage and
1118 * size the hash table.
1119 */
1120 count = 0;
1121 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
1122 for (; my_val != NULL; my_val = my_val->link) {
1123 if (T_Integer == my_val->type) {
1124 first = my_val->value.i;
1125 if (first > 1 && first <= NTP_MAXKEY)
1126 count++;
1127 } else {
1128 REQUIRE(T_Intrange == my_val->type);
1129 first = my_val->value.r.first;
1130 last = my_val->value.r.last;
1131 if (!(first > last || first < 1 ||
1132 last > NTP_MAXKEY)) {
1133 count += 1 + last - first;
1134 }
1135 }
1136 }
1137 if (0 < count)
1138 msyslog(LOG_INFO, "Found %d trusted keys.", count);
1139 auth_prealloc(count);
1140
1141 /* Keys Command */
1142 if (ptree->auth.keys)
1143 getauthkeys(ptree->auth.keys);
1144
1145 /* Control Key Command */
1146 if (ptree->auth.control_key)
1147 ctl_auth_keyid = (keyid_t)ptree->auth.control_key;
1148
1149 /* Trusted Key Command */
1150 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
1151 for (; my_val != NULL; my_val = my_val->link) {
1152 if (T_Integer == my_val->type) {
1153 first = my_val->value.i;
1154 if (first >= 1 && first <= NTP_MAXKEY) {
1155 authtrust((keyid_t)first, true);
1156 } else {
1157 msyslog(LOG_NOTICE,
1158 "CONFIG: Ignoring invalid trustedkey %d, min 1 max %d.",
1159 first, NTP_MAXKEY);
1160 }
1161 } else {
1162 first = my_val->value.r.first;
1163 last = my_val->value.r.last;
1164 if (first > last || first < 1 ||
1165 last > NTP_MAXKEY) {
1166 msyslog(LOG_NOTICE,
1167 "CONFIG: Ignoring invalid trustedkey range %d ... %d, min 1 max %d.",
1168 first, last, NTP_MAXKEY);
1169 } else {
1170 for (i = first; i <= last; i++) {
1171 authtrust((keyid_t)i, true);
1172 }
1173 }
1174 }
1175 }
1176 }
1177
1178
1179 static void
free_config_auth(config_tree * ptree)1180 free_config_auth(
1181 config_tree *ptree
1182 )
1183 {
1184 destroy_attr_val_fifo(ptree->auth.trusted_key_list);
1185 ptree->auth.trusted_key_list = NULL;
1186 }
1187
1188
1189 static void
config_tos(config_tree * ptree)1190 config_tos(
1191 config_tree *ptree
1192 )
1193 {
1194 attr_val * tos;
1195 int item;
1196 double val;
1197
1198 item = -1; /* quiet warning */
1199 tos = HEAD_PFIFO(ptree->orphan_cmds);
1200 for (; tos != NULL; tos = tos->link) {
1201 val = tos->value.d;
1202 switch(tos->attr) {
1203
1204 default:
1205 INSIST(0);
1206 break;
1207
1208 case T_Ceiling:
1209 if (val > STRATUM_UNSPEC - 1) {
1210 msyslog(LOG_WARNING,
1211 "CONFIG: Using maximum tos ceiling %d, %g requested",
1212 STRATUM_UNSPEC - 1, val);
1213 val = STRATUM_UNSPEC - 1;
1214 }
1215 item = PROTO_CEILING;
1216 break;
1217
1218 case T_Floor:
1219 item = PROTO_FLOOR;
1220 break;
1221
1222 case T_Orphan:
1223 item = PROTO_ORPHAN;
1224 break;
1225
1226 case T_Orphanwait:
1227 item = PROTO_ORPHWAIT;
1228 break;
1229
1230 case T_Mindist:
1231 item = PROTO_MINDIST;
1232 break;
1233
1234 case T_Maxdisp:
1235 item = PROTO_MAXDISP;
1236 break;
1237
1238 case T_Maxdist:
1239 item = PROTO_MAXDIST;
1240 break;
1241
1242 case T_Minclock:
1243 item = PROTO_MINCLOCK;
1244 break;
1245
1246 case T_Maxclock:
1247 item = PROTO_MAXCLOCK;
1248 break;
1249
1250 case T_Minsane:
1251 item = PROTO_MINSANE;
1252 break;
1253
1254 }
1255 proto_config(item, 0, val);
1256 }
1257 }
1258
1259
1260 static void
free_config_tos(config_tree * ptree)1261 free_config_tos(
1262 config_tree *ptree
1263 )
1264 {
1265 FREE_ATTR_VAL_FIFO(ptree->orphan_cmds);
1266 }
1267
1268
1269 static void
config_monitor(config_tree * ptree)1270 config_monitor(
1271 config_tree *ptree
1272 )
1273 {
1274 int_node *pfilegen_token;
1275 const char *filegen_string;
1276 const char *filegen_file;
1277 FILEGEN *filegen;
1278 filegen_node *my_node;
1279 attr_val *my_opts;
1280 int filegen_type;
1281 int filegen_flag;
1282
1283 /* Set the statistics directory */
1284 if (ptree->stats_dir)
1285 stats_config(STATS_STATSDIR, ptree->stats_dir);
1286
1287 /* NOTE:
1288 * Calling filegen_get is brain dead. Doing a string
1289 * comparison to find the relevant filegen structure is
1290 * expensive.
1291 *
1292 * Through the parser, we already know which filegen is
1293 * being specified. Hence, we should either store a
1294 * pointer to the specified structure in the syntax tree
1295 * or an index into a filegen array.
1296 *
1297 * Need to change the filegen code to reflect the above.
1298 */
1299
1300 /* Turn on the specified statistics */
1301 pfilegen_token = HEAD_PFIFO(ptree->stats_list);
1302 for (; pfilegen_token != NULL; pfilegen_token = pfilegen_token->link) {
1303 filegen_string = keyword(pfilegen_token->i);
1304 filegen = filegen_get(filegen_string);
1305 if (NULL == filegen) {
1306 msyslog(LOG_ERR,
1307 "CONFIG: stats %s unrecognized",
1308 filegen_string);
1309 continue;
1310 }
1311 DPRINT(4, ("enabling filegen for %s statistics '%s%s'\n",
1312 filegen_string, filegen->dir,
1313 filegen->fname));
1314 filegen_flag = filegen->flag;
1315 filegen_flag |= FGEN_FLAG_ENABLED;
1316 filegen_config(filegen, statsdir, filegen_string,
1317 filegen->type, (unsigned int)filegen_flag);
1318 }
1319
1320 /* Configure the statistics with the options */
1321 my_node = HEAD_PFIFO(ptree->filegen_opts);
1322 for (; my_node != NULL; my_node = my_node->link) {
1323 filegen_string = keyword(my_node->filegen_token);
1324 filegen = filegen_get(filegen_string);
1325 if (NULL == filegen) {
1326 msyslog(LOG_ERR,
1327 "CONFIG: filegen category '%s' unrecognized",
1328 filegen_string);
1329 continue;
1330 }
1331 filegen_file = filegen_string;
1332
1333 /* Initialize the filegen variables to their pre-configuration states */
1334 filegen_flag = filegen->flag;
1335 filegen_type = filegen->type;
1336
1337 /* "filegen ... enabled" is the default (when filegen is used) */
1338 filegen_flag |= FGEN_FLAG_ENABLED;
1339
1340 my_opts = HEAD_PFIFO(my_node->options);
1341 for (; my_opts != NULL; my_opts = my_opts->link) {
1342 switch (my_opts->attr) {
1343
1344 case T_File:
1345 filegen_file = my_opts->value.s;
1346 break;
1347
1348 case T_Type:
1349 switch (my_opts->value.i) {
1350
1351 default:
1352 INSIST(0);
1353 break;
1354
1355 case T_None:
1356 filegen_type = FILEGEN_NONE;
1357 break;
1358
1359 case T_Pid:
1360 filegen_type = FILEGEN_PID;
1361 break;
1362
1363 case T_Day:
1364 filegen_type = FILEGEN_DAY;
1365 break;
1366
1367 case T_Week:
1368 filegen_type = FILEGEN_WEEK;
1369 break;
1370
1371 case T_Month:
1372 filegen_type = FILEGEN_MONTH;
1373 break;
1374
1375 case T_Year:
1376 filegen_type = FILEGEN_YEAR;
1377 break;
1378
1379 case T_Age:
1380 filegen_type = FILEGEN_AGE;
1381 break;
1382 }
1383 break;
1384
1385 case T_Flag:
1386 switch (my_opts->value.i) {
1387
1388 case T_Link:
1389 filegen_flag |= FGEN_FLAG_LINK;
1390 break;
1391
1392 case T_Nolink:
1393 filegen_flag &= ~FGEN_FLAG_LINK;
1394 break;
1395
1396 case T_Enable:
1397 filegen_flag |= FGEN_FLAG_ENABLED;
1398 break;
1399
1400 case T_Disable:
1401 filegen_flag &= ~FGEN_FLAG_ENABLED;
1402 break;
1403
1404 default:
1405 msyslog(LOG_ERR,
1406 "CONFIG: Unknown filegen flag token %d",
1407 my_opts->value.i);
1408 exit(1);
1409 }
1410 break;
1411
1412 default:
1413 msyslog(LOG_ERR,
1414 "CONFIG: Unknown filegen option token %d",
1415 my_opts->attr);
1416 exit(1);
1417 }
1418 }
1419 filegen_config(filegen, statsdir, filegen_file,
1420 (unsigned int)filegen_type, (unsigned int)filegen_flag);
1421 }
1422 }
1423
1424
1425 static void
free_config_monitor(config_tree * ptree)1426 free_config_monitor(
1427 config_tree *ptree
1428 )
1429 {
1430 if (ptree->stats_dir) {
1431 free(ptree->stats_dir);
1432 ptree->stats_dir = NULL;
1433 }
1434
1435 FREE_INT_FIFO(ptree->stats_list);
1436 FREE_FILEGEN_FIFO(ptree->filegen_opts);
1437 }
1438
1439
1440 static void
config_access(config_tree * ptree)1441 config_access(
1442 config_tree *ptree
1443 )
1444 {
1445 static bool warned_signd;
1446 attr_val * my_opt;
1447 restrict_node * my_node;
1448 int_node * curr_flag;
1449 sockaddr_u addr;
1450 sockaddr_u mask;
1451 struct addrinfo hints;
1452 struct addrinfo * ai_list = NULL;
1453 struct addrinfo * pai;
1454 int rc;
1455 bool restrict_default;
1456 unsigned short flags;
1457 unsigned short mflags;
1458 bool range_err;
1459 const char * signd_warning =
1460 #ifdef ENABLE_MSSNTP
1461 "MS-SNTP signd operations currently block ntpd degrading service to all clients.";
1462 #else
1463 "mssntp restrict bit ignored, this ntpd was configured without --enable-mssntp.";
1464 #endif
1465
1466 /* Configure the mru options */
1467 my_opt = HEAD_PFIFO(ptree->mru_opts);
1468 for (; my_opt != NULL; my_opt = my_opt->link) {
1469
1470 range_err = false;
1471
1472 switch (my_opt->attr) {
1473
1474 case T_Incalloc:
1475 if (0 <= my_opt->value.i)
1476 mon_data.mru_incalloc = my_opt->value.u;
1477 else
1478 range_err = true;
1479 break;
1480
1481 case T_Incmem:
1482 if (0 <= my_opt->value.i)
1483 mon_data.mru_incalloc = (my_opt->value.u * 1024U)
1484 / sizeof(mon_entry);
1485 else
1486 range_err = true;
1487 break;
1488
1489 case T_Initalloc:
1490 if (0 <= my_opt->value.i)
1491 mon_data.mru_initalloc = my_opt->value.u;
1492 else
1493 range_err = true;
1494 break;
1495
1496 case T_Initmem:
1497 if (0 <= my_opt->value.i)
1498 mon_data.mru_initalloc = (my_opt->value.u * 1024U)
1499 / sizeof(mon_entry);
1500 else
1501 range_err = true;
1502 break;
1503
1504 case T_Mindepth:
1505 if (0 <= my_opt->value.i)
1506 mon_data.mru_mindepth = my_opt->value.u;
1507 else
1508 range_err = true;
1509 break;
1510
1511 case T_Maxage:
1512 mon_data.mru_maxage = my_opt->value.i;
1513 break;
1514
1515 case T_Minage:
1516 mon_data.mru_minage = my_opt->value.i;
1517 break;
1518
1519 case T_Maxdepth:
1520 if (0 <= my_opt->value.i)
1521 mon_data.mru_maxdepth = my_opt->value.u;
1522 else
1523 mon_data.mru_maxdepth = UINT_MAX;
1524 break;
1525
1526 case T_Maxmem:
1527 if (0 <= my_opt->value.i)
1528 mon_data.mru_maxdepth = (my_opt->value.u * 1024U) /
1529 sizeof(mon_entry);
1530 else
1531 mon_data.mru_maxdepth = UINT_MAX;
1532 break;
1533
1534 default:
1535 msyslog(LOG_ERR,
1536 "CONFIG: Unknown mru option %s (%d)",
1537 keyword(my_opt->attr), my_opt->attr);
1538 exit(1);
1539 }
1540 if (range_err)
1541 msyslog(LOG_ERR,
1542 "CONFIG: mru %s %d out of range, ignored.",
1543 keyword(my_opt->attr), my_opt->value.i);
1544 }
1545
1546 /* Configure the limit options */
1547 my_opt = HEAD_PFIFO(ptree->limit_opts);
1548 for (; my_opt != NULL; my_opt = my_opt->link) {
1549
1550 switch (my_opt->attr) {
1551
1552 default:
1553 INSIST(0);
1554 break;
1555
1556 case T_Average:
1557 mon_data.rate_limit = my_opt->value.d;
1558 break;
1559
1560 case T_Burst:
1561 mon_data.decay_time = my_opt->value.d;
1562 break;
1563
1564 case T_Kod:
1565 mon_data.kod_limit = my_opt->value.d;
1566 break;
1567
1568 }
1569 }
1570
1571 /* Configure the restrict options */
1572 my_node = HEAD_PFIFO(ptree->restrict_opts);
1573 for (; my_node != NULL; my_node = my_node->link) {
1574 int op;
1575 if (ai_list != NULL) {
1576 /* we do this here, to not need at every continue */
1577 freeaddrinfo(ai_list);
1578 ai_list = NULL;
1579 }
1580 /* Parse the flags */
1581 flags = 0;
1582 mflags = 0;
1583
1584 curr_flag = HEAD_PFIFO(my_node->flags);
1585 for (; curr_flag != NULL; curr_flag = curr_flag->link) {
1586 switch (curr_flag->i) {
1587
1588 default:
1589 INSIST(0);
1590 break;
1591
1592 case T_Ntpport:
1593 mflags |= RESM_NTPONLY;
1594 break;
1595
1596 case T_Source:
1597 mflags |= RESM_SOURCE;
1598 break;
1599
1600 case T_Flake:
1601 flags |= RES_FLAKE;
1602 break;
1603
1604 case T_Ignore:
1605 flags |= RES_IGNORE;
1606 break;
1607
1608 case T_Kod:
1609 flags |= RES_KOD;
1610 break;
1611
1612 case T_Mssntp:
1613 flags |= RES_MSSNTP;
1614 break;
1615
1616 case T_Limited:
1617 flags |= RES_LIMITED;
1618 break;
1619
1620 case T_Nomodify:
1621 flags |= RES_NOMODIFY;
1622 break;
1623
1624 case T_Nomrulist:
1625 flags |= RES_NOMRULIST;
1626 break;
1627
1628 case T_Nopeer:
1629 msyslog(LOG_ERR, "CONFIG: restrict nopeer ignored");
1630 break;
1631
1632 case T_Noquery:
1633 flags |= RES_NOQUERY;
1634 break;
1635
1636 case T_Noserve:
1637 flags |= RES_DONTSERVE;
1638 break;
1639
1640 case T_Notrap:
1641 msyslog(LOG_ERR, "CONFIG: restrict notrap ignored");
1642 break;
1643
1644 case T_Notrust:
1645 flags |= RES_DONTTRUST;
1646 break;
1647
1648 case T_Version:
1649 flags |= RES_VERSION;
1650 break;
1651 }
1652 }
1653
1654 if ((RES_MSSNTP & flags) && !warned_signd) {
1655 warned_signd = true;
1656 fprintf(stderr, "%s\n", signd_warning);
1657 msyslog(LOG_WARNING, "CONFIG: %s", signd_warning);
1658 }
1659
1660 /* It would be swell if we could identify the line number */
1661 if ((RES_KOD & flags) && !(RES_LIMITED & flags)) {
1662 const char *kod_where = (my_node->addr)
1663 ? my_node->addr->address
1664 : (mflags & RESM_SOURCE)
1665 ? "source"
1666 : "default";
1667 const char *kod_warn = "KOD does nothing without LIMITED.";
1668
1669 fprintf(stderr, "restrict %s: %s\n", kod_where, kod_warn);
1670 msyslog(LOG_WARNING, "CONFIG: restrict %s: %s", kod_where, kod_warn);
1671 }
1672
1673 ZERO_SOCK(&addr);
1674 pai = NULL;
1675 restrict_default = false;
1676
1677 if (NULL == my_node->addr) {
1678 ZERO_SOCK(&mask);
1679 if (!(RESM_SOURCE & mflags)) {
1680 /*
1681 * The user specified a default rule
1682 * without a -4 / -6 qualifier, add to
1683 * both lists
1684 */
1685 restrict_default = true;
1686 } else {
1687 /* apply "restrict source ..." */
1688 DPRINT(1, ("restrict source template mflags %x flags %x\n",
1689 mflags, flags));
1690 hack_restrict(RESTRICT_FLAGS, NULL,
1691 NULL, mflags, flags);
1692 continue;
1693 }
1694 } else {
1695
1696 /* Resolve the specified address */
1697 /* CIDR notation? */
1698 /* will overwrite my_node->mask-> address with CIDR */
1699 fix_node_cidr(my_node);
1700 /* type is always zero, AF_INET */
1701 AF(&addr) = (unsigned short)my_node->addr->type;
1702
1703 if (getnetnum(my_node->addr->address,
1704 &addr) != 1) {
1705 /*
1706 * Attempt a blocking lookup. This
1707 * is in violation of the nonblocking
1708 * design of ntpd's mainline code. The
1709 * alternative of running without the
1710 * restriction until the name resolved
1711 * seems worse.
1712 * Ideally some scheme could be used for
1713 * restrict directives in the startup
1714 * ntp.conf to delay starting up the
1715 * protocol machinery until after all
1716 * restrict hosts have been resolved.
1717 */
1718 ZERO(hints);
1719 hints.ai_protocol = IPPROTO_UDP;
1720 hints.ai_socktype = SOCK_DGRAM;
1721 hints.ai_family = my_node->addr->type;
1722 rc = getaddrinfo(my_node->addr->address,
1723 NTP_PORTA, &hints,
1724 &ai_list);
1725 if (rc) {
1726 msyslog(LOG_ERR,
1727 "CONFIG: restrict: ignoring line %d, address/host '%s' unusable.",
1728 my_node->line_no,
1729 my_node->addr->address);
1730 continue;
1731 }
1732 INSIST(ai_list != NULL);
1733 pai = ai_list;
1734 INSIST(pai->ai_addr != NULL);
1735 INSIST(sizeof(addr) >=
1736 pai->ai_addrlen);
1737 memcpy(&addr, pai->ai_addr,
1738 pai->ai_addrlen);
1739 INSIST(AF_INET == AF(&addr) ||
1740 AF_INET6 == AF(&addr));
1741 }
1742
1743 SET_HOSTMASK(&mask, AF(&addr));
1744
1745 /* Resolve the mask */
1746 if (my_node->mask) {
1747 ZERO_SOCK(&mask);
1748 AF(&mask) = my_node->mask->type;
1749 if (getnetnum(my_node->mask->address,
1750 &mask) != 1) {
1751 msyslog(LOG_ERR,
1752 "CONFIG: restrict: ignoring line %d, mask '%s' unusable.",
1753 my_node->line_no,
1754 my_node->mask->address);
1755 continue;
1756 }
1757 }
1758 }
1759 if (my_node->mode == T_Restrict)
1760 op = RESTRICT_FLAGS;
1761 else if (my_node->mode == T_Unrestrict
1762 && flags == 0 && mflags == 0)
1763 op = RESTRICT_REMOVE;
1764 else if (my_node->mode == T_Unrestrict)
1765 op = RESTRICT_UNFLAG;
1766 else
1767 continue; /* should never happen */
1768
1769 /* Set the flags */
1770 if (restrict_default) {
1771 /* default case, do both -4 and -6 */
1772 AF(&addr) = AF_INET;
1773 AF(&mask) = AF_INET;
1774 hack_restrict(op, &addr, &mask, mflags, flags);
1775 AF(&addr) = AF_INET6;
1776 AF(&mask) = AF_INET6;
1777 }
1778
1779 do {
1780 hack_restrict(op, &addr, &mask, mflags, flags);
1781 if (pai != NULL &&
1782 NULL != (pai = pai->ai_next)) {
1783 INSIST(pai->ai_addr != NULL);
1784 INSIST(sizeof(addr) >=
1785 pai->ai_addrlen);
1786 ZERO_SOCK(&addr);
1787 memcpy(&addr, pai->ai_addr,
1788 pai->ai_addrlen);
1789 INSIST(AF_INET == AF(&addr) ||
1790 AF_INET6 == AF(&addr));
1791 SET_HOSTMASK(&mask, AF(&addr));
1792 }
1793 } while (pai != NULL);
1794
1795 }
1796 if (ai_list != NULL) {
1797 /* coverity thinks this can happen, so just in case */
1798 freeaddrinfo(ai_list);
1799 ai_list = NULL;
1800 }
1801 /* coverity[leaked_storage] */
1802 }
1803
1804
1805 static void
free_config_access(config_tree * ptree)1806 free_config_access(
1807 config_tree *ptree
1808 )
1809 {
1810 FREE_ATTR_VAL_FIFO(ptree->mru_opts);
1811 FREE_ATTR_VAL_FIFO(ptree->limit_opts);
1812 FREE_RESTRICT_FIFO(ptree->restrict_opts);
1813 }
1814
1815
1816 static void
config_rlimit(config_tree * ptree)1817 config_rlimit(
1818 config_tree *ptree
1819 )
1820 {
1821 attr_val * rlimit_av;
1822
1823 rlimit_av = HEAD_PFIFO(ptree->rlimit);
1824 for (; rlimit_av != NULL; rlimit_av = rlimit_av->link) {
1825 switch (rlimit_av->attr) {
1826
1827 default:
1828 INSIST(0);
1829 break;
1830
1831 case T_Memlock:
1832 msyslog(LOG_WARNING, "CONFIG: memlock ignored");
1833 break;
1834
1835 case T_Stacksize:
1836 ntp_rlimit(RLIMIT_STACK,
1837 (rlim_t)(rlimit_av->value.i * 4096),
1838 4096,
1839 "4k");
1840 break;
1841
1842 case T_Filenum:
1843 ntp_rlimit(RLIMIT_NOFILE,
1844 (rlim_t)(rlimit_av->value.i),
1845 1,
1846 "");
1847 break;
1848
1849 }
1850 }
1851 }
1852
1853
1854 static void
config_tinker(config_tree * ptree)1855 config_tinker(
1856 config_tree *ptree
1857 )
1858 {
1859 attr_val * tinker;
1860 int item;
1861
1862 item = -1; /* quiet warning */
1863 tinker = HEAD_PFIFO(ptree->tinker);
1864 for (; tinker != NULL; tinker = tinker->link) {
1865 switch (tinker->attr) {
1866
1867 default:
1868 INSIST(0);
1869 break;
1870
1871 case T_Allan:
1872 item = LOOP_ALLAN;
1873 break;
1874
1875 case T_Dispersion:
1876 item = LOOP_PHI;
1877 break;
1878
1879 case T_Freq:
1880 item = LOOP_FREQ;
1881 break;
1882
1883 case T_Huffpuff:
1884 item = LOOP_HUFFPUFF;
1885 break;
1886
1887 case T_Panic:
1888 item = LOOP_PANIC;
1889 break;
1890
1891 case T_Step:
1892 item = LOOP_MAX;
1893 break;
1894
1895 case T_Stepback:
1896 item = LOOP_MAX_BACK;
1897 break;
1898
1899 case T_Stepfwd:
1900 item = LOOP_MAX_FWD;
1901 break;
1902
1903 case T_Stepout:
1904 item = LOOP_MINSTEP;
1905 break;
1906
1907 case T_Tick:
1908 #ifdef ENABLE_FUZZ
1909 item = LOOP_TICK;
1910 break;
1911 #else
1912 msyslog(LOG_ERR, "ERR: tinker tick not supported");
1913 continue;
1914 #endif
1915 }
1916 loop_config(item, tinker->value.d);
1917 }
1918 }
1919
1920 static void
config_nts(config_tree * ptree)1921 config_nts(
1922 config_tree *ptree
1923 )
1924 {
1925 attr_val * nts;
1926
1927 nts = HEAD_PFIFO(ptree->nts);
1928 for (; nts != NULL; nts = nts->link) {
1929 switch (nts->attr) {
1930
1931 default:
1932 #ifdef DISABLE_NTS
1933 msyslog(LOG_ERR, "CONFIG: nts not supported");
1934 break;
1935 #else
1936 INSIST(0);
1937 break;
1938 case T_Aead:
1939 ntsconfig.aead = estrdup(nts->value.s);
1940 break;
1941
1942 case T_Ca:
1943 ntsconfig.ca = estrdup(nts->value.s);
1944 break;
1945
1946 case T_Cert:
1947 ntsconfig.cert = estrdup(nts->value.s);
1948 break;
1949
1950 case T_Cookie:
1951 ntsconfig.KI = estrdup(nts->value.s);
1952 break;
1953
1954 case T_Disable:
1955 ntsconfig.ntsenable = false;
1956 break;
1957
1958 case T_Enable:
1959 ntsconfig.ntsenable = true;
1960 break;
1961
1962 case T_Key:
1963 ntsconfig.key = estrdup(nts->value.s);
1964 break;
1965
1966 case T_Maxtls:
1967 ntsconfig.maxtls = estrdup(nts->value.s);
1968 break;
1969
1970 case T_Mintls:
1971 ntsconfig.mintls = estrdup(nts->value.s);
1972 break;
1973
1974 case T_Tlsciphersuites:
1975 ntsconfig.tlsciphersuites = estrdup(nts->value.s);
1976 break;
1977 #endif
1978 }
1979 }
1980 }
1981
1982
1983 static void
free_config_rlimit(config_tree * ptree)1984 free_config_rlimit(
1985 config_tree *ptree
1986 )
1987 {
1988 FREE_ATTR_VAL_FIFO(ptree->rlimit);
1989 }
1990
1991 static void
free_config_tinker(config_tree * ptree)1992 free_config_tinker(
1993 config_tree *ptree
1994 )
1995 {
1996 FREE_ATTR_VAL_FIFO(ptree->tinker);
1997 }
1998
1999
2000 static void
free_config_nts(config_tree * ptree)2001 free_config_nts(
2002 config_tree *ptree
2003 )
2004 {
2005 FREE_ATTR_VAL_FIFO(ptree->nts);
2006 }
2007
2008
2009 /*
2010 * config_nic_rules - apply interface listen/ignore/drop items
2011 */
2012 static void
config_nic_rules(config_tree * ptree,bool input_from_file)2013 config_nic_rules(
2014 config_tree *ptree,
2015 bool input_from_file
2016 )
2017 {
2018 nic_rule_node * curr_node;
2019 sockaddr_u addr;
2020 nic_rule_match match_type;
2021 nic_rule_action action;
2022 char * if_name;
2023 char * pchSlash;
2024 int prefixlen;
2025 int addrbits;
2026
2027 curr_node = HEAD_PFIFO(ptree->nic_rules);
2028
2029 if (curr_node != NULL && have_interface_option) {
2030 msyslog(LOG_ERR,
2031 "CONFIG: interface/nic rules are not allowed with --interface (-I) or --novirtualips (-L)%s",
2032 (input_from_file) ? ", exiting" : "");
2033 if (input_from_file)
2034 exit(1);
2035 else
2036 return;
2037 }
2038
2039 for (; curr_node != NULL; curr_node = curr_node->link) {
2040 prefixlen = -1;
2041 if_name = curr_node->if_name;
2042 if (if_name != NULL)
2043 if_name = estrdup(if_name);
2044
2045 switch (curr_node->match_class) {
2046
2047 default:
2048 INSIST(false);
2049 break;
2050
2051 case 0:
2052 /*
2053 * 0 is out of range for valid token T_...
2054 * and in a nic_rules_node indicates the
2055 * interface descriptor is either a name or
2056 * address, stored in if_name in either case.
2057 */
2058 INSIST(if_name != NULL);
2059 pchSlash = strchr(if_name, '/');
2060 if (pchSlash != NULL)
2061 *pchSlash = '\0';
2062 if (is_ip_address(if_name, AF_UNSPEC, &addr)) {
2063 match_type = MATCH_IFADDR;
2064 if (pchSlash != NULL
2065 && 1 == sscanf(pchSlash + 1, "%d",
2066 &prefixlen)) {
2067 addrbits = 8 *
2068 SIZEOF_INADDR(AF(&addr));
2069 prefixlen = max(-1, prefixlen);
2070 prefixlen = min(prefixlen,
2071 addrbits);
2072 }
2073 } else {
2074 match_type = MATCH_IFNAME;
2075 if (pchSlash != NULL)
2076 *pchSlash = '/';
2077 }
2078 break;
2079
2080 case T_All:
2081 match_type = MATCH_ALL;
2082 break;
2083
2084 case T_Ipv4:
2085 match_type = MATCH_IPV4;
2086 break;
2087
2088 case T_Ipv6:
2089 match_type = MATCH_IPV6;
2090 break;
2091
2092 case T_Wildcard:
2093 match_type = MATCH_WILDCARD;
2094 break;
2095 }
2096
2097 switch (curr_node->action) {
2098
2099 default:
2100 /*
2101 * this assignment quiets a gcc "may be used
2102 * uninitialized" warning and is here for no
2103 * other reason.
2104 */
2105 action = ACTION_LISTEN;
2106 INSIST(false);
2107 break;
2108
2109 case T_Listen:
2110 action = ACTION_LISTEN;
2111 break;
2112
2113 case T_Ignore:
2114 action = ACTION_IGNORE;
2115 break;
2116
2117 case T_Drop:
2118 action = ACTION_DROP;
2119 break;
2120 }
2121
2122 add_nic_rule(match_type, if_name, prefixlen,
2123 action);
2124 timer_interfacetimeout(current_time + 2);
2125 if (if_name != NULL)
2126 free(if_name);
2127 }
2128 }
2129
2130
2131 static void
free_config_nic_rules(config_tree * ptree)2132 free_config_nic_rules(
2133 config_tree *ptree
2134 )
2135 {
2136 nic_rule_node *curr_node;
2137
2138 if (ptree->nic_rules != NULL) {
2139 for (;;) {
2140 UNLINK_FIFO(curr_node, *ptree->nic_rules, link);
2141 if (NULL == curr_node)
2142 break;
2143 free(curr_node->if_name);
2144 free(curr_node);
2145 }
2146 free(ptree->nic_rules);
2147 ptree->nic_rules = NULL;
2148 }
2149 }
2150
2151
2152 static void
apply_enable_disable(attr_val_fifo * fifo,int enable)2153 apply_enable_disable(
2154 attr_val_fifo * fifo,
2155 int enable
2156 )
2157 {
2158 attr_val *curr_flag;
2159 int option;
2160
2161 for (curr_flag = HEAD_PFIFO(fifo);
2162 curr_flag != NULL;
2163 curr_flag = curr_flag->link) {
2164
2165 option = curr_flag->value.i;
2166 switch (option) {
2167
2168 default:
2169 msyslog(LOG_ERR,
2170 "CONFIG: can not apply enable/disable token %d, unknown",
2171 option);
2172 break;
2173
2174 case T_Calibrate:
2175 proto_config(PROTO_CAL, (unsigned long)enable, 0.);
2176 break;
2177
2178 case T_Kernel:
2179 proto_config(PROTO_KERNEL, (unsigned long)enable, 0.);
2180 break;
2181
2182 case T_Monitor:
2183 proto_config(PROTO_MONITOR, (unsigned long)enable, 0.);
2184 break;
2185
2186 case T_Ntp:
2187 proto_config(PROTO_NTP, (unsigned long)enable, 0.);
2188 break;
2189
2190 case T_Stats:
2191 proto_config(PROTO_FILEGEN, (unsigned long)enable, 0.);
2192 break;
2193
2194 }
2195 }
2196 }
2197
2198
2199 static void
config_system_opts(config_tree * ptree)2200 config_system_opts(
2201 config_tree *ptree
2202 )
2203 {
2204 apply_enable_disable(ptree->enable_opts, 1);
2205 apply_enable_disable(ptree->disable_opts, 0);
2206 }
2207
2208
2209 static void
free_config_system_opts(config_tree * ptree)2210 free_config_system_opts(
2211 config_tree *ptree
2212 )
2213 {
2214 FREE_ATTR_VAL_FIFO(ptree->enable_opts);
2215 FREE_ATTR_VAL_FIFO(ptree->disable_opts);
2216 }
2217
2218
2219 static void
config_logconfig(config_tree * ptree)2220 config_logconfig(
2221 config_tree *ptree
2222 )
2223 {
2224 attr_val * my_lc;
2225
2226 my_lc = HEAD_PFIFO(ptree->logconfig);
2227 for (; my_lc != NULL; my_lc = my_lc->link) {
2228 switch (my_lc->attr) {
2229
2230 case '+':
2231 ntp_syslogmask |= get_logmask(my_lc->value.s);
2232 break;
2233
2234 case '-':
2235 ntp_syslogmask &= ~get_logmask(my_lc->value.s);
2236 break;
2237
2238 case '=':
2239 ntp_syslogmask = get_logmask(my_lc->value.s);
2240 break;
2241 default:
2242 INSIST(0);
2243 break;
2244 }
2245 }
2246 }
2247
2248
2249 static void
free_config_logconfig(config_tree * ptree)2250 free_config_logconfig(
2251 config_tree *ptree
2252 )
2253 {
2254 FREE_ATTR_VAL_FIFO(ptree->logconfig);
2255 }
2256
2257
2258 static void
config_phone(config_tree * ptree)2259 config_phone(
2260 config_tree *ptree
2261 )
2262 {
2263 size_t i;
2264 string_node * sn;
2265
2266 i = 0;
2267 sn = HEAD_PFIFO(ptree->phone);
2268 for (; sn != NULL; sn = sn->link) {
2269 /* need to leave array entry for NULL terminator */
2270 if (i < COUNTOF(sys_phone) - 1) {
2271 sys_phone[i++] = estrdup(sn->s);
2272 sys_phone[i] = NULL;
2273 } else {
2274 msyslog(LOG_INFO,
2275 "CONFIG: Number of phone entries exceeds %zu. Ignoring phone %s...",
2276 (COUNTOF(sys_phone) - 1), sn->s);
2277 }
2278 }
2279 }
2280
2281 static void
config_mdnstries(config_tree * ptree)2282 config_mdnstries(
2283 config_tree *ptree
2284 )
2285 {
2286 #if defined(HAVE_DNS_SD_H)
2287 mdnstries = ptree->mdnstries;
2288 #else
2289 UNUSED_ARG(ptree);
2290 #endif /* HAVE_DNS_SD_H */
2291 }
2292
2293 static void
free_config_phone(config_tree * ptree)2294 free_config_phone(
2295 config_tree *ptree
2296 )
2297 {
2298 FREE_STRING_FIFO(ptree->phone);
2299 }
2300
2301
2302 static void
config_setvar(config_tree * ptree)2303 config_setvar(
2304 config_tree *ptree
2305 )
2306 {
2307 setvar_node *my_node;
2308 size_t varlen, vallen, octets;
2309 char * str;
2310
2311 str = NULL;
2312 my_node = HEAD_PFIFO(ptree->setvar);
2313 for (; my_node != NULL; my_node = my_node->link) {
2314 varlen = strlen(my_node->var);
2315 vallen = strlen(my_node->val);
2316 octets = varlen + vallen + 1 + 1;
2317 str = erealloc(str, octets);
2318 snprintf(str, octets, "%s=%s", my_node->var,
2319 my_node->val);
2320 set_sys_var(str, octets, (my_node->isdefault)
2321 ? DEF
2322 : 0);
2323 }
2324 if (str != NULL) {
2325 free(str);
2326 }
2327 }
2328
2329
2330 static void
free_config_setvar(config_tree * ptree)2331 free_config_setvar(
2332 config_tree *ptree
2333 )
2334 {
2335 FREE_SETVAR_FIFO(ptree->setvar);
2336 }
2337
2338
2339 static void
config_fudge(config_tree * ptree)2340 config_fudge(
2341 config_tree *ptree
2342 )
2343 {
2344 addr_opts_node *curr_fudge;
2345 # ifdef REFCLOCK
2346 attr_val *curr_opt;
2347 sockaddr_u addr_sock;
2348 struct refclockstat clock_stat;
2349
2350 curr_fudge = HEAD_PFIFO(ptree->fudge);
2351 for (; curr_fudge != NULL; curr_fudge = curr_fudge->link) {
2352 bool err_flag = false;
2353
2354 /* Get the reference clock address and
2355 * ensure that it is sane
2356 */
2357 address_node *addr_node = curr_fudge->addr;
2358 ZERO_SOCK(&addr_sock);
2359 if (getnetnum(addr_node->address, &addr_sock)
2360 != 1) {
2361 err_flag = true;
2362 msyslog(LOG_ERR,
2363 "CONFIG: unrecognized fudge reference clock address %s, line ignored",
2364 socktoa(&addr_sock));
2365 }
2366
2367 if (!ISREFCLOCKADR(&addr_sock)) {
2368 err_flag = true;
2369 msyslog(LOG_ERR,
2370 "CONFIG: inappropriate address %s for the fudge command, line ignored",
2371 socktoa(&addr_sock));
2372 }
2373
2374 /* Parse all the options to the fudge command */
2375 ZERO(clock_stat);
2376 curr_opt = HEAD_PFIFO(curr_fudge->options);
2377 for (; curr_opt != NULL; curr_opt = curr_opt->link) {
2378 switch (curr_opt->attr) {
2379
2380 case T_Time1:
2381 clock_stat.haveflags |= CLK_HAVETIME1;
2382 clock_stat.fudgetime1 = curr_opt->value.d;
2383 break;
2384
2385 case T_Time2:
2386 clock_stat.haveflags |= CLK_HAVETIME2;
2387 clock_stat.fudgetime2 = curr_opt->value.d;
2388 break;
2389
2390 case T_Stratum:
2391 clock_stat.haveflags |= CLK_HAVEVAL1;
2392 clock_stat.fudgeval1 = curr_opt->value.i;
2393 break;
2394
2395 case T_Refid:
2396 clock_stat.haveflags |= CLK_HAVEVAL2;
2397 clock_stat.fudgeval2 = 0;
2398 memcpy(&clock_stat.fudgeval2,
2399 curr_opt->value.s,
2400 min(strlen(curr_opt->value.s), REFIDLEN));
2401 break;
2402
2403 case T_Flag1:
2404 clock_stat.haveflags |= CLK_HAVEFLAG1;
2405 if (curr_opt->value.i)
2406 clock_stat.flags |= CLK_FLAG1;
2407 else
2408 clock_stat.flags &= ~CLK_FLAG1;
2409 break;
2410
2411 case T_Flag2:
2412 clock_stat.haveflags |= CLK_HAVEFLAG2;
2413 if (curr_opt->value.i)
2414 clock_stat.flags |= CLK_FLAG2;
2415 else
2416 clock_stat.flags &= ~CLK_FLAG2;
2417 break;
2418
2419 case T_Flag3:
2420 clock_stat.haveflags |= CLK_HAVEFLAG3;
2421 if (curr_opt->value.i)
2422 clock_stat.flags |= CLK_FLAG3;
2423 else
2424 clock_stat.flags &= ~CLK_FLAG3;
2425 break;
2426
2427 case T_Flag4:
2428 clock_stat.haveflags |= CLK_HAVEFLAG4;
2429 if (curr_opt->value.i)
2430 clock_stat.flags |= CLK_FLAG4;
2431 else
2432 clock_stat.flags &= ~CLK_FLAG4;
2433 break;
2434
2435 default:
2436 msyslog(LOG_ERR,
2437 "CONFIG: Unexpected fudge flag %s (%d) for %s",
2438 token_name(curr_opt->attr),
2439 curr_opt->attr, socktoa(&addr_sock));
2440 exit(curr_opt->attr ? curr_opt->attr : 1);
2441 }
2442 }
2443 if (!err_flag)
2444 refclock_control(&addr_sock, &clock_stat, NULL);
2445 }
2446 # else
2447 curr_fudge = HEAD_PFIFO(ptree->fudge);
2448 if (curr_fudge != NULL)
2449 msyslog(LOG_ERR, "CONFIG: Fudge commands not supported: built without refclocks");
2450 # endif
2451 }
2452
2453
2454 static void
free_config_fudge(config_tree * ptree)2455 free_config_fudge(
2456 config_tree *ptree
2457 )
2458 {
2459 FREE_ADDR_OPTS_FIFO(ptree->fudge);
2460 }
2461
2462
2463 /* Clone of config_vars that only does log file. */
2464 static void
config_logfile(config_tree * ptree)2465 config_logfile(
2466 config_tree *ptree
2467 )
2468 {
2469 attr_val *curr_var;
2470
2471 curr_var = HEAD_PFIFO(ptree->vars);
2472 for (; curr_var != NULL; curr_var = curr_var->link) {
2473 /* Determine which variable to set and set it */
2474 switch (curr_var->attr) {
2475
2476 case T_Logfile:
2477 if (-1 == change_logfile(curr_var->value.s, true))
2478 msyslog(LOG_ERR,
2479 "CONFIG: Cannot open logfile %s: %s",
2480 curr_var->value.s, strerror(errno));
2481 /* Repeat critical info in logfile. Helps debugging. */
2482 announce_starting();
2483 break;
2484
2485 default:
2486 break;
2487 }
2488 }
2489 }
2490
2491
2492 static void
config_vars(config_tree * ptree)2493 config_vars(
2494 config_tree *ptree
2495 )
2496 {
2497 attr_val *curr_var;
2498
2499 curr_var = HEAD_PFIFO(ptree->vars);
2500 for (; curr_var != NULL; curr_var = curr_var->link) {
2501 /* Determine which variable to set and set it */
2502 switch (curr_var->attr) {
2503
2504 #ifdef ENABLE_FUZZ
2505 case T_Tick:
2506 loop_config(LOOP_TICK, curr_var->value.d);
2507 break;
2508 #endif
2509
2510 case T_Driftfile:
2511 if ('\0' == curr_var->value.s[0]) {
2512 stats_drift_file = 0;
2513 msyslog(LOG_INFO, "CONFIG: driftfile disabled");
2514 } else
2515 stats_config(STATS_FREQ_FILE, curr_var->value.s);
2516 break;
2517
2518 case T_Dscp:
2519 /* DSCP is in the upper 6 bits of the IP TOS/DS field */
2520 qos = curr_var->value.i << 2;
2521 break;
2522
2523 case T_WanderThreshold: /* FALLTHROUGH */
2524 case T_Nonvolatile:
2525 wander_threshold = curr_var->value.d;
2526 break;
2527
2528 case T_Leapfile:
2529 stats_config(STATS_LEAP_FILE, curr_var->value.s);
2530 break;
2531
2532 #ifdef ENABLE_LEAP_SMEAR
2533 case T_Leapsmearinterval:
2534 if (curr_var->value.i < 0) {
2535 msyslog(LOG_ERR, "CONFIG: negative leap smear interval ignored: %i", curr_var->value.i);
2536 break;
2537 }
2538 leap_smear_intv = curr_var->value.u;
2539 msyslog(LOG_INFO, "CONFIG: leap smear interval %u sec", leap_smear_intv);
2540 break;
2541 #endif
2542
2543 case T_Pidfile:
2544 stats_config(STATS_PID_FILE, curr_var->value.s);
2545 break;
2546
2547 case T_Logfile:
2548 /* processed in config_logfile */
2549 break;
2550
2551 default:
2552 msyslog(LOG_ERR,
2553 "CONFIG: config_vars(): unexpected token %d",
2554 curr_var->attr);
2555 }
2556 }
2557 }
2558
2559
2560 static void
free_config_vars(config_tree * ptree)2561 free_config_vars(
2562 config_tree *ptree
2563 )
2564 {
2565 FREE_ATTR_VAL_FIFO(ptree->vars);
2566 }
2567
2568
2569 /* Define a function to check if a resolved address is sane.
2570 * If yes, return true, else return false;
2571 */
2572 static bool
is_sane_resolved_address(sockaddr_u * peeraddr,int hmode)2573 is_sane_resolved_address(
2574 sockaddr_u * peeraddr,
2575 int hmode
2576 )
2577 {
2578 if (!ISREFCLOCKADR(peeraddr) && ISBADADR(peeraddr)) {
2579 msyslog(LOG_ERR,
2580 "CONFIG: attempt to configure invalid address %s",
2581 socktoa(peeraddr));
2582 return false;
2583 }
2584 /*
2585 * Shouldn't be able to specify multicast
2586 * address for server/peer!
2587 */
2588 if ((T_Server == hmode || T_Peer == hmode || T_Pool == hmode)
2589 && IS_MCAST(peeraddr)) {
2590 msyslog(LOG_ERR,
2591 "CONFIG: attempt to configure invalid address %s",
2592 socktoa(peeraddr));
2593 return false;
2594 }
2595
2596 if (IS_IPV6(peeraddr) && !ipv6_works)
2597 /* FIXME: error message */
2598 return false;
2599
2600 /* Ok, all tests succeeded, now we can return true */
2601 return true;
2602 }
2603
2604
2605 /*
2606 * peer_config - configure a new association
2607 *
2608 * RETURN: a pointer to the new peer structure
2609 * NULL if this would duplicate an existing peer
2610 */
2611 struct peer *
peer_config(sockaddr_u * srcadr,const char * hostname,endpt * dstadr,int htype,struct peer_ctl * ctl)2612 peer_config(
2613 sockaddr_u * srcadr,
2614 const char * hostname,
2615 endpt * dstadr,
2616 int htype,
2617 struct peer_ctl *ctl)
2618 {
2619 uint8_t cast_flags;
2620 uint8_t hmode;
2621
2622 /*
2623 * We do a dirty little jig to figure the cast flags. This is
2624 * probably not the best place to do this, at least until the
2625 * configure code is rebuilt. Note only one flag can be set.
2626 */
2627 switch (htype) {
2628
2629 case T_Pool:
2630 cast_flags = MDF_POOL;
2631 hmode = MODE_CLIENT;
2632 ctl->flags &= ~FLAG_PREEMPT;
2633 break;
2634
2635 case T_Peer:
2636 msyslog(LOG_ERR, "CONFIG: peer deprecated, treated as server: %s",
2637 NULL != hostname? hostname : socktoa(srcadr) );
2638 FALLTHRU
2639 case T_Server:
2640 cast_flags = MDF_UCAST;
2641 hmode = MODE_CLIENT;
2642 if (NULL != hostname)
2643 ctl->flags |= (FLAG_DNS | FLAG_LOOKUP);
2644 break;
2645
2646 default:
2647 msyslog(LOG_ERR, "CONFIG: peer_config, strange htype: %d", htype);
2648 cast_flags = MDF_UCAST;
2649 hmode = MODE_CLIENT;
2650 }
2651
2652 /*
2653 * Mobilize the association and initialize its variables. If
2654 * emulating ntpdate, force iburst. For pool,
2655 * strip FLAG_PREEMPT as the prototype associations are not
2656 * themselves preemptible, though the resulting associations
2657 * are.
2658 */
2659 ctl->flags |= FLAG_CONFIG;
2660 if (clock_ctl.mode_ntpdate)
2661 ctl->flags |= FLAG_IBURST;
2662 return newpeer(srcadr, hostname, dstadr, hmode,
2663 ctl, cast_flags, true);
2664 }
2665
2666
2667 static void
config_peers(config_tree * ptree)2668 config_peers(
2669 config_tree *ptree
2670 )
2671 {
2672 sockaddr_u peeraddr;
2673
2674 /* add servers named on the command line with iburst implied */
2675 for ( ; cmdline_server_count > 0;
2676 cmdline_server_count--, cmdline_servers++) {
2677 struct peer_ctl client_ctl;
2678 /* so any new members we introduce will be zeroed */
2679 memset(&client_ctl, '\0', sizeof(struct peer_ctl));
2680 client_ctl.version = NTP_VERSION;
2681 client_ctl.minpoll = NTP_MINDPOLL;
2682 client_ctl.maxpoll = NTP_MAXPOLL_UNK;
2683 client_ctl.flags = FLAG_IBURST;
2684 client_ctl.mode = 0;
2685 client_ctl.peerkey = 0;
2686 client_ctl.bias = 0;
2687
2688 ZERO_SOCK(&peeraddr);
2689 /*
2690 * If we have a numeric address, we can safely
2691 * proceed in the mainline with it. Otherwise, hand
2692 * the hostname off to the blocking child.
2693 */
2694 if (is_ip_address(*cmdline_servers, AF_UNSPEC, &peeraddr)) {
2695 SET_PORT(&peeraddr, NTP_PORT);
2696 if (is_sane_resolved_address(&peeraddr,
2697 T_Server))
2698 peer_config(
2699 &peeraddr,
2700 NULL,
2701 NULL,
2702 T_Server,
2703 &client_ctl);
2704 } else {
2705 /* we have a hostname to resolve */
2706 peer_config(
2707 &peeraddr,
2708 *cmdline_servers,
2709 NULL,
2710 T_Server,
2711 &client_ctl);
2712 }
2713 }
2714
2715 /* add associations from the configuration file */
2716 peer_node * curr_peer = HEAD_PFIFO(ptree->peers);
2717 for (; curr_peer != NULL; curr_peer = curr_peer->link) {
2718 ZERO_SOCK(&peeraddr);
2719
2720 if (T_Pool == curr_peer->host_mode) {
2721 AF(&peeraddr) = curr_peer->addr->type;
2722 peer_config(
2723 &peeraddr,
2724 curr_peer->addr->address,
2725 NULL,
2726 curr_peer->host_mode,
2727 &curr_peer->ctl);
2728 /*
2729 * If we have a numeric address, we can safely
2730 * proceed in the mainline with it.
2731 */
2732 } else if (is_ip_address(curr_peer->addr->address,
2733 curr_peer->addr->type, &peeraddr)) {
2734
2735 SET_PORT(&peeraddr, NTP_PORT);
2736 if (is_sane_resolved_address(&peeraddr, curr_peer->host_mode)) {
2737 #ifdef REFCLOCK
2738 /* save maxpoll from config line
2739 * newpeer smashes it
2740 */
2741 uint8_t maxpoll = curr_peer->ctl.maxpoll;
2742 #endif
2743 struct peer *peer = peer_config(
2744 &peeraddr,
2745 NULL,
2746 NULL,
2747 curr_peer->host_mode,
2748 &curr_peer->ctl);
2749 if ( NULL == peer )
2750 {
2751 /* duplicate peer !?, ignore */
2752 msyslog(LOG_INFO, "CONFIG: configpeers: Ignoring duplicate '%s'",
2753 socktoa(&peeraddr));
2754 continue;
2755 }
2756 if (ISREFCLOCKADR(&peeraddr))
2757 {
2758 #ifdef REFCLOCK
2759 uint8_t clktype;
2760 int unit;
2761 /*
2762 * We let the reference clock
2763 * support do clock dependent
2764 * initialization. This
2765 * includes setting the peer
2766 * timer, since the clock may
2767 * have requirements for this.
2768 */
2769 if (NTP_MAXPOLL_UNK == maxpoll)
2770 /* default maxpoll for
2771 * refclocks is minpoll
2772 */
2773 peer->cfg.maxpoll = peer->cfg.minpoll;
2774 clktype = (uint8_t)REFCLOCKTYPE(&peer->srcadr);
2775 unit = REFCLOCKUNIT(&peer->srcadr);
2776
2777 peer->cfg.path = curr_peer->ctl.path;
2778 peer->cfg.ppspath = curr_peer->ctl.ppspath;
2779 peer->cfg.baud = curr_peer->ctl.baud;
2780 if (refclock_newpeer(clktype,
2781 unit,
2782 peer))
2783 refclock_control(&peeraddr,
2784 &curr_peer->clock_stat,
2785 NULL);
2786 else
2787 /*
2788 * Dump it, something screwed up
2789 */
2790 unpeer(peer);
2791 #else /* REFCLOCK */
2792 msyslog(LOG_ERR,
2793 "INIT: ntpd was compiled without refclock support.");
2794 unpeer(peer);
2795 #endif /* REFCLOCK */
2796 }
2797
2798 }
2799 /* DNS lookup */
2800 } else {
2801 AF(&peeraddr) = curr_peer->addr->type;
2802 struct peer *peer = peer_config(
2803 &peeraddr,
2804 curr_peer->addr->address,
2805 NULL,
2806 curr_peer->host_mode,
2807 &curr_peer->ctl);
2808 if (NULL == peer)
2809 msyslog(LOG_INFO, "CONFIG: configpeers: Ignoring duplicate '%s'", curr_peer->addr->address);
2810 }
2811 }
2812 }
2813
2814 static void
free_config_peers(config_tree * ptree)2815 free_config_peers(
2816 config_tree *ptree
2817 )
2818 {
2819 peer_node *curr_peer;
2820
2821 if (ptree->peers != NULL) {
2822 for (;;) {
2823 UNLINK_FIFO(curr_peer, *ptree->peers, link);
2824 if (NULL == curr_peer)
2825 break;
2826 destroy_address_node(curr_peer->addr);
2827 free(curr_peer);
2828 }
2829 free(ptree->peers);
2830 ptree->peers = NULL;
2831 }
2832 }
2833
2834
2835 static void
config_unpeers(config_tree * ptree)2836 config_unpeers(
2837 config_tree *ptree
2838 )
2839 {
2840 sockaddr_u peeraddr;
2841 struct peer * p;
2842 const char * name;
2843 int rc;
2844
2845 unpeer_node * curr_unpeer = HEAD_PFIFO(ptree->unpeers);
2846 for (; curr_unpeer != NULL; curr_unpeer = curr_unpeer->link) {
2847 /*
2848 * Either AssocID will be zero, and we unpeer by name/
2849 * address addr, or it is nonzero and addr NULL.
2850 */
2851 if (curr_unpeer->assocID) {
2852 p = findpeerbyassoc(curr_unpeer->assocID);
2853 if (p != NULL) {
2854 msyslog(LOG_NOTICE, "CONFIG: unpeered %s",
2855 socktoa(&p->srcadr));
2856 peer_clear(p, "GONE", true);
2857 unpeer(p);
2858 }
2859
2860 continue;
2861 }
2862
2863 if (curr_unpeer->addr == NULL) {
2864 msyslog(LOG_ERR, "CONFIG: invalid address in unpeer command");
2865 continue;
2866 }
2867
2868 ZERO(peeraddr);
2869 AF(&peeraddr) = curr_unpeer->addr->type;
2870 name = curr_unpeer->addr->address;
2871 rc = getnetnum(name, &peeraddr);
2872 /* Do we have a numeric address? */
2873 if (rc > 0) {
2874 DPRINT(1, ("unpeer: searching for %s\n",
2875 socktoa(&peeraddr)));
2876 p = findexistingpeer(&peeraddr, NULL, NULL, -1);
2877 if (p != NULL) {
2878 msyslog(LOG_NOTICE, "CONFIG: unpeered %s",
2879 socktoa(&peeraddr));
2880 peer_clear(p, "GONE", true);
2881 unpeer(p);
2882 }
2883
2884 continue;
2885 }
2886
2887 /* It's not a numeric IP address... */
2888
2889 /* It's a hostname. */
2890 p = findexistingpeer(NULL, name, NULL, -1);
2891 if (p != NULL) {
2892 msyslog(LOG_NOTICE, "CONFIG: unpeered %s", name);
2893 peer_clear(p, "GONE", true);
2894 unpeer(p);
2895 }
2896 }
2897 }
2898
2899
2900 static void
free_config_unpeers(config_tree * ptree)2901 free_config_unpeers(
2902 config_tree *ptree
2903 )
2904 {
2905 unpeer_node *curr_unpeer;
2906
2907 if (ptree->unpeers != NULL) {
2908 for (;;) {
2909 UNLINK_FIFO(curr_unpeer, *ptree->unpeers, link);
2910 if (NULL == curr_unpeer)
2911 break;
2912 destroy_address_node(curr_unpeer->addr);
2913 free(curr_unpeer);
2914 }
2915 free(ptree->unpeers);
2916 }
2917 }
2918
2919
2920 static void
config_reset_counters(config_tree * ptree)2921 config_reset_counters(
2922 config_tree *ptree
2923 )
2924 {
2925 int_node *counter_set;
2926
2927 for (counter_set = HEAD_PFIFO(ptree->reset_counters);
2928 counter_set != NULL;
2929 counter_set = counter_set->link) {
2930 switch (counter_set->i) {
2931 default:
2932 DPRINT(1, ("config_reset_counters %s (%d) invalid\n",
2933 keyword(counter_set->i), counter_set->i));
2934 break;
2935
2936 case T_Allpeers:
2937 peer_all_reset();
2938 break;
2939
2940 case T_Auth:
2941 auth_reset_stats(current_time);
2942 break;
2943
2944 case T_Ctl:
2945 ctl_clr_stats();
2946 break;
2947
2948 case T_Io:
2949 io_clr_stats();
2950 break;
2951
2952 case T_Mem:
2953 peer_clr_stats();
2954 break;
2955
2956 case T_Sys:
2957 proto_clr_stats();
2958 break;
2959
2960 case T_Timer:
2961 timer_clr_stats();
2962 break;
2963 }
2964 }
2965 }
2966
2967
2968 static void
free_config_reset_counters(config_tree * ptree)2969 free_config_reset_counters(
2970 config_tree *ptree
2971 )
2972 {
2973 FREE_INT_FIFO(ptree->reset_counters);
2974 }
2975
2976
2977 static void
config_ntpd(config_tree * ptree,bool input_from_files)2978 config_ntpd(
2979 config_tree *ptree,
2980 bool input_from_files
2981 )
2982 {
2983
2984 /* Do this early so most errors go to new log file */
2985 /* Command line arg is earlier. */
2986 config_logfile(ptree);
2987
2988 config_nic_rules(ptree, input_from_files);
2989 config_monitor(ptree);
2990 config_auth(ptree);
2991 config_tos(ptree);
2992 config_access(ptree); /* before config_peers */
2993 config_tinker(ptree);
2994 config_nts(ptree);
2995 config_rlimit(ptree);
2996 config_system_opts(ptree);
2997 config_logconfig(ptree);
2998 config_phone(ptree);
2999 config_mdnstries(ptree);
3000 config_setvar(ptree);
3001 config_vars(ptree);
3002
3003 io_open_sockets();
3004
3005 config_peers(ptree);
3006 config_unpeers(ptree);
3007 config_fudge(ptree);
3008 config_reset_counters(ptree);
3009 }
3010
3011
3012 /*
3013 * config_remotely() - implements ntpd side of ntpq :config
3014 */
3015 void
config_remotely(sockaddr_u * remote_addr)3016 config_remotely(
3017 sockaddr_u * remote_addr
3018 )
3019 {
3020 char origin[128];
3021
3022 snprintf(origin, sizeof(origin), "remote config from %s",
3023 socktoa(remote_addr));
3024 lex_init_stack(origin, NULL); /* no checking needed... */
3025 init_syntax_tree(&cfgt);
3026 yyparse();
3027 lex_drop_stack();
3028
3029 cfgt.source.attr = CONF_SOURCE_NTPQ;
3030 cfgt.timestamp = time(NULL);
3031 cfgt.source.value.s = estrdup(socktoa(remote_addr));
3032
3033 DPRINT(1, ("Finished Parsing!!\n"));
3034
3035 save_and_apply_config_tree(false);
3036 }
3037
3038
3039 /*
3040 * getconfig() - return name of configuration file e.g /etc/ntp.conf
3041 */
3042 const char *
getconfig(const char * explicit_config)3043 getconfig(const char *explicit_config)
3044 {
3045 const char *config_file;
3046
3047 config_file = CONFIG_FILE;
3048
3049 if (explicit_config) {
3050 config_file = explicit_config;
3051 }
3052
3053 return config_file;
3054 }
3055
3056 /*
3057 * init_readconfig() - init for readconfig
3058 */
init_readconfig(void)3059 void init_readconfig(void)
3060 {
3061 init_syntax_tree(&cfgt);
3062 }
3063
3064 /*
3065 * readconfig() - process startup configuration file
3066 */
readconfig(const char * config_file)3067 void readconfig(const char *config_file)
3068 {
3069 char line[256];
3070 char dirpath[PATH_MAX];
3071 int srccount;
3072 /*
3073 * install a non default variable with this daemon version
3074 */
3075 snprintf(line, sizeof(line), "daemon_version=\"%s\"", ntpd_version());
3076 set_sys_var(line, strlen(line) + 1, RO);
3077
3078 atexit(free_all_config_trees);
3079
3080 #ifdef DEBUG
3081 #ifndef yydebug
3082 /* See comment above for yyparse */
3083 extern int yydebug;
3084 #endif
3085 yydebug = !!(debug >= 5);
3086 #endif
3087
3088 /* Moved to init_readconfig so command lines can contribute info
3089 * init_syntax_tree(&cfgt);
3090 */
3091 srccount = 0;
3092
3093 /* parse the plain config file if it exists */
3094 if (lex_init_stack(config_file, "r")) {
3095 msyslog(LOG_INFO, "CONFIG: readconfig: parsing file: %s", config_file);
3096 yyparse();
3097 ++srccount;
3098 //cfgt.source.value.s = estrdup(config_file);
3099 }
3100
3101 /* parse configs in parallel subdirectory if that exists */
3102 reparent(dirpath, sizeof(dirpath), config_file, CONFIG_DIR);
3103 if (is_directory(dirpath) && lex_push_file(dirpath)) {
3104 msyslog(LOG_INFO, "CONFIG: readconfig: parsing directory: %s", dirpath);
3105 yyparse();
3106 ++srccount;
3107 }
3108
3109 if (srccount == 0) {
3110 io_open_sockets();
3111 }
3112
3113 lex_drop_stack();
3114
3115 DPRINT(1, ("Finished Parsing!!\n"));
3116
3117 //cfgt.source.attr = CONF_SOURCE_FILE;
3118 cfgt.timestamp = time(NULL);
3119
3120 save_and_apply_config_tree(true);
3121 }
3122
3123
3124 /* hooks for ntpd.c */
3125
set_keys_file(char * keys)3126 void set_keys_file(char* keys)
3127 {
3128 cfgt.auth.keys = estrdup(keys);
3129 }
3130
set_trustedkey(keyid_t tkey)3131 void set_trustedkey(keyid_t tkey)
3132 {
3133 attr_val *val = create_attr_ival('i', tkey);
3134 attr_val *val2 = NULL;
3135 APPEND_G_FIFO(val2, val);
3136 CONCAT_G_FIFOS(cfgt.auth.trusted_key_list, val2);
3137 }
3138
3139
3140
3141 void
save_and_apply_config_tree(bool input_from_file)3142 save_and_apply_config_tree(bool input_from_file)
3143 {
3144 config_tree *ptree;
3145 config_tree *punlinked;
3146
3147 /*
3148 * Keep all the configuration trees applied since startup in
3149 * a list that can be used to dump the configuration back to
3150 * a text file.
3151 */
3152 ptree = emalloc(sizeof(*ptree));
3153 memcpy(ptree, &cfgt, sizeof(*ptree));
3154 ZERO(cfgt);
3155
3156 LINK_TAIL_SLIST(cfg_tree_history, ptree, link, config_tree);
3157
3158 /* The actual configuration done depends on whether we are
3159 * configuring the simulator or the daemon. Perform a check
3160 * and call the appropriate function as needed.
3161 */
3162
3163 config_ntpd(ptree, input_from_file);
3164
3165 UNLINK_SLIST(punlinked, cfg_tree_history, ptree, link,
3166 config_tree);
3167 INSIST(punlinked == ptree);
3168 free_config_tree(ptree);
3169 }
3170
3171
3172 /* FUNCTIONS COPIED FROM THE OLDER ntp_config.c
3173 * --------------------------------------------
3174 */
3175
3176
3177 /*
3178 * get_pfxmatch - find value for prefixmatch
3179 * and update char * accordingly
3180 */
3181 static uint32_t
get_pfxmatch(const char ** pstr,struct masks * m)3182 get_pfxmatch(
3183 const char ** pstr,
3184 struct masks * m
3185 )
3186 {
3187 while (m->name != NULL) {
3188 if (strncmp(*pstr, m->name, strlen(m->name)) == 0) {
3189 *pstr += strlen(m->name);
3190 return m->mask;
3191 } else {
3192 m++;
3193 }
3194 }
3195 return 0;
3196 }
3197
3198 /*
3199 * get_match - find logmask value
3200 */
3201 static uint32_t
get_match(const char * str,struct masks * m)3202 get_match(
3203 const char * str,
3204 struct masks * m
3205 )
3206 {
3207 while (m->name != NULL) {
3208 if (strcmp(str, m->name) == 0) {
3209 return m->mask;
3210 } else {
3211 m++;
3212 }
3213 }
3214 return 0;
3215 }
3216
3217 /*
3218 * get_logmask - build bitmask for ntp_syslogmask
3219 */
3220 static uint32_t
get_logmask(const char * str)3221 get_logmask(
3222 const char * str
3223 )
3224 {
3225 const char * t;
3226 uint32_t offset;
3227 uint32_t mask;
3228
3229 mask = get_match(str, logcfg_noclass_items);
3230 if (mask != 0)
3231 return mask;
3232
3233 t = str;
3234 offset = get_pfxmatch(&t, logcfg_class);
3235 mask = get_match(t, logcfg_class_items);
3236
3237 if (mask)
3238 return mask << offset;
3239 else
3240 msyslog(LOG_ERR, "CONFIG: logconfig: '%s' not recognized - ignored",
3241 str);
3242
3243 return 0;
3244 }
3245
3246 /*
3247 * check my_node->addr for CIDR notation
3248 * if so, convert to old addr/mask notation and override mask
3249 */
3250 static void
fix_node_cidr(restrict_node * my_node)3251 fix_node_cidr(
3252 restrict_node *my_node)
3253 {
3254 address_node *addr;
3255 char mask_s[40], *mask_p;
3256 char *cidr_p;
3257 char *colon_p;
3258 char *endptr;
3259 long cidr_len;
3260 int i;
3261 unsigned a[8];
3262
3263 REQUIRE(my_node);
3264 addr = my_node->addr;
3265 REQUIRE(addr);
3266
3267 cidr_p = strrchr(addr->address, '/');
3268 if (!cidr_p) {
3269 /* not CIDR, leave silently */
3270 return;
3271 }
3272 *cidr_p++ = '\0'; /* remove the '/' and beyond from address */
3273 /* get CIDR as int */
3274 errno = 0;
3275 cidr_len = strtol(cidr_p, &endptr, 10);
3276 if ( errno || (endptr == cidr_p) ) {
3277 /* conversion fail, leave silently */
3278 return;
3279 }
3280 if ( 0 >= cidr_len ) {
3281 /* negative or zero? leave silently */
3282 /* exiting on 0 avoids a bad shift warning from Coverity */
3283 return;
3284 }
3285 /* sadly, addr->type not previously set, look for colon */
3286 colon_p = strrchr(addr->address, ':');
3287 if (colon_p) {
3288 /* IPv6 */
3289 uint64_t mask_top = 0xFFFFFFFFFFFFFFFFU;
3290 uint64_t mask_bot = 0xFFFFFFFFFFFFFFFFU;
3291
3292 if ( 128 < cidr_len ) {
3293 /* out of range, leave silently */
3294 return;
3295 }
3296 if ( 64 >= cidr_len ) {
3297 mask_bot = 0;
3298 mask_top <<= 64 - cidr_len ;
3299 } else {
3300 mask_bot <<= 128 - cidr_len ;
3301 }
3302 for (i = 0; i < 4; i++)
3303 a[i] = mask_top >> (16 * (3 - i)) & 0xffffU;
3304 for (i = 0; i < 4; i++)
3305 a[i + 4] = mask_bot >> (16 * (3 - i)) & 0xffffU;
3306
3307 snprintf(mask_s, sizeof(mask_s), "%x:%x:%x:%x:%x:%x:%x:%x",
3308 a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
3309 } else {
3310 /* must be IPv4 */
3311 uint32_t mask_n = 0xFFFFFFFFU;
3312
3313 if ( 32 < cidr_len ) {
3314 /* out of range, leave silently */
3315 return;
3316 }
3317
3318 mask_n <<= 32 - cidr_len ;
3319 for (i = 0; i < 4; i++)
3320 a[i] = mask_n >> (8 * (3 - i)) & 0xff;
3321
3322 snprintf(mask_s, sizeof(mask_s), "%u.%u.%u.%u",
3323 a[0], a[1], a[2], a[3]);
3324 }
3325
3326 /* lose old mask */
3327 destroy_address_node(my_node->mask);
3328
3329 /* create mask node, yes AF_UNSPEC is weird... */
3330 mask_p = estrdup(mask_s);
3331 my_node->mask = create_address_node(mask_p, AF_UNSPEC);
3332 }
3333
3334 /*
3335 * getnetnum - return a net number (this is crude, but careful)
3336 *
3337 * returns 1 for success, and mysteriously, 0 for most failures, and
3338 * -1 if the address found is IPv6 and we believe IPv6 isn't working.
3339 */
3340 static int
getnetnum(const char * num,sockaddr_u * addr)3341 getnetnum(
3342 const char *num,
3343 sockaddr_u *addr
3344 )
3345 {
3346
3347 REQUIRE(AF_UNSPEC == AF(addr) ||
3348 AF_INET == AF(addr) ||
3349 AF_INET6 == AF(addr));
3350
3351 if (!is_ip_address(num, AF(addr), addr))
3352 return 0;
3353
3354 if (IS_IPV6(addr) && !ipv6_works)
3355 return -1;
3356
3357 # ifdef ISC_PLATFORM_HAVESALEN
3358 addr->sa.sa_len = SIZEOF_SOCKADDR(AF(addr));
3359 # endif
3360 SET_PORT(addr, NTP_PORT);
3361
3362 DPRINT(2, ("getnetnum given %s, got %s\n", num, socktoa(addr)));
3363
3364 return 1;
3365 }
3366
3367 void
ntp_rlimit(int rl_what,rlim_t rl_value,int rl_scale,const char * rl_sstr)3368 ntp_rlimit(
3369 int rl_what,
3370 rlim_t rl_value,
3371 int rl_scale,
3372 const char * rl_sstr
3373 )
3374 {
3375 struct rlimit rl;
3376
3377 #ifndef DEBUG
3378 UNUSED_ARG(rl_scale);
3379 UNUSED_ARG(rl_sstr);
3380 #endif
3381
3382 switch (rl_what) {
3383
3384 case RLIMIT_NOFILE:
3385 /*
3386 * For large systems the default file descriptor limit may
3387 * not be enough.
3388 */
3389 DPRINT(2, ("ntp_rlimit: NOFILE: %d %s\n",
3390 (int)rl_value / rl_scale, rl_sstr));
3391 rl.rlim_cur = rl.rlim_max = rl_value;
3392 if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
3393 msyslog(LOG_ERR, "CONFIG: Cannot set RLIMIT_NOFILE: %s", strerror(errno));
3394 break;
3395
3396 case RLIMIT_STACK:
3397 /*
3398 * Provide a way to set the stack limit to something
3399 * smaller, so that we don't lock a lot of unused
3400 * stack memory.
3401 */
3402 DPRINT(2, ("ntp_rlimit: STACK: %d %s pages\n",
3403 (int)rl_value / rl_scale, rl_sstr));
3404 if (-1 == getrlimit(RLIMIT_STACK, &rl)) {
3405 msyslog(LOG_ERR, "CONFIG: getrlimit(RLIMIT_STACK) failed: %s", strerror(errno));
3406 } else {
3407 if (rl_value > rl.rlim_max) {
3408 msyslog(LOG_WARNING,
3409 "CONFIG: ntp_rlimit: using maximum allowed stack limit %lu instead of %lu.",
3410 (unsigned long)rl.rlim_max,
3411 (unsigned long)rl_value);
3412 rl_value = rl.rlim_max;
3413 }
3414 rl.rlim_cur = rl_value;
3415 if (-1 == setrlimit(RLIMIT_STACK, &rl)) {
3416 msyslog(LOG_ERR,
3417 "CONFIG: ntp_rlimit: Cannot set RLIMIT_STACK: %s", strerror(errno));
3418 }
3419 }
3420 break;
3421
3422 default:
3423 INSIST(!"Unexpected setrlimit() case!");
3424 break;
3425 }
3426 }
3427