1 /* 2 * ntp_config.c - read and apply configuration information 3 */ 4 #ifdef HAVE_CONFIG_H 5 # include <config.h> 6 #endif 7 8 #ifdef HAVE_NETINFO 9 # include <netinfo/ni.h> 10 #endif 11 12 #include "ntpd.h" 13 #include "ntp_io.h" 14 #include "ntp_unixtime.h" 15 #include "ntp_refclock.h" 16 #include "ntp_filegen.h" 17 #include "ntp_stdlib.h" 18 #include <ntp_random.h> 19 #include <isc/net.h> 20 #include <isc/result.h> 21 22 #include <stdio.h> 23 #include <ctype.h> 24 #ifdef HAVE_SYS_PARAM_H 25 #include <sys/param.h> 26 #endif 27 #include <signal.h> 28 #ifndef SIGCHLD 29 # define SIGCHLD SIGCLD 30 #endif 31 #if !defined(VMS) 32 # ifdef HAVE_SYS_WAIT_H 33 # include <sys/wait.h> 34 # endif 35 #endif /* VMS */ 36 37 #ifdef SYS_WINNT 38 # include <io.h> 39 static HANDLE ResolverThreadHandle = NULL; 40 HANDLE ResolverEventHandle; 41 #else 42 int resolver_pipe_fd[2]; /* used to let the resolver process alert the parent process */ 43 #endif /* SYS_WINNT */ 44 45 /* 46 * [Bug 467]: Some linux headers collide with CONFIG_PHONE and CONFIG_KEYS 47 * so #include these later. 48 */ 49 50 #include "ntp_config.h" 51 #include "ntp_cmdargs.h" 52 53 extern int priority_done; 54 55 /* 56 * These routines are used to read the configuration file at 57 * startup time. An entry in the file must fit on a single line. 58 * Entries are processed as multiple tokens separated by white space 59 * Lines are considered terminated when a '#' is encountered. Blank 60 * lines are ignored. 61 */ 62 /* 63 * Translation table - keywords to function index 64 */ 65 struct keyword { 66 const char *text; 67 int keytype; 68 }; 69 70 /* 71 * Command keywords 72 */ 73 static struct keyword keywords[] = { 74 { "automax", CONFIG_AUTOMAX }, 75 { "broadcast", CONFIG_BROADCAST }, 76 { "broadcastclient", CONFIG_BROADCASTCLIENT }, 77 { "broadcastdelay", CONFIG_BDELAY }, 78 { "calldelay", CONFIG_CDELAY}, 79 #ifdef OPENSSL 80 { "crypto", CONFIG_CRYPTO }, 81 #endif /* OPENSSL */ 82 { "controlkey", CONFIG_CONTROLKEY }, 83 { "disable", CONFIG_DISABLE }, 84 { "driftfile", CONFIG_DRIFTFILE }, 85 { "enable", CONFIG_ENABLE }, 86 { "end", CONFIG_END }, 87 { "filegen", CONFIG_FILEGEN }, 88 { "fudge", CONFIG_FUDGE }, 89 { "includefile", CONFIG_INCLUDEFILE }, 90 { "keys", CONFIG_KEYS }, 91 { "keysdir", CONFIG_KEYSDIR }, 92 { "logconfig", CONFIG_LOGCONFIG }, 93 { "logfile", CONFIG_LOGFILE }, 94 { "manycastclient", CONFIG_MANYCASTCLIENT }, 95 { "manycastserver", CONFIG_MANYCASTSERVER }, 96 { "multicastclient", CONFIG_MULTICASTCLIENT }, 97 { "peer", CONFIG_PEER }, 98 { "phone", CONFIG_PHONE }, 99 { "pidfile", CONFIG_PIDFILE }, 100 { "discard", CONFIG_DISCARD }, 101 { "requestkey", CONFIG_REQUESTKEY }, 102 { "restrict", CONFIG_RESTRICT }, 103 { "revoke", CONFIG_REVOKE }, 104 { "server", CONFIG_SERVER }, 105 { "setvar", CONFIG_SETVAR }, 106 { "statistics", CONFIG_STATISTICS }, 107 { "statsdir", CONFIG_STATSDIR }, 108 { "tick", CONFIG_ADJ }, 109 { "tinker", CONFIG_TINKER }, 110 { "tos", CONFIG_TOS }, 111 { "trap", CONFIG_TRAP }, 112 { "trustedkey", CONFIG_TRUSTEDKEY }, 113 { "ttl", CONFIG_TTL }, 114 { "", CONFIG_UNKNOWN } 115 }; 116 117 /* 118 * "peer", "server", "broadcast" modifier keywords 119 */ 120 static struct keyword mod_keywords[] = { 121 { "autokey", CONF_MOD_SKEY }, 122 { "burst", CONF_MOD_BURST }, 123 { "iburst", CONF_MOD_IBURST }, 124 { "key", CONF_MOD_KEY }, 125 { "maxpoll", CONF_MOD_MAXPOLL }, 126 { "minpoll", CONF_MOD_MINPOLL }, 127 { "mode", CONF_MOD_MODE }, /* refclocks */ 128 { "noselect", CONF_MOD_NOSELECT }, 129 { "preempt", CONF_MOD_PREEMPT }, 130 { "true", CONF_MOD_TRUE }, 131 { "prefer", CONF_MOD_PREFER }, 132 { "ttl", CONF_MOD_TTL }, /* NTP peers */ 133 { "version", CONF_MOD_VERSION }, 134 { "dynamic", CONF_MOD_DYNAMIC }, 135 { "", CONFIG_UNKNOWN } 136 }; 137 138 /* 139 * "restrict" modifier keywords 140 */ 141 static struct keyword res_keywords[] = { 142 { "ignore", CONF_RES_IGNORE }, 143 { "limited", CONF_RES_LIMITED }, 144 { "kod", CONF_RES_DEMOBILIZE }, 145 { "lowpriotrap", CONF_RES_LPTRAP }, 146 { "mask", CONF_RES_MASK }, 147 { "nomodify", CONF_RES_NOMODIFY }, 148 { "nopeer", CONF_RES_NOPEER }, 149 { "noquery", CONF_RES_NOQUERY }, 150 { "noserve", CONF_RES_NOSERVE }, 151 { "notrap", CONF_RES_NOTRAP }, 152 { "notrust", CONF_RES_NOTRUST }, 153 { "ntpport", CONF_RES_NTPPORT }, 154 { "version", CONF_RES_VERSION }, 155 { "", CONFIG_UNKNOWN } 156 }; 157 158 /* 159 * "trap" modifier keywords 160 */ 161 static struct keyword trap_keywords[] = { 162 { "port", CONF_TRAP_PORT }, 163 { "interface", CONF_TRAP_INTERFACE }, 164 { "", CONFIG_UNKNOWN } 165 }; 166 167 /* 168 * "fudge" modifier keywords 169 */ 170 static struct keyword fudge_keywords[] = { 171 { "flag1", CONF_FDG_FLAG1 }, 172 { "flag2", CONF_FDG_FLAG2 }, 173 { "flag3", CONF_FDG_FLAG3 }, 174 { "flag4", CONF_FDG_FLAG4 }, 175 { "refid", CONF_FDG_REFID }, /* this mapping should be cleaned up (endianness, \0) - kd 20041031 */ 176 { "stratum", CONF_FDG_STRATUM }, 177 { "time1", CONF_FDG_TIME1 }, 178 { "time2", CONF_FDG_TIME2 }, 179 { "", CONFIG_UNKNOWN } 180 }; 181 182 /* 183 * "filegen" modifier keywords 184 */ 185 static struct keyword filegen_keywords[] = { 186 { "disable", CONF_FGEN_FLAG_DISABLE }, 187 { "enable", CONF_FGEN_FLAG_ENABLE }, 188 { "file", CONF_FGEN_FILE }, 189 { "link", CONF_FGEN_FLAG_LINK }, 190 { "nolink", CONF_FGEN_FLAG_NOLINK }, 191 { "type", CONF_FGEN_TYPE }, 192 { "", CONFIG_UNKNOWN } 193 }; 194 195 /* 196 * "type" modifier keywords 197 */ 198 static struct keyword fgen_types[] = { 199 { "age", FILEGEN_AGE }, 200 { "day", FILEGEN_DAY }, 201 { "month", FILEGEN_MONTH }, 202 { "none", FILEGEN_NONE }, 203 { "pid", FILEGEN_PID }, 204 { "week", FILEGEN_WEEK }, 205 { "year", FILEGEN_YEAR }, 206 { "", CONFIG_UNKNOWN} 207 }; 208 209 /* 210 * "enable", "disable" modifier keywords 211 */ 212 static struct keyword flags_keywords[] = { 213 { "auth", PROTO_AUTHENTICATE }, 214 { "bclient", PROTO_BROADCLIENT }, 215 { "calibrate", PROTO_CAL }, 216 { "kernel", PROTO_KERNEL }, 217 { "monitor", PROTO_MONITOR }, 218 { "ntp", PROTO_NTP }, 219 { "stats", PROTO_FILEGEN }, 220 { "", CONFIG_UNKNOWN } 221 }; 222 223 /* 224 * "discard" modifier keywords 225 */ 226 static struct keyword discard_keywords[] = { 227 { "average", CONF_DISCARD_AVERAGE }, 228 { "minimum", CONF_DISCARD_MINIMUM }, 229 { "monitor", CONF_DISCARD_MONITOR }, 230 { "", CONFIG_UNKNOWN } 231 }; 232 233 /* 234 * "tinker" modifier keywords 235 */ 236 static struct keyword tinker_keywords[] = { 237 { "step", CONF_CLOCK_MAX }, 238 { "panic", CONF_CLOCK_PANIC }, 239 { "dispersion", CONF_CLOCK_PHI }, 240 { "stepout", CONF_CLOCK_MINSTEP }, 241 { "allan", CONF_CLOCK_ALLAN }, 242 { "huffpuff", CONF_CLOCK_HUFFPUFF }, 243 { "freq", CONF_CLOCK_FREQ }, 244 { "", CONFIG_UNKNOWN } 245 }; 246 247 /* 248 * "tos" modifier keywords 249 */ 250 static struct keyword tos_keywords[] = { 251 { "minclock", CONF_TOS_MINCLOCK }, 252 { "maxclock", CONF_TOS_MAXCLOCK }, 253 { "minsane", CONF_TOS_MINSANE }, 254 { "floor", CONF_TOS_FLOOR }, 255 { "ceiling", CONF_TOS_CEILING }, 256 { "cohort", CONF_TOS_COHORT }, 257 { "mindist", CONF_TOS_MINDISP }, 258 { "maxdist", CONF_TOS_MAXDIST }, 259 { "maxhop", CONF_TOS_MAXHOP }, 260 { "beacon", CONF_TOS_BEACON }, 261 { "orphan", CONF_TOS_ORPHAN }, 262 { "", CONFIG_UNKNOWN } 263 }; 264 265 #ifdef OPENSSL 266 /* 267 * "crypto" modifier keywords 268 */ 269 static struct keyword crypto_keywords[] = { 270 { "cert", CONF_CRYPTO_CERT }, 271 { "gqpar", CONF_CRYPTO_GQPAR }, 272 { "host", CONF_CRYPTO_RSA }, 273 { "ident", CONF_CRYPTO_IDENT }, 274 { "iffpar", CONF_CRYPTO_IFFPAR }, 275 { "leap", CONF_CRYPTO_LEAP }, 276 { "mvpar", CONF_CRYPTO_MVPAR }, 277 { "pw", CONF_CRYPTO_PW }, 278 { "randfile", CONF_CRYPTO_RAND }, 279 { "sign", CONF_CRYPTO_SIGN }, 280 { "", CONFIG_UNKNOWN } 281 }; 282 #endif /* OPENSSL */ 283 284 /* 285 * Address type selection, IPv4 or IPv4. 286 * Used on various lines. 287 */ 288 static struct keyword addr_type[] = { 289 { "-4", CONF_ADDR_IPV4 }, 290 { "-6", CONF_ADDR_IPV6 }, 291 { "", CONFIG_UNKNOWN } 292 }; 293 294 /* 295 * "logconfig" building blocks 296 */ 297 struct masks { 298 const char *name; 299 unsigned long mask; 300 }; 301 302 static struct masks logcfg_class[] = { 303 { "clock", NLOG_OCLOCK }, 304 { "peer", NLOG_OPEER }, 305 { "sync", NLOG_OSYNC }, 306 { "sys", NLOG_OSYS }, 307 { (char *)0, 0 } 308 }; 309 310 static struct masks logcfg_item[] = { 311 { "info", NLOG_INFO }, 312 { "allinfo", NLOG_SYSINFO|NLOG_PEERINFO|NLOG_CLOCKINFO|NLOG_SYNCINFO }, 313 { "events", NLOG_EVENT }, 314 { "allevents", NLOG_SYSEVENT|NLOG_PEEREVENT|NLOG_CLOCKEVENT|NLOG_SYNCEVENT }, 315 { "status", NLOG_STATUS }, 316 { "allstatus", NLOG_SYSSTATUS|NLOG_PEERSTATUS|NLOG_CLOCKSTATUS|NLOG_SYNCSTATUS }, 317 { "statistics", NLOG_STATIST }, 318 { "allstatistics", NLOG_SYSSTATIST|NLOG_PEERSTATIST|NLOG_CLOCKSTATIST|NLOG_SYNCSTATIST }, 319 { "allclock", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OCLOCK }, 320 { "allpeer", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OPEER }, 321 { "allsys", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYS }, 322 { "allsync", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYNC }, 323 { "all", NLOG_SYSMASK|NLOG_PEERMASK|NLOG_CLOCKMASK|NLOG_SYNCMASK }, 324 { (char *)0, 0 } 325 }; 326 327 /* 328 * Limits on things 329 */ 330 #define MAXTOKENS 20 /* 20 tokens on line */ 331 #define MAXLINE 1024 /* maximum length of line */ 332 #define MAXPHONE 10 /* maximum number of phone strings */ 333 #define MAXPPS 20 /* maximum length of PPS device string */ 334 #define MAXINCLUDELEVEL 5 /* maximum include file levels */ 335 336 /* 337 * Miscellaneous macros 338 */ 339 #define STRSAME(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0) 340 #define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0') 341 #define ISSPACE(c) ((c) == ' ' || (c) == '\t') 342 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) 343 344 #define KEY_TYPE_MD5 4 345 346 /* 347 * File descriptor used by the resolver save routines, and temporary file 348 * name. 349 */ 350 int call_resolver = 1; /* ntp-genkeys sets this to 0, for example */ 351 static FILE *res_fp; 352 #ifndef SYS_WINNT 353 static char res_file[20]; /* enough for /tmp/ntpXXXXXX\0 */ 354 #define RES_TEMPFILE "/tmp/ntpXXXXXX" 355 #else 356 static char res_file[MAX_PATH]; 357 #endif /* SYS_WINNT */ 358 359 /* 360 * Definitions of things either imported from or exported to outside 361 */ 362 363 short default_ai_family = AF_UNSPEC; /* Default either IPv4 or IPv6 */ 364 char *sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */ 365 char *keysdir = NTP_KEYSDIR; /* crypto keys directory */ 366 #if defined(HAVE_SCHED_SETSCHEDULER) 367 int config_priority_override = 0; 368 int config_priority; 369 #endif 370 371 const char *config_file; 372 #ifdef HAVE_NETINFO 373 struct netinfo_config_state *config_netinfo = NULL; 374 int check_netinfo = 1; 375 #endif /* HAVE_NETINFO */ 376 #ifdef SYS_WINNT 377 char *alt_config_file; 378 LPTSTR temp; 379 char config_file_storage[MAX_PATH]; 380 char alt_config_file_storage[MAX_PATH]; 381 #endif /* SYS_WINNT */ 382 383 #ifdef HAVE_NETINFO 384 /* 385 * NetInfo configuration state 386 */ 387 struct netinfo_config_state { 388 void *domain; /* domain with config */ 389 ni_id config_dir; /* ID config dir */ 390 int prop_index; /* current property */ 391 int val_index; /* current value */ 392 char **val_list; /* value list */ 393 }; 394 #endif 395 396 /* 397 * Function prototypes 398 */ 399 static unsigned long get_pfxmatch P((char **, struct masks *)); 400 static unsigned long get_match P((char *, struct masks *)); 401 static unsigned long get_logmask P((char *)); 402 #ifdef HAVE_NETINFO 403 static struct netinfo_config_state *get_netinfo_config P((void)); 404 static void free_netinfo_config P((struct netinfo_config_state *)); 405 static int gettokens_netinfo P((struct netinfo_config_state *, char **, int *)); 406 #endif 407 static int gettokens P((FILE *, char *, char **, int *)); 408 static int matchkey P((char *, struct keyword *, int)); 409 enum gnn_type { 410 t_UNK, /* Unknown */ 411 t_REF, /* Refclock */ 412 t_MSK /* Network Mask */ 413 }; 414 static int getnetnum P((const char *, struct sockaddr_storage *, int, 415 enum gnn_type)); 416 static void save_resolve P((char *, int, int, int, int, u_int, int, 417 keyid_t, u_char *, u_char)); 418 static void do_resolve_internal P((void)); 419 static void abort_resolve P((void)); 420 #if !defined(VMS) && !defined(SYS_WINNT) 421 static RETSIGTYPE catchchild P((int)); 422 #endif /* VMS */ 423 424 /* 425 * get_pfxmatch - find value for prefixmatch 426 * and update char * accordingly 427 */ 428 static unsigned long 429 get_pfxmatch( 430 char ** s, 431 struct masks *m 432 ) 433 { 434 while (m->name) { 435 if (strncmp(*s, m->name, strlen(m->name)) == 0) { 436 *s += strlen(m->name); 437 return m->mask; 438 } else { 439 m++; 440 } 441 } 442 return 0; 443 } 444 445 /* 446 * get_match - find logmask value 447 */ 448 static unsigned long 449 get_match( 450 char *s, 451 struct masks *m 452 ) 453 { 454 while (m->name) { 455 if (strcmp(s, m->name) == 0) { 456 return m->mask; 457 } else { 458 m++; 459 } 460 } 461 return 0; 462 } 463 464 /* 465 * get_logmask - build bitmask for ntp_syslogmask 466 */ 467 static unsigned long 468 get_logmask( 469 char *s 470 ) 471 { 472 char *t; 473 unsigned long offset; 474 unsigned long mask; 475 476 t = s; 477 offset = get_pfxmatch(&t, logcfg_class); 478 mask = get_match(t, logcfg_item); 479 480 if (mask) 481 return mask << offset; 482 else 483 msyslog(LOG_ERR, "logconfig: illegal argument %s - ignored", s); 484 485 return 0; 486 } 487 488 489 /* 490 * getconfig - get command line options and read the configuration file 491 */ 492 void 493 getconfig( 494 int argc, 495 char *argv[] 496 ) 497 { 498 register int i; 499 int c; 500 int errflg; 501 int status; 502 int istart; 503 int peerversion; 504 int minpoll; 505 int maxpoll; 506 int ttl; 507 long stratum; 508 unsigned long ul; 509 keyid_t peerkey; 510 u_char *peerkeystr; 511 u_long fudgeflag; 512 u_int peerflags; 513 int hmode; 514 struct sockaddr_storage peeraddr; 515 struct sockaddr_storage maskaddr; 516 FILE *fp[MAXINCLUDELEVEL+1]; 517 FILE *includefile; 518 int includelevel = 0; 519 char line[MAXLINE]; 520 char *(tokens[MAXTOKENS]); 521 int ntokens = 0; 522 int tok = CONFIG_UNKNOWN; 523 struct interface *localaddr; 524 struct refclockstat clock_stat; 525 FILEGEN *filegen; 526 527 /* 528 * Initialize, initialize 529 */ 530 errflg = 0; 531 532 #ifndef SYS_WINNT 533 config_file = CONFIG_FILE; 534 #else 535 temp = CONFIG_FILE; 536 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) { 537 msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n"); 538 exit(1); 539 } 540 config_file = config_file_storage; 541 542 temp = ALT_CONFIG_FILE; 543 if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) { 544 msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n"); 545 exit(1); 546 } 547 alt_config_file = alt_config_file_storage; 548 549 #endif /* SYS_WINNT */ 550 res_fp = NULL; 551 ntp_syslogmask = NLOG_SYNCMASK; /* set more via logconfig */ 552 553 /* 554 * install a non default variable with this daemon version 555 */ 556 (void) sprintf(line, "daemon_version=\"%s\"", Version); 557 set_sys_var(line, strlen(line)+1, RO); 558 559 /* 560 * Say how we're setting the time of day 561 */ 562 (void) sprintf(line, "settimeofday=\"%s\"", set_tod_using); 563 set_sys_var(line, strlen(line)+1, RO); 564 565 /* 566 * Initialize the loop. 567 */ 568 loop_config(LOOP_DRIFTINIT, 0.); 569 570 getCmdOpts(argc, argv); 571 572 if ( 573 (fp[0] = fopen(FindConfig(config_file), "r")) == NULL 574 #ifdef HAVE_NETINFO 575 /* If there is no config_file, try NetInfo. */ 576 && check_netinfo && !(config_netinfo = get_netinfo_config()) 577 #endif /* HAVE_NETINFO */ 578 ) { 579 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file)); 580 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file)); 581 #ifdef SYS_WINNT 582 /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */ 583 584 if ((fp[0] = fopen(FindConfig(alt_config_file), "r")) == NULL) { 585 586 /* 587 * Broadcast clients can sometimes run without 588 * a configuration file. 589 */ 590 591 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file)); 592 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file)); 593 return; 594 } 595 #else /* not SYS_WINNT */ 596 return; 597 #endif /* not SYS_WINNT */ 598 } 599 600 proto_config(PROTO_MONITOR, 0, 0., NULL); 601 602 for (;;) { 603 if (tok == CONFIG_END) 604 break; 605 if (fp[includelevel]) 606 tok = gettokens(fp[includelevel], line, tokens, &ntokens); 607 #ifdef HAVE_NETINFO 608 else 609 tok = gettokens_netinfo(config_netinfo, tokens, &ntokens); 610 #endif /* HAVE_NETINFO */ 611 612 if (tok == CONFIG_UNKNOWN) { 613 if (includelevel > 0) { 614 fclose(fp[includelevel--]); 615 continue; 616 } else { 617 break; 618 } 619 } 620 621 switch(tok) { 622 case CONFIG_PEER: 623 case CONFIG_SERVER: 624 case CONFIG_MANYCASTCLIENT: 625 case CONFIG_BROADCAST: 626 if (tok == CONFIG_PEER) 627 hmode = MODE_ACTIVE; 628 else if (tok == CONFIG_SERVER) 629 hmode = MODE_CLIENT; 630 else if (tok == CONFIG_MANYCASTCLIENT) 631 hmode = MODE_CLIENT; 632 else 633 hmode = MODE_BROADCAST; 634 635 if (ntokens < 2) { 636 msyslog(LOG_ERR, 637 "No address for %s, line ignored", 638 tokens[0]); 639 break; 640 } 641 642 istart = 1; 643 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 644 peeraddr.ss_family = default_ai_family; 645 switch (matchkey(tokens[istart], addr_type, 0)) { 646 case CONF_ADDR_IPV4: 647 peeraddr.ss_family = AF_INET; 648 istart++; 649 break; 650 case CONF_ADDR_IPV6: 651 peeraddr.ss_family = AF_INET6; 652 istart++; 653 break; 654 } 655 656 status = getnetnum(tokens[istart], &peeraddr, 0, t_UNK); 657 if (status == -1) 658 break; /* Found IPv6 address */ 659 if(status != 1) { 660 errflg = -1; 661 } else { 662 errflg = 0; 663 664 if ( 665 #ifdef REFCLOCK 666 !ISREFCLOCKADR(&peeraddr) && 667 #endif 668 ISBADADR(&peeraddr)) { 669 msyslog(LOG_ERR, 670 "attempt to configure invalid address %s", 671 stoa(&peeraddr)); 672 break; 673 } 674 /* 675 * Shouldn't be able to specify multicast 676 * address for server/peer! 677 * and unicast address for manycastclient! 678 */ 679 if (peeraddr.ss_family == AF_INET) { 680 if (((tok == CONFIG_SERVER) || 681 (tok == CONFIG_PEER)) && 682 #ifdef REFCLOCK 683 !ISREFCLOCKADR(&peeraddr) && 684 #endif 685 IN_CLASSD(ntohl(((struct sockaddr_in*)&peeraddr)->sin_addr.s_addr))) { 686 msyslog(LOG_ERR, 687 "attempt to configure invalid address %s", 688 stoa(&peeraddr)); 689 break; 690 } 691 if ((tok == CONFIG_MANYCASTCLIENT) && 692 !IN_CLASSD(ntohl(((struct sockaddr_in*)&peeraddr)->sin_addr.s_addr))) { 693 msyslog(LOG_ERR, 694 "attempt to configure invalid address %s", 695 stoa(&peeraddr)); 696 break; 697 } 698 } 699 else if(peeraddr.ss_family == AF_INET6) { 700 if (((tok == CONFIG_SERVER) || 701 (tok == CONFIG_PEER)) && 702 #ifdef REFCLOCK 703 !ISREFCLOCKADR(&peeraddr) && 704 #endif 705 IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)&peeraddr)->sin6_addr)) { 706 msyslog(LOG_ERR, 707 "attempt to configure in valid address %s", 708 stoa(&peeraddr)); 709 break; 710 } 711 if ((tok == CONFIG_MANYCASTCLIENT) && 712 !IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)&peeraddr)->sin6_addr)) { 713 msyslog(LOG_ERR, 714 "attempt to configure in valid address %s", 715 stoa(&peeraddr)); 716 break; 717 } 718 } 719 } 720 if (peeraddr.ss_family == AF_INET6 && 721 isc_net_probeipv6() != ISC_R_SUCCESS) 722 break; 723 724 peerversion = NTP_VERSION; 725 minpoll = NTP_MINDPOLL; 726 maxpoll = NTP_MAXDPOLL; 727 peerkey = 0; 728 peerkeystr = (u_char *)"*"; 729 peerflags = 0; 730 ttl = 0; 731 istart++; 732 for (i = istart; i < ntokens; i++) 733 switch (matchkey(tokens[i], mod_keywords, 1)) { 734 case CONF_MOD_VERSION: 735 if (i >= ntokens-1) { 736 msyslog(LOG_ERR, 737 "peer/server version requires an argument"); 738 errflg = 1; 739 break; 740 } 741 peerversion = atoi(tokens[++i]); 742 if ((u_char)peerversion > NTP_VERSION 743 || (u_char)peerversion < NTP_OLDVERSION) { 744 msyslog(LOG_ERR, 745 "inappropriate version number %s, line ignored", 746 tokens[i]); 747 errflg = 1; 748 } 749 break; 750 751 case CONF_MOD_KEY: 752 if (i >= ntokens-1) { 753 msyslog(LOG_ERR, 754 "key: argument required"); 755 errflg = 1; 756 break; 757 } 758 peerkey = (int)atol(tokens[++i]); 759 peerflags |= FLAG_AUTHENABLE; 760 break; 761 762 case CONF_MOD_MINPOLL: 763 if (i >= ntokens-1) { 764 msyslog(LOG_ERR, 765 "minpoll: argument required"); 766 errflg = 1; 767 break; 768 } 769 minpoll = atoi(tokens[++i]); 770 if (minpoll < NTP_MINPOLL) { 771 msyslog(LOG_INFO, 772 "minpoll: provided value (%d) is below minimum (%d)", 773 minpoll, NTP_MINPOLL); 774 minpoll = NTP_MINPOLL; 775 } 776 break; 777 778 case CONF_MOD_MAXPOLL: 779 if (i >= ntokens-1) { 780 msyslog(LOG_ERR, 781 "maxpoll: argument required" 782 ); 783 errflg = 1; 784 break; 785 } 786 maxpoll = atoi(tokens[++i]); 787 if (maxpoll > NTP_MAXPOLL) { 788 msyslog(LOG_INFO, 789 "maxpoll: provided value (%d) is above maximum (%d)", 790 maxpoll, NTP_MAXPOLL); 791 maxpoll = NTP_MAXPOLL; 792 } 793 break; 794 795 case CONF_MOD_PREFER: 796 peerflags |= FLAG_PREFER; 797 break; 798 799 case CONF_MOD_PREEMPT: 800 peerflags |= FLAG_PREEMPT; 801 break; 802 803 case CONF_MOD_NOSELECT: 804 peerflags |= FLAG_NOSELECT; 805 break; 806 807 case CONF_MOD_TRUE: 808 peerflags |= FLAG_TRUE; 809 810 case CONF_MOD_BURST: 811 peerflags |= FLAG_BURST; 812 break; 813 814 case CONF_MOD_IBURST: 815 peerflags |= FLAG_IBURST; 816 break; 817 818 case CONF_MOD_DYNAMIC: 819 msyslog(LOG_WARNING, 820 "Warning: the \"dynamic\" keyword has been obsoleted" 821 " and will be removed in the next release\n"); 822 break; 823 824 #ifdef OPENSSL 825 case CONF_MOD_SKEY: 826 peerflags |= FLAG_SKEY | 827 FLAG_AUTHENABLE; 828 break; 829 #endif /* OPENSSL */ 830 831 case CONF_MOD_TTL: 832 if (i >= ntokens-1) { 833 msyslog(LOG_ERR, 834 "ttl: argument required"); 835 errflg = 1; 836 break; 837 } 838 ttl = atoi(tokens[++i]); 839 if (ttl >= MAX_TTL) { 840 msyslog(LOG_ERR, 841 "ttl: invalid argument"); 842 errflg = 1; 843 } 844 break; 845 846 case CONF_MOD_MODE: 847 if (i >= ntokens-1) { 848 msyslog(LOG_ERR, 849 "mode: argument required"); 850 errflg = 1; 851 break; 852 } 853 ttl = atoi(tokens[++i]); 854 break; 855 856 case CONFIG_UNKNOWN: 857 errflg = 1; 858 break; 859 } 860 if (minpoll > maxpoll) { 861 msyslog(LOG_ERR, 862 "config error: minpoll > maxpoll"); 863 errflg = 1; 864 } 865 if (errflg == 0) { 866 if (peer_config(&peeraddr, 867 ANY_INTERFACE_CHOOSE(&peeraddr), hmode, 868 peerversion, minpoll, maxpoll, peerflags, 869 ttl, peerkey, peerkeystr) == 0) { 870 msyslog(LOG_ERR, 871 "configuration of %s failed", 872 stoa(&peeraddr)); 873 } 874 } else if (errflg == -1) { 875 save_resolve(tokens[istart - 1], hmode, peerversion, 876 minpoll, maxpoll, peerflags, ttl, 877 peerkey, peerkeystr, peeraddr.ss_family); 878 } 879 break; 880 881 case CONFIG_DRIFTFILE: 882 if (ntokens >= 2) 883 stats_config(STATS_FREQ_FILE, tokens[1]); 884 else 885 stats_config(STATS_FREQ_FILE, (char *)0); 886 stats_write_period = stats_write_tolerance = 0; 887 if (ntokens >= 3) 888 stats_write_period = 60 * atol(tokens[2]); 889 if (stats_write_period <= 0) 890 stats_write_period = 3600; 891 if (ntokens >= 4) { 892 double ftemp; 893 sscanf(tokens[3], "%lf", &ftemp); 894 stats_write_tolerance = ftemp / 100; 895 } 896 break; 897 898 case CONFIG_PIDFILE: 899 if (ntokens >= 2) 900 stats_config(STATS_PID_FILE, tokens[1]); 901 else 902 stats_config(STATS_PID_FILE, (char *)0); 903 break; 904 905 case CONFIG_END: 906 for ( i = 0; i <= includelevel; i++ ) { 907 fclose(fp[i]); 908 } 909 break; 910 911 case CONFIG_INCLUDEFILE: 912 if (ntokens < 2) { 913 msyslog(LOG_ERR, "includefile needs one argument"); 914 break; 915 } 916 if (includelevel >= MAXINCLUDELEVEL) { 917 fprintf(stderr, "getconfig: Maximum include file level exceeded.\n"); 918 msyslog(LOG_INFO, "getconfig: Maximum include file level exceeded."); 919 break; 920 } 921 includefile = fopen(FindConfig(tokens[1]), "r"); 922 if (includefile == NULL) { 923 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(tokens[1])); 924 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(tokens[1])); 925 break; 926 } 927 fp[++includelevel] = includefile; 928 break; 929 930 case CONFIG_LOGFILE: 931 if (ntokens >= 2) { 932 FILE *new_file; 933 934 new_file = fopen(tokens[1], "a"); 935 if (new_file != NULL) { 936 NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */ 937 msyslog(LOG_NOTICE, "logging to file %s", tokens[1]); 938 if (syslog_file != NULL && 939 fileno(syslog_file) != fileno(new_file)) 940 (void)fclose(syslog_file); 941 942 syslog_file = new_file; 943 syslogit = 0; 944 } 945 else 946 msyslog(LOG_ERR, 947 "Cannot open log file %s", 948 tokens[1]); 949 } 950 else 951 msyslog(LOG_ERR, "logfile needs one argument"); 952 break; 953 954 case CONFIG_LOGCONFIG: 955 for (i = 1; i < ntokens; i++) 956 { 957 int add = 1; 958 int equals = 0; 959 char * s = &tokens[i][0]; 960 961 switch (*s) { 962 case '+': 963 case '-': 964 case '=': 965 add = *s == '+'; 966 equals = *s == '='; 967 s++; 968 break; 969 970 default: 971 break; 972 } 973 if (equals) { 974 ntp_syslogmask = get_logmask(s); 975 } else { 976 if (add) { 977 ntp_syslogmask |= get_logmask(s); 978 } else { 979 ntp_syslogmask &= ~get_logmask(s); 980 } 981 } 982 #ifdef DEBUG 983 if (debug) 984 printf("ntp_syslogmask = 0x%08lx (%s)\n", ntp_syslogmask, tokens[i]); 985 #endif 986 } 987 break; 988 989 case CONFIG_BROADCASTCLIENT: 990 if (ntokens == 1) { 991 proto_config(PROTO_BROADCLIENT, 1, 0., NULL); 992 } else { 993 proto_config(PROTO_BROADCLIENT, 2, 0., NULL); 994 } 995 break; 996 997 case CONFIG_MULTICASTCLIENT: 998 case CONFIG_MANYCASTSERVER: 999 if (ntokens > 1) { 1000 istart = 1; 1001 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 1002 peeraddr.ss_family = default_ai_family; 1003 switch (matchkey(tokens[istart], 1004 addr_type, 0)) { 1005 case CONF_ADDR_IPV4: 1006 peeraddr.ss_family = AF_INET; 1007 istart++; 1008 break; 1009 case CONF_ADDR_IPV6: 1010 peeraddr.ss_family = AF_INET6; 1011 istart++; 1012 break; 1013 } 1014 /* 1015 * Abuse maskaddr to store the prefered ip 1016 * version. 1017 */ 1018 memset((char *)&maskaddr, 0, sizeof(maskaddr)); 1019 maskaddr.ss_family = peeraddr.ss_family; 1020 1021 for (i = istart; i < ntokens; i++) { 1022 memset((char *)&peeraddr, 0, 1023 sizeof(peeraddr)); 1024 peeraddr.ss_family = maskaddr.ss_family; 1025 if (getnetnum(tokens[i], &peeraddr, 1, 1026 t_UNK) == 1) 1027 proto_config(PROTO_MULTICAST_ADD, 1028 0, 0., &peeraddr); 1029 } 1030 } else 1031 proto_config(PROTO_MULTICAST_ADD, 1032 0, 0., NULL); 1033 if (tok == CONFIG_MULTICASTCLIENT) 1034 proto_config(PROTO_MULTICAST_ADD, 1, 0., NULL); 1035 else if (tok == CONFIG_MANYCASTSERVER) 1036 sys_manycastserver = 1; 1037 break; 1038 1039 case CONFIG_KEYS: 1040 if (ntokens >= 2) { 1041 getauthkeys(tokens[1]); 1042 } 1043 break; 1044 1045 case CONFIG_KEYSDIR: 1046 if (ntokens < 2) { 1047 msyslog(LOG_ERR, 1048 "Keys directory name required"); 1049 break; 1050 } 1051 keysdir = (char *)emalloc(strlen(tokens[1]) + 1); 1052 strcpy(keysdir, tokens[1]); 1053 break; 1054 1055 case CONFIG_TINKER: 1056 for (i = 1; i < ntokens; i++) { 1057 int temp; 1058 double ftemp; 1059 1060 temp = matchkey(tokens[i++], tinker_keywords, 1); 1061 if (i > ntokens - 1) { 1062 msyslog(LOG_ERR, 1063 "tinker: missing argument"); 1064 errflg++; 1065 break; 1066 } 1067 sscanf(tokens[i], "%lf", &ftemp); 1068 switch(temp) { 1069 1070 case CONF_CLOCK_MAX: 1071 loop_config(LOOP_MAX, ftemp); 1072 break; 1073 1074 case CONF_CLOCK_PANIC: 1075 loop_config(LOOP_PANIC, ftemp); 1076 break; 1077 1078 case CONF_CLOCK_PHI: 1079 loop_config(LOOP_PHI, ftemp); 1080 break; 1081 1082 case CONF_CLOCK_MINSTEP: 1083 loop_config(LOOP_MINSTEP, ftemp); 1084 break; 1085 1086 case CONF_CLOCK_ALLAN: 1087 loop_config(LOOP_ALLAN, ftemp); 1088 break; 1089 1090 case CONF_CLOCK_HUFFPUFF: 1091 loop_config(LOOP_HUFFPUFF, ftemp); 1092 break; 1093 1094 case CONF_CLOCK_FREQ: 1095 loop_config(LOOP_FREQ, ftemp); 1096 break; 1097 } 1098 } 1099 break; 1100 1101 case CONFIG_TOS: 1102 for (i = 1; i < ntokens; i++) { 1103 int temp; 1104 double ftemp; 1105 1106 temp = matchkey(tokens[i++], tos_keywords, 1); 1107 if (i > ntokens - 1) { 1108 msyslog(LOG_ERR, 1109 "tos: missing argument"); 1110 errflg++; 1111 break; 1112 } 1113 sscanf(tokens[i], "%lf", &ftemp); 1114 switch(temp) { 1115 1116 case CONF_TOS_MINCLOCK: 1117 proto_config(PROTO_MINCLOCK, 0, ftemp, NULL); 1118 break; 1119 1120 case CONF_TOS_MAXCLOCK: 1121 proto_config(PROTO_MAXCLOCK, 0, ftemp, NULL); 1122 break; 1123 1124 case CONF_TOS_MINSANE: 1125 proto_config(PROTO_MINSANE, 0, ftemp, NULL); 1126 break; 1127 1128 case CONF_TOS_FLOOR: 1129 proto_config(PROTO_FLOOR, 0, ftemp, NULL); 1130 break; 1131 1132 case CONF_TOS_CEILING: 1133 proto_config(PROTO_CEILING, 0, ftemp, NULL); 1134 break; 1135 1136 case CONF_TOS_COHORT: 1137 proto_config(PROTO_COHORT, 0, ftemp, NULL); 1138 break; 1139 1140 case CONF_TOS_MINDISP: 1141 proto_config(PROTO_MINDISP, 0, ftemp, NULL); 1142 break; 1143 1144 case CONF_TOS_MAXDIST: 1145 proto_config(PROTO_MAXDIST, 0, ftemp, NULL); 1146 break; 1147 1148 case CONF_TOS_MAXHOP: 1149 proto_config(PROTO_MAXHOP, 0, ftemp, NULL); 1150 break; 1151 1152 case CONF_TOS_ORPHAN: 1153 proto_config(PROTO_ORPHAN, 0, ftemp, NULL); 1154 break; 1155 1156 case CONF_TOS_BEACON: 1157 proto_config(PROTO_BEACON, 0, ftemp, NULL); 1158 break; 1159 } 1160 } 1161 break; 1162 1163 case CONFIG_TTL: 1164 for (i = 1; i < ntokens && i < MAX_TTL; i++) { 1165 sys_ttl[i - 1] = (u_char) atoi(tokens[i]); 1166 sys_ttlmax = i - 1; 1167 } 1168 break; 1169 1170 case CONFIG_DISCARD: 1171 for (i = 1; i < ntokens; i++) { 1172 int temp; 1173 1174 temp = matchkey(tokens[i++], 1175 discard_keywords, 1); 1176 if (i > ntokens - 1) { 1177 msyslog(LOG_ERR, 1178 "discard: missing argument"); 1179 errflg++; 1180 break; 1181 } 1182 switch(temp) { 1183 case CONF_DISCARD_AVERAGE: 1184 res_avg_interval = atoi(tokens[i]); 1185 break; 1186 1187 case CONF_DISCARD_MINIMUM: 1188 res_min_interval = atoi(tokens[i]); 1189 break; 1190 1191 case CONF_DISCARD_MONITOR: 1192 mon_age = atoi(tokens[i]); 1193 break; 1194 1195 default: 1196 msyslog(LOG_ERR, 1197 "discard: unknown keyword"); 1198 break; 1199 } 1200 } 1201 break; 1202 1203 #ifdef OPENSSL 1204 case CONFIG_REVOKE: 1205 if (ntokens >= 2) 1206 sys_revoke = (u_char) max(atoi(tokens[1]), KEY_REVOKE); 1207 break; 1208 1209 case CONFIG_AUTOMAX: 1210 if (ntokens >= 2) 1211 sys_automax = 1 << max(atoi(tokens[1]), 10); 1212 break; 1213 1214 case CONFIG_CRYPTO: 1215 if (ntokens == 1) { 1216 crypto_config(CRYPTO_CONF_NONE, NULL); 1217 break; 1218 } 1219 for (i = 1; i < ntokens; i++) { 1220 int temp; 1221 1222 temp = matchkey(tokens[i++], 1223 crypto_keywords, 1); 1224 if (i > ntokens - 1) { 1225 msyslog(LOG_ERR, 1226 "crypto: missing argument"); 1227 errflg++; 1228 break; 1229 } 1230 switch(temp) { 1231 1232 case CONF_CRYPTO_CERT: 1233 crypto_config(CRYPTO_CONF_CERT, 1234 tokens[i]); 1235 break; 1236 1237 case CONF_CRYPTO_RSA: 1238 crypto_config(CRYPTO_CONF_PRIV, 1239 tokens[i]); 1240 break; 1241 1242 case CONF_CRYPTO_IDENT: 1243 crypto_config(CRYPTO_CONF_IDENT, 1244 tokens[i]); 1245 break; 1246 1247 case CONF_CRYPTO_IFFPAR: 1248 crypto_config(CRYPTO_CONF_IFFPAR, 1249 tokens[i]); 1250 break; 1251 1252 case CONF_CRYPTO_GQPAR: 1253 crypto_config(CRYPTO_CONF_GQPAR, 1254 tokens[i]); 1255 break; 1256 1257 case CONF_CRYPTO_MVPAR: 1258 crypto_config(CRYPTO_CONF_MVPAR, 1259 tokens[i]); 1260 break; 1261 1262 case CONF_CRYPTO_LEAP: 1263 crypto_config(CRYPTO_CONF_LEAP, 1264 tokens[i]); 1265 break; 1266 1267 case CONF_CRYPTO_PW: 1268 crypto_config(CRYPTO_CONF_PW, 1269 tokens[i]); 1270 break; 1271 1272 case CONF_CRYPTO_RAND: 1273 crypto_config(CRYPTO_CONF_RAND, 1274 tokens[i]); 1275 break; 1276 1277 case CONF_CRYPTO_SIGN: 1278 crypto_config(CRYPTO_CONF_SIGN, 1279 tokens[i]); 1280 break; 1281 1282 default: 1283 msyslog(LOG_ERR, 1284 "crypto: unknown keyword"); 1285 break; 1286 } 1287 } 1288 break; 1289 #endif /* OPENSSL */ 1290 1291 case CONFIG_RESTRICT: 1292 if (ntokens < 2) { 1293 msyslog(LOG_ERR, "restrict requires an address"); 1294 break; 1295 } 1296 istart = 1; 1297 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 1298 peeraddr.ss_family = default_ai_family; 1299 switch (matchkey(tokens[istart], addr_type, 0)) { 1300 case CONF_ADDR_IPV4: 1301 peeraddr.ss_family = AF_INET; 1302 istart++; 1303 break; 1304 case CONF_ADDR_IPV6: 1305 peeraddr.ss_family = AF_INET6; 1306 istart++; 1307 break; 1308 } 1309 1310 /* 1311 * Assume default means an IPv4 address, except 1312 * if forced by a -4 or -6. 1313 */ 1314 if (STREQ(tokens[istart], "default")) { 1315 if (peeraddr.ss_family == 0) 1316 peeraddr.ss_family = AF_INET; 1317 } else if (getnetnum(tokens[istart], &peeraddr, 1, 1318 t_UNK) != 1) 1319 break; 1320 1321 /* 1322 * Use peerversion as flags, peerkey as mflags. Ick. 1323 */ 1324 peerversion = 0; 1325 peerkey = 0; 1326 errflg = 0; 1327 SET_HOSTMASK(&maskaddr, peeraddr.ss_family); 1328 istart++; 1329 for (i = istart; i < ntokens; i++) { 1330 switch (matchkey(tokens[i], res_keywords, 1)) { 1331 case CONF_RES_MASK: 1332 if (i >= ntokens-1) { 1333 msyslog(LOG_ERR, 1334 "mask keyword needs argument"); 1335 errflg++; 1336 break; 1337 } 1338 i++; 1339 if (getnetnum(tokens[i], &maskaddr, 1, 1340 t_MSK) != 1) 1341 errflg++; 1342 break; 1343 1344 case CONF_RES_IGNORE: 1345 peerversion |= RES_IGNORE; 1346 break; 1347 1348 case CONF_RES_NOSERVE: 1349 peerversion |= RES_DONTSERVE; 1350 break; 1351 1352 case CONF_RES_NOTRUST: 1353 peerversion |= RES_DONTTRUST; 1354 break; 1355 1356 case CONF_RES_NOQUERY: 1357 peerversion |= RES_NOQUERY; 1358 break; 1359 1360 case CONF_RES_NOMODIFY: 1361 peerversion |= RES_NOMODIFY; 1362 break; 1363 1364 case CONF_RES_NOPEER: 1365 peerversion |= RES_NOPEER; 1366 break; 1367 1368 case CONF_RES_NOTRAP: 1369 peerversion |= RES_NOTRAP; 1370 break; 1371 1372 case CONF_RES_LPTRAP: 1373 peerversion |= RES_LPTRAP; 1374 break; 1375 1376 case CONF_RES_NTPPORT: 1377 peerkey |= RESM_NTPONLY; 1378 break; 1379 1380 case CONF_RES_VERSION: 1381 peerversion |= RES_VERSION; 1382 break; 1383 1384 case CONF_RES_DEMOBILIZE: 1385 peerversion |= RES_DEMOBILIZE; 1386 break; 1387 1388 case CONF_RES_LIMITED: 1389 peerversion |= RES_LIMITED; 1390 break; 1391 1392 case CONFIG_UNKNOWN: 1393 errflg++; 1394 break; 1395 } 1396 } 1397 if (SOCKNUL(&peeraddr)) 1398 ANYSOCK(&maskaddr); 1399 if (!errflg) 1400 hack_restrict(RESTRICT_FLAGS, &peeraddr, &maskaddr, 1401 (int)peerkey, peerversion); 1402 break; 1403 1404 case CONFIG_BDELAY: 1405 if (ntokens >= 2) { 1406 double tmp; 1407 1408 if (sscanf(tokens[1], "%lf", &tmp) != 1) { 1409 msyslog(LOG_ERR, 1410 "broadcastdelay value %s undecodable", 1411 tokens[1]); 1412 } else { 1413 proto_config(PROTO_BROADDELAY, 0, tmp, NULL); 1414 } 1415 } 1416 break; 1417 1418 case CONFIG_CDELAY: 1419 if (ntokens >= 2) { 1420 u_long ui; 1421 1422 if (sscanf(tokens[1], "%ld", &ui) != 1) 1423 msyslog(LOG_ERR, 1424 "illegal value - line ignored"); 1425 else 1426 proto_config(PROTO_CALLDELAY, ui, 0, NULL); 1427 } 1428 break; 1429 1430 case CONFIG_TRUSTEDKEY: 1431 for (i = 1; i < ntokens; i++) { 1432 keyid_t tkey; 1433 1434 tkey = atol(tokens[i]); 1435 if (tkey == 0) { 1436 msyslog(LOG_ERR, 1437 "trusted key %s unlikely", 1438 tokens[i]); 1439 } else { 1440 authtrust(tkey, 1); 1441 } 1442 } 1443 break; 1444 1445 case CONFIG_REQUESTKEY: 1446 if (ntokens >= 2) { 1447 if (!atouint(tokens[1], &ul)) { 1448 msyslog(LOG_ERR, 1449 "%s is undecodable as request key", 1450 tokens[1]); 1451 } else if (ul == 0) { 1452 msyslog(LOG_ERR, 1453 "%s makes a poor request keyid", 1454 tokens[1]); 1455 } else { 1456 #ifdef DEBUG 1457 if (debug > 3) 1458 printf( 1459 "set info_auth_key to %08lx\n", ul); 1460 #endif 1461 info_auth_keyid = (keyid_t)ul; 1462 } 1463 } 1464 break; 1465 1466 case CONFIG_CONTROLKEY: 1467 if (ntokens >= 2) { 1468 keyid_t ckey; 1469 1470 ckey = atol(tokens[1]); 1471 if (ckey == 0) { 1472 msyslog(LOG_ERR, 1473 "%s makes a poor control keyid", 1474 tokens[1]); 1475 } else { 1476 ctl_auth_keyid = ckey; 1477 } 1478 } 1479 break; 1480 1481 case CONFIG_TRAP: 1482 if (ntokens < 2) { 1483 msyslog(LOG_ERR, 1484 "no address for trap command, line ignored"); 1485 break; 1486 } 1487 istart = 1; 1488 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 1489 peeraddr.ss_family = default_ai_family; 1490 switch (matchkey(tokens[istart], addr_type, 0)) { 1491 case CONF_ADDR_IPV4: 1492 peeraddr.ss_family = AF_INET; 1493 istart++; 1494 break; 1495 case CONF_ADDR_IPV6: 1496 peeraddr.ss_family = AF_INET6; 1497 istart++; 1498 break; 1499 } 1500 1501 if (getnetnum(tokens[istart], &peeraddr, 1, t_UNK) != 1) 1502 break; 1503 1504 /* 1505 * Use peerversion for port number. Barf. 1506 */ 1507 errflg = 0; 1508 peerversion = 0; 1509 localaddr = 0; 1510 istart++; 1511 for (i = istart; i < ntokens-1; i++) 1512 switch (matchkey(tokens[i], trap_keywords, 1)) { 1513 case CONF_TRAP_PORT: 1514 if (i >= ntokens-1) { 1515 msyslog(LOG_ERR, 1516 "trap port requires an argument"); 1517 errflg = 1; 1518 break; 1519 } 1520 peerversion = atoi(tokens[++i]); 1521 if (peerversion <= 0 1522 || peerversion > 32767) { 1523 msyslog(LOG_ERR, 1524 "invalid port number %s, trap ignored", 1525 tokens[i]); 1526 errflg = 1; 1527 } 1528 break; 1529 1530 case CONF_TRAP_INTERFACE: 1531 if (i >= ntokens-1) { 1532 msyslog(LOG_ERR, 1533 "trap interface requires an argument"); 1534 errflg = 1; 1535 break; 1536 } 1537 1538 memset((char *)&maskaddr, 0, 1539 sizeof(maskaddr)); 1540 maskaddr.ss_family = peeraddr.ss_family; 1541 if (getnetnum(tokens[++i], 1542 &maskaddr, 1, t_UNK) != 1) { 1543 errflg = 1; 1544 break; 1545 } 1546 1547 localaddr = findinterface(&maskaddr); 1548 if (localaddr == NULL) { 1549 msyslog(LOG_ERR, 1550 "can't find interface with address %s", 1551 stoa(&maskaddr)); 1552 errflg = 1; 1553 } 1554 break; 1555 1556 case CONFIG_UNKNOWN: 1557 errflg++; 1558 break; 1559 } 1560 1561 if (!errflg) { 1562 if (peerversion != 0) 1563 ((struct sockaddr_in6*)&peeraddr)->sin6_port = htons( (u_short) peerversion); 1564 else 1565 ((struct sockaddr_in6*)&peeraddr)->sin6_port = htons(TRAPPORT); 1566 if (localaddr == NULL) 1567 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr); 1568 if (!ctlsettrap(&peeraddr, localaddr, 0, 1569 NTP_VERSION)) 1570 msyslog(LOG_ERR, 1571 "can't set trap for %s, no resources", 1572 stoa(&peeraddr)); 1573 } 1574 break; 1575 1576 case CONFIG_FUDGE: 1577 if (ntokens < 2) { 1578 msyslog(LOG_ERR, 1579 "no address for fudge command, line ignored"); 1580 break; 1581 } 1582 memset((char *)&peeraddr, 0, sizeof(peeraddr)); 1583 if (getnetnum(tokens[1], &peeraddr, 1, t_REF) != 1) 1584 break; 1585 1586 if (!ISREFCLOCKADR(&peeraddr)) { 1587 msyslog(LOG_ERR, 1588 "%s is inappropriate address for the fudge command, line ignored", 1589 stoa(&peeraddr)); 1590 break; 1591 } 1592 1593 memset((void *)&clock_stat, 0, sizeof clock_stat); 1594 fudgeflag = 0; 1595 errflg = 0; 1596 for (i = 2; i < ntokens-1; i++) { 1597 switch (c = matchkey(tokens[i], 1598 fudge_keywords, 1)) { 1599 case CONF_FDG_TIME1: 1600 if (sscanf(tokens[++i], "%lf", 1601 &clock_stat.fudgetime1) != 1) { 1602 msyslog(LOG_ERR, 1603 "fudge %s time1 value in error", 1604 stoa(&peeraddr)); 1605 errflg = i; 1606 break; 1607 } 1608 clock_stat.haveflags |= CLK_HAVETIME1; 1609 break; 1610 1611 case CONF_FDG_TIME2: 1612 if (sscanf(tokens[++i], "%lf", 1613 &clock_stat.fudgetime2) != 1) { 1614 msyslog(LOG_ERR, 1615 "fudge %s time2 value in error", 1616 stoa(&peeraddr)); 1617 errflg = i; 1618 break; 1619 } 1620 clock_stat.haveflags |= CLK_HAVETIME2; 1621 break; 1622 1623 1624 case CONF_FDG_STRATUM: 1625 if (!atoint(tokens[++i], &stratum)) 1626 { 1627 msyslog(LOG_ERR, 1628 "fudge %s stratum value in error", 1629 stoa(&peeraddr)); 1630 errflg = i; 1631 break; 1632 } 1633 clock_stat.fudgeval1 = stratum; 1634 clock_stat.haveflags |= CLK_HAVEVAL1; 1635 break; 1636 1637 case CONF_FDG_REFID: 1638 i++; 1639 memcpy(&clock_stat.fudgeval2, 1640 tokens[i], min(strlen(tokens[i]), 1641 4)); 1642 clock_stat.haveflags |= CLK_HAVEVAL2; 1643 break; 1644 1645 case CONF_FDG_FLAG1: 1646 case CONF_FDG_FLAG2: 1647 case CONF_FDG_FLAG3: 1648 case CONF_FDG_FLAG4: 1649 if (!atouint(tokens[++i], &fudgeflag) 1650 || fudgeflag > 1) { 1651 msyslog(LOG_ERR, 1652 "fudge %s flag value in error", 1653 stoa(&peeraddr)); 1654 errflg = i; 1655 break; 1656 } 1657 switch(c) { 1658 case CONF_FDG_FLAG1: 1659 c = CLK_FLAG1; 1660 clock_stat.haveflags|=CLK_HAVEFLAG1; 1661 break; 1662 case CONF_FDG_FLAG2: 1663 c = CLK_FLAG2; 1664 clock_stat.haveflags|=CLK_HAVEFLAG2; 1665 break; 1666 case CONF_FDG_FLAG3: 1667 c = CLK_FLAG3; 1668 clock_stat.haveflags|=CLK_HAVEFLAG3; 1669 break; 1670 case CONF_FDG_FLAG4: 1671 c = CLK_FLAG4; 1672 clock_stat.haveflags|=CLK_HAVEFLAG4; 1673 break; 1674 } 1675 if (fudgeflag == 0) 1676 clock_stat.flags &= ~c; 1677 else 1678 clock_stat.flags |= c; 1679 break; 1680 1681 case CONFIG_UNKNOWN: 1682 errflg = -1; 1683 break; 1684 } 1685 } 1686 1687 #ifdef REFCLOCK 1688 /* 1689 * If reference clock support isn't defined the 1690 * fudge line will still be accepted and syntax 1691 * checked, but will essentially do nothing. 1692 */ 1693 if (!errflg) { 1694 refclock_control(&peeraddr, &clock_stat, 1695 (struct refclockstat *)0); 1696 } 1697 #endif 1698 break; 1699 1700 case CONFIG_STATSDIR: 1701 if (ntokens >= 2) 1702 stats_config(STATS_STATSDIR,tokens[1]); 1703 break; 1704 1705 case CONFIG_STATISTICS: 1706 for (i = 1; i < ntokens; i++) { 1707 filegen = filegen_get(tokens[i]); 1708 1709 if (filegen == NULL) { 1710 msyslog(LOG_ERR, 1711 "no statistics named %s available", 1712 tokens[i]); 1713 continue; 1714 } 1715 #ifdef DEBUG 1716 if (debug > 3) 1717 printf("enabling filegen for %s statistics \"%s%s\"\n", 1718 tokens[i], filegen->prefix, filegen->basename); 1719 #endif 1720 filegen->flag |= FGEN_FLAG_ENABLED; 1721 } 1722 break; 1723 1724 case CONFIG_FILEGEN: 1725 if (ntokens < 2) { 1726 msyslog(LOG_ERR, 1727 "no id for filegen command, line ignored"); 1728 break; 1729 } 1730 1731 filegen = filegen_get(tokens[1]); 1732 if (filegen == NULL) { 1733 msyslog(LOG_ERR, 1734 "unknown filegen \"%s\" ignored", 1735 tokens[1]); 1736 break; 1737 } 1738 /* 1739 * peerversion is (ab)used for filegen file (index) 1740 * peerkey is (ab)used for filegen type 1741 * peerflags is (ab)used for filegen flags 1742 */ 1743 peerversion = 0; 1744 peerkey = filegen->type; 1745 peerflags = filegen->flag; 1746 errflg = 0; 1747 1748 for (i = 2; i < ntokens; i++) { 1749 switch (matchkey(tokens[i], 1750 filegen_keywords, 1)) { 1751 case CONF_FGEN_FILE: 1752 if (i >= ntokens - 1) { 1753 msyslog(LOG_ERR, 1754 "filegen %s file requires argument", 1755 tokens[1]); 1756 errflg = i; 1757 break; 1758 } 1759 peerversion = ++i; 1760 break; 1761 case CONF_FGEN_TYPE: 1762 if (i >= ntokens -1) { 1763 msyslog(LOG_ERR, 1764 "filegen %s type requires argument", 1765 tokens[1]); 1766 errflg = i; 1767 break; 1768 } 1769 peerkey = matchkey(tokens[++i], 1770 fgen_types, 1); 1771 if (peerkey == CONFIG_UNKNOWN) { 1772 msyslog(LOG_ERR, 1773 "filegen %s unknown type \"%s\"", 1774 tokens[1], tokens[i]); 1775 errflg = i; 1776 break; 1777 } 1778 break; 1779 1780 case CONF_FGEN_FLAG_LINK: 1781 peerflags |= FGEN_FLAG_LINK; 1782 break; 1783 1784 case CONF_FGEN_FLAG_NOLINK: 1785 peerflags &= ~FGEN_FLAG_LINK; 1786 break; 1787 1788 case CONF_FGEN_FLAG_ENABLE: 1789 peerflags |= FGEN_FLAG_ENABLED; 1790 break; 1791 1792 case CONF_FGEN_FLAG_DISABLE: 1793 peerflags &= ~FGEN_FLAG_ENABLED; 1794 break; 1795 } 1796 } 1797 if (!errflg) 1798 filegen_config(filegen, tokens[peerversion], 1799 (u_char)peerkey, (u_char)peerflags); 1800 break; 1801 1802 case CONFIG_SETVAR: 1803 if (ntokens < 2) { 1804 msyslog(LOG_ERR, 1805 "no value for setvar command - line ignored"); 1806 } else { 1807 set_sys_var(tokens[1], strlen(tokens[1])+1, 1808 (u_short) (RW | 1809 ((((ntokens > 2) 1810 && !strcmp(tokens[2], 1811 "default"))) 1812 ? DEF 1813 : 0))); 1814 } 1815 break; 1816 1817 case CONFIG_ENABLE: 1818 for (i = 1; i < ntokens; i++) { 1819 int flag; 1820 1821 flag = matchkey(tokens[i], flags_keywords, 1); 1822 if (flag == CONFIG_UNKNOWN) { 1823 msyslog(LOG_ERR, 1824 "enable unknown flag %s", 1825 tokens[i]); 1826 errflg = 1; 1827 break; 1828 } 1829 proto_config(flag, 1, 0., NULL); 1830 } 1831 break; 1832 1833 case CONFIG_DISABLE: 1834 for (i = 1; i < ntokens; i++) { 1835 int flag; 1836 1837 flag = matchkey(tokens[i], flags_keywords, 1); 1838 if (flag == CONFIG_UNKNOWN) { 1839 msyslog(LOG_ERR, 1840 "disable unknown flag %s", 1841 tokens[i]); 1842 errflg = 1; 1843 break; 1844 } 1845 proto_config(flag, 0, 0., NULL); 1846 } 1847 break; 1848 1849 case CONFIG_PHONE: 1850 for (i = 1; i < ntokens && i < MAXPHONE - 1; i++) { 1851 sys_phone[i - 1] = 1852 emalloc(strlen(tokens[i]) + 1); 1853 strcpy(sys_phone[i - 1], tokens[i]); 1854 } 1855 sys_phone[i] = NULL; 1856 break; 1857 1858 case CONFIG_ADJ: { 1859 double ftemp; 1860 1861 sscanf(tokens[1], "%lf", &ftemp); 1862 proto_config(PROTO_ADJ, 0, ftemp, NULL); 1863 } 1864 break; 1865 1866 } 1867 } 1868 if (fp[0]) 1869 (void)fclose(fp[0]); 1870 1871 #ifdef HAVE_NETINFO 1872 if (config_netinfo) 1873 free_netinfo_config(config_netinfo); 1874 #endif /* HAVE_NETINFO */ 1875 1876 #if !defined(VMS) && !defined(SYS_VXWORKS) 1877 /* find a keyid */ 1878 if (info_auth_keyid == 0) 1879 req_keyid = 65535; 1880 else 1881 req_keyid = info_auth_keyid; 1882 1883 /* if doesn't exist, make up one at random */ 1884 if (!authhavekey(req_keyid)) { 1885 char rankey[9]; 1886 int j; 1887 1888 for (i = 0; i < 8; i++) 1889 for (j = 1; j < 100; ++j) { 1890 rankey[i] = (char) (arc4random() & 0xff); 1891 if (rankey[i] != 0) break; 1892 } 1893 rankey[8] = 0; 1894 authusekey(req_keyid, KEY_TYPE_MD5, (u_char *)rankey); 1895 authtrust(req_keyid, 1); 1896 if (!authhavekey(req_keyid)) { 1897 msyslog(LOG_ERR, "getconfig: Couldn't generate a valid random key!"); 1898 /* HMS: Should this be fatal? */ 1899 } 1900 } 1901 1902 /* save keyid so we will accept config requests with it */ 1903 info_auth_keyid = req_keyid; 1904 #endif /* !defined(VMS) && !defined(SYS_VXWORKS) */ 1905 1906 if (res_fp != NULL) { 1907 if (call_resolver) { 1908 /* 1909 * Need name resolution 1910 */ 1911 do_resolve_internal(); 1912 } 1913 } 1914 } 1915 1916 1917 #ifdef HAVE_NETINFO 1918 1919 /* 1920 * get_netinfo_config - find the nearest NetInfo domain with an ntp 1921 * configuration and initialize the configuration state. 1922 */ 1923 static struct netinfo_config_state * 1924 get_netinfo_config() 1925 { 1926 ni_status status; 1927 void *domain; 1928 ni_id config_dir; 1929 struct netinfo_config_state *config; 1930 1931 if (ni_open(NULL, ".", &domain) != NI_OK) return NULL; 1932 1933 while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) { 1934 void *next_domain; 1935 if (ni_open(domain, "..", &next_domain) != NI_OK) { 1936 ni_free(next_domain); 1937 break; 1938 } 1939 ni_free(domain); 1940 domain = next_domain; 1941 } 1942 if (status != NI_OK) { 1943 ni_free(domain); 1944 return NULL; 1945 } 1946 1947 config = (struct netinfo_config_state *)malloc(sizeof(struct netinfo_config_state)); 1948 config->domain = domain; 1949 config->config_dir = config_dir; 1950 config->prop_index = 0; 1951 config->val_index = 0; 1952 config->val_list = NULL; 1953 1954 return config; 1955 } 1956 1957 1958 1959 /* 1960 * free_netinfo_config - release NetInfo configuration state 1961 */ 1962 static void 1963 free_netinfo_config(struct netinfo_config_state *config) 1964 { 1965 ni_free(config->domain); 1966 free(config); 1967 } 1968 1969 1970 1971 /* 1972 * gettokens_netinfo - return tokens from NetInfo 1973 */ 1974 static int 1975 gettokens_netinfo ( 1976 struct netinfo_config_state *config, 1977 char **tokenlist, 1978 int *ntokens 1979 ) 1980 { 1981 int prop_index = config->prop_index; 1982 int val_index = config->val_index; 1983 char **val_list = config->val_list; 1984 1985 /* 1986 * Iterate through each keyword and look for a property that matches it. 1987 */ 1988 again: 1989 if (!val_list) { 1990 for (; prop_index < (sizeof(keywords)/sizeof(keywords[0])); prop_index++) 1991 { 1992 ni_namelist namelist; 1993 struct keyword current_prop = keywords[prop_index]; 1994 1995 /* 1996 * For each value associated in the property, we're going to return 1997 * a separate line. We squirrel away the values in the config state 1998 * so the next time through, we don't need to do this lookup. 1999 */ 2000 NI_INIT(&namelist); 2001 if (ni_lookupprop(config->domain, &config->config_dir, current_prop.text, &namelist) == NI_OK) { 2002 ni_index index; 2003 2004 /* Found the property, but it has no values */ 2005 if (namelist.ni_namelist_len == 0) continue; 2006 2007 if (! (val_list = config->val_list = (char**)malloc(sizeof(char*) * (namelist.ni_namelist_len + 1)))) 2008 { msyslog(LOG_ERR, "out of memory while configuring"); break; } 2009 2010 for (index = 0; index < namelist.ni_namelist_len; index++) { 2011 char *value = namelist.ni_namelist_val[index]; 2012 2013 if (! (val_list[index] = (char*)malloc(strlen(value)+1))) 2014 { msyslog(LOG_ERR, "out of memory while configuring"); break; } 2015 2016 strcpy(val_list[index], value); 2017 } 2018 val_list[index] = NULL; 2019 2020 break; 2021 } 2022 ni_namelist_free(&namelist); 2023 } 2024 config->prop_index = prop_index; 2025 } 2026 2027 /* No list; we're done here. */ 2028 if (!val_list) return CONFIG_UNKNOWN; 2029 2030 /* 2031 * We have a list of values for the current property. 2032 * Iterate through them and return each in order. 2033 */ 2034 if (val_list[val_index]) 2035 { 2036 int ntok = 1; 2037 int quoted = 0; 2038 char *tokens = val_list[val_index]; 2039 2040 msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]); 2041 2042 (const char*)tokenlist[0] = keywords[prop_index].text; 2043 for (ntok = 1; ntok < MAXTOKENS; ntok++) { 2044 tokenlist[ntok] = tokens; 2045 while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted)) 2046 quoted ^= (*tokens++ == '"'); 2047 2048 if (ISEOL(*tokens)) { 2049 *tokens = '\0'; 2050 break; 2051 } else { /* must be space */ 2052 *tokens++ = '\0'; 2053 while (ISSPACE(*tokens)) tokens++; 2054 if (ISEOL(*tokens)) break; 2055 } 2056 } 2057 2058 if (ntok == MAXTOKENS) { 2059 /* HMS: chomp it to lose the EOL? */ 2060 msyslog(LOG_ERR, 2061 "gettokens_netinfo: too many tokens. Ignoring: %s", 2062 tokens); 2063 } else { 2064 *ntokens = ntok + 1; 2065 } 2066 2067 config->val_index++; /* HMS: Should this be in the 'else'? */ 2068 2069 return keywords[prop_index].keytype; 2070 } 2071 2072 /* We're done with the current property. */ 2073 prop_index = ++config->prop_index; 2074 2075 /* Free val_list and reset counters. */ 2076 for (val_index = 0; val_list[val_index]; val_index++) 2077 free(val_list[val_index]); 2078 free(val_list); val_list = config->val_list = NULL; val_index = config->val_index = 0; 2079 2080 goto again; 2081 } 2082 2083 #endif /* HAVE_NETINFO */ 2084 2085 2086 /* 2087 * gettokens - read a line and return tokens 2088 */ 2089 static int 2090 gettokens ( 2091 FILE *fp, 2092 char *line, 2093 char **tokenlist, 2094 int *ntokens 2095 ) 2096 { 2097 register char *cp; 2098 register int ntok; 2099 register int quoted = 0; 2100 2101 /* 2102 * Find start of first token 2103 */ 2104 again: 2105 while ((cp = fgets(line, MAXLINE, fp)) != NULL) { 2106 cp = line; 2107 while (ISSPACE(*cp)) 2108 cp++; 2109 if (!ISEOL(*cp)) 2110 break; 2111 } 2112 if (cp == NULL) { 2113 *ntokens = 0; 2114 return CONFIG_UNKNOWN; /* hack. Is recognized as EOF */ 2115 } 2116 2117 /* 2118 * Now separate out the tokens 2119 */ 2120 for (ntok = 0; ntok < MAXTOKENS; ntok++) { 2121 tokenlist[ntok] = cp; 2122 while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted)) 2123 quoted ^= (*cp++ == '"'); 2124 2125 if (ISEOL(*cp)) { 2126 *cp = '\0'; 2127 break; 2128 } else { /* must be space */ 2129 *cp++ = '\0'; 2130 while (ISSPACE(*cp)) 2131 cp++; 2132 if (ISEOL(*cp)) 2133 break; 2134 } 2135 } 2136 2137 /* Heiko: Remove leading and trailing quotes around tokens */ 2138 { 2139 int i,j = 0; 2140 2141 2142 for (i = 0; i < ntok; i++) { 2143 /* Now check if the first char is a quote and remove that */ 2144 if ( tokenlist[ntok][0] == '"' ) 2145 tokenlist[ntok]++; 2146 2147 /* Now check the last char ... */ 2148 j = strlen(tokenlist[ntok])-1; 2149 if ( tokenlist[ntok][j] == '"' ) 2150 tokenlist[ntok][j] = '\0'; 2151 } 2152 2153 } 2154 2155 if (ntok == MAXTOKENS) { 2156 --ntok; 2157 /* HMS: chomp it to lose the EOL? */ 2158 msyslog(LOG_ERR, 2159 "gettokens: too many tokens on the line. Ignoring %s", 2160 cp); 2161 } else { 2162 /* 2163 * Return the match 2164 */ 2165 *ntokens = ntok + 1; 2166 ntok = matchkey(tokenlist[0], keywords, 1); 2167 if (ntok == CONFIG_UNKNOWN) 2168 goto again; 2169 } 2170 2171 return ntok; 2172 } 2173 2174 2175 2176 /* 2177 * matchkey - match a keyword to a list 2178 */ 2179 static int 2180 matchkey( 2181 register char *word, 2182 register struct keyword *keys, 2183 int complain 2184 ) 2185 { 2186 for (;;) { 2187 if (keys->keytype == CONFIG_UNKNOWN) { 2188 if (complain) 2189 msyslog(LOG_ERR, 2190 "configure: keyword \"%s\" unknown, line ignored", 2191 word); 2192 return CONFIG_UNKNOWN; 2193 } 2194 if (STRSAME(word, keys->text)) 2195 return keys->keytype; 2196 keys++; 2197 } 2198 } 2199 2200 2201 /* 2202 * getnetnum - return a net number (this is crude, but careful) 2203 */ 2204 static int 2205 getnetnum( 2206 const char *num, 2207 struct sockaddr_storage *addr, 2208 int complain, 2209 enum gnn_type a_type 2210 ) 2211 { 2212 struct addrinfo hints; 2213 struct addrinfo *ptr; 2214 int retval; 2215 2216 #if 0 2217 printf("getnetnum: <%s> is a %s (%d)\n", 2218 num, 2219 (a_type == t_UNK) 2220 ? "t_UNK" 2221 : (a_type == t_REF) 2222 ? "t_REF" 2223 : (a_type == t_MSK) 2224 ? "t_MSK" 2225 : "???", 2226 a_type); 2227 #endif 2228 2229 /* Get host address. Looking for UDP datagram connection */ 2230 memset(&hints, 0, sizeof (hints)); 2231 if (addr->ss_family == AF_INET || addr->ss_family == AF_INET6) 2232 hints.ai_family = addr->ss_family; 2233 else 2234 hints.ai_family = AF_UNSPEC; 2235 /* 2236 * If we don't have an IPv6 stack, just look up IPv4 addresses 2237 */ 2238 if (isc_net_probeipv6() != ISC_R_SUCCESS) 2239 hints.ai_family = AF_INET; 2240 2241 hints.ai_socktype = SOCK_DGRAM; 2242 2243 if (a_type != t_UNK) { 2244 hints.ai_flags = AI_NUMERICHOST; 2245 } 2246 2247 #ifdef DEBUG 2248 if (debug > 3) 2249 printf("getnetnum: calling getaddrinfo(%s,...)\n", num); 2250 #endif 2251 retval = getaddrinfo(num, "ntp", &hints, &ptr); 2252 if (retval != 0 || 2253 (ptr->ai_family == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) { 2254 if (complain) 2255 msyslog(LOG_ERR, 2256 "getaddrinfo: \"%s\" invalid host address, ignored", 2257 num); 2258 #ifdef DEBUG 2259 if (debug > 0) 2260 printf( 2261 "getaddrinfo: \"%s\" invalid host address%s.\n", 2262 num, (complain) 2263 ? ", ignored" 2264 : ""); 2265 #endif 2266 if (retval == 0 && 2267 ptr->ai_family == AF_INET6 && 2268 isc_net_probeipv6() != ISC_R_SUCCESS) 2269 { 2270 return -1; 2271 } 2272 else { 2273 return 0; 2274 } 2275 } 2276 2277 memcpy(addr, ptr->ai_addr, ptr->ai_addrlen); 2278 #ifdef DEBUG 2279 if (debug > 1) 2280 printf("getnetnum given %s, got %s (%s/%d)\n", 2281 num, stoa(addr), 2282 (a_type == t_UNK) 2283 ? "t_UNK" 2284 : (a_type == t_REF) 2285 ? "t_REF" 2286 : (a_type == t_MSK) 2287 ? "t_MSK" 2288 : "???", 2289 a_type); 2290 #endif 2291 freeaddrinfo(ptr); 2292 return 1; 2293 } 2294 2295 2296 #if !defined(VMS) && !defined(SYS_WINNT) 2297 /* 2298 * catchchild - receive the resolver's exit status 2299 */ 2300 static RETSIGTYPE 2301 catchchild( 2302 int sig 2303 ) 2304 { 2305 /* 2306 * We only start up one child, and if we're here 2307 * it should have already exited. Hence the following 2308 * shouldn't hang. If it does, please tell me. 2309 */ 2310 #if !defined (SYS_WINNT) && !defined(SYS_VXWORKS) 2311 (void) wait(0); 2312 #endif /* SYS_WINNT && VXWORKS*/ 2313 } 2314 #endif /* VMS */ 2315 2316 2317 /* 2318 * save_resolve - save configuration info into a file for later name resolution 2319 */ 2320 static void 2321 save_resolve( 2322 char *name, 2323 int mode, 2324 int version, 2325 int minpoll, 2326 int maxpoll, 2327 u_int flags, 2328 int ttl, 2329 keyid_t keyid, 2330 u_char *keystr, 2331 u_char peeraf 2332 ) 2333 { 2334 #ifndef SYS_VXWORKS 2335 if (res_fp == NULL) { 2336 #ifndef SYS_WINNT 2337 (void) strcpy(res_file, RES_TEMPFILE); 2338 #else 2339 /* no /tmp directory under NT */ 2340 { 2341 if(!(GetTempPath((DWORD)MAX_PATH, (LPTSTR)res_file))) { 2342 msyslog(LOG_ERR, "cannot get pathname for temporary directory: %m"); 2343 return; 2344 } 2345 (void) strcat(res_file, "ntpdXXXXXX"); 2346 } 2347 #endif /* SYS_WINNT */ 2348 #ifdef HAVE_MKSTEMP 2349 { 2350 int fd; 2351 2352 res_fp = NULL; 2353 if ((fd = mkstemp(res_file)) != -1) 2354 res_fp = fdopen(fd, "r+"); 2355 } 2356 #else 2357 (void) mktemp(res_file); 2358 res_fp = fopen(res_file, "w"); 2359 #endif 2360 if (res_fp == NULL) { 2361 msyslog(LOG_ERR, "open failed for %s: %m", res_file); 2362 return; 2363 } 2364 } 2365 #ifdef DEBUG 2366 if (debug) { 2367 printf("resolving %s\n", name); 2368 } 2369 #endif 2370 2371 (void)fprintf(res_fp, "%s %u %d %d %d %d %d %d %u %s\n", name, peeraf, 2372 mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr); 2373 #ifdef DEBUG 2374 if (debug > 1) 2375 printf("config: %s %u %d %d %d %d %x %d %u %s\n", name, peeraf, mode, 2376 version, minpoll, maxpoll, flags, ttl, keyid, keystr); 2377 #endif 2378 2379 #else /* SYS_VXWORKS */ 2380 /* save resolve info to a struct */ 2381 #endif /* SYS_VXWORKS */ 2382 } 2383 2384 2385 /* 2386 * abort_resolve - terminate the resolver stuff and delete the file 2387 */ 2388 static void 2389 abort_resolve(void) 2390 { 2391 /* 2392 * In an ideal world we would might reread the file and 2393 * log the hosts which aren't getting configured. Since 2394 * this is too much work, however, just close and delete 2395 * the temp file. 2396 */ 2397 if (res_fp != NULL) 2398 (void) fclose(res_fp); 2399 res_fp = NULL; 2400 2401 #ifndef SYS_VXWORKS /* we don't open the file to begin with */ 2402 #if !defined(VMS) 2403 (void) unlink(res_file); 2404 #else 2405 (void) delete(res_file); 2406 #endif /* VMS */ 2407 #endif /* SYS_VXWORKS */ 2408 } 2409 2410 2411 /* 2412 * do_resolve_internal - start up the resolver function (not program) 2413 */ 2414 /* 2415 * On VMS, this routine will simply refuse to resolve anything. 2416 * 2417 * Possible implementation: keep `res_file' in memory, do async 2418 * name resolution via QIO, update from within completion AST. 2419 * I'm unlikely to find the time for doing this, though. -wjm 2420 */ 2421 static void 2422 do_resolve_internal(void) 2423 { 2424 int i; 2425 2426 if (res_fp == NULL) { 2427 /* belch */ 2428 msyslog(LOG_ERR, 2429 "do_resolve_internal: Fatal: res_fp == NULL"); 2430 exit(1); 2431 } 2432 2433 /* we are done with this now */ 2434 (void) fclose(res_fp); 2435 res_fp = NULL; 2436 2437 #if !defined(VMS) && !defined (SYS_VXWORKS) 2438 req_file = res_file; /* set up pointer to res file */ 2439 #ifndef SYS_WINNT 2440 (void) signal_no_reset(SIGCHLD, catchchild); 2441 2442 #ifndef SYS_VXWORKS 2443 /* the parent process will write to the pipe 2444 * in order to wake up to child process 2445 * which may be waiting in a select() call 2446 * on the read fd */ 2447 if (pipe(resolver_pipe_fd) < 0) { 2448 msyslog(LOG_ERR, 2449 "unable to open resolver pipe"); 2450 exit(1); 2451 } 2452 2453 i = fork(); 2454 /* Shouldn't the code below be re-ordered? 2455 * I.e. first check if the fork() returned an error, then 2456 * check whether we're parent or child. 2457 * Martin Burnicki 2458 */ 2459 if (i == 0) { 2460 /* 2461 * this used to close everything 2462 * I don't think this is necessary 2463 */ 2464 /* 2465 * To the unknown commenter above: 2466 * Well, I think it's better to clean up 2467 * after oneself. I have had problems with 2468 * refclock-io when intres was running - things 2469 * where fine again when ntpintres was gone. 2470 * So some systems react erratic at least. 2471 * 2472 * Frank Kardel 2473 * 2474 * 94-11-16: 2475 * Further debugging has proven that the above is 2476 * absolutely harmful. The internal resolver 2477 * is still in the SIGIO process group and the lingering 2478 * async io information causes it to process requests from 2479 * all file decriptor causing a race between the NTP daemon 2480 * and the resolver. which then eats data when it wins 8-(. 2481 * It is absolutly necessary to kill any IO associations 2482 * shared with the NTP daemon. 2483 * 2484 * We also block SIGIO (currently no ports means to 2485 * disable the signal handle for IO). 2486 * 2487 * Thanks to wgstuken@informatik.uni-erlangen.de to notice 2488 * that it is the ntp-resolver child running into trouble. 2489 * 2490 * THUS: 2491 */ 2492 2493 /* This is the child process who will read the pipe, 2494 * so we close the write fd */ 2495 close(resolver_pipe_fd[1]); 2496 closelog(); 2497 kill_asyncio(0); 2498 2499 (void) signal_no_reset(SIGCHLD, SIG_DFL); 2500 2501 #ifdef DEBUG 2502 if (0) 2503 debug = 2; 2504 #endif 2505 2506 # ifndef LOG_DAEMON 2507 openlog("ntpd_initres", LOG_PID); 2508 # else /* LOG_DAEMON */ 2509 2510 # ifndef LOG_NTP 2511 # define LOG_NTP LOG_DAEMON 2512 # endif 2513 openlog("ntpd_initres", LOG_PID | LOG_NDELAY, LOG_NTP); 2514 #ifndef SYS_CYGWIN32 2515 # ifdef DEBUG 2516 if (debug) 2517 setlogmask(LOG_UPTO(LOG_DEBUG)); 2518 else 2519 # endif /* DEBUG */ 2520 setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ 2521 # endif /* LOG_DAEMON */ 2522 #endif 2523 2524 ntp_intres(); 2525 2526 /* 2527 * If we got here, the intres code screwed up. 2528 * Print something so we don't die without complaint 2529 */ 2530 msyslog(LOG_ERR, "call to ntp_intres lost"); 2531 abort_resolve(); 2532 exit(1); 2533 } 2534 #else 2535 /* vxWorks spawns a thread... -casey */ 2536 i = sp (ntp_intres); 2537 /*i = taskSpawn("ntp_intres",100,VX_FP_TASK,20000,ntp_intres);*/ 2538 #endif 2539 if (i == -1) { 2540 msyslog(LOG_ERR, "fork() failed, can't start ntp_intres: %m"); 2541 (void) signal_no_reset(SIGCHLD, SIG_DFL); 2542 abort_resolve(); 2543 } 2544 else { 2545 /* This is the parent process who will write to the pipe, 2546 * so we close the read fd */ 2547 close(resolver_pipe_fd[0]); 2548 } 2549 #else /* SYS_WINNT */ 2550 { 2551 /* NT's equivalent of fork() is _spawn(), but the start point 2552 * of the new process is an executable filename rather than 2553 * a function name as desired here. 2554 */ 2555 DWORD dwThreadId; 2556 fflush(stdout); 2557 ResolverEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); 2558 if (ResolverEventHandle == NULL) { 2559 msyslog(LOG_ERR, "Unable to create resolver event object, can't start ntp_intres"); 2560 abort_resolve(); 2561 } 2562 ResolverThreadHandle = CreateThread( 2563 NULL, /* no security attributes */ 2564 0, /* use default stack size */ 2565 (LPTHREAD_START_ROUTINE) ntp_intres, /* thread function */ 2566 NULL, /* argument to thread function */ 2567 0, /* use default creation flags */ 2568 &dwThreadId); /* returns the thread identifier */ 2569 if (ResolverThreadHandle == NULL) { 2570 msyslog(LOG_ERR, "CreateThread() failed, can't start ntp_intres"); 2571 CloseHandle(ResolverEventHandle); 2572 ResolverEventHandle = NULL; 2573 abort_resolve(); 2574 } 2575 } 2576 #endif /* SYS_WINNT */ 2577 #else /* VMS VX_WORKS */ 2578 msyslog(LOG_ERR, 2579 "Name resolution not implemented for VMS - use numeric addresses"); 2580 abort_resolve(); 2581 #endif /* VMS VX_WORKS */ 2582 } 2583