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