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