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 (c) 2006 10 */ 11 12 #ifdef HAVE_CONFIG_H 13 # include <config.h> 14 #endif 15 16 #ifdef HAVE_NETINFO 17 # include <netinfo/ni.h> 18 #endif 19 20 #include <stdio.h> 21 #include <ctype.h> 22 #ifdef HAVE_SYS_PARAM_H 23 # include <sys/param.h> 24 #endif 25 #include <signal.h> 26 #ifndef SIGCHLD 27 # define SIGCHLD SIGCLD 28 #endif 29 #ifdef HAVE_SYS_WAIT_H 30 # include <sys/wait.h> 31 #endif 32 #include <time.h> 33 34 #include <isc/net.h> 35 #include <isc/result.h> 36 37 #include "ntp.h" 38 #include "ntpd.h" 39 #include "ntp_io.h" 40 #include "ntp_unixtime.h" 41 #include "ntp_refclock.h" 42 #include "ntp_clockdev.h" 43 #include "ntp_filegen.h" 44 #include "ntp_stdlib.h" 45 #include "ntp_assert.h" 46 #include "ntp_random.h" 47 /* 48 * [Bug 467]: Some linux headers collide with CONFIG_PHONE and CONFIG_KEYS 49 * so #include these later. 50 */ 51 #include "ntp_config.h" 52 #include "ntp_cmdargs.h" 53 #include "ntp_scanner.h" 54 #include "ntp_parser.h" 55 #include "ntpd-opts.h" 56 57 #ifndef IGNORE_DNS_ERRORS 58 # define DNSFLAGS 0 59 #else 60 # define DNSFLAGS GAIR_F_IGNDNSERR 61 #endif 62 63 extern int yyparse(void); 64 65 /* Bug 2817 */ 66 #if defined(HAVE_SYS_MMAN_H) 67 # include <sys/mman.h> 68 #endif 69 70 /* list of servers from command line for config_peers() */ 71 int cmdline_server_count; 72 char ** cmdline_servers; 73 74 /* Current state of memory locking: 75 * -1: default 76 * 0: memory locking disabled 77 * 1: Memory locking enabled 78 */ 79 int cur_memlock = -1; 80 81 /* 82 * "logconfig" building blocks 83 */ 84 struct masks { 85 const char * const name; 86 const u_int32 mask; 87 }; 88 89 static struct masks logcfg_class[] = { 90 { "clock", NLOG_OCLOCK }, 91 { "peer", NLOG_OPEER }, 92 { "sync", NLOG_OSYNC }, 93 { "sys", NLOG_OSYS }, 94 { NULL, 0 } 95 }; 96 97 /* logcfg_noclass_items[] masks are complete and must not be shifted */ 98 static struct masks logcfg_noclass_items[] = { 99 { "allall", NLOG_SYSMASK | NLOG_PEERMASK | NLOG_CLOCKMASK | NLOG_SYNCMASK }, 100 { "allinfo", NLOG_SYSINFO | NLOG_PEERINFO | NLOG_CLOCKINFO | NLOG_SYNCINFO }, 101 { "allevents", NLOG_SYSEVENT | NLOG_PEEREVENT | NLOG_CLOCKEVENT | NLOG_SYNCEVENT }, 102 { "allstatus", NLOG_SYSSTATUS | NLOG_PEERSTATUS | NLOG_CLOCKSTATUS | NLOG_SYNCSTATUS }, 103 { "allstatistics", NLOG_SYSSTATIST | NLOG_PEERSTATIST | NLOG_CLOCKSTATIST | NLOG_SYNCSTATIST }, 104 /* the remainder are misspellings of clockall, peerall, sysall, and syncall. */ 105 { "allclock", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OCLOCK }, 106 { "allpeer", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OPEER }, 107 { "allsys", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYS }, 108 { "allsync", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYNC }, 109 { NULL, 0 } 110 }; 111 112 /* logcfg_class_items[] masks are shiftable by NLOG_O* counts */ 113 static struct masks logcfg_class_items[] = { 114 { "all", NLOG_INFO | NLOG_EVENT | NLOG_STATUS | NLOG_STATIST }, 115 { "info", NLOG_INFO }, 116 { "events", NLOG_EVENT }, 117 { "status", NLOG_STATUS }, 118 { "statistics", NLOG_STATIST }, 119 { NULL, 0 } 120 }; 121 122 typedef struct peer_resolved_ctx_tag { 123 int flags; 124 int host_mode; /* T_* token identifier */ 125 u_short family; 126 keyid_t keyid; 127 u_char hmode; /* MODE_* */ 128 u_char version; 129 u_char minpoll; 130 u_char maxpoll; 131 u_int32 ttl; 132 const char * group; 133 int was_initializing; 134 } peer_resolved_ctx; 135 136 /* Limits */ 137 #define MAXPHONE 10 /* maximum number of phone strings */ 138 #define MAXPPS 20 /* maximum length of PPS device string */ 139 140 /* 141 * Poll Skew List array has an entry for each supported poll 142 * interval. 143 */ 144 #define PSL_ENTRIES (NTP_MAXPOLL - NTP_MINPOLL + 1) 145 static psl_item psl[PSL_ENTRIES]; 146 147 /* 148 * Miscellaneous macros 149 */ 150 #define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0') 151 #define ISSPACE(c) ((c) == ' ' || (c) == '\t') 152 153 #define _UC(str) ((char *)(intptr_t)(str)) 154 155 /* 156 * Definitions of things either imported from or exported to outside 157 */ 158 extern int yydebug; /* ntp_parser.c (.y) */ 159 config_tree cfgt; /* Parser output stored here */ 160 config_tree *cfg_tree_history; /* History of configs */ 161 char * sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */ 162 char default_keysdir[] = NTP_KEYSDIR; 163 char * keysdir = default_keysdir; /* crypto keys directory */ 164 char * saveconfigdir; 165 #if defined(HAVE_SCHED_SETSCHEDULER) 166 int config_priority_override = 0; 167 int config_priority; 168 #endif 169 170 const char *config_file; 171 static char default_ntp_signd_socket[] = 172 #ifdef NTP_SIGND_PATH 173 NTP_SIGND_PATH; 174 #else 175 ""; 176 #endif 177 char *ntp_signd_socket = default_ntp_signd_socket; 178 #ifdef HAVE_NETINFO 179 struct netinfo_config_state *config_netinfo = NULL; 180 int check_netinfo = 1; 181 #endif /* HAVE_NETINFO */ 182 #ifdef SYS_WINNT 183 char *alt_config_file; 184 LPTSTR temp; 185 char config_file_storage[MAX_PATH]; 186 char alt_config_file_storage[MAX_PATH]; 187 #endif /* SYS_WINNT */ 188 189 #ifdef HAVE_NETINFO 190 /* 191 * NetInfo configuration state 192 */ 193 struct netinfo_config_state { 194 void *domain; /* domain with config */ 195 ni_id config_dir; /* ID config dir */ 196 int prop_index; /* current property */ 197 int val_index; /* current value */ 198 char **val_list; /* value list */ 199 }; 200 #endif 201 202 struct REMOTE_CONFIG_INFO remote_config; /* Remote configuration buffer and 203 pointer info */ 204 int old_config_style = 1; /* A boolean flag, which when set, 205 * indicates that the old configuration 206 * format with a newline at the end of 207 * every command is being used 208 */ 209 int cryptosw; /* crypto command called */ 210 211 extern char *stats_drift_file; /* name of the driftfile */ 212 213 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED 214 /* 215 * backwards compatibility flags 216 */ 217 bc_entry bc_list[] = { 218 { T_Bc_bugXXXX, 1 } /* default enabled */ 219 }; 220 221 /* 222 * declare an int pointer for each flag for quick testing without 223 * walking bc_list. If the pointer is consumed by libntp rather 224 * than ntpd, declare it in a libntp source file pointing to storage 225 * initialized with the appropriate value for other libntp clients, and 226 * redirect it to point into bc_list during ntpd startup. 227 */ 228 int *p_bcXXXX_enabled = &bc_list[0].enabled; 229 #endif 230 231 /* FUNCTION PROTOTYPES */ 232 233 static void init_syntax_tree(config_tree *); 234 static void apply_enable_disable(attr_val_fifo *q, int enable); 235 236 #ifdef FREE_CFG_T 237 static void free_auth_node(config_tree *); 238 static void free_all_config_trees(void); 239 240 static void free_config_access(config_tree *); 241 static void free_config_auth(config_tree *); 242 static void free_config_fudge(config_tree *); 243 static void free_config_device(config_tree *); 244 static void free_config_logconfig(config_tree *); 245 static void free_config_monitor(config_tree *); 246 static void free_config_nic_rules(config_tree *); 247 static void free_config_other_modes(config_tree *); 248 static void free_config_phone(config_tree *); 249 static void free_config_reset_counters(config_tree *); 250 static void free_config_rlimit(config_tree *); 251 static void free_config_setvar(config_tree *); 252 static void free_config_system_opts(config_tree *); 253 static void free_config_tinker(config_tree *); 254 static void free_config_tos(config_tree *); 255 static void free_config_trap(config_tree *); 256 static void free_config_ttl(config_tree *); 257 static void free_config_vars(config_tree *); 258 259 #ifdef SIM 260 static void free_config_sim(config_tree *); 261 #else /* !SIM follows */ 262 static void free_config_peers(config_tree *); 263 static void free_config_unpeers(config_tree *); 264 static int is_sane_resolved_address(sockaddr_u *peeraddr, int hmode); 265 #endif /* !SIM */ 266 static void destroy_address_fifo(address_fifo *); 267 #define FREE_ADDRESS_FIFO(pf) \ 268 do { \ 269 destroy_address_fifo(pf); \ 270 (pf) = NULL; \ 271 } while (0) 272 void free_all_config_trees(void); /* atexit() */ 273 static void free_config_tree(config_tree *ptree); 274 #endif /* FREE_CFG_T */ 275 276 static void destroy_restrict_node(restrict_node *my_node); 277 static void save_and_apply_config_tree(int/*BOOL*/ from_file); 278 static void destroy_int_fifo(int_fifo *); 279 #define FREE_INT_FIFO(pf) \ 280 do { \ 281 destroy_int_fifo(pf); \ 282 (pf) = NULL; \ 283 } while (0) 284 static void destroy_string_fifo(string_fifo *); 285 #define FREE_STRING_FIFO(pf) \ 286 do { \ 287 destroy_string_fifo(pf); \ 288 (pf) = NULL; \ 289 } while (0) 290 static void destroy_attr_val_fifo(attr_val_fifo *); 291 #define FREE_ATTR_VAL_FIFO(pf) \ 292 do { \ 293 destroy_attr_val_fifo(pf); \ 294 (pf) = NULL; \ 295 } while (0) 296 static void destroy_filegen_fifo(filegen_fifo *); 297 #define FREE_FILEGEN_FIFO(pf) \ 298 do { \ 299 destroy_filegen_fifo(pf); \ 300 (pf) = NULL; \ 301 } while (0) 302 static void destroy_restrict_fifo(restrict_fifo *); 303 #define FREE_RESTRICT_FIFO(pf) \ 304 do { \ 305 destroy_restrict_fifo(pf); \ 306 (pf) = NULL; \ 307 } while (0) 308 static void destroy_setvar_fifo(setvar_fifo *); 309 #define FREE_SETVAR_FIFO(pf) \ 310 do { \ 311 destroy_setvar_fifo(pf); \ 312 (pf) = NULL; \ 313 } while (0) 314 static void destroy_addr_opts_fifo(addr_opts_fifo *); 315 #define FREE_ADDR_OPTS_FIFO(pf) \ 316 do { \ 317 destroy_addr_opts_fifo(pf); \ 318 (pf) = NULL; \ 319 } while (0) 320 321 static void config_logconfig(config_tree *); 322 static void config_monitor(config_tree *); 323 static void config_rlimit(config_tree *); 324 static void config_system_opts(config_tree *); 325 static void config_tinker(config_tree *); 326 static void config_tos(config_tree *); 327 static void config_vars(config_tree *); 328 329 #ifdef SIM 330 static sockaddr_u *get_next_address(address_node *addr); 331 static void config_sim(config_tree *); 332 static void config_ntpdsim(config_tree *); 333 #else /* !SIM follows */ 334 static void config_ntpd(config_tree *, int/*BOOL*/ input_from_file); 335 static void config_other_modes(config_tree *); 336 static void config_auth(config_tree *); 337 static void attrtopsl(u_char log2_poll, attr_val *avp); 338 static void config_access(config_tree *); 339 static void config_mdnstries(config_tree *); 340 static void config_phone(config_tree *); 341 static void config_setvar(config_tree *); 342 static int config_tos_clock(config_tree *); 343 static void config_ttl(config_tree *); 344 static void config_trap(config_tree *); 345 static void config_fudge(config_tree *); 346 static void config_device(config_tree *); 347 static void config_peers(config_tree *); 348 static void config_unpeers(config_tree *); 349 static void config_nic_rules(config_tree *, int/*BOOL*/ input_from_file); 350 static void config_reset_counters(config_tree *); 351 static u_char get_correct_host_mode(int token); 352 static int peerflag_bits(peer_node *); 353 354 #ifdef WORKER 355 static void peer_name_resolved(int, int, void *, const char *, const char *, 356 const struct addrinfo *, 357 const struct addrinfo *); 358 static void unpeer_name_resolved(int, int, void *, const char *, const char *, 359 const struct addrinfo *, 360 const struct addrinfo *); 361 static void trap_name_resolved(int, int, void *, const char *, const char *, 362 const struct addrinfo *, 363 const struct addrinfo *); 364 #endif /* WORKER */ 365 #endif /* !SIM */ 366 367 enum gnn_type { 368 t_UNK, /* Unknown */ 369 t_REF, /* Refclock */ 370 t_MSK /* Network Mask */ 371 }; 372 373 static void ntpd_set_tod_using(const char *); 374 static char * normal_dtoa(double); 375 static u_int32 get_pfxmatch(const char **, struct masks *); 376 static u_int32 get_match(const char *, struct masks *); 377 static u_int32 get_logmask(const char *); 378 static int/*BOOL*/ is_refclk_addr(const address_node * addr); 379 380 static int getnetnum(const char *num, sockaddr_u *addr, int complain, 381 enum gnn_type a_type); 382 383 #if defined(__GNUC__) /* this covers CLANG, too */ 384 static void __attribute__((__noreturn__,format(printf,1,2))) fatal_error(const char *fmt, ...) 385 #elif defined(_MSC_VER) 386 static void __declspec(noreturn) fatal_error(const char *fmt, ...) 387 #else 388 static void fatal_error(const char *fmt, ...) 389 #endif 390 { 391 va_list va; 392 393 va_start(va, fmt); 394 mvsyslog(LOG_EMERG, fmt, va); 395 va_end(va); 396 _exit(1); 397 } 398 399 400 /* FUNCTIONS FOR INITIALIZATION 401 * ---------------------------- 402 */ 403 404 #ifdef FREE_CFG_T 405 static void 406 free_auth_node( 407 config_tree *ptree 408 ) 409 { 410 if (ptree->auth.keys) { 411 free(ptree->auth.keys); 412 ptree->auth.keys = NULL; 413 } 414 415 if (ptree->auth.keysdir) { 416 free(ptree->auth.keysdir); 417 ptree->auth.keysdir = NULL; 418 } 419 420 if (ptree->auth.ntp_signd_socket) { 421 free(ptree->auth.ntp_signd_socket); 422 ptree->auth.ntp_signd_socket = NULL; 423 } 424 } 425 #endif /* DEBUG */ 426 427 428 static void 429 init_syntax_tree( 430 config_tree *ptree 431 ) 432 { 433 ZERO(*ptree); 434 ptree->mdnstries = 5; 435 } 436 437 438 #ifdef FREE_CFG_T 439 static void 440 free_all_config_trees(void) 441 { 442 config_tree *ptree; 443 config_tree *pnext; 444 445 ptree = cfg_tree_history; 446 447 while (ptree != NULL) { 448 pnext = ptree->link; 449 free_config_tree(ptree); 450 ptree = pnext; 451 } 452 } 453 454 455 static void 456 free_config_tree( 457 config_tree *ptree 458 ) 459 { 460 #if defined(_MSC_VER) && defined (_DEBUG) 461 _CrtCheckMemory(); 462 #endif 463 464 if (ptree->source.value.s != NULL) 465 free(ptree->source.value.s); 466 467 free_config_other_modes(ptree); 468 free_config_auth(ptree); 469 free_config_tos(ptree); 470 free_config_monitor(ptree); 471 free_config_access(ptree); 472 free_config_tinker(ptree); 473 free_config_rlimit(ptree); 474 free_config_system_opts(ptree); 475 free_config_logconfig(ptree); 476 free_config_phone(ptree); 477 free_config_setvar(ptree); 478 free_config_ttl(ptree); 479 free_config_trap(ptree); 480 free_config_fudge(ptree); 481 free_config_device(ptree); 482 free_config_vars(ptree); 483 free_config_nic_rules(ptree); 484 free_config_reset_counters(ptree); 485 #ifdef SIM 486 free_config_sim(ptree); 487 #else /* !SIM follows */ 488 free_config_peers(ptree); 489 free_config_unpeers(ptree); 490 #endif /* !SIM */ 491 free_auth_node(ptree); 492 493 free(ptree); 494 495 #if defined(_MSC_VER) && defined (_DEBUG) 496 _CrtCheckMemory(); 497 #endif 498 } 499 #endif /* FREE_CFG_T */ 500 501 502 #ifdef SAVECONFIG 503 /* Dump all trees */ 504 int 505 dump_all_config_trees( 506 FILE *df, 507 int comment 508 ) 509 { 510 config_tree * cfg_ptr; 511 int return_value; 512 time_t now = time(NULL); 513 struct tm tm = *localtime(&now); 514 515 fprintf(df, "#NTF:D %04d%02d%02d@%02d:%02d:%02d\n", 516 tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, 517 tm.tm_hour, tm.tm_min, tm.tm_sec); 518 fprintf(df, "#NTF:V %s\n", Version); 519 520 return_value = 0; 521 for (cfg_ptr = cfg_tree_history; 522 cfg_ptr != NULL; 523 cfg_ptr = cfg_ptr->link) 524 return_value |= dump_config_tree(cfg_ptr, df, comment); 525 526 return return_value; 527 } 528 529 530 /* The config dumper */ 531 int 532 dump_config_tree( 533 config_tree *ptree, 534 FILE *df, 535 int comment 536 ) 537 { 538 peer_node *peern; 539 unpeer_node *unpeern; 540 attr_val *atrv; 541 address_node *addr; 542 address_node *peer_addr; 543 address_node *fudge_addr; 544 filegen_node *fgen_node; 545 restrict_node *rest_node; 546 addr_opts_node *addr_opts; 547 setvar_node *setv_node; 548 nic_rule_node *rule_node; 549 int_node *i_n; 550 int_node *counter_set; 551 string_node *str_node; 552 553 const char *s = NULL; 554 char *s1; 555 char *s2; 556 char timestamp[80]; 557 int enable; 558 559 DPRINTF(1, ("dump_config_tree(%p)\n", ptree)); 560 561 if (comment) { 562 if (!strftime(timestamp, sizeof(timestamp), 563 "%Y-%m-%d %H:%M:%S", 564 localtime(&ptree->timestamp))) 565 timestamp[0] = '\0'; 566 567 fprintf(df, "# %s %s %s\n", 568 timestamp, 569 (CONF_SOURCE_NTPQ == ptree->source.attr) 570 ? "ntpq remote config from" 571 : "startup configuration file", 572 ptree->source.value.s); 573 } 574 575 /* 576 * For options without documentation we just output the name 577 * and its data value 578 */ 579 atrv = HEAD_PFIFO(ptree->vars); 580 for ( ; atrv != NULL; atrv = atrv->link) { 581 switch (atrv->type) { 582 #ifdef DEBUG 583 default: 584 fprintf(df, "\n# dump error:\n" 585 "# unknown vars type %d (%s) for %s\n", 586 atrv->type, token_name(atrv->type), 587 token_name(atrv->attr)); 588 break; 589 #endif 590 case T_Double: 591 fprintf(df, "%s %s\n", keyword(atrv->attr), 592 normal_dtoa(atrv->value.d)); 593 break; 594 595 case T_Integer: 596 fprintf(df, "%s %d\n", keyword(atrv->attr), 597 atrv->value.i); 598 break; 599 600 case T_String: 601 fprintf(df, "%s \"%s\"", keyword(atrv->attr), 602 atrv->value.s); 603 if (T_Driftfile == atrv->attr && 604 atrv->link != NULL && 605 T_WanderThreshold == atrv->link->attr) { 606 atrv = atrv->link; 607 fprintf(df, " %s\n", 608 normal_dtoa(atrv->value.d)); 609 } else if (T_Leapfile == atrv->attr) { 610 fputs((atrv->flag 611 ? " checkhash\n" 612 : " ignorehash\n"), 613 df); 614 } else { 615 fprintf(df, "\n"); 616 } 617 break; 618 } 619 } 620 621 atrv = HEAD_PFIFO(ptree->logconfig); 622 if (atrv != NULL) { 623 fprintf(df, "logconfig"); 624 for ( ; atrv != NULL; atrv = atrv->link) 625 fprintf(df, " %c%s", atrv->attr, atrv->value.s); 626 fprintf(df, "\n"); 627 } 628 629 if (ptree->stats_dir) 630 fprintf(df, "statsdir \"%s\"\n", ptree->stats_dir); 631 632 i_n = HEAD_PFIFO(ptree->stats_list); 633 if (i_n != NULL) { 634 fprintf(df, "statistics"); 635 for ( ; i_n != NULL; i_n = i_n->link) 636 fprintf(df, " %s", keyword(i_n->i)); 637 fprintf(df, "\n"); 638 } 639 640 fgen_node = HEAD_PFIFO(ptree->filegen_opts); 641 for ( ; fgen_node != NULL; fgen_node = fgen_node->link) { 642 atrv = HEAD_PFIFO(fgen_node->options); 643 if (atrv != NULL) { 644 fprintf(df, "filegen %s", 645 keyword(fgen_node->filegen_token)); 646 for ( ; atrv != NULL; atrv = atrv->link) { 647 switch (atrv->attr) { 648 #ifdef DEBUG 649 default: 650 fprintf(df, "\n# dump error:\n" 651 "# unknown filegen option token %s\n" 652 "filegen %s", 653 token_name(atrv->attr), 654 keyword(fgen_node->filegen_token)); 655 break; 656 #endif 657 case T_File: 658 fprintf(df, " file %s", 659 atrv->value.s); 660 break; 661 662 case T_Type: 663 fprintf(df, " type %s", 664 keyword(atrv->value.i)); 665 break; 666 667 case T_Flag: 668 fprintf(df, " %s", 669 keyword(atrv->value.i)); 670 break; 671 } 672 } 673 fprintf(df, "\n"); 674 } 675 } 676 677 atrv = HEAD_PFIFO(ptree->auth.crypto_cmd_list); 678 if (atrv != NULL) { 679 fprintf(df, "crypto"); 680 for ( ; atrv != NULL; atrv = atrv->link) { 681 fprintf(df, " %s %s", keyword(atrv->attr), 682 atrv->value.s); 683 } 684 fprintf(df, "\n"); 685 } 686 687 if (ptree->auth.revoke != 0) 688 fprintf(df, "revoke %d\n", ptree->auth.revoke); 689 690 if (ptree->auth.keysdir != NULL) 691 fprintf(df, "keysdir \"%s\"\n", ptree->auth.keysdir); 692 693 if (ptree->auth.keys != NULL) 694 fprintf(df, "keys \"%s\"\n", ptree->auth.keys); 695 696 atrv = HEAD_PFIFO(ptree->auth.trusted_key_list); 697 if (atrv != NULL) { 698 fprintf(df, "trustedkey"); 699 for ( ; atrv != NULL; atrv = atrv->link) { 700 if (T_Integer == atrv->type) 701 fprintf(df, " %d", atrv->value.i); 702 else if (T_Intrange == atrv->type) 703 fprintf(df, " (%d ... %d)", 704 atrv->value.r.first, 705 atrv->value.r.last); 706 #ifdef DEBUG 707 else 708 fprintf(df, "\n# dump error:\n" 709 "# unknown trustedkey attr type %d\n" 710 "trustedkey", atrv->type); 711 #endif 712 } 713 fprintf(df, "\n"); 714 } 715 716 if (ptree->auth.control_key) 717 fprintf(df, "controlkey %d\n", ptree->auth.control_key); 718 719 if (ptree->auth.request_key) 720 fprintf(df, "requestkey %d\n", ptree->auth.request_key); 721 722 /* dump enable list, then disable list */ 723 for (enable = 1; enable >= 0; enable--) { 724 atrv = (enable) 725 ? HEAD_PFIFO(ptree->enable_opts) 726 : HEAD_PFIFO(ptree->disable_opts); 727 if (atrv != NULL) { 728 fprintf(df, "%s", (enable) 729 ? "enable" 730 : "disable"); 731 for ( ; atrv != NULL; atrv = atrv->link) 732 fprintf(df, " %s", 733 keyword(atrv->value.i)); 734 fprintf(df, "\n"); 735 } 736 } 737 738 atrv = HEAD_PFIFO(ptree->orphan_cmds); 739 if (atrv != NULL) { 740 fprintf(df, "tos"); 741 for ( ; atrv != NULL; atrv = atrv->link) { 742 switch (atrv->type) { 743 #ifdef DEBUG 744 default: 745 fprintf(df, "\n# dump error:\n" 746 "# unknown tos attr type %d %s\n" 747 "tos", atrv->type, 748 token_name(atrv->type)); 749 break; 750 #endif 751 case T_Integer: 752 if (atrv->attr == T_Basedate) { 753 struct calendar jd; 754 ntpcal_rd_to_date(&jd, atrv->value.i + DAY_NTP_STARTS); 755 fprintf(df, " %s \"%04hu-%02hu-%02hu\"", 756 keyword(atrv->attr), jd.year, 757 (u_short)jd.month, 758 (u_short)jd.monthday); 759 } else { 760 fprintf(df, " %s %d", 761 keyword(atrv->attr), 762 atrv->value.i); 763 } 764 break; 765 766 case T_Double: 767 fprintf(df, " %s %s", 768 keyword(atrv->attr), 769 normal_dtoa(atrv->value.d)); 770 break; 771 } 772 } 773 fprintf(df, "\n"); 774 } 775 776 atrv = HEAD_PFIFO(ptree->rlimit); 777 if (atrv != NULL) { 778 fprintf(df, "rlimit"); 779 for ( ; atrv != NULL; atrv = atrv->link) { 780 INSIST(T_Integer == atrv->type); 781 fprintf(df, " %s %d", keyword(atrv->attr), 782 atrv->value.i); 783 } 784 fprintf(df, "\n"); 785 } 786 787 atrv = HEAD_PFIFO(ptree->tinker); 788 if (atrv != NULL) { 789 fprintf(df, "tinker"); 790 for ( ; atrv != NULL; atrv = atrv->link) { 791 INSIST(T_Double == atrv->type); 792 fprintf(df, " %s %s", keyword(atrv->attr), 793 normal_dtoa(atrv->value.d)); 794 } 795 fprintf(df, "\n"); 796 } 797 798 if (ptree->broadcastclient) 799 fprintf(df, "broadcastclient\n"); 800 801 peern = HEAD_PFIFO(ptree->peers); 802 for ( ; peern != NULL; peern = peern->link) { 803 addr = peern->addr; 804 fprintf(df, "%s", keyword(peern->host_mode)); 805 switch (addr->type) { 806 #ifdef DEBUG 807 default: 808 fprintf(df, "# dump error:\n" 809 "# unknown peer family %d for:\n" 810 "%s", addr->type, 811 keyword(peern->host_mode)); 812 break; 813 #endif 814 case AF_UNSPEC: 815 break; 816 817 case AF_INET: 818 fprintf(df, " -4"); 819 break; 820 821 case AF_INET6: 822 fprintf(df, " -6"); 823 break; 824 } 825 fprintf(df, " %s", addr->address); 826 827 if (peern->minpoll != 0) 828 fprintf(df, " minpoll %u", peern->minpoll); 829 830 if (peern->maxpoll != 0) 831 fprintf(df, " maxpoll %u", peern->maxpoll); 832 833 if (peern->ttl != 0) { 834 if (strlen(addr->address) > 8 835 && !memcmp(addr->address, "127.127.", 8)) 836 fprintf(df, " mode %u", peern->ttl); 837 else 838 fprintf(df, " ttl %u", peern->ttl); 839 } 840 841 if (peern->peerversion != NTP_VERSION) 842 fprintf(df, " version %u", peern->peerversion); 843 844 if (peern->peerkey != 0) 845 fprintf(df, " key %u", peern->peerkey); 846 847 if (peern->group != NULL) 848 fprintf(df, " ident \"%s\"", peern->group); 849 850 atrv = HEAD_PFIFO(peern->peerflags); 851 for ( ; atrv != NULL; atrv = atrv->link) { 852 INSIST(T_Flag == atrv->attr); 853 INSIST(T_Integer == atrv->type); 854 fprintf(df, " %s", keyword(atrv->value.i)); 855 } 856 857 fprintf(df, "\n"); 858 859 addr_opts = HEAD_PFIFO(ptree->fudge); 860 for ( ; addr_opts != NULL; addr_opts = addr_opts->link) { 861 peer_addr = peern->addr; 862 fudge_addr = addr_opts->addr; 863 864 s1 = peer_addr->address; 865 s2 = fudge_addr->address; 866 867 if (strcmp(s1, s2)) 868 continue; 869 870 fprintf(df, "fudge %s", s1); 871 872 for (atrv = HEAD_PFIFO(addr_opts->options); 873 atrv != NULL; 874 atrv = atrv->link) { 875 876 switch (atrv->type) { 877 #ifdef DEBUG 878 default: 879 fprintf(df, "\n# dump error:\n" 880 "# unknown fudge atrv->type %d\n" 881 "fudge %s", atrv->type, 882 s1); 883 break; 884 #endif 885 case T_Double: 886 fprintf(df, " %s %s", 887 keyword(atrv->attr), 888 normal_dtoa(atrv->value.d)); 889 break; 890 891 case T_Integer: 892 fprintf(df, " %s %d", 893 keyword(atrv->attr), 894 atrv->value.i); 895 break; 896 897 case T_String: 898 fprintf(df, " %s %s", 899 keyword(atrv->attr), 900 atrv->value.s); 901 break; 902 } 903 } 904 fprintf(df, "\n"); 905 } 906 907 addr_opts = HEAD_PFIFO(ptree->device); 908 for ( ; addr_opts != NULL; addr_opts = addr_opts->link) { 909 peer_addr = peern->addr; 910 fudge_addr = addr_opts->addr; 911 912 s1 = peer_addr->address; 913 s2 = fudge_addr->address; 914 915 if (strcmp(s1, s2)) 916 continue; 917 918 fprintf(df, "device %s", s1); 919 920 for (atrv = HEAD_PFIFO(addr_opts->options); 921 atrv != NULL; 922 atrv = atrv->link) { 923 924 switch (atrv->type) { 925 #ifdef DEBUG 926 default: 927 fprintf(df, "\n# dump error:\n" 928 "# unknown device atrv->type %d\n" 929 "device %s", atrv->type, 930 s1); 931 break; 932 #endif 933 case T_String: 934 fprintf(df, " %s %s", 935 keyword(atrv->attr), 936 atrv->value.s); 937 break; 938 } 939 } 940 fprintf(df, "\n"); 941 } 942 } 943 944 addr = HEAD_PFIFO(ptree->manycastserver); 945 if (addr != NULL) { 946 fprintf(df, "manycastserver"); 947 for ( ; addr != NULL; addr = addr->link) 948 fprintf(df, " %s", addr->address); 949 fprintf(df, "\n"); 950 } 951 952 addr = HEAD_PFIFO(ptree->multicastclient); 953 if (addr != NULL) { 954 fprintf(df, "multicastclient"); 955 for ( ; addr != NULL; addr = addr->link) 956 fprintf(df, " %s", addr->address); 957 fprintf(df, "\n"); 958 } 959 960 961 for (unpeern = HEAD_PFIFO(ptree->unpeers); 962 unpeern != NULL; 963 unpeern = unpeern->link) 964 fprintf(df, "unpeer %s\n", unpeern->addr->address); 965 966 atrv = HEAD_PFIFO(ptree->mru_opts); 967 if (atrv != NULL) { 968 fprintf(df, "mru"); 969 for ( ; atrv != NULL; atrv = atrv->link) 970 fprintf(df, " %s %d", keyword(atrv->attr), 971 atrv->value.i); 972 fprintf(df, "\n"); 973 } 974 975 atrv = HEAD_PFIFO(ptree->discard_opts); 976 if (atrv != NULL) { 977 fprintf(df, "discard"); 978 for ( ; atrv != NULL; atrv = atrv->link) 979 fprintf(df, " %s %d", keyword(atrv->attr), 980 atrv->value.i); 981 fprintf(df, "\n"); 982 } 983 984 atrv = HEAD_PFIFO(ptree->pollskewlist); 985 if (atrv != NULL) { 986 fprintf(df, "pollskewlist"); 987 for ( ; atrv != NULL; atrv = atrv->link) { 988 if (-1 == atrv->attr) { 989 fprintf(df, " default"); 990 } else { 991 fprintf(df, " %d", atrv->attr); 992 } 993 fprintf(df, " %d|%d", 994 atrv->value.r.first, atrv->value.r.last); 995 } 996 fprintf(df, "\n"); 997 } 998 999 for (rest_node = HEAD_PFIFO(ptree->restrict_opts); 1000 rest_node != NULL; 1001 rest_node = rest_node->link) { 1002 int/*BOOL*/ is_default = FALSE; 1003 int/*BOOL*/ omit_mask; 1004 sockaddr_u mask; 1005 sockaddr_u onesmask; 1006 1007 s = NULL; 1008 atrv = HEAD_PFIFO(rest_node->flag_tok_fifo); 1009 for (; atrv != NULL; atrv = atrv->link) { 1010 if ( T_Integer == atrv->type 1011 && T_Source == atrv->attr) { 1012 s = keyword(T_Source); 1013 break; 1014 } 1015 } 1016 if (NULL == rest_node->addr) { 1017 if (NULL == s) { 1018 s = keyword(T_Default); 1019 /* Don't need to set is_default here */ 1020 } 1021 } else { 1022 const char *ap = rest_node->addr->address; 1023 const char *mp = ""; 1024 1025 if (rest_node->mask) 1026 mp = rest_node->mask->address; 1027 1028 if ( rest_node->addr->type == AF_INET 1029 && !strcmp(mp, "0.0.0.0") 1030 && !strcmp(ap, mp)) { 1031 is_default = TRUE; 1032 s = "-4 default"; 1033 } else if ( rest_node->mask 1034 && rest_node->mask->type == AF_INET6 1035 && !strcmp(mp, "::") 1036 && !strcmp(ap, mp)) { 1037 is_default = TRUE; 1038 s = "-6 default"; 1039 } else { 1040 if (NULL == s) { 1041 s = ap; 1042 } else { 1043 LIB_GETBUF(s1); 1044 snprintf(s1, LIB_BUFLENGTH, 1045 "%s %s", 1046 keyword(T_Source), ap); 1047 s = s1; 1048 } 1049 } 1050 } 1051 fprintf(df, "%s %s", 1052 keyword(rest_node->remove 1053 ? T_Delrestrict 1054 : T_Restrict), 1055 s); 1056 if (rest_node->mask != NULL && !is_default) { 1057 ZERO(mask); 1058 AF(&mask) = AF_UNSPEC; 1059 omit_mask = (0 != getnetnum(rest_node->mask->address, 1060 &mask, 0, t_UNK)); 1061 if (omit_mask) { 1062 SET_HOSTMASK(&onesmask, AF(&mask)); 1063 omit_mask = SOCK_EQ(&mask, &onesmask); 1064 } 1065 if (!omit_mask) { 1066 fprintf(df, " mask %s", 1067 rest_node->mask->address); 1068 } 1069 } 1070 if (-1 != rest_node->ippeerlimit) { 1071 fprintf(df, " ippeerlimit %d", 1072 rest_node->ippeerlimit); 1073 } 1074 atrv = HEAD_PFIFO(rest_node->flag_tok_fifo); 1075 for ( ; atrv != NULL; atrv = atrv->link) { 1076 if ( T_Integer == atrv->type 1077 && T_Source != atrv->attr) { 1078 fprintf(df, " %s", keyword(atrv->attr)); 1079 } 1080 } 1081 fprintf(df, "\n"); 1082 /**/ 1083 #if 0 1084 msyslog(LOG_INFO, "Dumping flag_tok_fifo:"); 1085 atrv = HEAD_PFIFO(rest_node->flag_tok_fifo); 1086 for ( ; atrv != NULL; atrv = atrv->link) { 1087 msyslog(LOG_INFO, "- flag_tok_fifo: flags: %08x", atrv->flag); 1088 switch(atrv->type) { 1089 case T_Integer: 1090 msyslog(LOG_INFO, "- T_Integer: attr <%s>/%d, value %d", 1091 keyword(atrv->attr), atrv->attr, atrv->value.i); 1092 break; 1093 default: 1094 msyslog(LOG_INFO, "- Other: attr <%s>/%d, value ???", 1095 keyword(atrv->attr), atrv->attr); 1096 break; 1097 1098 } 1099 } 1100 #endif 1101 /**/ 1102 } 1103 1104 rule_node = HEAD_PFIFO(ptree->nic_rules); 1105 for ( ; rule_node != NULL; rule_node = rule_node->link) { 1106 fprintf(df, "interface %s %s\n", 1107 keyword(rule_node->action), 1108 (rule_node->match_class) 1109 ? keyword(rule_node->match_class) 1110 : rule_node->if_name); 1111 } 1112 1113 str_node = HEAD_PFIFO(ptree->phone); 1114 if (str_node != NULL) { 1115 fprintf(df, "phone"); 1116 for ( ; str_node != NULL; str_node = str_node->link) 1117 fprintf(df, " \"%s\"", str_node->s); 1118 fprintf(df, "\n"); 1119 } 1120 1121 setv_node = HEAD_PFIFO(ptree->setvar); 1122 for ( ; setv_node != NULL; setv_node = setv_node->link) { 1123 s1 = quote_if_needed(setv_node->var); 1124 s2 = quote_if_needed(setv_node->val); 1125 fprintf(df, "setvar %s = %s", s1, s2); 1126 free(s1); 1127 free(s2); 1128 if (setv_node->isdefault) 1129 fprintf(df, " default"); 1130 fprintf(df, "\n"); 1131 } 1132 1133 i_n = HEAD_PFIFO(ptree->ttl); 1134 if (i_n != NULL) { 1135 fprintf(df, "ttl"); 1136 for( ; i_n != NULL; i_n = i_n->link) 1137 fprintf(df, " %d", i_n->i); 1138 fprintf(df, "\n"); 1139 } 1140 1141 addr_opts = HEAD_PFIFO(ptree->trap); 1142 for ( ; addr_opts != NULL; addr_opts = addr_opts->link) { 1143 addr = addr_opts->addr; 1144 fprintf(df, "trap %s", addr->address); 1145 atrv = HEAD_PFIFO(addr_opts->options); 1146 for ( ; atrv != NULL; atrv = atrv->link) { 1147 switch (atrv->attr) { 1148 #ifdef DEBUG 1149 default: 1150 fprintf(df, "\n# dump error:\n" 1151 "# unknown trap token %d\n" 1152 "trap %s", atrv->attr, 1153 addr->address); 1154 break; 1155 #endif 1156 case T_Port: 1157 fprintf(df, " port %d", atrv->value.i); 1158 break; 1159 1160 case T_Interface: 1161 fprintf(df, " interface %s", 1162 atrv->value.s); 1163 break; 1164 } 1165 } 1166 fprintf(df, "\n"); 1167 } 1168 1169 counter_set = HEAD_PFIFO(ptree->reset_counters); 1170 if (counter_set != NULL) { 1171 fprintf(df, "reset"); 1172 for ( ; counter_set != NULL; 1173 counter_set = counter_set->link) 1174 fprintf(df, " %s", keyword(counter_set->i)); 1175 fprintf(df, "\n"); 1176 } 1177 1178 return 0; 1179 } 1180 #endif /* SAVECONFIG */ 1181 1182 1183 /* generic fifo routines for structs linked by 1st member */ 1184 void * 1185 append_gen_fifo( 1186 void *fifo, 1187 void *entry 1188 ) 1189 { 1190 gen_fifo *pf; 1191 gen_node *pe; 1192 1193 pf = fifo; 1194 pe = entry; 1195 if (NULL == pf) 1196 pf = emalloc_zero(sizeof(*pf)); 1197 else 1198 CHECK_FIFO_CONSISTENCY(*pf); 1199 if (pe != NULL) 1200 LINK_FIFO(*pf, pe, link); 1201 CHECK_FIFO_CONSISTENCY(*pf); 1202 1203 return pf; 1204 } 1205 1206 1207 void * 1208 concat_gen_fifos( 1209 void *first, 1210 void *second 1211 ) 1212 { 1213 gen_fifo *pf1; 1214 gen_fifo *pf2; 1215 1216 pf1 = first; 1217 pf2 = second; 1218 if (NULL == pf1) 1219 return pf2; 1220 if (NULL == pf2) 1221 return pf1; 1222 1223 CONCAT_FIFO(*pf1, *pf2, link); 1224 free(pf2); 1225 1226 return pf1; 1227 } 1228 1229 void* 1230 destroy_gen_fifo( 1231 void *fifo, 1232 fifo_deleter func 1233 ) 1234 { 1235 any_node * np = NULL; 1236 any_node_fifo * pf1 = fifo; 1237 1238 if (pf1 != NULL) { 1239 if (!func) 1240 func = free; 1241 for (;;) { 1242 UNLINK_FIFO(np, *pf1, link); 1243 if (np == NULL) 1244 break; 1245 (*func)(np); 1246 } 1247 free(pf1); 1248 } 1249 return NULL; 1250 } 1251 1252 /* FUNCTIONS FOR CREATING NODES ON THE SYNTAX TREE 1253 * ----------------------------------------------- 1254 */ 1255 1256 void 1257 destroy_attr_val( 1258 attr_val * av 1259 ) 1260 { 1261 if (av) { 1262 if (T_String == av->type) 1263 free(av->value.s); 1264 free(av); 1265 } 1266 } 1267 1268 attr_val * 1269 create_attr_dval( 1270 int attr, 1271 double value 1272 ) 1273 { 1274 attr_val *my_val; 1275 1276 my_val = emalloc_zero(sizeof(*my_val)); 1277 my_val->attr = attr; 1278 my_val->value.d = value; 1279 my_val->type = T_Double; 1280 1281 return my_val; 1282 } 1283 1284 1285 attr_val * 1286 create_attr_ival( 1287 int attr, 1288 int value 1289 ) 1290 { 1291 attr_val *my_val; 1292 1293 my_val = emalloc_zero(sizeof(*my_val)); 1294 my_val->attr = attr; 1295 my_val->value.i = value; 1296 my_val->type = T_Integer; 1297 1298 return my_val; 1299 } 1300 1301 1302 attr_val * 1303 create_attr_uval( 1304 int attr, 1305 u_int value 1306 ) 1307 { 1308 attr_val *my_val; 1309 1310 my_val = emalloc_zero(sizeof(*my_val)); 1311 my_val->attr = attr; 1312 my_val->value.u = value; 1313 my_val->type = T_U_int; 1314 1315 return my_val; 1316 } 1317 1318 1319 attr_val * 1320 create_attr_rval( 1321 int attr, 1322 int first, 1323 int last 1324 ) 1325 { 1326 attr_val *my_val; 1327 1328 my_val = emalloc_zero(sizeof(*my_val)); 1329 my_val->attr = attr; 1330 my_val->value.r.first = first; 1331 my_val->value.r.last = last; 1332 my_val->type = T_Intrange; 1333 1334 return my_val; 1335 } 1336 1337 1338 attr_val * 1339 create_attr_sval( 1340 int attr, 1341 const char *s 1342 ) 1343 { 1344 attr_val *my_val; 1345 1346 my_val = emalloc_zero(sizeof(*my_val)); 1347 my_val->attr = attr; 1348 if (NULL == s) /* free() hates NULL */ 1349 s = estrdup(""); 1350 my_val->value.s = _UC(s); 1351 my_val->type = T_String; 1352 1353 return my_val; 1354 } 1355 1356 1357 int_node * 1358 create_int_node( 1359 int val 1360 ) 1361 { 1362 int_node *i_n; 1363 1364 i_n = emalloc_zero(sizeof(*i_n)); 1365 i_n->i = val; 1366 1367 return i_n; 1368 } 1369 1370 1371 string_node * 1372 create_string_node( 1373 char *str 1374 ) 1375 { 1376 string_node *sn; 1377 1378 sn = emalloc_zero(sizeof(*sn)); 1379 sn->s = str; 1380 1381 return sn; 1382 } 1383 1384 1385 address_node * 1386 create_address_node( 1387 char * addr, 1388 int type 1389 ) 1390 { 1391 address_node *my_node; 1392 1393 REQUIRE(NULL != addr); 1394 REQUIRE(AF_INET == type || AF_INET6 == type || AF_UNSPEC == type); 1395 my_node = emalloc_zero(sizeof(*my_node)); 1396 my_node->address = addr; 1397 my_node->type = (u_short)type; 1398 1399 return my_node; 1400 } 1401 1402 1403 void 1404 destroy_address_node( 1405 address_node *my_node 1406 ) 1407 { 1408 if (NULL == my_node) 1409 return; 1410 REQUIRE(NULL != my_node->address); 1411 1412 free(my_node->address); 1413 free(my_node); 1414 } 1415 1416 1417 peer_node * 1418 create_peer_node( 1419 int hmode, 1420 address_node * addr, 1421 attr_val_fifo * options 1422 ) 1423 { 1424 peer_node *my_node; 1425 attr_val *option; 1426 int freenode; 1427 int errflag = 0; 1428 1429 my_node = emalloc_zero(sizeof(*my_node)); 1430 1431 /* Initialize node values to default */ 1432 my_node->peerversion = NTP_VERSION; 1433 1434 /* Now set the node to the read values */ 1435 my_node->host_mode = hmode; 1436 my_node->addr = addr; 1437 1438 /* 1439 * the options FIFO mixes items that will be saved in the 1440 * peer_node as explicit members, such as minpoll, and 1441 * those that are moved intact to the peer_node's peerflags 1442 * FIFO. The options FIFO is consumed and reclaimed here. 1443 */ 1444 1445 if (options != NULL) 1446 CHECK_FIFO_CONSISTENCY(*options); 1447 while (options != NULL) { 1448 UNLINK_FIFO(option, *options, link); 1449 if (NULL == option) { 1450 free(options); 1451 break; 1452 } 1453 1454 freenode = 1; 1455 /* Check the kind of option being set */ 1456 switch (option->attr) { 1457 1458 case T_Flag: 1459 APPEND_G_FIFO(my_node->peerflags, option); 1460 freenode = 0; 1461 break; 1462 1463 case T_Minpoll: 1464 if (option->value.i < NTP_MINPOLL || 1465 option->value.i > UCHAR_MAX) { 1466 msyslog(LOG_INFO, 1467 "minpoll: provided value (%d) is out of range [%d-%d])", 1468 option->value.i, NTP_MINPOLL, 1469 UCHAR_MAX); 1470 my_node->minpoll = NTP_MINPOLL; 1471 } else { 1472 my_node->minpoll = 1473 (u_char)option->value.u; 1474 } 1475 break; 1476 1477 case T_Maxpoll: 1478 if (option->value.i < 0 || 1479 option->value.i > NTP_MAXPOLL) { 1480 msyslog(LOG_INFO, 1481 "maxpoll: provided value (%d) is out of range [0-%d])", 1482 option->value.i, NTP_MAXPOLL); 1483 my_node->maxpoll = NTP_MAXPOLL; 1484 } else { 1485 my_node->maxpoll = 1486 (u_char)option->value.u; 1487 } 1488 break; 1489 1490 case T_Ttl: 1491 if (is_refclk_addr(addr)) { 1492 msyslog(LOG_ERR, "'ttl' does not apply for refclocks"); 1493 errflag = 1; 1494 } else if (option->value.u >= MAX_TTL) { 1495 msyslog(LOG_ERR, "ttl: invalid argument"); 1496 errflag = 1; 1497 } else { 1498 my_node->ttl = (u_char)option->value.u; 1499 } 1500 break; 1501 1502 case T_Mode: 1503 if (is_refclk_addr(addr)) { 1504 my_node->ttl = option->value.u; 1505 } else { 1506 msyslog(LOG_ERR, "'mode' does not apply for network peers"); 1507 errflag = 1; 1508 } 1509 break; 1510 1511 case T_Key: 1512 if (option->value.u >= KEYID_T_MAX) { 1513 msyslog(LOG_ERR, "key: invalid argument"); 1514 errflag = 1; 1515 } else { 1516 my_node->peerkey = 1517 (keyid_t)option->value.u; 1518 } 1519 break; 1520 1521 case T_Version: 1522 if (option->value.u >= UCHAR_MAX) { 1523 msyslog(LOG_ERR, "version: invalid argument"); 1524 errflag = 1; 1525 } else { 1526 my_node->peerversion = 1527 (u_char)option->value.u; 1528 } 1529 break; 1530 1531 case T_Ident: 1532 my_node->group = option->value.s; 1533 break; 1534 1535 default: 1536 msyslog(LOG_ERR, 1537 "Unknown peer/server option token %s", 1538 token_name(option->attr)); 1539 errflag = 1; 1540 } 1541 if (freenode) 1542 free(option); 1543 } 1544 1545 /* Check if errors were reported. If yes, ignore the node */ 1546 if (errflag) { 1547 free(my_node); 1548 my_node = NULL; 1549 } 1550 1551 return my_node; 1552 } 1553 1554 1555 unpeer_node * 1556 create_unpeer_node( 1557 address_node *addr 1558 ) 1559 { 1560 unpeer_node * my_node; 1561 u_long u; 1562 const u_char * pch; 1563 1564 my_node = emalloc_zero(sizeof(*my_node)); 1565 1566 /* 1567 * From the parser's perspective an association ID fits into 1568 * its generic T_String definition of a name/address "address". 1569 * We treat all valid 16-bit numbers as association IDs. 1570 */ 1571 for (u = 0, pch = (u_char*)addr->address; isdigit(*pch); ++pch) { 1572 /* accumulate with overflow retention */ 1573 u = (10 * u + *pch - '0') | (u & 0xFF000000u); 1574 } 1575 1576 if (!*pch && u <= ASSOCID_MAX) { 1577 my_node->assocID = (associd_t)u; 1578 my_node->addr = NULL; 1579 destroy_address_node(addr); 1580 } else { 1581 my_node->assocID = 0; 1582 my_node->addr = addr; 1583 } 1584 1585 return my_node; 1586 } 1587 1588 filegen_node * 1589 create_filegen_node( 1590 int filegen_token, 1591 attr_val_fifo * options 1592 ) 1593 { 1594 filegen_node *my_node; 1595 1596 my_node = emalloc_zero(sizeof(*my_node)); 1597 my_node->filegen_token = filegen_token; 1598 my_node->options = options; 1599 1600 return my_node; 1601 } 1602 1603 1604 restrict_node * 1605 create_restrict_node( 1606 address_node * addr, 1607 address_node * mask, 1608 short ippeerlimit, 1609 attr_val_fifo * flag_tok_fifo, 1610 int/*BOOL*/ remove, 1611 int nline, 1612 int ncol 1613 ) 1614 { 1615 restrict_node *my_node; 1616 1617 my_node = emalloc_zero(sizeof(*my_node)); 1618 my_node->addr = addr; 1619 my_node->mask = mask; 1620 my_node->ippeerlimit = ippeerlimit; 1621 my_node->flag_tok_fifo = flag_tok_fifo; 1622 my_node->remove = remove; 1623 my_node->line_no = nline; 1624 my_node->column = ncol; 1625 1626 return my_node; 1627 } 1628 1629 1630 static void 1631 destroy_restrict_node( 1632 restrict_node *my_node 1633 ) 1634 { 1635 /* With great care, free all the memory occupied by 1636 * the restrict node 1637 */ 1638 destroy_address_node(my_node->addr); 1639 destroy_address_node(my_node->mask); 1640 destroy_attr_val_fifo(my_node->flag_tok_fifo); 1641 free(my_node); 1642 } 1643 1644 1645 static void 1646 destroy_int_fifo( 1647 int_fifo * fifo 1648 ) 1649 { 1650 int_node * i_n; 1651 1652 if (fifo != NULL) { 1653 for (;;) { 1654 UNLINK_FIFO(i_n, *fifo, link); 1655 if (i_n == NULL) 1656 break; 1657 free(i_n); 1658 } 1659 free(fifo); 1660 } 1661 } 1662 1663 1664 static void 1665 destroy_string_fifo( 1666 string_fifo * fifo 1667 ) 1668 { 1669 string_node * sn; 1670 1671 if (fifo != NULL) { 1672 for (;;) { 1673 UNLINK_FIFO(sn, *fifo, link); 1674 if (sn == NULL) 1675 break; 1676 free(sn->s); 1677 free(sn); 1678 } 1679 free(fifo); 1680 } 1681 } 1682 1683 1684 static void 1685 destroy_attr_val_fifo( 1686 attr_val_fifo * av_fifo 1687 ) 1688 { 1689 attr_val * av; 1690 1691 if (av_fifo != NULL) { 1692 for (;;) { 1693 UNLINK_FIFO(av, *av_fifo, link); 1694 if (av == NULL) 1695 break; 1696 destroy_attr_val(av); 1697 } 1698 free(av_fifo); 1699 } 1700 } 1701 1702 1703 static void 1704 destroy_filegen_fifo( 1705 filegen_fifo * fifo 1706 ) 1707 { 1708 filegen_node * fg; 1709 1710 if (fifo != NULL) { 1711 for (;;) { 1712 UNLINK_FIFO(fg, *fifo, link); 1713 if (fg == NULL) 1714 break; 1715 destroy_attr_val_fifo(fg->options); 1716 free(fg); 1717 } 1718 free(fifo); 1719 } 1720 } 1721 1722 1723 static void 1724 destroy_restrict_fifo( 1725 restrict_fifo * fifo 1726 ) 1727 { 1728 restrict_node * rn; 1729 1730 if (fifo != NULL) { 1731 for (;;) { 1732 UNLINK_FIFO(rn, *fifo, link); 1733 if (rn == NULL) 1734 break; 1735 destroy_restrict_node(rn); 1736 } 1737 free(fifo); 1738 } 1739 } 1740 1741 1742 static void 1743 destroy_setvar_fifo( 1744 setvar_fifo * fifo 1745 ) 1746 { 1747 setvar_node * sv; 1748 1749 if (fifo != NULL) { 1750 for (;;) { 1751 UNLINK_FIFO(sv, *fifo, link); 1752 if (sv == NULL) 1753 break; 1754 free(sv->var); 1755 free(sv->val); 1756 free(sv); 1757 } 1758 free(fifo); 1759 } 1760 } 1761 1762 1763 static void 1764 destroy_addr_opts_fifo( 1765 addr_opts_fifo * fifo 1766 ) 1767 { 1768 addr_opts_node * aon; 1769 1770 if (fifo != NULL) { 1771 for (;;) { 1772 UNLINK_FIFO(aon, *fifo, link); 1773 if (aon == NULL) 1774 break; 1775 destroy_address_node(aon->addr); 1776 destroy_attr_val_fifo(aon->options); 1777 free(aon); 1778 } 1779 free(fifo); 1780 } 1781 } 1782 1783 1784 setvar_node * 1785 create_setvar_node( 1786 char * var, 1787 char * val, 1788 int isdefault 1789 ) 1790 { 1791 setvar_node * my_node; 1792 char * pch; 1793 1794 /* do not allow = in the variable name */ 1795 pch = strchr(var, '='); 1796 if (NULL != pch) 1797 *pch = '\0'; 1798 1799 /* Now store the string into a setvar_node */ 1800 my_node = emalloc_zero(sizeof(*my_node)); 1801 my_node->var = var; 1802 my_node->val = val; 1803 my_node->isdefault = isdefault; 1804 1805 return my_node; 1806 } 1807 1808 1809 nic_rule_node * 1810 create_nic_rule_node( 1811 int match_class, 1812 char *if_name, /* interface name or numeric address */ 1813 int action 1814 ) 1815 { 1816 nic_rule_node *my_node; 1817 1818 REQUIRE(match_class != 0 || if_name != NULL); 1819 1820 my_node = emalloc_zero(sizeof(*my_node)); 1821 my_node->match_class = match_class; 1822 my_node->if_name = if_name; 1823 my_node->action = action; 1824 1825 return my_node; 1826 } 1827 1828 1829 addr_opts_node * 1830 create_addr_opts_node( 1831 address_node * addr, 1832 attr_val_fifo * options 1833 ) 1834 { 1835 addr_opts_node *my_node; 1836 1837 my_node = emalloc_zero(sizeof(*my_node)); 1838 my_node->addr = addr; 1839 my_node->options = options; 1840 1841 return my_node; 1842 } 1843 1844 1845 #ifdef SIM 1846 script_info * 1847 create_sim_script_info( 1848 double duration, 1849 attr_val_fifo * script_queue 1850 ) 1851 { 1852 script_info *my_info; 1853 attr_val *my_attr_val; 1854 1855 my_info = emalloc_zero(sizeof(*my_info)); 1856 1857 /* Initialize Script Info with default values*/ 1858 my_info->duration = duration; 1859 my_info->prop_delay = NET_DLY; 1860 my_info->proc_delay = PROC_DLY; 1861 1862 /* Traverse the script_queue and fill out non-default values */ 1863 1864 for (my_attr_val = HEAD_PFIFO(script_queue); 1865 my_attr_val != NULL; 1866 my_attr_val = my_attr_val->link) { 1867 1868 /* Set the desired value */ 1869 switch (my_attr_val->attr) { 1870 1871 case T_Freq_Offset: 1872 my_info->freq_offset = my_attr_val->value.d; 1873 break; 1874 1875 case T_Wander: 1876 my_info->wander = my_attr_val->value.d; 1877 break; 1878 1879 case T_Jitter: 1880 my_info->jitter = my_attr_val->value.d; 1881 break; 1882 1883 case T_Prop_Delay: 1884 my_info->prop_delay = my_attr_val->value.d; 1885 break; 1886 1887 case T_Proc_Delay: 1888 my_info->proc_delay = my_attr_val->value.d; 1889 break; 1890 1891 default: 1892 msyslog(LOG_ERR, "Unknown script token %d", 1893 my_attr_val->attr); 1894 } 1895 } 1896 1897 return my_info; 1898 } 1899 #endif /* SIM */ 1900 1901 1902 #ifdef SIM 1903 static sockaddr_u * 1904 get_next_address( 1905 address_node *addr 1906 ) 1907 { 1908 const char addr_prefix[] = "192.168.0."; 1909 static int curr_addr_num = 1; 1910 #define ADDR_LENGTH 16 + 1 /* room for 192.168.1.255 */ 1911 char addr_string[ADDR_LENGTH]; 1912 sockaddr_u *final_addr; 1913 struct addrinfo *ptr; 1914 int gai_err; 1915 1916 final_addr = emalloc(sizeof(*final_addr)); 1917 1918 if (addr->type == T_String) { 1919 snprintf(addr_string, sizeof(addr_string), "%s%d", 1920 addr_prefix, curr_addr_num++); 1921 printf("Selecting ip address %s for hostname %s\n", 1922 addr_string, addr->address); 1923 gai_err = getaddrinfo(addr_string, "ntp", NULL, &ptr); 1924 } else { 1925 gai_err = getaddrinfo(addr->address, "ntp", NULL, &ptr); 1926 } 1927 1928 if (gai_err) { 1929 fprintf(stderr, "ERROR!! Could not get a new address\n"); 1930 exit(1); 1931 } 1932 memcpy(final_addr, ptr->ai_addr, ptr->ai_addrlen); 1933 fprintf(stderr, "Successful in setting ip address of simulated server to: %s\n", 1934 stoa(final_addr)); 1935 freeaddrinfo(ptr); 1936 1937 return final_addr; 1938 } 1939 #endif /* SIM */ 1940 1941 1942 #ifdef SIM 1943 server_info * 1944 create_sim_server( 1945 address_node * addr, 1946 double server_offset, 1947 script_info_fifo * script 1948 ) 1949 { 1950 server_info *my_info; 1951 1952 my_info = emalloc_zero(sizeof(*my_info)); 1953 my_info->server_time = server_offset; 1954 my_info->addr = get_next_address(addr); 1955 my_info->script = script; 1956 UNLINK_FIFO(my_info->curr_script, *my_info->script, link); 1957 1958 return my_info; 1959 } 1960 #endif /* SIM */ 1961 1962 sim_node * 1963 create_sim_node( 1964 attr_val_fifo * init_opts, 1965 server_info_fifo * servers 1966 ) 1967 { 1968 sim_node *my_node; 1969 1970 my_node = emalloc(sizeof(*my_node)); 1971 my_node->init_opts = init_opts; 1972 my_node->servers = servers; 1973 1974 return my_node; 1975 } 1976 1977 1978 1979 1980 /* FUNCTIONS FOR PERFORMING THE CONFIGURATION 1981 * ------------------------------------------ 1982 */ 1983 1984 #ifndef SIM 1985 static void 1986 config_other_modes( 1987 config_tree * ptree 1988 ) 1989 { 1990 sockaddr_u addr_sock; 1991 address_node * addr_node; 1992 1993 if (ptree->broadcastclient) 1994 proto_config(PROTO_BROADCLIENT, ptree->broadcastclient, 1995 0., NULL); 1996 1997 addr_node = HEAD_PFIFO(ptree->manycastserver); 1998 while (addr_node != NULL) { 1999 ZERO_SOCK(&addr_sock); 2000 AF(&addr_sock) = addr_node->type; 2001 if (1 == getnetnum(addr_node->address, &addr_sock, 1, 2002 t_UNK)) { 2003 proto_config(PROTO_MULTICAST_ADD, 2004 0, 0., &addr_sock); 2005 sys_manycastserver = 1; 2006 } 2007 addr_node = addr_node->link; 2008 } 2009 2010 /* Configure the multicast clients */ 2011 addr_node = HEAD_PFIFO(ptree->multicastclient); 2012 if (addr_node != NULL) { 2013 do { 2014 ZERO_SOCK(&addr_sock); 2015 AF(&addr_sock) = addr_node->type; 2016 if (1 == getnetnum(addr_node->address, 2017 &addr_sock, 1, t_UNK)) { 2018 proto_config(PROTO_MULTICAST_ADD, 0, 0., 2019 &addr_sock); 2020 } 2021 addr_node = addr_node->link; 2022 } while (addr_node != NULL); 2023 proto_config(PROTO_MULTICAST_ADD, 1, 0., NULL); 2024 } 2025 } 2026 #endif /* !SIM */ 2027 2028 2029 #ifdef FREE_CFG_T 2030 static void 2031 destroy_address_fifo( 2032 address_fifo * pfifo 2033 ) 2034 { 2035 address_node * addr_node; 2036 2037 if (pfifo != NULL) { 2038 for (;;) { 2039 UNLINK_FIFO(addr_node, *pfifo, link); 2040 if (addr_node == NULL) 2041 break; 2042 destroy_address_node(addr_node); 2043 } 2044 free(pfifo); 2045 } 2046 } 2047 2048 2049 static void 2050 free_config_other_modes( 2051 config_tree *ptree 2052 ) 2053 { 2054 FREE_ADDRESS_FIFO(ptree->manycastserver); 2055 FREE_ADDRESS_FIFO(ptree->multicastclient); 2056 } 2057 #endif /* FREE_CFG_T */ 2058 2059 2060 #ifndef SIM 2061 static void 2062 config_auth( 2063 config_tree *ptree 2064 ) 2065 { 2066 attr_val * my_val; 2067 int first; 2068 int last; 2069 int i; 2070 int count; 2071 #ifdef AUTOKEY 2072 int item; 2073 #endif 2074 2075 /* Crypto Command */ 2076 #ifdef AUTOKEY 2077 my_val = HEAD_PFIFO(ptree->auth.crypto_cmd_list); 2078 for (; my_val != NULL; my_val = my_val->link) { 2079 switch (my_val->attr) { 2080 2081 default: 2082 fatal_error("config_auth: attr-token=%d", my_val->attr); 2083 2084 case T_Host: 2085 item = CRYPTO_CONF_PRIV; 2086 break; 2087 2088 case T_Ident: 2089 item = CRYPTO_CONF_IDENT; 2090 break; 2091 2092 case T_Pw: 2093 item = CRYPTO_CONF_PW; 2094 break; 2095 2096 case T_Randfile: 2097 item = CRYPTO_CONF_RAND; 2098 break; 2099 2100 case T_Digest: 2101 item = CRYPTO_CONF_NID; 2102 break; 2103 } 2104 crypto_config(item, my_val->value.s); 2105 } 2106 #endif /* AUTOKEY */ 2107 2108 /* Keysdir Command */ 2109 if (ptree->auth.keysdir) { 2110 if (keysdir != default_keysdir) 2111 free(keysdir); 2112 keysdir = estrdup(ptree->auth.keysdir); 2113 } 2114 2115 2116 /* ntp_signd_socket Command */ 2117 if (ptree->auth.ntp_signd_socket) { 2118 if (ntp_signd_socket != default_ntp_signd_socket) 2119 free(ntp_signd_socket); 2120 ntp_signd_socket = estrdup(ptree->auth.ntp_signd_socket); 2121 } 2122 2123 #ifdef AUTOKEY 2124 if (ptree->auth.cryptosw && !cryptosw) { 2125 crypto_setup(); 2126 cryptosw = 1; 2127 } 2128 #endif /* AUTOKEY */ 2129 2130 /* 2131 * Count the number of trusted keys to preallocate storage and 2132 * size the hash table. 2133 */ 2134 count = 0; 2135 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list); 2136 for (; my_val != NULL; my_val = my_val->link) { 2137 if (T_Integer == my_val->type) { 2138 first = my_val->value.i; 2139 if (first > 1 && first <= NTP_MAXKEY) 2140 count++; 2141 } else { 2142 REQUIRE(T_Intrange == my_val->type); 2143 first = my_val->value.r.first; 2144 last = my_val->value.r.last; 2145 if (!(first > last || first < 1 || 2146 last > NTP_MAXKEY)) { 2147 count += 1 + last - first; 2148 } 2149 } 2150 } 2151 auth_prealloc_symkeys(count); 2152 2153 /* Keys Command */ 2154 if (ptree->auth.keys) 2155 getauthkeys(ptree->auth.keys); 2156 2157 /* Control Key Command */ 2158 if (ptree->auth.control_key) 2159 ctl_auth_keyid = (keyid_t)ptree->auth.control_key; 2160 2161 /* Requested Key Command */ 2162 if (ptree->auth.request_key) { 2163 DPRINTF(4, ("set info_auth_keyid to %08lx\n", 2164 (u_long) ptree->auth.request_key)); 2165 info_auth_keyid = (keyid_t)ptree->auth.request_key; 2166 } 2167 2168 /* Trusted Key Command */ 2169 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list); 2170 for (; my_val != NULL; my_val = my_val->link) { 2171 if (T_Integer == my_val->type) { 2172 first = my_val->value.i; 2173 if (first >= 1 && first <= NTP_MAXKEY) { 2174 authtrust(first, TRUE); 2175 } else { 2176 msyslog(LOG_NOTICE, 2177 "Ignoring invalid trustedkey %d, min 1 max %d.", 2178 first, NTP_MAXKEY); 2179 } 2180 } else { 2181 first = my_val->value.r.first; 2182 last = my_val->value.r.last; 2183 if (first > last || first < 1 || 2184 last > NTP_MAXKEY) { 2185 msyslog(LOG_NOTICE, 2186 "Ignoring invalid trustedkey range %d ... %d, min 1 max %d.", 2187 first, last, NTP_MAXKEY); 2188 } else { 2189 for (i = first; i <= last; i++) { 2190 authtrust(i, TRUE); 2191 } 2192 } 2193 } 2194 } 2195 2196 #ifdef AUTOKEY 2197 /* crypto revoke command */ 2198 if (ptree->auth.revoke > 2 && ptree->auth.revoke < 32) 2199 sys_revoke = (u_char)ptree->auth.revoke; 2200 else if (ptree->auth.revoke) 2201 msyslog(LOG_ERR, 2202 "'revoke' value %d ignored", 2203 ptree->auth.revoke); 2204 #endif /* AUTOKEY */ 2205 } 2206 #endif /* !SIM */ 2207 2208 2209 #ifdef FREE_CFG_T 2210 static void 2211 free_config_auth( 2212 config_tree *ptree 2213 ) 2214 { 2215 destroy_attr_val_fifo(ptree->auth.crypto_cmd_list); 2216 ptree->auth.crypto_cmd_list = NULL; 2217 destroy_attr_val_fifo(ptree->auth.trusted_key_list); 2218 ptree->auth.trusted_key_list = NULL; 2219 } 2220 #endif /* FREE_CFG_T */ 2221 2222 2223 #ifndef SIM 2224 /* Configure low-level clock-related parameters. Return TRUE if the 2225 * clock might need adjustment like era-checking after the call, FALSE 2226 * otherwise. 2227 */ 2228 static int/*BOOL*/ 2229 config_tos_clock( 2230 config_tree* ptree 2231 ) 2232 { 2233 int ret; 2234 attr_val* tos; 2235 2236 ret = FALSE; 2237 tos = HEAD_PFIFO(ptree->orphan_cmds); 2238 for (; tos != NULL; tos = tos->link) { 2239 switch (tos->attr) { 2240 2241 default: 2242 break; 2243 2244 case T_Basedate: 2245 basedate_set_day(tos->value.i); 2246 ret = TRUE; 2247 break; 2248 } 2249 } 2250 2251 if (basedate_get_day() <= NTP_TO_UNIX_DAYS) { 2252 basedate_set_day(basedate_eval_buildstamp() - 11); 2253 } 2254 return ret; 2255 } 2256 #endif /* !SIM */ 2257 2258 2259 static void 2260 config_tos( 2261 config_tree *ptree 2262 ) 2263 { 2264 char const improper_operation_msg[] = 2265 " - daemon will not operate properly!"; 2266 attr_val * tos; 2267 int item; 2268 double val; 2269 2270 /* [Bug 2896] For the daemon to work properly it is essential 2271 * that minsane < minclock <= maxclock. 2272 * 2273 * If either constraint is violated, the daemon will be or might 2274 * become dysfunctional. Fixing the values is too fragile here, 2275 * since three variables with interdependecies are involved. We 2276 * just log an error but do not stop: This might be caused by 2277 * remote config, and it might be fixed by remote config, too. 2278 */ 2279 int l_maxclock = sys_maxclock; 2280 int l_minclock = sys_minclock; 2281 int l_minsane = sys_minsane; 2282 int l_floor = sys_floor; 2283 int l_ceiling = sys_ceiling; 2284 2285 /* -*- phase one: inspect / sanitize the values */ 2286 tos = HEAD_PFIFO(ptree->orphan_cmds); 2287 for (; tos != NULL; tos = tos->link) { 2288 /* not all attributes are doubles (any more), so loading 2289 * 'val' in all cases is not a good idea: It should be 2290 * done as needed in every case processed here. 2291 */ 2292 switch(tos->attr) { 2293 default: 2294 break; 2295 2296 case T_Bcpollbstep: 2297 val = tos->value.d; 2298 if (val > 4) { 2299 msyslog(LOG_WARNING, 2300 "Using maximum tos bcpollbstep %d, %d requested", 2301 4, (int)val); 2302 tos->value.d = 4; 2303 } else if (val < 0) { 2304 msyslog(LOG_WARNING, 2305 "Using minimum tos bcpollbstep %d, %d requested", 2306 0, (int)val); 2307 tos->value.d = 0; 2308 } 2309 break; 2310 2311 case T_Floor: 2312 l_floor = (int)tos->value.d; 2313 if (l_floor > STRATUM_UNSPEC - 1) { 2314 msyslog(LOG_WARNING, 2315 "Using maximum tos floor %d, %d requested", 2316 STRATUM_UNSPEC - 1, l_floor); 2317 tos->value.d = STRATUM_UNSPEC - 1; 2318 } 2319 else if (l_floor < 0) { 2320 msyslog(LOG_WARNING, 2321 "Using minimum tos floor %d, %d requested", 2322 0, l_floor); 2323 tos->value.d = 0; 2324 } 2325 l_floor = (int)tos->value.d; 2326 break; 2327 2328 case T_Ceiling: 2329 l_ceiling = (int)tos->value.d; 2330 if (l_ceiling > STRATUM_UNSPEC - 1) { 2331 msyslog(LOG_WARNING, 2332 "Using maximum tos ceiling %d, %d requested", 2333 STRATUM_UNSPEC - 1, l_ceiling); 2334 tos->value.d = STRATUM_UNSPEC - 1; 2335 } 2336 else if (l_ceiling < 0) { 2337 msyslog(LOG_WARNING, 2338 "Using minimum tos ceiling %d, %d requested", 2339 0, l_ceiling); 2340 tos->value.d = 0; 2341 } 2342 l_ceiling = (int)tos->value.d; 2343 break; 2344 2345 case T_Minclock: 2346 val = tos->value.d; 2347 if ((int)tos->value.d < 1) 2348 tos->value.d = 1; 2349 l_minclock = (int)tos->value.d; 2350 break; 2351 2352 case T_Maxclock: 2353 val = tos->value.d; 2354 if ((int)tos->value.d < 1) 2355 tos->value.d = 1; 2356 l_maxclock = (int)tos->value.d; 2357 break; 2358 2359 case T_Minsane: 2360 val = tos->value.d; 2361 if ((int)tos->value.d < 0) 2362 tos->value.d = 0; 2363 l_minsane = (int)tos->value.d; 2364 break; 2365 } 2366 } 2367 2368 if ( ! (l_minsane < l_minclock && l_minclock <= l_maxclock)) { 2369 msyslog(LOG_ERR, "Must have tos " 2370 "minsane (%d) < minclock (%d) <= maxclock (%d)%s", 2371 l_minsane, l_minclock, l_maxclock, 2372 improper_operation_msg); 2373 } 2374 2375 if (l_floor > l_ceiling) { 2376 msyslog(LOG_ERR, "Must have tos " 2377 "floor (%d) <= ceiling (%d)%s", 2378 l_floor, l_ceiling, improper_operation_msg); 2379 } 2380 2381 /* -*- phase two: forward the values to the protocol machinery */ 2382 tos = HEAD_PFIFO(ptree->orphan_cmds); 2383 for (; tos != NULL; tos = tos->link) { 2384 switch(tos->attr) { 2385 2386 default: 2387 fatal_error("config-tos: attr-token=%d", tos->attr); 2388 2389 case T_Bcpollbstep: 2390 item = PROTO_BCPOLLBSTEP; 2391 break; 2392 2393 case T_Ceiling: 2394 item = PROTO_CEILING; 2395 break; 2396 2397 case T_Floor: 2398 item = PROTO_FLOOR; 2399 break; 2400 2401 case T_Cohort: 2402 item = PROTO_COHORT; 2403 break; 2404 2405 case T_Orphan: 2406 item = PROTO_ORPHAN; 2407 break; 2408 2409 case T_Orphanwait: 2410 item = PROTO_ORPHWAIT; 2411 break; 2412 2413 case T_Mindist: 2414 item = PROTO_MINDISP; 2415 break; 2416 2417 case T_Maxdist: 2418 item = PROTO_MAXDIST; 2419 break; 2420 2421 case T_Minclock: 2422 item = PROTO_MINCLOCK; 2423 break; 2424 2425 case T_Maxclock: 2426 item = PROTO_MAXCLOCK; 2427 break; 2428 2429 case T_Minsane: 2430 item = PROTO_MINSANE; 2431 break; 2432 2433 case T_Beacon: 2434 item = PROTO_BEACON; 2435 break; 2436 2437 case T_Basedate: 2438 continue; /* SKIP proto-config for this! */ 2439 } 2440 proto_config(item, 0, tos->value.d, NULL); 2441 } 2442 } 2443 2444 2445 #ifdef FREE_CFG_T 2446 static void 2447 free_config_tos( 2448 config_tree *ptree 2449 ) 2450 { 2451 FREE_ATTR_VAL_FIFO(ptree->orphan_cmds); 2452 } 2453 #endif /* FREE_CFG_T */ 2454 2455 2456 static void 2457 config_monitor( 2458 config_tree* ptree 2459 ) 2460 { 2461 int_node * pfilegen_token; 2462 const char * filegen_string; 2463 const char * filegen_file; 2464 FILEGEN * filegen; 2465 filegen_node * my_node; 2466 attr_val* my_opts; 2467 int filegen_type; 2468 int filegen_flag; 2469 2470 /* Set the statistics directory */ 2471 if (ptree->stats_dir) { 2472 stats_config(STATS_STATSDIR, ptree->stats_dir, TRUE); 2473 } 2474 2475 /* NOTE: 2476 * Calling filegen_get is brain dead. Doing a string 2477 * comparison to find the relavant filegen structure is 2478 * expensive. 2479 * 2480 * Through the parser, we already know which filegen is 2481 * being specified. Hence, we should either store a 2482 * pointer to the specified structure in the syntax tree 2483 * or an index into a filegen array. 2484 * 2485 * Need to change the filegen code to reflect the above. 2486 */ 2487 2488 /* Turn on the specified statistics */ 2489 pfilegen_token = HEAD_PFIFO(ptree->stats_list); 2490 for (; pfilegen_token != NULL; pfilegen_token = pfilegen_token->link) { 2491 filegen_string = keyword(pfilegen_token->i); 2492 filegen = filegen_get(filegen_string); 2493 if (NULL == filegen) { 2494 msyslog(LOG_ERR, 2495 "stats %s unrecognized", 2496 filegen_string); 2497 continue; 2498 } 2499 DPRINTF(4, ("enabling filegen for %s statistics '%s%s'\n", 2500 filegen_string, filegen->dir, 2501 filegen->fname)); 2502 filegen_flag = filegen->flag; 2503 filegen_flag |= FGEN_FLAG_ENABLED; 2504 filegen_config(filegen, statsdir, filegen_string, 2505 filegen->type, filegen_flag); 2506 } 2507 2508 /* Configure the statistics with the options */ 2509 my_node = HEAD_PFIFO(ptree->filegen_opts); 2510 for (; my_node != NULL; my_node = my_node->link) { 2511 filegen_string = keyword(my_node->filegen_token); 2512 filegen = filegen_get(filegen_string); 2513 if (NULL == filegen) { 2514 msyslog(LOG_ERR, 2515 "filegen category '%s' unrecognized", 2516 filegen_string); 2517 continue; 2518 } 2519 filegen_file = filegen_string; 2520 2521 /* Initialize the filegen variables to their pre-configuration states */ 2522 filegen_flag = filegen->flag; 2523 filegen_type = filegen->type; 2524 2525 /* "filegen ... enabled" is the default (when filegen is used) */ 2526 filegen_flag |= FGEN_FLAG_ENABLED; 2527 2528 my_opts = HEAD_PFIFO(my_node->options); 2529 for (; my_opts != NULL; my_opts = my_opts->link) { 2530 switch (my_opts->attr) { 2531 2532 case T_File: 2533 filegen_file = my_opts->value.s; 2534 break; 2535 2536 case T_Type: 2537 switch (my_opts->value.i) { 2538 2539 default: 2540 fatal_error("config-monitor: type-token=%d", my_opts->value.i); 2541 2542 case T_None: 2543 filegen_type = FILEGEN_NONE; 2544 break; 2545 2546 case T_Pid: 2547 filegen_type = FILEGEN_PID; 2548 break; 2549 2550 case T_Day: 2551 filegen_type = FILEGEN_DAY; 2552 break; 2553 2554 case T_Week: 2555 filegen_type = FILEGEN_WEEK; 2556 break; 2557 2558 case T_Month: 2559 filegen_type = FILEGEN_MONTH; 2560 break; 2561 2562 case T_Year: 2563 filegen_type = FILEGEN_YEAR; 2564 break; 2565 2566 case T_Age: 2567 filegen_type = FILEGEN_AGE; 2568 break; 2569 } 2570 break; 2571 2572 case T_Flag: 2573 switch (my_opts->value.i) { 2574 2575 case T_Link: 2576 filegen_flag |= FGEN_FLAG_LINK; 2577 break; 2578 2579 case T_Nolink: 2580 filegen_flag &= ~FGEN_FLAG_LINK; 2581 break; 2582 2583 case T_Enable: 2584 filegen_flag |= FGEN_FLAG_ENABLED; 2585 break; 2586 2587 case T_Disable: 2588 filegen_flag &= ~FGEN_FLAG_ENABLED; 2589 break; 2590 2591 default: 2592 msyslog(LOG_ERR, 2593 "Unknown filegen flag token %d", 2594 my_opts->value.i); 2595 exit(1); 2596 } 2597 break; 2598 2599 default: 2600 msyslog(LOG_ERR, 2601 "Unknown filegen option token %d", 2602 my_opts->attr); 2603 exit(1); 2604 } 2605 } 2606 filegen_config(filegen, statsdir, filegen_file, 2607 filegen_type, filegen_flag); 2608 } 2609 } 2610 2611 2612 #ifdef FREE_CFG_T 2613 static void 2614 free_config_monitor( 2615 config_tree *ptree 2616 ) 2617 { 2618 if (ptree->stats_dir) { 2619 free(ptree->stats_dir); 2620 ptree->stats_dir = NULL; 2621 } 2622 2623 FREE_INT_FIFO(ptree->stats_list); 2624 FREE_FILEGEN_FIFO(ptree->filegen_opts); 2625 } 2626 #endif /* FREE_CFG_T */ 2627 2628 2629 #ifndef SIM 2630 static void 2631 config_access( 2632 config_tree *ptree 2633 ) 2634 { 2635 static int warned_signd; 2636 attr_val * my_opt; 2637 restrict_node * my_node; 2638 sockaddr_u addr; 2639 sockaddr_u mask; 2640 struct addrinfo hints; 2641 struct addrinfo * ai_list; 2642 struct addrinfo * pai; 2643 int rc; 2644 int/*BOOL*/ success; 2645 int/*BOOL*/ restrict_default; 2646 u_short rflags; 2647 u_short mflags; 2648 short ippeerlimit; 2649 int range_err; 2650 attr_val * atrv; 2651 attr_val * dflt_psl_atr; 2652 const char * signd_warning = 2653 #ifdef HAVE_NTP_SIGND 2654 "MS-SNTP signd operations currently block ntpd degrading service to all clients.\n"; 2655 #else 2656 "mssntp restrict bit ignored, this ntpd was configured without --enable-ntp-signd.\n"; 2657 #endif 2658 2659 /* Configure the mru options */ 2660 my_opt = HEAD_PFIFO(ptree->mru_opts); 2661 for (; my_opt != NULL; my_opt = my_opt->link) { 2662 2663 range_err = FALSE; 2664 2665 switch (my_opt->attr) { 2666 2667 case T_Incalloc: 2668 if (0 <= my_opt->value.i) 2669 mru_incalloc = my_opt->value.u; 2670 else 2671 range_err = TRUE; 2672 break; 2673 2674 case T_Incmem: 2675 if (0 <= my_opt->value.i) 2676 mru_incalloc = (my_opt->value.u * 1024U) 2677 / sizeof(mon_entry); 2678 else 2679 range_err = TRUE; 2680 break; 2681 2682 case T_Initalloc: 2683 if (0 <= my_opt->value.i) 2684 mru_initalloc = my_opt->value.u; 2685 else 2686 range_err = TRUE; 2687 break; 2688 2689 case T_Initmem: 2690 if (0 <= my_opt->value.i) 2691 mru_initalloc = (my_opt->value.u * 1024U) 2692 / sizeof(mon_entry); 2693 else 2694 range_err = TRUE; 2695 break; 2696 2697 case T_Mindepth: 2698 if (0 <= my_opt->value.i) 2699 mru_mindepth = my_opt->value.u; 2700 else 2701 range_err = TRUE; 2702 break; 2703 2704 case T_Maxage: 2705 mru_maxage = my_opt->value.i; 2706 break; 2707 2708 case T_Maxdepth: 2709 if (0 <= my_opt->value.i) 2710 mru_maxdepth = my_opt->value.u; 2711 else 2712 mru_maxdepth = UINT_MAX; 2713 break; 2714 2715 case T_Maxmem: 2716 if (0 <= my_opt->value.i) 2717 mru_maxdepth = (my_opt->value.u * 1024U) / 2718 sizeof(mon_entry); 2719 else 2720 mru_maxdepth = UINT_MAX; 2721 break; 2722 2723 default: 2724 msyslog(LOG_ERR, 2725 "Unknown mru option %s (%d)", 2726 keyword(my_opt->attr), my_opt->attr); 2727 exit(1); 2728 } 2729 if (range_err) 2730 msyslog(LOG_ERR, 2731 "mru %s %d out of range, ignored.", 2732 keyword(my_opt->attr), my_opt->value.i); 2733 } 2734 2735 /* Configure the discard options */ 2736 my_opt = HEAD_PFIFO(ptree->discard_opts); 2737 for (; my_opt != NULL; my_opt = my_opt->link) { 2738 2739 switch (my_opt->attr) { 2740 2741 case T_Average: 2742 if (0 <= my_opt->value.i && 2743 my_opt->value.i <= UCHAR_MAX) 2744 ntp_minpoll = (u_char)my_opt->value.u; 2745 else 2746 msyslog(LOG_ERR, 2747 "discard average %d out of range, ignored.", 2748 my_opt->value.i); 2749 break; 2750 2751 case T_Minimum: 2752 ntp_minpkt = my_opt->value.i; 2753 break; 2754 2755 case T_Monitor: 2756 mon_age = my_opt->value.i; 2757 break; 2758 2759 default: 2760 msyslog(LOG_ERR, 2761 "Unknown discard option %s (%d)", 2762 keyword(my_opt->attr), my_opt->attr); 2763 exit(1); 2764 } 2765 } 2766 2767 /* Configure each line of restrict options */ 2768 my_node = HEAD_PFIFO(ptree->restrict_opts); 2769 2770 for (; my_node != NULL; my_node = my_node->link) { 2771 2772 /* Grab the ippeerlmit */ 2773 ippeerlimit = my_node->ippeerlimit; 2774 2775 /* Parse the flags */ 2776 rflags = 0; 2777 mflags = 0; 2778 2779 my_opt = HEAD_PFIFO(my_node->flag_tok_fifo); 2780 for (; my_opt != NULL; my_opt = my_opt->link) { 2781 switch (my_opt->attr) { 2782 2783 default: 2784 fatal_error("config_access: Unknown flag-type-token=%s/%d", keyword(my_opt->attr), my_opt->attr); 2785 2786 case T_Ntpport: 2787 mflags |= RESM_NTPONLY; 2788 break; 2789 2790 case T_Source: 2791 mflags |= RESM_SOURCE; 2792 break; 2793 2794 case T_Flake: 2795 rflags |= RES_FLAKE; 2796 break; 2797 2798 case T_Ignore: 2799 rflags |= RES_IGNORE; 2800 break; 2801 2802 case T_Kod: 2803 rflags |= RES_KOD; 2804 break; 2805 2806 case T_Limited: 2807 rflags |= RES_LIMITED; 2808 break; 2809 2810 case T_Lowpriotrap: 2811 rflags |= RES_LPTRAP; 2812 break; 2813 2814 case T_Mssntp: 2815 rflags |= RES_MSSNTP; 2816 break; 2817 2818 case T_Nomodify: 2819 rflags |= RES_NOMODIFY; 2820 break; 2821 2822 case T_Nomrulist: 2823 rflags |= RES_NOMRULIST; 2824 break; 2825 2826 case T_Noepeer: 2827 rflags |= RES_NOEPEER; 2828 break; 2829 2830 case T_Nopeer: 2831 rflags |= RES_NOPEER; 2832 break; 2833 2834 case T_Noquery: 2835 rflags |= RES_NOQUERY; 2836 break; 2837 2838 case T_Noserve: 2839 rflags |= RES_DONTSERVE; 2840 break; 2841 2842 case T_Notrap: 2843 rflags |= RES_NOTRAP; 2844 break; 2845 2846 case T_Notrust: 2847 rflags |= RES_DONTTRUST; 2848 break; 2849 2850 case T_ServerresponseFuzz: 2851 rflags |= RES_SRVRSPFUZ; 2852 break; 2853 2854 case T_Version: 2855 rflags |= RES_VERSION; 2856 break; 2857 } 2858 } 2859 2860 if ((RES_MSSNTP & rflags) && !warned_signd) { 2861 warned_signd = TRUE; 2862 fprintf(stderr, "%s", signd_warning); 2863 msyslog(LOG_WARNING, "%s", signd_warning); 2864 } 2865 2866 if ((RES_KOD & rflags) && !(RES_LIMITED & rflags)) { 2867 const char *kod_where = (my_node->addr) 2868 ? my_node->addr->address 2869 : (mflags & RESM_SOURCE) 2870 ? "source" 2871 : "default"; 2872 const char *kod_warn = "'kod' does nothing without 'limited'.\n"; 2873 2874 fprintf(stderr, "line %d col %d restrict %s: %s", 2875 my_node->line_no, my_node->column, 2876 kod_where, kod_warn); 2877 msyslog(LOG_WARNING, "line %d col %d restrict %s: %s", 2878 my_node->line_no, my_node->column, 2879 kod_where, kod_warn); 2880 } 2881 2882 ZERO_SOCK(&addr); 2883 ai_list = NULL; 2884 pai = NULL; 2885 restrict_default = FALSE; 2886 2887 if (NULL == my_node->addr) { 2888 ZERO_SOCK(&mask); 2889 if (!(RESM_SOURCE & mflags)) { 2890 /* 2891 * The user specified a default rule 2892 * without a -4 / -6 qualifier, add to 2893 * both lists 2894 */ 2895 restrict_default = TRUE; 2896 } else { 2897 /* apply "restrict source ..." */ 2898 success = hack_restrict(RESTRICT_FLAGS, 2899 NULL, NULL, 2900 ippeerlimit, 2901 mflags, rflags, 2902 0); 2903 if (!success) { 2904 msyslog(LOG_ERR, 2905 "unable to save restrict source"); 2906 } 2907 continue; 2908 } 2909 } else { 2910 /* Resolve the specified address */ 2911 AF(&addr) = (u_short)my_node->addr->type; 2912 2913 if (getnetnum(my_node->addr->address, 2914 &addr, 1, t_UNK) != 1) { 2915 /* 2916 * Attempt a blocking lookup. This 2917 * is in violation of the nonblocking 2918 * design of ntpd's mainline code. The 2919 * alternative of running without the 2920 * restriction until the name resolved 2921 * seems worse. 2922 * Ideally some scheme could be used for 2923 * restrict directives in the startup 2924 * ntp.conf to delay starting up the 2925 * protocol machinery until after all 2926 * restrict hosts have been resolved. 2927 */ 2928 ai_list = NULL; 2929 ZERO(hints); 2930 hints.ai_protocol = IPPROTO_UDP; 2931 hints.ai_socktype = SOCK_DGRAM; 2932 hints.ai_family = my_node->addr->type; 2933 rc = getaddrinfo(my_node->addr->address, 2934 "ntp", &hints, 2935 &ai_list); 2936 if (rc) { 2937 msyslog(LOG_ERR, 2938 "restrict: line %d col %d" 2939 " address/host '%s' unusable.", 2940 my_node->line_no, 2941 my_node->column, 2942 my_node->addr->address); 2943 continue; 2944 } 2945 INSIST(ai_list != NULL); 2946 pai = ai_list; 2947 INSIST(pai->ai_addr != NULL); 2948 INSIST(sizeof(addr) >= pai->ai_addrlen); 2949 memcpy(&addr, pai->ai_addr, 2950 pai->ai_addrlen); 2951 INSIST(AF_INET == AF(&addr) || 2952 AF_INET6 == AF(&addr)); 2953 } 2954 2955 /* default to all-ones mask for single address */ 2956 SET_HOSTMASK(&mask, AF(&addr)); 2957 2958 /* Ignore mask if addr from hostname [Bug 3872] */ 2959 if (NULL == ai_list && my_node->mask) { 2960 ZERO_SOCK(&mask); 2961 AF(&mask) = my_node->mask->type; 2962 if (getnetnum(my_node->mask->address, 2963 &mask, 1, t_MSK) != 1) { 2964 msyslog(LOG_ERR, 2965 "restrict: line %d col %d" 2966 " mask '%s' unusable.", 2967 my_node->line_no, 2968 my_node->column, 2969 my_node->mask->address); 2970 continue; 2971 } 2972 } 2973 } 2974 2975 /* Set the flags */ 2976 if (restrict_default) { 2977 AF(&addr) = AF_INET; 2978 AF(&mask) = AF_INET; 2979 success = hack_restrict( 2980 RESTRICT_FLAGS, 2981 &addr, 2982 &mask, 2983 ippeerlimit, 2984 mflags, 2985 rflags, 2986 0 2987 ); 2988 if (!success) { 2989 msyslog(LOG_ERR, 2990 "unable to save %s %s restriction", 2991 stoa(&addr), stoa(&mask)); 2992 } 2993 AF(&addr) = AF_INET6; 2994 AF(&mask) = AF_INET6; 2995 } 2996 2997 do { 2998 success = hack_restrict( 2999 my_node->remove 3000 ? RESTRICT_REMOVE 3001 : RESTRICT_FLAGS, 3002 &addr, 3003 &mask, 3004 ippeerlimit, 3005 mflags, 3006 rflags, 3007 0); 3008 if (!success) { 3009 msyslog(LOG_ERR, 3010 "unable to %s %s %s restriction", 3011 my_node->remove 3012 ? "delete" 3013 : "save", 3014 stoa(&addr), stoa(&mask)); 3015 } 3016 if (pai != NULL && 3017 NULL != (pai = pai->ai_next)) { 3018 INSIST(pai->ai_addr != NULL); 3019 INSIST(sizeof(addr) >= 3020 pai->ai_addrlen); 3021 ZERO_SOCK(&addr); 3022 memcpy(&addr, pai->ai_addr, 3023 pai->ai_addrlen); 3024 INSIST(AF_INET == AF(&addr) || 3025 AF_INET6 == AF(&addr)); 3026 SET_HOSTMASK(&mask, AF(&addr)); 3027 } 3028 } while (pai != NULL); 3029 3030 if (ai_list != NULL) { 3031 freeaddrinfo(ai_list); 3032 } 3033 } 3034 3035 /* 3036 * pollskewlist 3037 */ 3038 atrv = HEAD_PFIFO(ptree->pollskewlist); 3039 if (NULL == atrv) { 3040 /* don't touch the poll skew list */ 3041 return; 3042 } 3043 ZERO(psl); 3044 /* 3045 * First, find the last default pollskewlist item. 3046 */ 3047 dflt_psl_atr = NULL; 3048 for ( ; atrv != NULL; atrv = atrv->link) { 3049 if (-1 == atrv->attr) { /* default */ 3050 dflt_psl_atr = atrv; 3051 } else if ( atrv->attr < NTP_MINPOLL 3052 || atrv->attr > NTP_MAXPOLL) { 3053 msyslog(LOG_ERR, 3054 "Poll %d out of bounds [%d-%d] for pollskewlist", 3055 atrv->attr, NTP_MINPOLL, NTP_MAXPOLL); 3056 } 3057 } 3058 3059 /* If we have a nonzero default, put it in all entries */ 3060 if ( dflt_psl_atr 3061 && ( 0 != dflt_psl_atr->value.r.first 3062 || 0 != dflt_psl_atr->value.r.last)) { 3063 int i; 3064 3065 for (i = NTP_MINPOLL; i <= NTP_MAXPOLL; ++i) { 3066 attrtopsl(i, dflt_psl_atr); 3067 } 3068 } 3069 3070 /* Finally, update the PSL with any explicit entries */ 3071 atrv = HEAD_PFIFO(ptree->pollskewlist); 3072 for ( ; atrv != NULL; atrv = atrv->link) { 3073 if (atrv->attr >= NTP_MINPOLL && atrv->attr <= NTP_MAXPOLL) { 3074 attrtopsl(atrv->attr, atrv); 3075 } 3076 } 3077 3078 #if 0 3079 int p; 3080 msyslog(LOG_INFO, "Dumping PSL:"); 3081 for (p = NTP_MINPOLL; p <= NTP_MAXPOLL; ++p) { 3082 psl_item psi; 3083 3084 if (0 == get_pollskew(p, &psi)) { 3085 msyslog(LOG_INFO, "poll %d: sub %d, qty %d, msk %d", 3086 p, psi.sub, psi.qty, psi.msk); 3087 } else { 3088 msyslog(LOG_ERR, "Dumping PSL: get_pollskew(%d) failed!", p); 3089 } 3090 } 3091 #endif 3092 } 3093 3094 3095 static void 3096 attrtopsl( 3097 u_char log2_poll, 3098 attr_val * avp 3099 ) 3100 { 3101 int pao = log2_poll - NTP_MINPOLL; /* poll array offset */ 3102 u_int32 lower = (u_short)avp->value.r.first; /* ntp_parser.y ensures */ 3103 u_int32 upper = (u_short)avp->value.r.last; /* non-neg. first/last */ 3104 u_int psmax = 1 << (log2_poll - 1); 3105 u_int32 qmsk; 3106 3107 DEBUG_INSIST(pao >= 0 && pao < COUNTOF(psl)); 3108 3109 if (lower > psmax) { 3110 msyslog(LOG_WARNING, "pollskewlist %d lower bound reduced from %d to %d", 3111 log2_poll, lower, psmax); 3112 lower = psmax; 3113 } 3114 if (upper > psmax) { 3115 msyslog(LOG_WARNING, "pollskewlist %d upper bound reduced from %d to %d", 3116 log2_poll, upper, psmax); 3117 upper = psmax; 3118 } 3119 psl[pao].sub = lower; 3120 psl[pao].qty = lower + upper; 3121 3122 qmsk = 1; 3123 while (qmsk < (lower + upper)) { 3124 qmsk <<= 1; 3125 qmsk |= 1; 3126 } 3127 psl[pao].msk = qmsk; 3128 } 3129 #endif /* !SIM */ 3130 3131 3132 int 3133 get_pollskew( 3134 int p, 3135 psl_item *rv 3136 ) 3137 { 3138 #ifdef DISABLE_BUG3767_FIX 3139 DEBUG_INSIST(NTP_MINPOLL <= p && NTP_MAXPOLL >= p); 3140 #endif 3141 if (NTP_MINPOLL <= p && p <= NTP_MAXPOLL) { 3142 *rv = psl[p - NTP_MINPOLL]; 3143 return 0; 3144 } else { 3145 msyslog(LOG_DEBUG, "get_pollskew(%d): out of range", p); 3146 return -1; 3147 } 3148 3149 /* NOTREACHED */ 3150 } 3151 3152 3153 #ifdef FREE_CFG_T 3154 static void 3155 free_config_access( 3156 config_tree *ptree 3157 ) 3158 { 3159 FREE_ATTR_VAL_FIFO(ptree->mru_opts); 3160 FREE_ATTR_VAL_FIFO(ptree->discard_opts); 3161 FREE_RESTRICT_FIFO(ptree->restrict_opts); 3162 } 3163 #endif /* FREE_CFG_T */ 3164 3165 3166 static void 3167 config_rlimit( 3168 config_tree *ptree 3169 ) 3170 { 3171 attr_val * rlimit_av; 3172 3173 rlimit_av = HEAD_PFIFO(ptree->rlimit); 3174 for (; rlimit_av != NULL; rlimit_av = rlimit_av->link) { 3175 switch (rlimit_av->attr) { 3176 3177 default: 3178 fatal_error("config-rlimit: value-token=%d", rlimit_av->attr); 3179 3180 case T_Memlock: 3181 /* What if we HAVE_OPT(SAVECONFIGQUIT) ? */ 3182 if (HAVE_OPT( SAVECONFIGQUIT )) { 3183 break; 3184 } 3185 if (rlimit_av->value.i == -1) { 3186 # if defined(HAVE_MLOCKALL) 3187 if (cur_memlock != 0) { 3188 if (-1 == munlockall()) { 3189 msyslog(LOG_ERR, "munlockall() failed: %m"); 3190 } 3191 } 3192 cur_memlock = 0; 3193 # endif /* HAVE_MLOCKALL */ 3194 } else if (rlimit_av->value.i >= 0) { 3195 #if defined(RLIMIT_MEMLOCK) 3196 # if defined(HAVE_MLOCKALL) 3197 if (cur_memlock != 1) { 3198 if (-1 == mlockall(MCL_CURRENT|MCL_FUTURE)) { 3199 msyslog(LOG_ERR, "mlockall() failed: %m"); 3200 } 3201 } 3202 # endif /* HAVE_MLOCKALL */ 3203 ntp_rlimit(RLIMIT_MEMLOCK, 3204 (rlim_t)(rlimit_av->value.i * 1024 * 1024), 3205 1024 * 1024, 3206 "MB"); 3207 cur_memlock = 1; 3208 #else 3209 /* STDERR as well would be fine... */ 3210 msyslog(LOG_WARNING, "'rlimit memlock' specified but is not available on this system."); 3211 #endif /* RLIMIT_MEMLOCK */ 3212 } else { 3213 msyslog(LOG_WARNING, "'rlimit memlock' value of %d is unexpected!", rlimit_av->value.i); 3214 } 3215 break; 3216 3217 case T_Stacksize: 3218 #if defined(RLIMIT_STACK) 3219 ntp_rlimit(RLIMIT_STACK, 3220 (rlim_t)(rlimit_av->value.i * 4096), 3221 4096, 3222 "4k"); 3223 #else 3224 /* STDERR as well would be fine... */ 3225 msyslog(LOG_WARNING, "'rlimit stacksize' specified but is not available on this system."); 3226 #endif /* RLIMIT_STACK */ 3227 break; 3228 3229 case T_Filenum: 3230 #if defined(RLIMIT_NOFILE) 3231 ntp_rlimit(RLIMIT_NOFILE, 3232 (rlim_t)(rlimit_av->value.i), 3233 1, 3234 ""); 3235 #else 3236 /* STDERR as well would be fine... */ 3237 msyslog(LOG_WARNING, "'rlimit filenum' specified but is not available on this system."); 3238 #endif /* RLIMIT_NOFILE */ 3239 break; 3240 3241 } 3242 } 3243 } 3244 3245 3246 static void 3247 config_tinker( 3248 config_tree *ptree 3249 ) 3250 { 3251 attr_val * tinker; 3252 int item; 3253 3254 tinker = HEAD_PFIFO(ptree->tinker); 3255 for (; tinker != NULL; tinker = tinker->link) { 3256 switch (tinker->attr) { 3257 3258 default: 3259 fatal_error("config_tinker: attr-token=%d", tinker->attr); 3260 3261 case T_Allan: 3262 item = LOOP_ALLAN; 3263 break; 3264 3265 case T_Dispersion: 3266 item = LOOP_PHI; 3267 break; 3268 3269 case T_Freq: 3270 item = LOOP_FREQ; 3271 break; 3272 3273 case T_Huffpuff: 3274 item = LOOP_HUFFPUFF; 3275 break; 3276 3277 case T_Panic: 3278 item = LOOP_PANIC; 3279 break; 3280 3281 case T_Step: 3282 item = LOOP_MAX; 3283 break; 3284 3285 case T_Stepback: 3286 item = LOOP_MAX_BACK; 3287 break; 3288 3289 case T_Stepfwd: 3290 item = LOOP_MAX_FWD; 3291 break; 3292 3293 case T_Stepout: 3294 item = LOOP_MINSTEP; 3295 break; 3296 3297 case T_Tick: 3298 item = LOOP_TICK; 3299 break; 3300 } 3301 loop_config(item, tinker->value.d); 3302 } 3303 } 3304 3305 3306 #ifdef FREE_CFG_T 3307 static void 3308 free_config_rlimit( 3309 config_tree *ptree 3310 ) 3311 { 3312 FREE_ATTR_VAL_FIFO(ptree->rlimit); 3313 } 3314 3315 static void 3316 free_config_tinker( 3317 config_tree *ptree 3318 ) 3319 { 3320 FREE_ATTR_VAL_FIFO(ptree->tinker); 3321 } 3322 #endif /* FREE_CFG_T */ 3323 3324 3325 /* 3326 * config_nic_rules - apply interface listen/ignore/drop items 3327 */ 3328 #ifndef SIM 3329 static void 3330 config_nic_rules( 3331 config_tree *ptree, 3332 int/*BOOL*/ input_from_file 3333 ) 3334 { 3335 nic_rule_node * curr_node; 3336 sockaddr_u addr; 3337 nic_rule_match match_type; 3338 nic_rule_action action; 3339 char * if_name; 3340 char * pchSlash; 3341 int prefixlen; 3342 int addrbits; 3343 3344 curr_node = HEAD_PFIFO(ptree->nic_rules); 3345 3346 if (curr_node != NULL 3347 && (HAVE_OPT( NOVIRTUALIPS ) || HAVE_OPT( INTERFACE ))) { 3348 msyslog(LOG_ERR, 3349 "interface/nic rules are not allowed with --interface (-I) or --novirtualips (-L)%s", 3350 (input_from_file) ? ", exiting" : ""); 3351 if (input_from_file) 3352 exit(1); 3353 else 3354 return; 3355 } 3356 3357 for (; curr_node != NULL; curr_node = curr_node->link) { 3358 prefixlen = -1; 3359 if_name = curr_node->if_name; 3360 if (if_name != NULL) 3361 if_name = estrdup(if_name); 3362 3363 switch (curr_node->match_class) { 3364 default: 3365 #ifdef DEBUG 3366 fatal_error("config_nic_rules: match-class-token=%d", curr_node->match_class); 3367 #endif 3368 case T_All: 3369 match_type = MATCH_ALL; 3370 break; 3371 3372 case 0: 3373 /* 3374 * 0 is out of range for valid token T_... 3375 * and in a nic_rules_node indicates the 3376 * interface descriptor is either a name or 3377 * address, stored in if_name in either case. 3378 */ 3379 INSIST(if_name != NULL); 3380 pchSlash = strchr(if_name, '/'); 3381 if (pchSlash != NULL) 3382 *pchSlash = '\0'; 3383 if (is_ip_address(if_name, AF_UNSPEC, &addr)) { 3384 match_type = MATCH_IFADDR; 3385 if (pchSlash != NULL 3386 && 1 == sscanf(pchSlash + 1, "%d", 3387 &prefixlen)) { 3388 addrbits = 8 * 3389 SIZEOF_INADDR(AF(&addr)); 3390 prefixlen = max(-1, prefixlen); 3391 prefixlen = min(prefixlen, 3392 addrbits); 3393 } 3394 } else { 3395 match_type = MATCH_IFNAME; 3396 if (pchSlash != NULL) 3397 *pchSlash = '/'; 3398 } 3399 break; 3400 3401 case T_Ipv4: 3402 match_type = MATCH_IPV4; 3403 break; 3404 3405 case T_Ipv6: 3406 match_type = MATCH_IPV6; 3407 break; 3408 3409 case T_Wildcard: 3410 match_type = MATCH_WILDCARD; 3411 break; 3412 } 3413 3414 switch (curr_node->action) { 3415 default: 3416 #ifdef DEBUG 3417 fatal_error("config_nic_rules: action-token=%d", curr_node->action); 3418 #endif 3419 case T_Listen: 3420 action = ACTION_LISTEN; 3421 break; 3422 3423 case T_Ignore: 3424 action = ACTION_IGNORE; 3425 break; 3426 3427 case T_Drop: 3428 action = ACTION_DROP; 3429 break; 3430 } 3431 3432 add_nic_rule(match_type, if_name, prefixlen, 3433 action); 3434 if (!initializing && !scan_addrs_once) { 3435 endpt_scan_timer = 1 + current_time; 3436 } 3437 if (if_name != NULL) 3438 free(if_name); 3439 } 3440 } 3441 #endif /* !SIM */ 3442 3443 3444 #ifdef FREE_CFG_T 3445 static void 3446 free_config_nic_rules( 3447 config_tree *ptree 3448 ) 3449 { 3450 nic_rule_node *curr_node; 3451 3452 if (ptree->nic_rules != NULL) { 3453 for (;;) { 3454 UNLINK_FIFO(curr_node, *ptree->nic_rules, link); 3455 if (NULL == curr_node) 3456 break; 3457 free(curr_node->if_name); 3458 free(curr_node); 3459 } 3460 free(ptree->nic_rules); 3461 ptree->nic_rules = NULL; 3462 } 3463 } 3464 #endif /* FREE_CFG_T */ 3465 3466 3467 static void 3468 apply_enable_disable( 3469 attr_val_fifo * fifo, 3470 int enable 3471 ) 3472 { 3473 attr_val *curr_tok_fifo; 3474 int option; 3475 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED 3476 bc_entry *pentry; 3477 #endif 3478 3479 for (curr_tok_fifo = HEAD_PFIFO(fifo); 3480 curr_tok_fifo != NULL; 3481 curr_tok_fifo = curr_tok_fifo->link) { 3482 3483 option = curr_tok_fifo->value.i; 3484 switch (option) { 3485 3486 default: 3487 msyslog(LOG_ERR, 3488 "can not apply enable/disable token %d, unknown", 3489 option); 3490 break; 3491 3492 case T_Auth: 3493 proto_config(PROTO_AUTHENTICATE, enable, 0., NULL); 3494 break; 3495 3496 case T_Bclient: 3497 proto_config(PROTO_BROADCLIENT, enable, 0., NULL); 3498 break; 3499 3500 case T_Calibrate: 3501 proto_config(PROTO_CAL, enable, 0., NULL); 3502 break; 3503 3504 case T_Kernel: 3505 proto_config(PROTO_KERNEL, enable, 0., NULL); 3506 break; 3507 3508 case T_Monitor: 3509 proto_config(PROTO_MONITOR, enable, 0., NULL); 3510 break; 3511 3512 case T_Mode7: 3513 proto_config(PROTO_MODE7, enable, 0., NULL); 3514 break; 3515 3516 case T_Ntp: 3517 proto_config(PROTO_NTP, enable, 0., NULL); 3518 break; 3519 3520 case T_PCEdigest: 3521 proto_config(PROTO_PCEDIGEST, enable, 0., NULL); 3522 break; 3523 3524 case T_Stats: 3525 proto_config(PROTO_FILEGEN, enable, 0., NULL); 3526 break; 3527 3528 case T_UEcrypto: 3529 proto_config(PROTO_UECRYPTO, enable, 0., NULL); 3530 break; 3531 3532 case T_UEcryptonak: 3533 proto_config(PROTO_UECRYPTONAK, enable, 0., NULL); 3534 break; 3535 3536 case T_UEdigest: 3537 proto_config(PROTO_UEDIGEST, enable, 0., NULL); 3538 break; 3539 3540 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED 3541 case T_Bc_bugXXXX: 3542 pentry = bc_list; 3543 while (pentry->token) { 3544 if (pentry->token == option) 3545 break; 3546 pentry++; 3547 } 3548 if (!pentry->token) { 3549 msyslog(LOG_ERR, 3550 "compat token %d not in bc_list[]", 3551 option); 3552 continue; 3553 } 3554 pentry->enabled = enable; 3555 break; 3556 #endif 3557 } 3558 } 3559 } 3560 3561 3562 static void 3563 config_system_opts( 3564 config_tree *ptree 3565 ) 3566 { 3567 apply_enable_disable(ptree->enable_opts, 1); 3568 apply_enable_disable(ptree->disable_opts, 0); 3569 } 3570 3571 3572 #ifdef FREE_CFG_T 3573 static void 3574 free_config_system_opts( 3575 config_tree *ptree 3576 ) 3577 { 3578 FREE_ATTR_VAL_FIFO(ptree->enable_opts); 3579 FREE_ATTR_VAL_FIFO(ptree->disable_opts); 3580 } 3581 #endif /* FREE_CFG_T */ 3582 3583 3584 static void 3585 config_logconfig( 3586 config_tree *ptree 3587 ) 3588 { 3589 attr_val * my_lc; 3590 3591 my_lc = HEAD_PFIFO(ptree->logconfig); 3592 for (; my_lc != NULL; my_lc = my_lc->link) { 3593 switch (my_lc->attr) { 3594 3595 case '+': 3596 ntp_syslogmask |= get_logmask(my_lc->value.s); 3597 break; 3598 3599 case '-': 3600 ntp_syslogmask &= ~get_logmask(my_lc->value.s); 3601 break; 3602 3603 case '=': 3604 ntp_syslogmask = get_logmask(my_lc->value.s); 3605 break; 3606 default: 3607 fatal_error("config-logconfig: modifier='%c'", my_lc->attr); 3608 } 3609 } 3610 } 3611 3612 3613 #ifdef FREE_CFG_T 3614 static void 3615 free_config_logconfig( 3616 config_tree *ptree 3617 ) 3618 { 3619 FREE_ATTR_VAL_FIFO(ptree->logconfig); 3620 } 3621 #endif /* FREE_CFG_T */ 3622 3623 3624 #ifndef SIM 3625 static void 3626 config_phone( 3627 config_tree *ptree 3628 ) 3629 { 3630 size_t i; 3631 string_node * sn; 3632 3633 i = 0; 3634 sn = HEAD_PFIFO(ptree->phone); 3635 for (; sn != NULL; sn = sn->link) { 3636 /* need to leave array entry for NULL terminator */ 3637 if (i < COUNTOF(sys_phone) - 1) { 3638 sys_phone[i++] = estrdup(sn->s); 3639 sys_phone[i] = NULL; 3640 } else { 3641 msyslog(LOG_INFO, 3642 "phone: Number of phone entries exceeds %zu. Ignoring phone %s...", 3643 (COUNTOF(sys_phone) - 1), sn->s); 3644 } 3645 } 3646 } 3647 3648 static void 3649 config_mdnstries( 3650 config_tree *ptree 3651 ) 3652 { 3653 #ifdef HAVE_DNSREGISTRATION 3654 extern int mdnstries; 3655 mdnstries = ptree->mdnstries; 3656 #endif /* HAVE_DNSREGISTRATION */ 3657 } 3658 #endif /* !SIM */ 3659 3660 #ifdef FREE_CFG_T 3661 static void 3662 free_config_phone( 3663 config_tree *ptree 3664 ) 3665 { 3666 FREE_STRING_FIFO(ptree->phone); 3667 } 3668 #endif /* FREE_CFG_T */ 3669 3670 3671 #ifndef SIM 3672 static void 3673 config_setvar( 3674 config_tree *ptree 3675 ) 3676 { 3677 setvar_node *my_node; 3678 size_t varlen, vallen, octets; 3679 char * str; 3680 3681 str = NULL; 3682 my_node = HEAD_PFIFO(ptree->setvar); 3683 for (; my_node != NULL; my_node = my_node->link) { 3684 varlen = strlen(my_node->var); 3685 vallen = strlen(my_node->val); 3686 octets = varlen + vallen + 1 + 1; 3687 str = erealloc(str, octets); 3688 snprintf(str, octets, "%s=%s", my_node->var, 3689 my_node->val); 3690 set_sys_var(str, octets, (my_node->isdefault) 3691 ? DEF 3692 : 0); 3693 } 3694 if (str != NULL) 3695 free(str); 3696 } 3697 #endif /* !SIM */ 3698 3699 3700 #ifdef FREE_CFG_T 3701 static void 3702 free_config_setvar( 3703 config_tree *ptree 3704 ) 3705 { 3706 FREE_SETVAR_FIFO(ptree->setvar); 3707 } 3708 #endif /* FREE_CFG_T */ 3709 3710 3711 #ifndef SIM 3712 static void 3713 config_ttl( 3714 config_tree *ptree 3715 ) 3716 { 3717 size_t i = 0; 3718 int_node *curr_ttl; 3719 3720 /* [Bug 3465] There is a built-in default for the TTLs. We must 3721 * overwrite 'sys_ttlmax' if we change that preset, and leave it 3722 * alone otherwise! 3723 */ 3724 curr_ttl = HEAD_PFIFO(ptree->ttl); 3725 for (; curr_ttl != NULL; curr_ttl = curr_ttl->link) { 3726 if (i < COUNTOF(sys_ttl)) 3727 sys_ttl[i++] = (u_char)curr_ttl->i; 3728 else 3729 msyslog(LOG_INFO, 3730 "ttl: Number of TTL entries exceeds %zu. Ignoring TTL %d...", 3731 COUNTOF(sys_ttl), curr_ttl->i); 3732 } 3733 if (0 != i) /* anything written back at all? */ 3734 sys_ttlmax = i - 1; 3735 } 3736 #endif /* !SIM */ 3737 3738 3739 #ifdef FREE_CFG_T 3740 static void 3741 free_config_ttl( 3742 config_tree *ptree 3743 ) 3744 { 3745 FREE_INT_FIFO(ptree->ttl); 3746 } 3747 #endif /* FREE_CFG_T */ 3748 3749 3750 #ifndef SIM 3751 static void 3752 config_trap( 3753 config_tree *ptree 3754 ) 3755 { 3756 addr_opts_node *curr_trap; 3757 attr_val *curr_opt; 3758 sockaddr_u addr_sock; 3759 sockaddr_u peeraddr; 3760 endpt *localaddr; 3761 struct addrinfo hints; 3762 char port_text[8]; 3763 settrap_parms *pstp; 3764 u_short port; 3765 int err_flag; 3766 int rc; 3767 3768 /* silence warning about addr_sock potentially uninitialized */ 3769 AF(&addr_sock) = AF_UNSPEC; 3770 3771 curr_trap = HEAD_PFIFO(ptree->trap); 3772 for (; curr_trap != NULL; curr_trap = curr_trap->link) { 3773 err_flag = 0; 3774 port = 0; 3775 localaddr = NULL; 3776 3777 curr_opt = HEAD_PFIFO(curr_trap->options); 3778 for (; curr_opt != NULL; curr_opt = curr_opt->link) { 3779 if (T_Port == curr_opt->attr) { 3780 if (curr_opt->value.i < 1 3781 || curr_opt->value.i > USHRT_MAX) { 3782 msyslog(LOG_ERR, 3783 "invalid port number " 3784 "%d, trap ignored", 3785 curr_opt->value.i); 3786 err_flag = 1; 3787 } 3788 port = (u_short)curr_opt->value.i; 3789 } 3790 else if (T_Interface == curr_opt->attr) { 3791 /* Resolve the interface address */ 3792 ZERO_SOCK(&addr_sock); 3793 if (getnetnum(curr_opt->value.s, 3794 &addr_sock, 1, t_UNK) != 1) { 3795 err_flag = 1; 3796 break; 3797 } 3798 3799 localaddr = findinterface(&addr_sock); 3800 3801 if (NULL == localaddr) { 3802 msyslog(LOG_ERR, 3803 "can't find interface with address %s", 3804 stoa(&addr_sock)); 3805 err_flag = 1; 3806 } 3807 } 3808 } 3809 3810 /* Now process the trap for the specified interface 3811 * and port number 3812 */ 3813 if (!err_flag) { 3814 if (!port) 3815 port = TRAPPORT; 3816 ZERO_SOCK(&peeraddr); 3817 rc = getnetnum(curr_trap->addr->address, 3818 &peeraddr, 1, t_UNK); 3819 if (1 != rc) { 3820 #ifndef WORKER 3821 msyslog(LOG_ERR, 3822 "trap: unable to use IP address %s.", 3823 curr_trap->addr->address); 3824 #else /* WORKER follows */ 3825 /* 3826 * save context and hand it off 3827 * for name resolution. 3828 */ 3829 ZERO(hints); 3830 hints.ai_protocol = IPPROTO_UDP; 3831 hints.ai_socktype = SOCK_DGRAM; 3832 snprintf(port_text, sizeof(port_text), 3833 "%u", port); 3834 hints.ai_flags = Z_AI_NUMERICSERV; 3835 pstp = emalloc_zero(sizeof(*pstp)); 3836 if (localaddr != NULL) { 3837 hints.ai_family = localaddr->family; 3838 pstp->ifaddr_nonnull = 1; 3839 memcpy(&pstp->ifaddr, 3840 &localaddr->sin, 3841 sizeof(pstp->ifaddr)); 3842 } 3843 rc = getaddrinfo_sometime( 3844 curr_trap->addr->address, 3845 port_text, &hints, 3846 INITIAL_DNS_RETRY, 3847 &trap_name_resolved, 3848 pstp); 3849 if (!rc) 3850 msyslog(LOG_ERR, 3851 "config_trap: getaddrinfo_sometime(%s,%s): %m", 3852 curr_trap->addr->address, 3853 port_text); 3854 #endif /* WORKER */ 3855 continue; 3856 } 3857 /* port is at same location for v4 and v6 */ 3858 SET_PORT(&peeraddr, port); 3859 3860 if (NULL == localaddr) 3861 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr); 3862 else 3863 AF(&peeraddr) = AF(&addr_sock); 3864 3865 if (!ctlsettrap(&peeraddr, localaddr, 0, 3866 NTP_VERSION)) 3867 msyslog(LOG_ERR, 3868 "set trap %s -> %s failed.", 3869 latoa(localaddr), 3870 stoa(&peeraddr)); 3871 } 3872 } 3873 } 3874 3875 3876 /* 3877 * trap_name_resolved() 3878 * 3879 * Callback invoked when config_trap()'s DNS lookup completes. 3880 */ 3881 # ifdef WORKER 3882 static void 3883 trap_name_resolved( 3884 int rescode, 3885 int gai_errno, 3886 void * context, 3887 const char * name, 3888 const char * service, 3889 const struct addrinfo * hints, 3890 const struct addrinfo * res 3891 ) 3892 { 3893 settrap_parms *pstp; 3894 endpt *localaddr; 3895 sockaddr_u peeraddr; 3896 3897 (void)gai_errno; 3898 (void)service; 3899 (void)hints; 3900 pstp = context; 3901 if (rescode) { 3902 msyslog(LOG_ERR, 3903 "giving up resolving trap host %s: %s (%d)", 3904 name, gai_strerror(rescode), rescode); 3905 free(pstp); 3906 return; 3907 } 3908 INSIST(sizeof(peeraddr) >= res->ai_addrlen); 3909 ZERO(peeraddr); 3910 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen); 3911 localaddr = NULL; 3912 if (pstp->ifaddr_nonnull) 3913 localaddr = findinterface(&pstp->ifaddr); 3914 if (NULL == localaddr) 3915 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr); 3916 if (!ctlsettrap(&peeraddr, localaddr, 0, NTP_VERSION)) 3917 msyslog(LOG_ERR, "set trap %s -> %s failed.", 3918 latoa(localaddr), stoa(&peeraddr)); 3919 free(pstp); 3920 } 3921 # endif /* WORKER */ 3922 #endif /* !SIM */ 3923 3924 3925 #ifdef FREE_CFG_T 3926 static void 3927 free_config_trap( 3928 config_tree *ptree 3929 ) 3930 { 3931 FREE_ADDR_OPTS_FIFO(ptree->trap); 3932 } 3933 #endif /* FREE_CFG_T */ 3934 3935 3936 #ifndef SIM 3937 static void 3938 config_fudge( 3939 config_tree *ptree 3940 ) 3941 { 3942 addr_opts_node *curr_fudge; 3943 attr_val *curr_opt; 3944 sockaddr_u addr_sock; 3945 address_node *addr_node; 3946 struct refclockstat clock_stat; 3947 char refidstr[5]; 3948 int err_flag; 3949 3950 curr_fudge = HEAD_PFIFO(ptree->fudge); 3951 for (; curr_fudge != NULL; curr_fudge = curr_fudge->link) { 3952 err_flag = 0; 3953 3954 /* Get the reference clock address and 3955 * ensure that it is sane 3956 */ 3957 addr_node = curr_fudge->addr; 3958 ZERO_SOCK(&addr_sock); 3959 if (getnetnum(addr_node->address, &addr_sock, 1, t_REF) 3960 != 1) { 3961 err_flag = 1; 3962 msyslog(LOG_ERR, 3963 "unrecognized fudge reference clock address %s, line ignored", 3964 addr_node->address); 3965 } else if (!ISREFCLOCKADR(&addr_sock)) { 3966 err_flag = 1; 3967 msyslog(LOG_ERR, 3968 "inappropriate address %s for the fudge command, line ignored", 3969 stoa(&addr_sock)); 3970 } 3971 3972 /* Parse all the options to the fudge command */ 3973 ZERO(clock_stat); 3974 /* some things are not necessarily cleared by ZERO...*/ 3975 clock_stat.fudgeminjitter = 0.0; 3976 clock_stat.fudgetime1 = 0.0; 3977 clock_stat.fudgetime2 = 0.0; 3978 curr_opt = HEAD_PFIFO(curr_fudge->options); 3979 for (; curr_opt != NULL; curr_opt = curr_opt->link) { 3980 switch (curr_opt->attr) { 3981 3982 case T_Time1: 3983 clock_stat.haveflags |= CLK_HAVETIME1; 3984 clock_stat.fudgetime1 = curr_opt->value.d; 3985 break; 3986 3987 case T_Time2: 3988 clock_stat.haveflags |= CLK_HAVETIME2; 3989 clock_stat.fudgetime2 = curr_opt->value.d; 3990 break; 3991 3992 case T_Stratum: 3993 clock_stat.haveflags |= CLK_HAVEVAL1; 3994 clock_stat.fudgeval1 = curr_opt->value.i; 3995 break; 3996 3997 case T_Refid: 3998 clock_stat.haveflags |= CLK_HAVEVAL2; 3999 /* 4000 * strncpy() does exactly what we want 4001 * here, do not be tempted to replace 4002 * it with strlcpy(), we want it to 4003 * zero-fill refid's less than 4 chars 4004 * because we're going to stuff it 4005 * into a u_int32. 4006 */ 4007 strncpy(refidstr, curr_opt->value.s, 4008 sizeof refidstr - 1); 4009 memcpy(&clock_stat.fudgeval2, refidstr, 4010 sizeof clock_stat.fudgeval2); 4011 break; 4012 4013 case T_Flag1: 4014 clock_stat.haveflags |= CLK_HAVEFLAG1; 4015 if (curr_opt->value.i) 4016 clock_stat.flags |= CLK_FLAG1; 4017 else 4018 clock_stat.flags &= ~CLK_FLAG1; 4019 break; 4020 4021 case T_Flag2: 4022 clock_stat.haveflags |= CLK_HAVEFLAG2; 4023 if (curr_opt->value.i) 4024 clock_stat.flags |= CLK_FLAG2; 4025 else 4026 clock_stat.flags &= ~CLK_FLAG2; 4027 break; 4028 4029 case T_Flag3: 4030 clock_stat.haveflags |= CLK_HAVEFLAG3; 4031 if (curr_opt->value.i) 4032 clock_stat.flags |= CLK_FLAG3; 4033 else 4034 clock_stat.flags &= ~CLK_FLAG3; 4035 break; 4036 4037 case T_Flag4: 4038 clock_stat.haveflags |= CLK_HAVEFLAG4; 4039 if (curr_opt->value.i) 4040 clock_stat.flags |= CLK_FLAG4; 4041 else 4042 clock_stat.flags &= ~CLK_FLAG4; 4043 break; 4044 4045 case T_Minjitter: 4046 clock_stat.haveflags |= CLK_HAVEMINJIT; 4047 clock_stat.fudgeminjitter = curr_opt->value.d; 4048 break; 4049 4050 default: 4051 msyslog(LOG_ERR, 4052 "Unexpected fudge flag %s (%d) for %s", 4053 token_name(curr_opt->attr), 4054 curr_opt->attr, addr_node->address); 4055 exit(curr_opt->attr ? curr_opt->attr : 1); 4056 } 4057 } 4058 # ifdef REFCLOCK 4059 if (!err_flag) 4060 refclock_control(&addr_sock, &clock_stat, NULL); 4061 # endif 4062 } 4063 } 4064 #endif /* !SIM */ 4065 4066 #ifndef SIM 4067 static void 4068 config_device( 4069 config_tree *ptree 4070 ) 4071 { 4072 addr_opts_node *curr_device; 4073 attr_val *curr_opt; 4074 sockaddr_u addr_sock; 4075 address_node *addr_node; 4076 char *ttyName, *ppsName; 4077 4078 curr_device = HEAD_PFIFO(ptree->device); 4079 for (; curr_device != NULL; curr_device = curr_device->link) { 4080 /* Get the reference clock address and 4081 * ensure that it is sane 4082 */ 4083 addr_node = curr_device->addr; 4084 ZERO_SOCK(&addr_sock); 4085 if (getnetnum(addr_node->address, &addr_sock, 1, t_REF) 4086 != 1) { 4087 msyslog(LOG_ERR, 4088 "unrecognized device reference clock address %s, line ignored", 4089 addr_node->address); 4090 continue; 4091 } 4092 if (!ISREFCLOCKADR(&addr_sock)) { 4093 msyslog(LOG_ERR, 4094 "inappropriate address %s for the device command, line ignored", 4095 stoa(&addr_sock)); 4096 continue; 4097 } 4098 4099 ppsName = ttyName = NULL; 4100 curr_opt = HEAD_PFIFO(curr_device->options); 4101 for (; curr_opt != NULL; curr_opt = curr_opt->link) { 4102 switch (curr_opt->attr) { 4103 4104 case T_TimeData: 4105 ttyName = curr_opt->value.s; 4106 break; 4107 4108 case T_PpsData: 4109 ppsName = curr_opt->value.s; 4110 break; 4111 4112 default: 4113 msyslog(LOG_ERR, 4114 "Unexpected device spec %s (%d) for %s", 4115 token_name(curr_opt->attr), 4116 curr_opt->attr, addr_node->address); 4117 exit(curr_opt->attr ? curr_opt->attr : 1); 4118 } 4119 } 4120 # ifdef REFCLOCK 4121 clockdev_update(&addr_sock, ttyName, ppsName); 4122 # endif 4123 } 4124 } 4125 #endif /* !SIM */ 4126 4127 4128 #ifdef FREE_CFG_T 4129 static void 4130 free_config_fudge( 4131 config_tree *ptree 4132 ) 4133 { 4134 FREE_ADDR_OPTS_FIFO(ptree->fudge); 4135 } 4136 4137 static void 4138 free_config_device( 4139 config_tree *ptree 4140 ) 4141 { 4142 FREE_ADDR_OPTS_FIFO(ptree->device); 4143 } 4144 #endif /* FREE_CFG_T */ 4145 4146 4147 static void 4148 config_vars( 4149 config_tree *ptree 4150 ) 4151 { 4152 attr_val *curr_var; 4153 int len; 4154 4155 curr_var = HEAD_PFIFO(ptree->vars); 4156 for (; curr_var != NULL; curr_var = curr_var->link) { 4157 /* Determine which variable to set and set it */ 4158 switch (curr_var->attr) { 4159 4160 case T_Broadcastdelay: 4161 proto_config(PROTO_BROADDELAY, 0, curr_var->value.d, NULL); 4162 break; 4163 4164 case T_Tick: 4165 loop_config(LOOP_TICK, curr_var->value.d); 4166 break; 4167 4168 case T_Driftfile: 4169 if ('\0' == curr_var->value.s[0]) 4170 msyslog(LOG_INFO, "config: driftfile disabled"); 4171 stats_config(STATS_FREQ_FILE, curr_var->value.s, TRUE); 4172 break; 4173 4174 case T_Dscp: 4175 /* DSCP is in the upper 6 bits of the IP TOS/DS field */ 4176 qos = curr_var->value.i << 2; 4177 break; 4178 4179 case T_Ident: 4180 sys_ident = curr_var->value.s; 4181 break; 4182 4183 case T_WanderThreshold: /* FALLTHROUGH */ 4184 case T_Nonvolatile: 4185 wander_threshold = curr_var->value.d; 4186 break; 4187 4188 case T_Leapfile: 4189 stats_config(STATS_LEAP_FILE, curr_var->value.s, curr_var->flag); 4190 break; 4191 4192 #ifdef LEAP_SMEAR 4193 case T_Leapsmearinterval: 4194 leap_smear_intv = curr_var->value.i; 4195 msyslog(LOG_INFO, "config: leap smear interval %i s", leap_smear_intv); 4196 break; 4197 #endif 4198 4199 case T_Pidfile: 4200 stats_config(STATS_PID_FILE, curr_var->value.s, 0); 4201 break; 4202 4203 case T_Logfile: 4204 if (-1 == change_logfile(curr_var->value.s, TRUE)) 4205 msyslog(LOG_ERR, 4206 "Cannot open logfile %s: %m", 4207 curr_var->value.s); 4208 break; 4209 4210 case T_Saveconfigdir: 4211 if (saveconfigdir != NULL) 4212 free(saveconfigdir); 4213 len = strlen(curr_var->value.s); 4214 if (0 == len) { 4215 saveconfigdir = NULL; 4216 } else if (DIR_SEP != curr_var->value.s[len - 1] 4217 #ifdef SYS_WINNT /* slash is also a dir. sep. on Windows */ 4218 && '/' != curr_var->value.s[len - 1] 4219 #endif 4220 ) { 4221 len++; 4222 saveconfigdir = emalloc(len + 1); 4223 snprintf(saveconfigdir, len + 1, 4224 "%s%c", 4225 curr_var->value.s, 4226 DIR_SEP); 4227 } else { 4228 saveconfigdir = estrdup( 4229 curr_var->value.s); 4230 } 4231 break; 4232 4233 case T_Automax: 4234 #ifdef AUTOKEY 4235 if (curr_var->value.i > 2 && curr_var->value.i < 32) 4236 sys_automax = (u_char)curr_var->value.i; 4237 else 4238 msyslog(LOG_ERR, 4239 "'automax' value %d ignored", 4240 curr_var->value.i); 4241 #endif 4242 break; 4243 4244 default: 4245 msyslog(LOG_ERR, 4246 "config_vars(): unexpected token %d", 4247 curr_var->attr); 4248 } 4249 } 4250 } 4251 4252 4253 #ifdef FREE_CFG_T 4254 static void 4255 free_config_vars( 4256 config_tree *ptree 4257 ) 4258 { 4259 FREE_ATTR_VAL_FIFO(ptree->vars); 4260 } 4261 #endif /* FREE_CFG_T */ 4262 4263 4264 #ifndef SIM 4265 /* Define a function to check if a resolved address is sane. 4266 * If yes, return 1, else return 0; 4267 */ 4268 static int 4269 is_sane_resolved_address( 4270 sockaddr_u * peeraddr, 4271 int hmode 4272 ) 4273 { 4274 if (!ISREFCLOCKADR(peeraddr) && ISBADADR(peeraddr)) { 4275 msyslog(LOG_ERR, 4276 "attempt to configure invalid address %s", 4277 stoa(peeraddr)); 4278 return 0; 4279 } 4280 /* 4281 * Shouldn't be able to specify: 4282 * - multicast address for server/peer! 4283 * - unicast address for manycastclient! 4284 */ 4285 if ((T_Server == hmode || T_Peer == hmode || T_Pool == hmode) 4286 && IS_MCAST(peeraddr)) { 4287 msyslog(LOG_ERR, 4288 "attempt to configure invalid address %s", 4289 stoa(peeraddr)); 4290 return 0; 4291 } 4292 if (T_Manycastclient == hmode && !IS_MCAST(peeraddr)) { 4293 msyslog(LOG_ERR, 4294 "attempt to configure invalid address %s", 4295 stoa(peeraddr)); 4296 return 0; 4297 } 4298 4299 if (IS_IPV6(peeraddr) && !ipv6_works) 4300 return 0; 4301 4302 /* Ok, all tests succeeded, now we can return 1 */ 4303 return 1; 4304 } 4305 4306 4307 static u_char 4308 get_correct_host_mode( 4309 int token 4310 ) 4311 { 4312 switch (token) { 4313 4314 case T_Server: 4315 case T_Pool: 4316 case T_Manycastclient: 4317 return MODE_CLIENT; 4318 4319 case T_Peer: 4320 return MODE_ACTIVE; 4321 4322 case T_Broadcast: 4323 return MODE_BROADCAST; 4324 4325 default: 4326 return 0; 4327 } 4328 } 4329 4330 4331 /* 4332 * peerflag_bits() get config_peers() peerflags value from a 4333 * peer_node's queue of flag attr_val entries. 4334 */ 4335 static int 4336 peerflag_bits( 4337 peer_node *pn 4338 ) 4339 { 4340 int peerflags; 4341 attr_val *option; 4342 int hmode; 4343 4344 DEBUG_INSIST(pn); 4345 /* translate peerflags options to bits */ 4346 peerflags = 0; 4347 hmode = pn->host_mode; 4348 option = HEAD_PFIFO(pn->peerflags); 4349 for (; option != NULL; option = option->link) { 4350 switch (option->value.i) { 4351 4352 default: 4353 fatal_error("peerflag_bits: option-token=%d", option->value.i); 4354 4355 case T_Autokey: 4356 peerflags |= FLAG_SKEY; 4357 break; 4358 4359 case T_Burst: 4360 peerflags |= FLAG_BURST; 4361 break; 4362 4363 case T_Iburst: 4364 peerflags |= FLAG_IBURST; 4365 break; 4366 4367 case T_Noselect: 4368 peerflags |= FLAG_NOSELECT; 4369 break; 4370 4371 case T_Preempt: 4372 peerflags |= FLAG_PREEMPT; 4373 break; 4374 4375 case T_Prefer: 4376 peerflags |= FLAG_PREFER; 4377 break; 4378 4379 case T_True: 4380 peerflags |= FLAG_TRUE; 4381 break; 4382 4383 case T_Xleave: 4384 peerflags |= FLAG_XLEAVE; 4385 break; 4386 4387 case T_Xmtnonce: 4388 if ( MODE_CLIENT == hmode ) { 4389 peerflags |= FLAG_LOOPNONCE; 4390 } 4391 break; 4392 } 4393 } 4394 4395 return peerflags; 4396 } 4397 4398 4399 static void 4400 config_peers( 4401 config_tree *ptree 4402 ) 4403 { 4404 sockaddr_u peeraddr; 4405 struct addrinfo hints; 4406 peer_node * curr_peer; 4407 peer_resolved_ctx * ctx; 4408 u_char hmode; 4409 4410 /* add servers named on the command line with iburst implied */ 4411 for (; 4412 cmdline_server_count > 0; 4413 cmdline_server_count--, cmdline_servers++) { 4414 4415 ZERO_SOCK(&peeraddr); 4416 /* 4417 * If we have a numeric address, we can safely 4418 * proceed in the mainline with it. Otherwise, hand 4419 * the hostname off to the blocking child. 4420 * 4421 * Note that if we're told to add the peer here, we 4422 * do that regardless of ippeerlimit. 4423 */ 4424 if (is_ip_address(*cmdline_servers, AF_UNSPEC, 4425 &peeraddr)) { 4426 4427 SET_PORT(&peeraddr, NTP_PORT); 4428 if (is_sane_resolved_address(&peeraddr, 4429 T_Server)) 4430 peer_config( 4431 &peeraddr, 4432 NULL, 4433 NULL, 4434 -1, 4435 MODE_CLIENT, 4436 NTP_VERSION, 4437 0, 4438 0, 4439 FLAG_IBURST, 4440 0, 4441 0, 4442 NULL); 4443 } else { 4444 /* we have a hostname to resolve */ 4445 # ifdef WORKER 4446 ctx = emalloc_zero(sizeof(*ctx)); 4447 ctx->family = AF_UNSPEC; 4448 ctx->host_mode = T_Server; 4449 ctx->hmode = MODE_CLIENT; 4450 ctx->version = NTP_VERSION; 4451 ctx->flags = FLAG_IBURST; 4452 ctx->was_initializing = initializing; 4453 4454 ZERO(hints); 4455 hints.ai_family = (u_short)ctx->family; 4456 hints.ai_socktype = SOCK_DGRAM; 4457 hints.ai_protocol = IPPROTO_UDP; 4458 4459 getaddrinfo_sometime_ex(*cmdline_servers, 4460 "ntp", &hints, 4461 INITIAL_DNS_RETRY, 4462 &peer_name_resolved, 4463 (void *)ctx, DNSFLAGS); 4464 # else /* !WORKER follows */ 4465 msyslog(LOG_ERR, 4466 "hostname %s can not be used, please use IP address instead.", 4467 curr_peer->addr->address); 4468 # endif 4469 } 4470 } 4471 4472 /* add associations from the configuration file */ 4473 curr_peer = HEAD_PFIFO(ptree->peers); 4474 for (; curr_peer != NULL; curr_peer = curr_peer->link) { 4475 ZERO_SOCK(&peeraddr); 4476 /* Find the correct host-mode */ 4477 hmode = get_correct_host_mode(curr_peer->host_mode); 4478 INSIST(hmode != 0); 4479 4480 if (T_Pool == curr_peer->host_mode) { 4481 AF(&peeraddr) = curr_peer->addr->type; 4482 peer_config( 4483 &peeraddr, 4484 curr_peer->addr->address, 4485 NULL, 4486 -1, 4487 hmode, 4488 curr_peer->peerversion, 4489 curr_peer->minpoll, 4490 curr_peer->maxpoll, 4491 peerflag_bits(curr_peer), 4492 curr_peer->ttl, 4493 curr_peer->peerkey, 4494 curr_peer->group); 4495 /* 4496 * If we have a numeric address, we can safely 4497 * proceed in the mainline with it. Otherwise, hand 4498 * the hostname off to the blocking child. 4499 */ 4500 } else if (is_ip_address(curr_peer->addr->address, 4501 curr_peer->addr->type, &peeraddr)) { 4502 4503 SET_PORT(&peeraddr, NTP_PORT); 4504 if (is_sane_resolved_address(&peeraddr, 4505 curr_peer->host_mode)) 4506 peer_config( 4507 &peeraddr, 4508 NULL, 4509 NULL, 4510 -1, 4511 hmode, 4512 curr_peer->peerversion, 4513 curr_peer->minpoll, 4514 curr_peer->maxpoll, 4515 peerflag_bits(curr_peer), 4516 curr_peer->ttl, 4517 curr_peer->peerkey, 4518 curr_peer->group); 4519 } else { 4520 /* we have a hostname to resolve */ 4521 # ifdef WORKER 4522 ctx = emalloc_zero(sizeof(*ctx)); 4523 ctx->family = curr_peer->addr->type; 4524 ctx->host_mode = curr_peer->host_mode; 4525 ctx->hmode = hmode; 4526 ctx->version = curr_peer->peerversion; 4527 ctx->minpoll = curr_peer->minpoll; 4528 ctx->maxpoll = curr_peer->maxpoll; 4529 ctx->flags = peerflag_bits(curr_peer); 4530 ctx->ttl = curr_peer->ttl; 4531 ctx->keyid = curr_peer->peerkey; 4532 ctx->group = curr_peer->group; 4533 ctx->was_initializing = initializing; 4534 4535 ZERO(hints); 4536 hints.ai_family = ctx->family; 4537 hints.ai_socktype = SOCK_DGRAM; 4538 hints.ai_protocol = IPPROTO_UDP; 4539 4540 getaddrinfo_sometime_ex(curr_peer->addr->address, 4541 "ntp", &hints, 4542 INITIAL_DNS_RETRY, 4543 &peer_name_resolved, ctx, 4544 DNSFLAGS); 4545 # else /* !WORKER follows */ 4546 msyslog(LOG_ERR, 4547 "hostname %s can not be used, please use IP address instead.", 4548 curr_peer->addr->address); 4549 # endif 4550 } 4551 } 4552 } 4553 4554 4555 /* 4556 * peer_name_resolved() 4557 * 4558 * Callback invoked when config_peers()'s DNS lookup completes. 4559 */ 4560 #ifdef WORKER 4561 static void 4562 peer_name_resolved( 4563 int rescode, 4564 int gai_errno, 4565 void * context, 4566 const char * name, 4567 const char * service, 4568 const struct addrinfo * hints, 4569 const struct addrinfo * res 4570 ) 4571 { 4572 sockaddr_u peeraddr; 4573 peer_resolved_ctx * ctx; 4574 u_short af; 4575 const char * fam_spec; 4576 4577 (void)gai_errno; 4578 (void)service; 4579 (void)hints; 4580 ctx = context; 4581 4582 DPRINTF(1, ("peer_name_resolved(%s) rescode %d\n", name, rescode)); 4583 4584 if (rescode) { 4585 free(ctx); 4586 msyslog(LOG_ERR, 4587 "giving up resolving host %s: %s (%d)", 4588 name, gai_strerror(rescode), rescode); 4589 return; 4590 } 4591 4592 /* Loop to configure a single association */ 4593 for (; res != NULL; res = res->ai_next) { 4594 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen); 4595 if (is_sane_resolved_address(&peeraddr, 4596 ctx->host_mode)) { 4597 NLOG(NLOG_SYSINFO) { 4598 af = ctx->family; 4599 fam_spec = (AF_INET6 == af) 4600 ? "(AAAA) " 4601 : (AF_INET == af) 4602 ? "(A) " 4603 : ""; 4604 msyslog(LOG_INFO, "DNS %s %s-> %s", 4605 name, fam_spec, 4606 stoa(&peeraddr)); 4607 } 4608 4609 /* 4610 * peer_clear needs to know if this association was specified 4611 * in the startup configuration file to set the next poll time. 4612 */ 4613 if (ctx->was_initializing) { 4614 INSIST(!initializing); 4615 initializing = TRUE; 4616 } 4617 4618 peer_config( 4619 &peeraddr, 4620 NULL, 4621 NULL, 4622 -1, 4623 ctx->hmode, 4624 ctx->version, 4625 ctx->minpoll, 4626 ctx->maxpoll, 4627 ctx->flags, 4628 ctx->ttl, 4629 ctx->keyid, 4630 ctx->group); 4631 4632 if (ctx->was_initializing) { 4633 initializing = FALSE; 4634 } 4635 4636 break; 4637 } 4638 } 4639 free(ctx); 4640 } 4641 #endif /* WORKER */ 4642 4643 4644 #ifdef FREE_CFG_T 4645 static void 4646 free_config_peers( 4647 config_tree *ptree 4648 ) 4649 { 4650 peer_node *curr_peer; 4651 4652 if (ptree->peers != NULL) { 4653 for (;;) { 4654 UNLINK_FIFO(curr_peer, *ptree->peers, link); 4655 if (NULL == curr_peer) 4656 break; 4657 destroy_address_node(curr_peer->addr); 4658 destroy_attr_val_fifo(curr_peer->peerflags); 4659 free(curr_peer); 4660 } 4661 free(ptree->peers); 4662 ptree->peers = NULL; 4663 } 4664 } 4665 #endif /* FREE_CFG_T */ 4666 4667 4668 static void 4669 config_unpeers( 4670 config_tree *ptree 4671 ) 4672 { 4673 sockaddr_u peeraddr; 4674 struct addrinfo hints; 4675 unpeer_node * curr_unpeer; 4676 struct peer * p; 4677 const char * name; 4678 int rc; 4679 4680 curr_unpeer = HEAD_PFIFO(ptree->unpeers); 4681 for (; curr_unpeer != NULL; curr_unpeer = curr_unpeer->link) { 4682 /* 4683 * If we have no address attached, assume we have to 4684 * unpeer by AssocID. 4685 */ 4686 if (!curr_unpeer->addr) { 4687 p = findpeerbyassoc(curr_unpeer->assocID); 4688 if (p != NULL) { 4689 msyslog(LOG_NOTICE, "unpeered %s", 4690 stoa(&p->srcadr)); 4691 peer_clear(p, "GONE"); 4692 unpeer(p); 4693 } 4694 continue; 4695 } 4696 4697 ZERO(peeraddr); 4698 AF(&peeraddr) = curr_unpeer->addr->type; 4699 name = curr_unpeer->addr->address; 4700 rc = getnetnum(name, &peeraddr, 0, t_UNK); 4701 /* Do we have a numeric address? */ 4702 if (rc > 0) { 4703 DPRINTF(1, ("unpeer: searching for %s\n", 4704 stoa(&peeraddr))); 4705 p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL); 4706 if (p != NULL) { 4707 msyslog(LOG_NOTICE, "unpeered %s", 4708 stoa(&peeraddr)); 4709 peer_clear(p, "GONE"); 4710 unpeer(p); 4711 } 4712 continue; 4713 } 4714 /* 4715 * It's not a numeric IP address, it's a hostname. 4716 * Check for associations with a matching hostname. 4717 */ 4718 for (p = peer_list; p != NULL; p = p->p_link) 4719 if (p->hostname != NULL) 4720 if (!strcasecmp(p->hostname, name)) 4721 break; 4722 if (p != NULL) { 4723 msyslog(LOG_NOTICE, "unpeered %s", name); 4724 peer_clear(p, "GONE"); 4725 unpeer(p); 4726 } 4727 /* Resolve the hostname to address(es). */ 4728 # ifdef WORKER 4729 ZERO(hints); 4730 hints.ai_family = curr_unpeer->addr->type; 4731 hints.ai_socktype = SOCK_DGRAM; 4732 hints.ai_protocol = IPPROTO_UDP; 4733 getaddrinfo_sometime(name, "ntp", &hints, 4734 INITIAL_DNS_RETRY, 4735 &unpeer_name_resolved, NULL); 4736 # else /* !WORKER follows */ 4737 msyslog(LOG_ERR, 4738 "hostname %s can not be used, please use IP address instead.", 4739 name); 4740 # endif 4741 } 4742 } 4743 4744 4745 /* 4746 * unpeer_name_resolved() 4747 * 4748 * Callback invoked when config_unpeers()'s DNS lookup completes. 4749 */ 4750 #ifdef WORKER 4751 static void 4752 unpeer_name_resolved( 4753 int rescode, 4754 int gai_errno, 4755 void * context, 4756 const char * name, 4757 const char * service, 4758 const struct addrinfo * hints, 4759 const struct addrinfo * res 4760 ) 4761 { 4762 sockaddr_u peeraddr; 4763 struct peer * peer; 4764 u_short af; 4765 const char * fam_spec; 4766 4767 (void)context; 4768 (void)hints; 4769 DPRINTF(1, ("unpeer_name_resolved(%s) rescode %d\n", name, rescode)); 4770 4771 if (rescode) { 4772 msyslog(LOG_ERR, "giving up resolving unpeer %s: %s (%d)", 4773 name, gai_strerror(rescode), rescode); 4774 return; 4775 } 4776 /* 4777 * Loop through the addresses found 4778 */ 4779 for (; res != NULL; res = res->ai_next) { 4780 INSIST(res->ai_addrlen <= sizeof(peeraddr)); 4781 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen); 4782 DPRINTF(1, ("unpeer: searching for peer %s\n", 4783 stoa(&peeraddr))); 4784 peer = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL); 4785 if (peer != NULL) { 4786 af = AF(&peeraddr); 4787 fam_spec = (AF_INET6 == af) 4788 ? "(AAAA) " 4789 : (AF_INET == af) 4790 ? "(A) " 4791 : ""; 4792 msyslog(LOG_NOTICE, "unpeered %s %s-> %s", name, 4793 fam_spec, stoa(&peeraddr)); 4794 peer_clear(peer, "GONE"); 4795 unpeer(peer); 4796 } 4797 } 4798 } 4799 #endif /* WORKER */ 4800 4801 4802 #ifdef FREE_CFG_T 4803 static void 4804 free_config_unpeers( 4805 config_tree *ptree 4806 ) 4807 { 4808 unpeer_node *curr_unpeer; 4809 4810 if (ptree->unpeers != NULL) { 4811 for (;;) { 4812 UNLINK_FIFO(curr_unpeer, *ptree->unpeers, link); 4813 if (NULL == curr_unpeer) 4814 break; 4815 destroy_address_node(curr_unpeer->addr); 4816 free(curr_unpeer); 4817 } 4818 free(ptree->unpeers); 4819 } 4820 } 4821 #endif /* FREE_CFG_T */ 4822 #endif /* !SIM */ 4823 4824 4825 #ifndef SIM 4826 static void 4827 config_reset_counters( 4828 config_tree *ptree 4829 ) 4830 { 4831 int_node *counter_set; 4832 4833 for (counter_set = HEAD_PFIFO(ptree->reset_counters); 4834 counter_set != NULL; 4835 counter_set = counter_set->link) { 4836 switch (counter_set->i) { 4837 default: 4838 DPRINTF(1, ("config_reset_counters %s (%d) invalid\n", 4839 keyword(counter_set->i), counter_set->i)); 4840 break; 4841 4842 case T_Allpeers: 4843 peer_all_reset(); 4844 break; 4845 4846 case T_Auth: 4847 reset_auth_stats(); 4848 break; 4849 4850 case T_Ctl: 4851 ctl_clr_stats(); 4852 break; 4853 4854 case T_Io: 4855 io_clr_stats(); 4856 break; 4857 4858 case T_Mem: 4859 peer_clr_stats(); 4860 break; 4861 4862 case T_Sys: 4863 proto_clr_stats(); 4864 break; 4865 4866 case T_Timer: 4867 timer_clr_stats(); 4868 break; 4869 } 4870 } 4871 } 4872 #endif /* !SIM */ 4873 4874 4875 #ifdef FREE_CFG_T 4876 static void 4877 free_config_reset_counters( 4878 config_tree *ptree 4879 ) 4880 { 4881 FREE_INT_FIFO(ptree->reset_counters); 4882 } 4883 #endif /* FREE_CFG_T */ 4884 4885 4886 #ifdef SIM 4887 static void 4888 config_sim( 4889 config_tree *ptree 4890 ) 4891 { 4892 int i; 4893 server_info *serv_info; 4894 attr_val *init_stmt; 4895 sim_node *sim_n; 4896 4897 /* Check if a simulate block was found in the configuration code. 4898 * If not, return an error and exit 4899 */ 4900 sim_n = HEAD_PFIFO(ptree->sim_details); 4901 if (NULL == sim_n) { 4902 fprintf(stderr, "ERROR!! I couldn't find a \"simulate\" block for configuring the simulator.\n"); 4903 fprintf(stderr, "\tCheck your configuration file.\n"); 4904 exit(1); 4905 } 4906 4907 /* Process the initialization statements 4908 * ------------------------------------- 4909 */ 4910 init_stmt = HEAD_PFIFO(sim_n->init_opts); 4911 for (; init_stmt != NULL; init_stmt = init_stmt->link) { 4912 switch(init_stmt->attr) { 4913 4914 case T_Beep_Delay: 4915 simulation.beep_delay = init_stmt->value.d; 4916 break; 4917 4918 case T_Sim_Duration: 4919 simulation.end_time = init_stmt->value.d; 4920 break; 4921 4922 default: 4923 fprintf(stderr, 4924 "Unknown simulator init token %d\n", 4925 init_stmt->attr); 4926 exit(1); 4927 } 4928 } 4929 4930 /* Process the server list 4931 * ----------------------- 4932 */ 4933 simulation.num_of_servers = 0; 4934 serv_info = HEAD_PFIFO(sim_n->servers); 4935 for (; serv_info != NULL; serv_info = serv_info->link) 4936 simulation.num_of_servers++; 4937 simulation.servers = eallocarray(simulation.num_of_servers, 4938 sizeof(simulation.servers[0])); 4939 4940 i = 0; 4941 serv_info = HEAD_PFIFO(sim_n->servers); 4942 for (; serv_info != NULL; serv_info = serv_info->link) { 4943 if (NULL == serv_info) { 4944 fprintf(stderr, "Simulator server list is corrupt\n"); 4945 exit(1); 4946 } else { 4947 simulation.servers[i] = *serv_info; 4948 simulation.servers[i].link = NULL; 4949 i++; 4950 } 4951 } 4952 4953 printf("Creating server associations\n"); 4954 create_server_associations(); 4955 fprintf(stderr,"\tServer associations successfully created!!\n"); 4956 } 4957 4958 4959 #ifdef FREE_CFG_T 4960 static void 4961 free_config_sim( 4962 config_tree *ptree 4963 ) 4964 { 4965 sim_node *sim_n; 4966 server_info *serv_n; 4967 script_info *script_n; 4968 4969 if (NULL == ptree->sim_details) 4970 return; 4971 sim_n = HEAD_PFIFO(ptree->sim_details); 4972 free(ptree->sim_details); 4973 ptree->sim_details = NULL; 4974 if (NULL == sim_n) 4975 return; 4976 4977 FREE_ATTR_VAL_FIFO(sim_n->init_opts); 4978 for (;;) { 4979 UNLINK_FIFO(serv_n, *sim_n->servers, link); 4980 if (NULL == serv_n) 4981 break; 4982 free(serv_n->curr_script); 4983 if (serv_n->script != NULL) { 4984 for (;;) { 4985 UNLINK_FIFO(script_n, *serv_n->script, 4986 link); 4987 if (script_n == NULL) 4988 break; 4989 free(script_n); 4990 } 4991 free(serv_n->script); 4992 } 4993 free(serv_n); 4994 } 4995 free(sim_n); 4996 } 4997 #endif /* FREE_CFG_T */ 4998 #endif /* SIM */ 4999 5000 5001 /* Define two different config functions. One for the daemon and the other for 5002 * the simulator. The simulator ignores a lot of the standard ntpd configuration 5003 * options 5004 */ 5005 #ifndef SIM 5006 static void 5007 config_ntpd( 5008 config_tree *ptree, 5009 int/*BOOL*/ input_from_files 5010 ) 5011 { 5012 /* [Bug 3435] check and esure clock sanity if configured from 5013 * file and clock sanity parameters (-> basedate) are given. Do 5014 * this ASAP, so we don't disturb the closed loop controller. 5015 */ 5016 if (input_from_files) { 5017 if (config_tos_clock(ptree)) 5018 clamp_systime(); 5019 } 5020 5021 config_nic_rules(ptree, input_from_files); 5022 config_monitor(ptree); 5023 config_auth(ptree); 5024 config_tos(ptree); 5025 config_access(ptree); 5026 config_tinker(ptree); 5027 config_rlimit(ptree); 5028 config_system_opts(ptree); 5029 config_logconfig(ptree); 5030 config_phone(ptree); 5031 config_mdnstries(ptree); 5032 config_setvar(ptree); 5033 config_ttl(ptree); 5034 config_vars(ptree); 5035 5036 io_open_sockets(); /* [bug 2837] dep. on config_vars() */ 5037 5038 config_trap(ptree); /* [bug 2923] dep. on io_open_sockets() */ 5039 config_other_modes(ptree); 5040 config_device(ptree); 5041 config_peers(ptree); 5042 config_unpeers(ptree); 5043 config_fudge(ptree); 5044 config_reset_counters(ptree); 5045 5046 #ifdef DEBUG 5047 if (debug > 1) { 5048 dump_restricts(); 5049 } 5050 #endif 5051 5052 #ifdef TEST_BLOCKING_WORKER 5053 { 5054 struct addrinfo hints; 5055 5056 ZERO(hints); 5057 hints.ai_socktype = SOCK_STREAM; 5058 hints.ai_protocol = IPPROTO_TCP; 5059 getaddrinfo_sometime("www.cnn.com", "ntp", &hints, 5060 INITIAL_DNS_RETRY, 5061 gai_test_callback, (void *)1); 5062 hints.ai_family = AF_INET6; 5063 getaddrinfo_sometime("ipv6.google.com", "ntp", &hints, 5064 INITIAL_DNS_RETRY, 5065 gai_test_callback, (void *)0x600); 5066 } 5067 #endif 5068 } 5069 #endif /* !SIM */ 5070 5071 5072 #ifdef SIM 5073 static void 5074 config_ntpdsim( 5075 config_tree *ptree 5076 ) 5077 { 5078 printf("Configuring Simulator...\n"); 5079 printf("Some ntpd-specific commands in the configuration file will be ignored.\n"); 5080 5081 config_tos(ptree); 5082 config_monitor(ptree); 5083 config_tinker(ptree); 5084 if (0) 5085 config_rlimit(ptree); /* not needed for the simulator */ 5086 config_system_opts(ptree); 5087 config_logconfig(ptree); 5088 config_vars(ptree); 5089 config_sim(ptree); 5090 } 5091 #endif /* SIM */ 5092 5093 5094 /* 5095 * config_remotely() - implements ntpd side of ntpq :config 5096 */ 5097 void 5098 config_remotely( 5099 sockaddr_u * remote_addr 5100 ) 5101 { 5102 char origin[128]; 5103 5104 snprintf(origin, sizeof(origin), "remote config from %s", 5105 stoa(remote_addr)); 5106 lex_init_stack(origin, NULL); /* no checking needed... */ 5107 init_syntax_tree(&cfgt); 5108 yyparse(); 5109 lex_drop_stack(); 5110 5111 cfgt.source.attr = CONF_SOURCE_NTPQ; 5112 cfgt.timestamp = time(NULL); 5113 cfgt.source.value.s = estrdup(stoa(remote_addr)); 5114 5115 DPRINTF(1, ("Finished Parsing!!\n")); 5116 5117 save_and_apply_config_tree(FALSE); 5118 } 5119 5120 5121 /* 5122 * getconfig() - process startup configuration file e.g /etc/ntp.conf 5123 */ 5124 void 5125 getconfig( 5126 int argc, 5127 char ** argv 5128 ) 5129 { 5130 char line[256]; 5131 5132 #ifdef DEBUG 5133 atexit(free_all_config_trees); 5134 #endif 5135 #ifndef SYS_WINNT 5136 config_file = CONFIG_FILE; 5137 #else 5138 temp = CONFIG_FILE; 5139 if (!ExpandEnvironmentStringsA(temp, config_file_storage, 5140 sizeof(config_file_storage))) { 5141 msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m"); 5142 exit(1); 5143 } 5144 config_file = config_file_storage; 5145 5146 temp = ALT_CONFIG_FILE; 5147 if (!ExpandEnvironmentStringsA(temp, alt_config_file_storage, 5148 sizeof(alt_config_file_storage))) { 5149 msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m"); 5150 exit(1); 5151 } 5152 alt_config_file = alt_config_file_storage; 5153 #endif /* SYS_WINNT */ 5154 5155 /* 5156 * install a non default variable with this daemon version 5157 */ 5158 snprintf(line, sizeof(line), "daemon_version=\"%s\"", Version); 5159 set_sys_var(line, strlen(line) + 1, RO); 5160 5161 /* 5162 * Set up for the first time step to install a variable showing 5163 * which syscall is being used to step. 5164 */ 5165 set_tod_using = &ntpd_set_tod_using; 5166 5167 getCmdOpts(argc, argv); 5168 init_syntax_tree(&cfgt); 5169 if ( 5170 !lex_init_stack(FindConfig(config_file), "r") 5171 #ifdef HAVE_NETINFO 5172 /* If there is no config_file, try NetInfo. */ 5173 && check_netinfo && !(config_netinfo = get_netinfo_config()) 5174 #endif /* HAVE_NETINFO */ 5175 ) { 5176 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(config_file)); 5177 #ifndef SYS_WINNT 5178 io_open_sockets(); 5179 5180 return; 5181 #else 5182 /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */ 5183 5184 if (!lex_init_stack(FindConfig(alt_config_file), "r")) { 5185 /* 5186 * Broadcast clients can sometimes run without 5187 * a configuration file. 5188 */ 5189 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(alt_config_file)); 5190 io_open_sockets(); 5191 5192 return; 5193 } 5194 cfgt.source.value.s = estrdup(alt_config_file); 5195 #endif /* SYS_WINNT */ 5196 } else { 5197 cfgt.source.value.s = estrdup(config_file); 5198 } 5199 5200 /*** BULK OF THE PARSER ***/ 5201 #ifdef DEBUG 5202 yydebug = (debug >= 9); 5203 #endif 5204 yyparse(); 5205 lex_drop_stack(); 5206 5207 DPRINTF(1, ("Finished Parsing!!\n")); 5208 5209 cfgt.source.attr = CONF_SOURCE_FILE; 5210 cfgt.timestamp = time(NULL); 5211 5212 save_and_apply_config_tree(TRUE); 5213 5214 #ifdef HAVE_NETINFO 5215 if (config_netinfo) 5216 free_netinfo_config(config_netinfo); 5217 #endif /* HAVE_NETINFO */ 5218 } 5219 5220 5221 void 5222 save_and_apply_config_tree(int/*BOOL*/ input_from_file) 5223 { 5224 config_tree *ptree; 5225 #ifndef SAVECONFIG 5226 config_tree *punlinked; 5227 #endif 5228 5229 /* 5230 * Keep all the configuration trees applied since startup in 5231 * a list that can be used to dump the configuration back to 5232 * a text file. 5233 */ 5234 ptree = emalloc(sizeof(*ptree)); 5235 memcpy(ptree, &cfgt, sizeof(*ptree)); 5236 ZERO(cfgt); 5237 5238 LINK_TAIL_SLIST(cfg_tree_history, ptree, link, config_tree); 5239 5240 #ifdef SAVECONFIG 5241 if (HAVE_OPT( SAVECONFIGQUIT )) { 5242 FILE *dumpfile; 5243 int err; 5244 int dumpfailed; 5245 5246 dumpfile = fopen(OPT_ARG( SAVECONFIGQUIT ), "w"); 5247 if (NULL == dumpfile) { 5248 err = errno; 5249 mfprintf(stderr, 5250 "can not create save file %s, error %d %m\n", 5251 OPT_ARG(SAVECONFIGQUIT), err); 5252 exit(err); 5253 } 5254 5255 dumpfailed = dump_all_config_trees(dumpfile, 0); 5256 if (dumpfailed) 5257 fprintf(stderr, 5258 "--saveconfigquit %s error %d\n", 5259 OPT_ARG( SAVECONFIGQUIT ), 5260 dumpfailed); 5261 else 5262 fprintf(stderr, 5263 "configuration saved to %s\n", 5264 OPT_ARG( SAVECONFIGQUIT )); 5265 5266 exit(dumpfailed); 5267 } 5268 #endif /* SAVECONFIG */ 5269 5270 /* The actual configuration done depends on whether we are configuring the 5271 * simulator or the daemon. Perform a check and call the appropriate 5272 * function as needed. 5273 */ 5274 5275 #ifndef SIM 5276 config_ntpd(ptree, input_from_file); 5277 #else 5278 config_ntpdsim(ptree); 5279 #endif 5280 5281 /* 5282 * With configure --disable-saveconfig, there's no use keeping 5283 * the config tree around after application, so free it. 5284 */ 5285 #ifndef SAVECONFIG 5286 UNLINK_SLIST(punlinked, cfg_tree_history, ptree, link, 5287 config_tree); 5288 INSIST(punlinked == ptree); 5289 free_config_tree(ptree); 5290 #endif 5291 } 5292 5293 /* Hack to disambiguate 'server' statements for refclocks and network peers. 5294 * Please note the qualification 'hack'. It's just that. 5295 */ 5296 static int/*BOOL*/ 5297 is_refclk_addr( 5298 const address_node * addr 5299 ) 5300 { 5301 return addr && addr->address && !strncmp(addr->address, "127.127.", 8); 5302 } 5303 5304 static void 5305 ntpd_set_tod_using( 5306 const char *which 5307 ) 5308 { 5309 char line[128]; 5310 5311 snprintf(line, sizeof(line), "settimeofday=\"%s\"", which); 5312 set_sys_var(line, strlen(line) + 1, RO); 5313 } 5314 5315 5316 static char * 5317 normal_dtoa( 5318 double d 5319 ) 5320 { 5321 char * buf; 5322 char * pch_e; 5323 char * pch_nz; 5324 5325 LIB_GETBUF(buf); 5326 snprintf(buf, LIB_BUFLENGTH, "%g", d); 5327 5328 /* use lowercase 'e', strip any leading zeroes in exponent */ 5329 pch_e = strchr(buf, 'e'); 5330 if (NULL == pch_e) { 5331 pch_e = strchr(buf, 'E'); 5332 if (NULL == pch_e) 5333 return buf; 5334 *pch_e = 'e'; 5335 } 5336 pch_e++; 5337 if ('-' == *pch_e) 5338 pch_e++; 5339 pch_nz = pch_e; 5340 while ('0' == *pch_nz) 5341 pch_nz++; 5342 if (pch_nz > pch_e) { 5343 memmove(pch_e, pch_nz, 1 + strlen(pch_nz)); 5344 } 5345 return buf; 5346 } 5347 5348 5349 /* FUNCTIONS COPIED FROM THE OLDER ntp_config.c 5350 * -------------------------------------------- 5351 */ 5352 5353 5354 /* 5355 * get_pfxmatch - find value for prefixmatch 5356 * and update char * accordingly 5357 */ 5358 static u_int32 5359 get_pfxmatch( 5360 const char ** pstr, 5361 struct masks * m 5362 ) 5363 { 5364 while (m->name != NULL) { 5365 if (strncmp(*pstr, m->name, strlen(m->name)) == 0) { 5366 *pstr += strlen(m->name); 5367 return m->mask; 5368 } else { 5369 m++; 5370 } 5371 } 5372 return 0; 5373 } 5374 5375 /* 5376 * get_match - find logmask value 5377 */ 5378 static u_int32 5379 get_match( 5380 const char * str, 5381 struct masks * m 5382 ) 5383 { 5384 while (m->name != NULL) { 5385 if (strcmp(str, m->name) == 0) 5386 return m->mask; 5387 else 5388 m++; 5389 } 5390 return 0; 5391 } 5392 5393 /* 5394 * get_logmask - build bitmask for ntp_syslogmask 5395 */ 5396 static u_int32 5397 get_logmask( 5398 const char * str 5399 ) 5400 { 5401 const char * t; 5402 u_int32 offset; 5403 u_int32 mask; 5404 5405 mask = get_match(str, logcfg_noclass_items); 5406 if (mask != 0) 5407 return mask; 5408 5409 t = str; 5410 offset = get_pfxmatch(&t, logcfg_class); 5411 mask = get_match(t, logcfg_class_items); 5412 5413 if (mask) 5414 return mask << offset; 5415 else 5416 msyslog(LOG_ERR, "logconfig: '%s' not recognized - ignored", 5417 str); 5418 5419 return 0; 5420 } 5421 5422 5423 #ifdef HAVE_NETINFO 5424 5425 /* 5426 * get_netinfo_config - find the nearest NetInfo domain with an ntp 5427 * configuration and initialize the configuration state. 5428 */ 5429 static struct netinfo_config_state * 5430 get_netinfo_config(void) 5431 { 5432 ni_status status; 5433 void *domain; 5434 ni_id config_dir; 5435 struct netinfo_config_state *config; 5436 5437 if (ni_open(NULL, ".", &domain) != NI_OK) return NULL; 5438 5439 while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) { 5440 void *next_domain; 5441 if (ni_open(domain, "..", &next_domain) != NI_OK) { 5442 ni_free(next_domain); 5443 break; 5444 } 5445 ni_free(domain); 5446 domain = next_domain; 5447 } 5448 if (status != NI_OK) { 5449 ni_free(domain); 5450 return NULL; 5451 } 5452 5453 config = emalloc(sizeof(*config)); 5454 config->domain = domain; 5455 config->config_dir = config_dir; 5456 config->prop_index = 0; 5457 config->val_index = 0; 5458 config->val_list = NULL; 5459 5460 return config; 5461 } 5462 5463 5464 /* 5465 * free_netinfo_config - release NetInfo configuration state 5466 */ 5467 static void 5468 free_netinfo_config( 5469 struct netinfo_config_state *config 5470 ) 5471 { 5472 ni_free(config->domain); 5473 free(config); 5474 } 5475 5476 5477 /* 5478 * gettokens_netinfo - return tokens from NetInfo 5479 */ 5480 static int 5481 gettokens_netinfo ( 5482 struct netinfo_config_state *config, 5483 char **tokenlist, 5484 int *ntokens 5485 ) 5486 { 5487 int prop_index = config->prop_index; 5488 int val_index = config->val_index; 5489 char **val_list = config->val_list; 5490 5491 /* 5492 * Iterate through each keyword and look for a property that matches it. 5493 */ 5494 again: 5495 if (!val_list) { 5496 for (; prop_index < COUNTOF(keywords); prop_index++) 5497 { 5498 ni_namelist namelist; 5499 struct keyword current_prop = keywords[prop_index]; 5500 ni_index index; 5501 5502 /* 5503 * For each value associated in the property, we're going to return 5504 * a separate line. We squirrel away the values in the config state 5505 * so the next time through, we don't need to do this lookup. 5506 */ 5507 NI_INIT(&namelist); 5508 if (NI_OK == ni_lookupprop(config->domain, 5509 &config->config_dir, current_prop.text, 5510 &namelist)) { 5511 5512 /* Found the property, but it has no values */ 5513 if (namelist.ni_namelist_len == 0) continue; 5514 5515 config->val_list = 5516 eallocarray( 5517 (namelist.ni_namelist_len + 1), 5518 sizeof(char*)); 5519 val_list = config->val_list; 5520 5521 for (index = 0; 5522 index < namelist.ni_namelist_len; 5523 index++) { 5524 char *value; 5525 5526 value = namelist.ni_namelist_val[index]; 5527 val_list[index] = estrdup(value); 5528 } 5529 val_list[index] = NULL; 5530 5531 break; 5532 } 5533 ni_namelist_free(&namelist); 5534 } 5535 config->prop_index = prop_index; 5536 } 5537 5538 /* No list; we're done here. */ 5539 if (!val_list) 5540 return CONFIG_UNKNOWN; 5541 5542 /* 5543 * We have a list of values for the current property. 5544 * Iterate through them and return each in order. 5545 */ 5546 if (val_list[val_index]) { 5547 int ntok = 1; 5548 int quoted = 0; 5549 char *tokens = val_list[val_index]; 5550 5551 msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]); 5552 5553 (const char*)tokenlist[0] = keywords[prop_index].text; 5554 for (ntok = 1; ntok < MAXTOKENS; ntok++) { 5555 tokenlist[ntok] = tokens; 5556 while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted)) 5557 quoted ^= (*tokens++ == '"'); 5558 5559 if (ISEOL(*tokens)) { 5560 *tokens = '\0'; 5561 break; 5562 } else { /* must be space */ 5563 *tokens++ = '\0'; 5564 while (ISSPACE(*tokens)) 5565 tokens++; 5566 if (ISEOL(*tokens)) 5567 break; 5568 } 5569 } 5570 5571 if (ntok == MAXTOKENS) { 5572 /* HMS: chomp it to lose the EOL? */ 5573 msyslog(LOG_ERR, 5574 "gettokens_netinfo: too many tokens. Ignoring: %s", 5575 tokens); 5576 } else { 5577 *ntokens = ntok + 1; 5578 } 5579 5580 config->val_index++; /* HMS: Should this be in the 'else'? */ 5581 5582 return keywords[prop_index].keytype; 5583 } 5584 5585 /* We're done with the current property. */ 5586 prop_index = ++config->prop_index; 5587 5588 /* Free val_list and reset counters. */ 5589 for (val_index = 0; val_list[val_index]; val_index++) 5590 free(val_list[val_index]); 5591 free(val_list); 5592 val_list = config->val_list = NULL; 5593 val_index = config->val_index = 0; 5594 5595 goto again; 5596 } 5597 #endif /* HAVE_NETINFO */ 5598 5599 5600 /* 5601 * getnetnum - return a net number (this is crude, but careful) 5602 * 5603 * returns 1 for success, and mysteriously, 0 for most failures, and 5604 * -1 if the address found is IPv6 and we believe IPv6 isn't working. 5605 */ 5606 static int 5607 getnetnum( 5608 const char *num, 5609 sockaddr_u *addr, 5610 int complain, /* ignored */ 5611 enum gnn_type a_type /* ignored */ 5612 ) 5613 { 5614 REQUIRE(AF_UNSPEC == AF(addr) || 5615 AF_INET == AF(addr) || 5616 AF_INET6 == AF(addr)); 5617 5618 if (!is_ip_address(num, AF(addr), addr)) { 5619 return 0; 5620 } 5621 # ifdef ISC_PLATFORM_HAVESALEN 5622 addr->sa.sa_len = SIZEOF_SOCKADDR(AF(addr)); 5623 # endif 5624 SET_PORT(addr, NTP_PORT); 5625 5626 if (IS_IPV6(addr) && !ipv6_works) { 5627 return -1; 5628 } else { 5629 return 1; 5630 } 5631 } 5632 5633 5634 #if defined(HAVE_SETRLIMIT) 5635 void 5636 ntp_rlimit( 5637 int rl_what, 5638 rlim_t rl_value, 5639 int rl_scale, 5640 const char * rl_sstr 5641 ) 5642 { 5643 struct rlimit rl; 5644 5645 switch (rl_what) { 5646 # ifdef RLIMIT_MEMLOCK 5647 case RLIMIT_MEMLOCK: 5648 if (HAVE_OPT( SAVECONFIGQUIT )) { 5649 break; 5650 } 5651 /* 5652 * The default RLIMIT_MEMLOCK is very low on Linux systems. 5653 * Unless we increase this limit malloc calls are likely to 5654 * fail if we drop root privilege. To be useful the value 5655 * has to be larger than the largest ntpd resident set size. 5656 */ 5657 DPRINTF(2, ("ntp_rlimit: MEMLOCK: %d %s\n", 5658 (int)(rl_value / rl_scale), rl_sstr)); 5659 rl.rlim_cur = rl.rlim_max = rl_value; 5660 if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) 5661 msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m"); 5662 break; 5663 # endif /* RLIMIT_MEMLOCK */ 5664 5665 # ifdef RLIMIT_NOFILE 5666 case RLIMIT_NOFILE: 5667 /* 5668 * For large systems the default file descriptor limit may 5669 * not be enough. 5670 */ 5671 DPRINTF(2, ("ntp_rlimit: NOFILE: %d %s\n", 5672 (int)(rl_value / rl_scale), rl_sstr)); 5673 rl.rlim_cur = rl.rlim_max = rl_value; 5674 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 5675 msyslog(LOG_ERR, "Cannot set RLIMIT_NOFILE: %m"); 5676 break; 5677 # endif /* RLIMIT_NOFILE */ 5678 5679 # ifdef RLIMIT_STACK 5680 case RLIMIT_STACK: 5681 /* 5682 * Provide a way to set the stack limit to something 5683 * smaller, so that we don't lock a lot of unused 5684 * stack memory. 5685 */ 5686 DPRINTF(2, ("ntp_rlimit: STACK: %d %s pages\n", 5687 (int)(rl_value / rl_scale), rl_sstr)); 5688 if (-1 == getrlimit(RLIMIT_STACK, &rl)) { 5689 msyslog(LOG_ERR, "getrlimit(RLIMIT_STACK) failed: %m"); 5690 } else { 5691 if (rl_value > rl.rlim_max) { 5692 msyslog(LOG_WARNING, 5693 "ntp_rlimit: using maximum allowed stack limit %lu instead of %lu.", 5694 (u_long)rl.rlim_max, 5695 (u_long)rl_value); 5696 rl_value = rl.rlim_max; 5697 } 5698 rl.rlim_cur = rl_value; 5699 if (-1 == setrlimit(RLIMIT_STACK, &rl)) { 5700 msyslog(LOG_ERR, 5701 "ntp_rlimit: Cannot set RLIMIT_STACK: %m"); 5702 } 5703 } 5704 break; 5705 # endif /* RLIMIT_STACK */ 5706 5707 default: 5708 fatal_error("ntp_rlimit: unexpected RLIMIT case: %d", rl_what); 5709 } 5710 } 5711 #endif /* HAVE_SETRLIMIT */ 5712