diff options
Diffstat (limited to 'contrib/ntp/ntpd/ntp_config.c')
-rw-r--r-- | contrib/ntp/ntpd/ntp_config.c | 2371 |
1 files changed, 0 insertions, 2371 deletions
diff --git a/contrib/ntp/ntpd/ntp_config.c b/contrib/ntp/ntpd/ntp_config.c deleted file mode 100644 index f1428b1..0000000 --- a/contrib/ntp/ntpd/ntp_config.c +++ /dev/null @@ -1,2371 +0,0 @@ -/* - * ntp_config.c - read and apply configuration information - */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#ifdef HAVE_NETINFO -# include <netinfo/ni.h> -#endif - -#include "ntpd.h" -#include "ntp_io.h" -#include "ntp_unixtime.h" -#include "ntp_refclock.h" -#include "ntp_filegen.h" -#include "ntp_stdlib.h" -#include "ntp_config.h" -#include "ntp_cmdargs.h" - -#include <stdio.h> -#include <ctype.h> -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#include <signal.h> -#ifndef SIGCHLD -# define SIGCHLD SIGCLD -#endif -#if !defined(VMS) -# ifdef HAVE_SYS_WAIT_H -# include <sys/wait.h> -# endif -#endif /* VMS */ - -#ifdef SYS_WINNT -# include <io.h> -extern HANDLE ResolverThreadHandle; -#endif /* SYS_WINNT */ - -#include <netdb.h> - -extern int priority_done; - -/* - * These routines are used to read the configuration file at - * startup time. An entry in the file must fit on a single line. - * Entries are processed as multiple tokens separated by white space - * Lines are considered terminated when a '#' is encountered. Blank - * lines are ignored. - */ -/* - * Translation table - keywords to function index - */ -struct keyword { - const char *text; - int keytype; -}; - -/* - * Command keywords - */ -static struct keyword keywords[] = { - { "automax", CONFIG_AUTOMAX }, - { "broadcast", CONFIG_BROADCAST }, - { "broadcastclient", CONFIG_BROADCASTCLIENT }, - { "broadcastdelay", CONFIG_BDELAY }, - { "calldelay", CONFIG_CDELAY}, -#ifdef OPENSSL - { "crypto", CONFIG_CRYPTO }, -#endif /* OPENSSL */ - { "controlkey", CONFIG_CONTROLKEY }, - { "disable", CONFIG_DISABLE }, - { "driftfile", CONFIG_DRIFTFILE }, - { "enable", CONFIG_ENABLE }, - { "filegen", CONFIG_FILEGEN }, - { "fudge", CONFIG_FUDGE }, - { "includefile", CONFIG_INCLUDEFILE }, - { "keys", CONFIG_KEYS }, - { "keysdir", CONFIG_KEYSDIR }, - { "logconfig", CONFIG_LOGCONFIG }, - { "logfile", CONFIG_LOGFILE }, - { "manycastclient", CONFIG_MANYCASTCLIENT }, - { "manycastserver", CONFIG_MANYCASTSERVER }, - { "multicastclient", CONFIG_MULTICASTCLIENT }, - { "peer", CONFIG_PEER }, - { "phone", CONFIG_PHONE }, - { "pidfile", CONFIG_PIDFILE }, - { "discard", CONFIG_DISCARD }, - { "requestkey", CONFIG_REQUESTKEY }, - { "restrict", CONFIG_RESTRICT }, - { "revoke", CONFIG_REVOKE }, - { "server", CONFIG_SERVER }, - { "setvar", CONFIG_SETVAR }, - { "statistics", CONFIG_STATISTICS }, - { "statsdir", CONFIG_STATSDIR }, - { "tick", CONFIG_ADJ }, - { "tinker", CONFIG_TINKER }, - { "tos", CONFIG_TOS }, - { "trap", CONFIG_TRAP }, - { "trustedkey", CONFIG_TRUSTEDKEY }, - { "ttl", CONFIG_TTL }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "peer", "server", "broadcast" modifier keywords - */ -static struct keyword mod_keywords[] = { - { "autokey", CONF_MOD_SKEY }, - { "burst", CONF_MOD_BURST }, - { "iburst", CONF_MOD_IBURST }, - { "key", CONF_MOD_KEY }, - { "maxpoll", CONF_MOD_MAXPOLL }, - { "minpoll", CONF_MOD_MINPOLL }, - { "mode", CONF_MOD_MODE }, /* refclocks */ - { "noselect", CONF_MOD_NOSELECT }, - { "prefer", CONF_MOD_PREFER }, - { "ttl", CONF_MOD_TTL }, /* NTP peers */ - { "version", CONF_MOD_VERSION }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "restrict" modifier keywords - */ -static struct keyword res_keywords[] = { - { "ignore", CONF_RES_IGNORE }, - { "limited", CONF_RES_LIMITED }, - { "kod", CONF_RES_DEMOBILIZE }, - { "lowpriotrap", CONF_RES_LPTRAP }, - { "mask", CONF_RES_MASK }, - { "nomodify", CONF_RES_NOMODIFY }, - { "nopeer", CONF_RES_NOPEER }, - { "noquery", CONF_RES_NOQUERY }, - { "noserve", CONF_RES_NOSERVE }, - { "notrap", CONF_RES_NOTRAP }, - { "notrust", CONF_RES_NOTRUST }, - { "ntpport", CONF_RES_NTPPORT }, - { "version", CONF_RES_VERSION }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "trap" modifier keywords - */ -static struct keyword trap_keywords[] = { - { "port", CONF_TRAP_PORT }, - { "interface", CONF_TRAP_INTERFACE }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "fudge" modifier keywords - */ -static struct keyword fudge_keywords[] = { - { "flag1", CONF_FDG_FLAG1 }, - { "flag2", CONF_FDG_FLAG2 }, - { "flag3", CONF_FDG_FLAG3 }, - { "flag4", CONF_FDG_FLAG4 }, - { "refid", CONF_FDG_REFID }, - { "stratum", CONF_FDG_STRATUM }, - { "time1", CONF_FDG_TIME1 }, - { "time2", CONF_FDG_TIME2 }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "filegen" modifier keywords - */ -static struct keyword filegen_keywords[] = { - { "disable", CONF_FGEN_FLAG_DISABLE }, - { "enable", CONF_FGEN_FLAG_ENABLE }, - { "file", CONF_FGEN_FILE }, - { "link", CONF_FGEN_FLAG_LINK }, - { "nolink", CONF_FGEN_FLAG_NOLINK }, - { "type", CONF_FGEN_TYPE }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "type" modifier keywords - */ -static struct keyword fgen_types[] = { - { "age", FILEGEN_AGE }, - { "day", FILEGEN_DAY }, - { "month", FILEGEN_MONTH }, - { "none", FILEGEN_NONE }, - { "pid", FILEGEN_PID }, - { "week", FILEGEN_WEEK }, - { "year", FILEGEN_YEAR }, - { "", CONFIG_UNKNOWN} -}; - -/* - * "enable", "disable" modifier keywords - */ -static struct keyword flags_keywords[] = { - { "auth", PROTO_AUTHENTICATE }, - { "bclient", PROTO_BROADCLIENT }, - { "calibrate", PROTO_CAL }, - { "kernel", PROTO_KERNEL }, - { "monitor", PROTO_MONITOR }, - { "ntp", PROTO_NTP }, - { "pps", PROTO_PPS }, - { "stats", PROTO_FILEGEN }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "discard" modifier keywords - */ -static struct keyword discard_keywords[] = { - { "average", CONF_DISCARD_AVERAGE }, - { "minimum", CONF_DISCARD_MINIMUM }, - { "monitor", CONF_DISCARD_MONITOR }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "tinker" modifier keywords - */ -static struct keyword tinker_keywords[] = { - { "step", CONF_CLOCK_MAX }, - { "panic", CONF_CLOCK_PANIC }, - { "dispersion", CONF_CLOCK_PHI }, - { "stepout", CONF_CLOCK_MINSTEP }, - { "allan", CONF_CLOCK_ALLAN }, - { "huffpuff", CONF_CLOCK_HUFFPUFF }, - { "freq", CONF_CLOCK_FREQ }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "tos" modifier keywords - */ -static struct keyword tos_keywords[] = { - { "minclock", CONF_TOS_MINCLOCK }, - { "minsane", CONF_TOS_MINSANE }, - { "floor", CONF_TOS_FLOOR }, - { "ceiling", CONF_TOS_CEILING }, - { "cohort", CONF_TOS_COHORT }, - { "", CONFIG_UNKNOWN } -}; - -#ifdef OPENSSL -/* - * "crypto" modifier keywords - */ -static struct keyword crypto_keywords[] = { - { "cert", CONF_CRYPTO_CERT }, - { "gqpar", CONF_CRYPTO_GQPAR }, - { "host", CONF_CRYPTO_RSA }, - { "iffpar", CONF_CRYPTO_IFFPAR }, - { "leap", CONF_CRYPTO_LEAP }, - { "mvpar", CONF_CRYPTO_MVPAR }, - { "pw", CONF_CRYPTO_PW }, - { "randfile", CONF_CRYPTO_RAND }, - { "sign", CONF_CRYPTO_SIGN }, - { "", CONFIG_UNKNOWN } -}; -#endif /* OPENSSL */ - -/* - * Address type selection, IPv4 or IPv4. - * Used on various lines. - */ -static struct keyword addr_type[] = { - { "-4", CONF_ADDR_IPV4 }, - { "-6", CONF_ADDR_IPV6 }, - { "", CONFIG_UNKNOWN } -}; - -/* - * "logconfig" building blocks - */ -struct masks { - const char *name; - unsigned long mask; -}; - -static struct masks logcfg_class[] = { - { "clock", NLOG_OCLOCK }, - { "peer", NLOG_OPEER }, - { "sync", NLOG_OSYNC }, - { "sys", NLOG_OSYS }, - { (char *)0, 0 } -}; - -static struct masks logcfg_item[] = { - { "info", NLOG_INFO }, - { "allinfo", NLOG_SYSINFO|NLOG_PEERINFO|NLOG_CLOCKINFO|NLOG_SYNCINFO }, - { "events", NLOG_EVENT }, - { "allevents", NLOG_SYSEVENT|NLOG_PEEREVENT|NLOG_CLOCKEVENT|NLOG_SYNCEVENT }, - { "status", NLOG_STATUS }, - { "allstatus", NLOG_SYSSTATUS|NLOG_PEERSTATUS|NLOG_CLOCKSTATUS|NLOG_SYNCSTATUS }, - { "statistics", NLOG_STATIST }, - { "allstatistics", NLOG_SYSSTATIST|NLOG_PEERSTATIST|NLOG_CLOCKSTATIST|NLOG_SYNCSTATIST }, - { "allclock", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OCLOCK }, - { "allpeer", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OPEER }, - { "allsys", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYS }, - { "allsync", (NLOG_INFO|NLOG_STATIST|NLOG_EVENT|NLOG_STATUS)<<NLOG_OSYNC }, - { "all", NLOG_SYSMASK|NLOG_PEERMASK|NLOG_CLOCKMASK|NLOG_SYNCMASK }, - { (char *)0, 0 } -}; - -/* - * Limits on things - */ -#define MAXTOKENS 20 /* 20 tokens on line */ -#define MAXLINE 1024 /* maximum length of line */ -#define MAXPHONE 5 /* maximum number of phone strings */ -#define MAXPPS 20 /* maximum length of PPS device string */ -#define MAXINCLUDELEVEL 5 /* maximum include file levels */ - -/* - * Miscellaneous macros - */ -#define STRSAME(s1, s2) (*(s1) == *(s2) && strcmp((s1), (s2)) == 0) -#define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0') -#define ISSPACE(c) ((c) == ' ' || (c) == '\t') -#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) - -#define KEY_TYPE_MD5 4 - -/* - * File descriptor used by the resolver save routines, and temporary file - * name. - */ -int call_resolver = 1; /* ntp-genkeys sets this to 0, for example */ -static FILE *res_fp; -#ifndef SYS_WINNT -static char res_file[20]; /* enough for /tmp/ntpXXXXXX\0 */ -#define RES_TEMPFILE "/tmp/ntpXXXXXX" -#else -static char res_file[MAX_PATH]; -#endif /* SYS_WINNT */ - -/* - * Definitions of things either imported from or exported to outside - */ -char const *progname; -char sys_phone[MAXPHONE][MAXDIAL]; /* ACTS phone numbers */ -char *keysdir = NTP_KEYSDIR; /* crypto keys directory */ -char pps_device[MAXPPS + 1]; /* PPS device name */ -#if defined(HAVE_SCHED_SETSCHEDULER) -int config_priority_override = 0; -int config_priority; -#endif - -const char *config_file; -#ifdef HAVE_NETINFO - struct netinfo_config_state *config_netinfo = NULL; - int check_netinfo = 1; -#endif /* HAVE_NETINFO */ -#ifdef SYS_WINNT - char *alt_config_file; - LPTSTR temp; - char config_file_storage[MAX_PATH]; - char alt_config_file_storage[MAX_PATH]; -#endif /* SYS_WINNT */ - -#ifdef HAVE_NETINFO -/* - * NetInfo configuration state - */ -struct netinfo_config_state { - void *domain; /* domain with config */ - ni_id config_dir; /* ID config dir */ - int prop_index; /* current property */ - int val_index; /* current value */ - char **val_list; /* value list */ -}; -#endif - -/* - * Function prototypes - */ -static unsigned long get_pfxmatch P((char **, struct masks *)); -static unsigned long get_match P((char *, struct masks *)); -static unsigned long get_logmask P((char *)); -#ifdef HAVE_NETINFO -static struct netinfo_config_state *get_netinfo_config P((void)); -static void free_netinfo_config P((struct netinfo_config_state *)); -static int gettokens_netinfo P((struct netinfo_config_state *, char **, int *)); -#endif -static int gettokens P((FILE *, char *, char **, int *)); -static int matchkey P((char *, struct keyword *, int)); -static int getnetnum P((const char *, struct sockaddr_storage *, int)); -static void save_resolve P((char *, int, int, int, int, u_int, int, - keyid_t, u_char *)); -static void do_resolve_internal P((void)); -static void abort_resolve P((void)); -#if !defined(VMS) && !defined(SYS_WINNT) -static RETSIGTYPE catchchild P((int)); -#endif /* VMS */ - -/* - * get_pfxmatch - find value for prefixmatch - * and update char * accordingly - */ -static unsigned long -get_pfxmatch( - char ** s, - struct masks *m - ) -{ - while (m->name) { - if (strncmp(*s, m->name, strlen(m->name)) == 0) { - *s += strlen(m->name); - return m->mask; - } else { - m++; - } - } - return 0; -} - -/* - * get_match - find logmask value - */ -static unsigned long -get_match( - char *s, - struct masks *m - ) -{ - while (m->name) { - if (strcmp(s, m->name) == 0) { - return m->mask; - } else { - m++; - } - } - return 0; -} - -/* - * get_logmask - build bitmask for ntp_syslogmask - */ -static unsigned long -get_logmask( - char *s - ) -{ - char *t; - unsigned long offset; - unsigned long mask; - - t = s; - offset = get_pfxmatch(&t, logcfg_class); - mask = get_match(t, logcfg_item); - - if (mask) - return mask << offset; - else - msyslog(LOG_ERR, "logconfig: illegal argument %s - ignored", s); - - return 0; -} - - -/* - * getconfig - get command line options and read the configuration file - */ -void -getconfig( - int argc, - char *argv[] - ) -{ - register int i; - int c; - int errflg; - int istart; - int peerversion; - int minpoll; - int maxpoll; - int ttl; - long stratum; - unsigned long ul; - keyid_t peerkey; - u_char *peerkeystr; - u_long fudgeflag; - u_int peerflags; - int hmode; - struct sockaddr_storage peeraddr; - struct sockaddr_storage maskaddr; - FILE *fp[MAXINCLUDELEVEL+1]; - FILE *includefile; - int includelevel = 0; - char line[MAXLINE]; - char *(tokens[MAXTOKENS]); - int ntokens = 0; - int tok = CONFIG_UNKNOWN; - struct interface *localaddr; - struct refclockstat clock_stat; - FILEGEN *filegen; - - /* - * Initialize, initialize - */ - errflg = 0; - /* HMS: don't initialize debug to 0 here! */ -#ifndef SYS_WINNT - config_file = CONFIG_FILE; -#else - temp = CONFIG_FILE; - if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) { - msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n"); - exit(1); - } - config_file = config_file_storage; - - temp = ALT_CONFIG_FILE; - if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) { - msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n"); - exit(1); - } - alt_config_file = alt_config_file_storage; - -#endif /* SYS_WINNT */ - progname = argv[0]; - res_fp = NULL; - memset((char *)sys_phone, 0, sizeof(sys_phone)); - ntp_syslogmask = NLOG_SYNCMASK; /* set more via logconfig */ - - /* - * install a non default variable with this daemon version - */ - (void) sprintf(line, "daemon_version=\"%s\"", Version); - set_sys_var(line, strlen(line)+1, RO); - - /* - * Say how we're setting the time of day - */ - (void) sprintf(line, "settimeofday=\"%s\"", set_tod_using); - set_sys_var(line, strlen(line)+1, RO); - - /* - * Initialize the loop. - */ - loop_config(LOOP_DRIFTINIT, 0.); - - getCmdOpts(argc, argv); - - if ( - (fp[0] = fopen(FindConfig(config_file), "r")) == NULL -#ifdef HAVE_NETINFO - /* If there is no config_file, try NetInfo. */ - && check_netinfo && !(config_netinfo = get_netinfo_config()) -#endif /* HAVE_NETINFO */ - ) { - fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(config_file)); - msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(config_file)); -#ifdef SYS_WINNT - /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */ - - if ((fp[0] = fopen(FindConfig(alt_config_file), "r")) == NULL) { - - /* - * Broadcast clients can sometimes run without - * a configuration file. - */ - - fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(alt_config_file)); - msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(alt_config_file)); - return; - } -#else /* not SYS_WINNT */ - return; -#endif /* not SYS_WINNT */ - } - - for (;;) { - if (fp[includelevel]) - tok = gettokens(fp[includelevel], line, tokens, &ntokens); -#ifdef HAVE_NETINFO - else - tok = gettokens_netinfo(config_netinfo, tokens, &ntokens); -#endif /* HAVE_NETINFO */ - - if (tok == CONFIG_UNKNOWN) { - if (includelevel > 0) { - fclose(fp[includelevel--]); - continue; - } else { - break; - } - } - - switch(tok) { - case CONFIG_PEER: - case CONFIG_SERVER: - case CONFIG_MANYCASTCLIENT: - case CONFIG_BROADCAST: - if (tok == CONFIG_PEER) - hmode = MODE_ACTIVE; - else if (tok == CONFIG_SERVER) - hmode = MODE_CLIENT; - else if (tok == CONFIG_MANYCASTCLIENT) - hmode = MODE_CLIENT; - else - hmode = MODE_BROADCAST; - - if (ntokens < 2) { - msyslog(LOG_ERR, - "No address for %s, line ignored", - tokens[0]); - break; - } - - istart = 1; - memset((char *)&peeraddr, 0, sizeof(peeraddr)); - switch (matchkey(tokens[istart], addr_type, 0)) { - case CONF_ADDR_IPV4: - peeraddr.ss_family = AF_INET; - istart++; - break; - case CONF_ADDR_IPV6: - peeraddr.ss_family = AF_INET6; - istart++; - break; - } - - if (!getnetnum(tokens[istart], &peeraddr, 0)) { - errflg = -1; - } else { - errflg = 0; - - if ( -#ifdef REFCLOCK - !ISREFCLOCKADR(&peeraddr) && -#endif - ISBADADR(&peeraddr)) { - msyslog(LOG_ERR, - "attempt to configure invalid address %s", - stoa(&peeraddr)); - break; - } - /* - * Shouldn't be able to specify multicast - * address for server/peer! - * and unicast address for manycastclient! - */ - if (peeraddr.ss_family == AF_INET) { - if (((tok == CONFIG_SERVER) || - (tok == CONFIG_PEER)) && -#ifdef REFCLOCK - !ISREFCLOCKADR(&peeraddr) && -#endif - IN_CLASSD(ntohl(((struct sockaddr_in*)&peeraddr)->sin_addr.s_addr))) { - msyslog(LOG_ERR, - "attempt to configure invalid address %s", - stoa(&peeraddr)); - break; - } - if ((tok == CONFIG_MANYCASTCLIENT) && - !IN_CLASSD(ntohl(((struct sockaddr_in*)&peeraddr)->sin_addr.s_addr))) { - msyslog(LOG_ERR, - "attempt to configure invalid address %s", - stoa(&peeraddr)); - break; - } - } - else if(peeraddr.ss_family == AF_INET6) { - if (((tok == CONFIG_SERVER) || - (tok == CONFIG_PEER)) && -#ifdef REFCLOCK - !ISREFCLOCKADR(&peeraddr) && -#endif - IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)&peeraddr)->sin6_addr)) { - msyslog(LOG_ERR, - "attempt to configure in valid address %s", - stoa(&peeraddr)); - break; - } - if ((tok == CONFIG_MANYCASTCLIENT) && - !IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)&peeraddr)->sin6_addr)) { - msyslog(LOG_ERR, - "attempt to configure in valid address %s", - stoa(&peeraddr)); - break; - } - } - } - - peerversion = NTP_VERSION; - minpoll = NTP_MINDPOLL; - maxpoll = NTP_MAXDPOLL; - peerkey = 0; - peerkeystr = (u_char *)"*"; - peerflags = 0; - ttl = 0; - istart++; - for (i = istart; i < ntokens; i++) - switch (matchkey(tokens[i], mod_keywords, 1)) { - case CONF_MOD_VERSION: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "peer/server version requires an argument"); - errflg = 1; - break; - } - peerversion = atoi(tokens[++i]); - if ((u_char)peerversion > NTP_VERSION - || (u_char)peerversion < NTP_OLDVERSION) { - msyslog(LOG_ERR, - "inappropriate version number %s, line ignored", - tokens[i]); - errflg = 1; - } - break; - - case CONF_MOD_KEY: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "key: argument required"); - errflg = 1; - break; - } - peerkey = (int)atol(tokens[++i]); - peerflags |= FLAG_AUTHENABLE; - break; - - case CONF_MOD_MINPOLL: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "minpoll: argument required"); - errflg = 1; - break; - } - minpoll = atoi(tokens[++i]); - if (minpoll < NTP_MINPOLL) { - msyslog(LOG_INFO, - "minpoll: provided value (%d) is below minimum (%d)", - minpoll, NTP_MINPOLL); - minpoll = NTP_MINPOLL; - } - break; - - case CONF_MOD_MAXPOLL: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "maxpoll: argument required" - ); - errflg = 1; - break; - } - maxpoll = atoi(tokens[++i]); - if (maxpoll > NTP_MAXPOLL) { - msyslog(LOG_INFO, - "maxpoll: provided value (%d) is above maximum (%d)", - maxpoll, NTP_MAXPOLL); - maxpoll = NTP_MAXPOLL; - } - break; - - case CONF_MOD_PREFER: - peerflags |= FLAG_PREFER; - break; - - case CONF_MOD_NOSELECT: - peerflags |= FLAG_NOSELECT; - break; - - case CONF_MOD_BURST: - peerflags |= FLAG_BURST; - break; - - case CONF_MOD_IBURST: - peerflags |= FLAG_IBURST; - break; -#ifdef OPENSSL - case CONF_MOD_SKEY: - peerflags |= FLAG_SKEY | - FLAG_AUTHENABLE; - break; -#endif /* OPENSSL */ - - case CONF_MOD_TTL: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "ttl: argument required"); - errflg = 1; - break; - } - ttl = atoi(tokens[++i]); - if (ttl >= MAX_TTL) { - msyslog(LOG_ERR, - "ttl: invalid argument"); - errflg = 1; - } - break; - - case CONF_MOD_MODE: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "mode: argument required"); - errflg = 1; - break; - } - ttl = atoi(tokens[++i]); - break; - - case CONFIG_UNKNOWN: - errflg = 1; - break; - } - if (minpoll > maxpoll) { - msyslog(LOG_ERR, - "config error: minpoll > maxpoll"); - errflg = 1; - } - if (errflg == 0) { - if (peer_config(&peeraddr, - ANY_INTERFACE_CHOOSE(&peeraddr), hmode, - peerversion, minpoll, maxpoll, peerflags, - ttl, peerkey, peerkeystr) == 0) { - msyslog(LOG_ERR, - "configuration of %s failed", - stoa(&peeraddr)); - } - if (tok == CONFIG_MANYCASTCLIENT) - proto_config(PROTO_MULTICAST_ADD, - 0, 0., &peeraddr); - - } else if (errflg == -1) { - save_resolve(tokens[1], hmode, peerversion, - minpoll, maxpoll, peerflags, ttl, - peerkey, peerkeystr); - } - break; - - case CONFIG_DRIFTFILE: - if (ntokens >= 2) - stats_config(STATS_FREQ_FILE, tokens[1]); - else - stats_config(STATS_FREQ_FILE, (char *)0); - break; - - case CONFIG_PIDFILE: - if (ntokens >= 2) - stats_config(STATS_PID_FILE, tokens[1]); - else - stats_config(STATS_PID_FILE, (char *)0); - break; - - case CONFIG_INCLUDEFILE: - if (ntokens < 2) { - msyslog(LOG_ERR, "includefile needs one argument"); - break; - } - if (includelevel >= MAXINCLUDELEVEL) { - fprintf(stderr, "getconfig: Maximum include file level exceeded.\n"); - msyslog(LOG_INFO, "getconfig: Maximum include file level exceeded."); - break; - } - includefile = fopen(FindConfig(tokens[1]), "r"); - if (includefile == NULL) { - fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig(tokens[1])); - msyslog(LOG_INFO, "getconfig: Couldn't open <%s>", FindConfig(tokens[1])); - break; - } - fp[++includelevel] = includefile; - break; - - case CONFIG_LOGFILE: - if (ntokens >= 2) { - FILE *new_file; - - new_file = fopen(tokens[1], "a"); - if (new_file != NULL) { - NLOG(NLOG_SYSINFO) /* conditional if clause for conditional syslog */ - msyslog(LOG_NOTICE, "logging to file %s", tokens[1]); - if (syslog_file != NULL && - fileno(syslog_file) != fileno(new_file)) - (void)fclose(syslog_file); - - syslog_file = new_file; - syslogit = 0; - } - else - msyslog(LOG_ERR, - "Cannot open log file %s", - tokens[1]); - } - else - msyslog(LOG_ERR, "logfile needs one argument"); - break; - - case CONFIG_LOGCONFIG: - for (i = 1; i < ntokens; i++) - { - int add = 1; - int equals = 0; - char * s = &tokens[i][0]; - - switch (*s) { - case '+': - case '-': - case '=': - add = *s == '+'; - equals = *s == '='; - s++; - break; - - default: - break; - } - if (equals) { - ntp_syslogmask = get_logmask(s); - } else { - if (add) { - ntp_syslogmask |= get_logmask(s); - } else { - ntp_syslogmask &= ~get_logmask(s); - } - } -#ifdef DEBUG - if (debug) - printf("ntp_syslogmask = 0x%08lx (%s)\n", ntp_syslogmask, tokens[i]); -#endif - } - break; - - case CONFIG_BROADCASTCLIENT: - proto_config(PROTO_BROADCLIENT, 1, 0., NULL); - break; - - case CONFIG_MULTICASTCLIENT: - case CONFIG_MANYCASTSERVER: - if (ntokens > 1) { - istart = 1; - memset((char *)&peeraddr, 0, sizeof(peeraddr)); - switch (matchkey(tokens[istart], - addr_type, 0)) { - case CONF_ADDR_IPV4: - peeraddr.ss_family = AF_INET; - istart++; - break; - case CONF_ADDR_IPV6: - peeraddr.ss_family = AF_INET6; - istart++; - break; - } - /* - * Abuse maskaddr to store the prefered ip - * version. - */ - memset((char *)&maskaddr, 0, sizeof(maskaddr)); - maskaddr.ss_family = peeraddr.ss_family; - - for (i = istart; i < ntokens; i++) { - memset((char *)&peeraddr, 0, - sizeof(peeraddr)); - peeraddr.ss_family = maskaddr.ss_family; - if (getnetnum(tokens[i], &peeraddr, 1)) - proto_config(PROTO_MULTICAST_ADD, - 0, 0., &peeraddr); - } - } else - proto_config(PROTO_MULTICAST_ADD, - 0, 0., NULL); - if (tok == CONFIG_MULTICASTCLIENT) - sys_bclient = 1; - else if (tok == CONFIG_MANYCASTSERVER) - sys_manycastserver = 1; - break; - - case CONFIG_KEYS: - if (ntokens >= 2) { - getauthkeys(tokens[1]); - } - break; - - case CONFIG_KEYSDIR: - if (ntokens < 2) { - msyslog(LOG_ERR, - "Keys directory name required"); - break; - } - keysdir = emalloc(strlen(tokens[1]) + 1); - strcpy(keysdir, tokens[1]); - break; - - case CONFIG_TINKER: - for (i = 1; i < ntokens; i++) { - int temp; - double ftemp; - - temp = matchkey(tokens[i++], tinker_keywords, 1); - if (i > ntokens - 1) { - msyslog(LOG_ERR, - "tinker: missing argument"); - errflg++; - break; - } - sscanf(tokens[i], "%lf", &ftemp); - switch(temp) { - - case CONF_CLOCK_MAX: - loop_config(LOOP_MAX, ftemp); - break; - - case CONF_CLOCK_PANIC: - loop_config(LOOP_PANIC, ftemp); - break; - - case CONF_CLOCK_PHI: - loop_config(LOOP_PHI, ftemp); - break; - - case CONF_CLOCK_MINSTEP: - loop_config(LOOP_MINSTEP, ftemp); - break; - - case CONF_CLOCK_ALLAN: - loop_config(LOOP_ALLAN, ftemp); - break; - - case CONF_CLOCK_HUFFPUFF: - loop_config(LOOP_HUFFPUFF, ftemp); - break; - - case CONF_CLOCK_FREQ: - loop_config(LOOP_FREQ, ftemp); - break; - } - } - break; - - case CONFIG_TOS: - for (i = 1; i < ntokens; i++) { - int temp; - double ftemp; - - temp = matchkey(tokens[i++], tos_keywords, 1); - if (i > ntokens - 1) { - msyslog(LOG_ERR, - "tinker: missing argument"); - errflg++; - break; - } - sscanf(tokens[i], "%lf", &ftemp); - switch(temp) { - - case CONF_TOS_MINCLOCK: - proto_config(PROTO_MINCLOCK, 0, ftemp, NULL); - break; - - case CONF_TOS_MINSANE: - proto_config(PROTO_MINSANE, 0, ftemp, NULL); - break; - - case CONF_TOS_FLOOR: - proto_config(PROTO_FLOOR, 0, ftemp, NULL); - break; - - case CONF_TOS_CEILING: - proto_config(PROTO_CEILING, 0, ftemp, NULL); - break; - - case CONF_TOS_COHORT: - proto_config(PROTO_COHORT, 0, ftemp, NULL); - break; - } - } - break; - - case CONFIG_TTL: - for (i = 1; i < ntokens && i < MAX_TTL; i++) { - sys_ttl[i - 1] = (u_char) atoi(tokens[i]); - sys_ttlmax = i - 1; - } - break; - - case CONFIG_DISCARD: - for (i = 1; i < ntokens; i++) { - int temp; - - temp = matchkey(tokens[i++], - discard_keywords, 1); - if (i > ntokens - 1) { - msyslog(LOG_ERR, - "discard: missing argument"); - errflg++; - break; - } - switch(temp) { - case CONF_DISCARD_AVERAGE: - res_avg_interval = atoi(tokens[i++]); - break; - - case CONF_DISCARD_MINIMUM: - res_min_interval = atoi(tokens[i++]); - break; - - case CONF_DISCARD_MONITOR: - mon_age = atoi(tokens[i++]); - break; - - default: - msyslog(LOG_ERR, - "discard: unknown keyword"); - break; - } - } - break; - -#ifdef OPENSSL - case CONFIG_REVOKE: - if (ntokens >= 2) - sys_revoke = (u_char) max(atoi(tokens[1]), KEY_REVOKE); - break; - - case CONFIG_AUTOMAX: - if (ntokens >= 2) - sys_automax = 1 << max(atoi(tokens[1]), 10); - break; - - case CONFIG_CRYPTO: - if (ntokens == 1) { - crypto_config(CRYPTO_CONF_NONE, NULL); - break; - } - for (i = 1; i < ntokens; i++) { - int temp; - - temp = matchkey(tokens[i++], - crypto_keywords, 1); - if (i > ntokens - 1) { - msyslog(LOG_ERR, - "crypto: missing argument"); - errflg++; - break; - } - switch(temp) { - - case CONF_CRYPTO_CERT: - crypto_config(CRYPTO_CONF_CERT, - tokens[i]); - break; - - case CONF_CRYPTO_RSA: - crypto_config(CRYPTO_CONF_PRIV, - tokens[i]); - break; - - case CONF_CRYPTO_IFFPAR: - crypto_config(CRYPTO_CONF_IFFPAR, - tokens[i]); - break; - - case CONF_CRYPTO_GQPAR: - crypto_config(CRYPTO_CONF_GQPAR, - tokens[i]); - break; - - case CONF_CRYPTO_MVPAR: - crypto_config(CRYPTO_CONF_MVPAR, - tokens[i]); - break; - - case CONF_CRYPTO_LEAP: - crypto_config(CRYPTO_CONF_LEAP, - tokens[i]); - break; - - case CONF_CRYPTO_PW: - crypto_config(CRYPTO_CONF_PW, - tokens[i]); - break; - - case CONF_CRYPTO_RAND: - crypto_config(CRYPTO_CONF_RAND, - tokens[i]); - break; - - case CONF_CRYPTO_SIGN: - crypto_config(CRYPTO_CONF_SIGN, - tokens[i]); - break; - - default: - msyslog(LOG_ERR, - "crypto: unknown keyword"); - break; - } - } - break; -#endif /* OPENSSL */ - - case CONFIG_RESTRICT: - if (ntokens < 2) { - msyslog(LOG_ERR, "restrict requires an address"); - break; - } - istart = 1; - memset((char *)&peeraddr, 0, sizeof(peeraddr)); - switch (matchkey(tokens[istart], addr_type, 0)) { - case CONF_ADDR_IPV4: - peeraddr.ss_family = AF_INET; - istart++; - break; - case CONF_ADDR_IPV6: - peeraddr.ss_family = AF_INET6; - istart++; - break; - } - - /* - * Assume default means an IPv4 address, except - * if forced by a -4 or -6. - */ - if (STREQ(tokens[istart], "default")) { - if (peeraddr.ss_family == 0) - peeraddr.ss_family = AF_INET; - } else if (!getnetnum(tokens[istart], &peeraddr, 1)) - break; - - /* - * Use peerversion as flags, peerkey as mflags. Ick. - */ - peerversion = 0; - peerkey = 0; - errflg = 0; - SET_HOSTMASK(&maskaddr, peeraddr.ss_family); - istart++; - for (i = istart; i < ntokens; i++) { - switch (matchkey(tokens[i], res_keywords, 1)) { - case CONF_RES_MASK: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "mask keyword needs argument"); - errflg++; - break; - } - i++; - if (!getnetnum(tokens[i], &maskaddr, 1)) - errflg++; - break; - - case CONF_RES_IGNORE: - peerversion |= RES_IGNORE; - break; - - case CONF_RES_NOSERVE: - peerversion |= RES_DONTSERVE; - break; - - case CONF_RES_NOTRUST: - peerversion |= RES_DONTTRUST; - break; - - case CONF_RES_NOQUERY: - peerversion |= RES_NOQUERY; - break; - - case CONF_RES_NOMODIFY: - peerversion |= RES_NOMODIFY; - break; - - case CONF_RES_NOPEER: - peerversion |= RES_NOPEER; - break; - - case CONF_RES_NOTRAP: - peerversion |= RES_NOTRAP; - break; - - case CONF_RES_LPTRAP: - peerversion |= RES_LPTRAP; - break; - - case CONF_RES_NTPPORT: - peerkey |= RESM_NTPONLY; - break; - - case CONF_RES_VERSION: - peerversion |= RES_VERSION; - break; - - case CONF_RES_DEMOBILIZE: - peerversion |= RES_DEMOBILIZE; - break; - - case CONF_RES_LIMITED: - peerversion |= RES_LIMITED; - break; - - case CONFIG_UNKNOWN: - errflg++; - break; - } - } - if (SOCKNUL(&peeraddr)) - ANYSOCK(&maskaddr); - if (!errflg) - hack_restrict(RESTRICT_FLAGS, &peeraddr, &maskaddr, - (int)peerkey, peerversion); - break; - - case CONFIG_BDELAY: - if (ntokens >= 2) { - double tmp; - - if (sscanf(tokens[1], "%lf", &tmp) != 1) { - msyslog(LOG_ERR, - "broadcastdelay value %s undecodable", - tokens[1]); - } else { - proto_config(PROTO_BROADDELAY, 0, tmp, NULL); - } - } - break; - - case CONFIG_CDELAY: - if (ntokens >= 2) { - u_long ui; - - if (sscanf(tokens[1], "%ld", &ui) != 1) - msyslog(LOG_ERR, - "illegal value - line ignored"); - else - proto_config(PROTO_CALLDELAY, ui, 0, NULL); - } - break; - - case CONFIG_TRUSTEDKEY: - for (i = 1; i < ntokens; i++) { - keyid_t tkey; - - tkey = atol(tokens[i]); - if (tkey == 0) { - msyslog(LOG_ERR, - "trusted key %s unlikely", - tokens[i]); - } else { - authtrust(tkey, 1); - } - } - break; - - case CONFIG_REQUESTKEY: - if (ntokens >= 2) { - if (!atouint(tokens[1], &ul)) { - msyslog(LOG_ERR, - "%s is undecodable as request key", - tokens[1]); - } else if (ul == 0) { - msyslog(LOG_ERR, - "%s makes a poor request keyid", - tokens[1]); - } else { -#ifdef DEBUG - if (debug > 3) - printf( - "set info_auth_key to %08lx\n", ul); -#endif - info_auth_keyid = (keyid_t)ul; - } - } - break; - - case CONFIG_CONTROLKEY: - if (ntokens >= 2) { - keyid_t ckey; - - ckey = atol(tokens[1]); - if (ckey == 0) { - msyslog(LOG_ERR, - "%s makes a poor control keyid", - tokens[1]); - } else { - ctl_auth_keyid = ckey; - } - } - break; - - case CONFIG_TRAP: - if (ntokens < 2) { - msyslog(LOG_ERR, - "no address for trap command, line ignored"); - break; - } - istart = 1; - memset((char *)&peeraddr, 0, sizeof(peeraddr)); - switch (matchkey(tokens[istart], addr_type, 0)) { - case CONF_ADDR_IPV4: - peeraddr.ss_family = AF_INET; - istart++; - break; - case CONF_ADDR_IPV6: - peeraddr.ss_family = AF_INET6; - istart++; - break; - } - - if (!getnetnum(tokens[istart], &peeraddr, 1)) - break; - - /* - * Use peerversion for port number. Barf. - */ - errflg = 0; - peerversion = 0; - localaddr = 0; - istart++; - for (i = istart; i < ntokens-1; i++) - switch (matchkey(tokens[i], trap_keywords, 1)) { - case CONF_TRAP_PORT: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "trap port requires an argument"); - errflg = 1; - break; - } - peerversion = atoi(tokens[++i]); - if (peerversion <= 0 - || peerversion > 32767) { - msyslog(LOG_ERR, - "invalid port number %s, trap ignored", - tokens[i]); - errflg = 1; - } - break; - - case CONF_TRAP_INTERFACE: - if (i >= ntokens-1) { - msyslog(LOG_ERR, - "trap interface requires an argument"); - errflg = 1; - break; - } - - memset((char *)&maskaddr, 0, - sizeof(maskaddr)); - maskaddr.ss_family = peeraddr.ss_family; - if (!getnetnum(tokens[++i], - &maskaddr, 1)) { - errflg = 1; - break; - } - - localaddr = findinterface(&maskaddr); - if (localaddr == NULL) { - msyslog(LOG_ERR, - "can't find interface with address %s", - stoa(&maskaddr)); - errflg = 1; - } - break; - - case CONFIG_UNKNOWN: - errflg++; - break; - } - - if (!errflg) { - if (peerversion != 0) - ((struct sockaddr_in6*)&peeraddr)->sin6_port = htons( (u_short) peerversion); - else - ((struct sockaddr_in6*)&peeraddr)->sin6_port = htons(TRAPPORT); - if (localaddr == NULL) - localaddr = ANY_INTERFACE_CHOOSE(&peeraddr); - if (!ctlsettrap(&peeraddr, localaddr, 0, - NTP_VERSION)) - msyslog(LOG_ERR, - "can't set trap for %s, no resources", - stoa(&peeraddr)); - } - break; - - case CONFIG_FUDGE: - if (ntokens < 2) { - msyslog(LOG_ERR, - "no address for fudge command, line ignored"); - break; - } - memset((char *)&peeraddr, 0, sizeof(peeraddr)); - if (!getnetnum(tokens[1], &peeraddr, 1)) - break; - - if (!ISREFCLOCKADR(&peeraddr)) { - msyslog(LOG_ERR, - "%s is inappropriate address for the fudge command, line ignored", - stoa(&peeraddr)); - break; - } - - memset((void *)&clock_stat, 0, sizeof clock_stat); - fudgeflag = 0; - errflg = 0; - for (i = 2; i < ntokens-1; i++) { - switch (c = matchkey(tokens[i], - fudge_keywords, 1)) { - case CONF_FDG_TIME1: - if (sscanf(tokens[++i], "%lf", - &clock_stat.fudgetime1) != 1) { - msyslog(LOG_ERR, - "fudge %s time1 value in error", - stoa(&peeraddr)); - errflg = i; - break; - } - clock_stat.haveflags |= CLK_HAVETIME1; - break; - - case CONF_FDG_TIME2: - if (sscanf(tokens[++i], "%lf", - &clock_stat.fudgetime2) != 1) { - msyslog(LOG_ERR, - "fudge %s time2 value in error", - stoa(&peeraddr)); - errflg = i; - break; - } - clock_stat.haveflags |= CLK_HAVETIME2; - break; - - - case CONF_FDG_STRATUM: - if (!atoint(tokens[++i], &stratum)) - { - msyslog(LOG_ERR, - "fudge %s stratum value in error", - stoa(&peeraddr)); - errflg = i; - break; - } - clock_stat.fudgeval1 = stratum; - clock_stat.haveflags |= CLK_HAVEVAL1; - break; - - case CONF_FDG_REFID: - /* HMS: Endianness and 0 bytes? */ - /* XXX */ - strncpy((char *)&clock_stat.fudgeval2, - tokens[++i], 4); - clock_stat.haveflags |= CLK_HAVEVAL2; - break; - - case CONF_FDG_FLAG1: - case CONF_FDG_FLAG2: - case CONF_FDG_FLAG3: - case CONF_FDG_FLAG4: - if (!atouint(tokens[++i], &fudgeflag) - || fudgeflag > 1) { - msyslog(LOG_ERR, - "fudge %s flag value in error", - stoa(&peeraddr)); - errflg = i; - break; - } - switch(c) { - case CONF_FDG_FLAG1: - c = CLK_FLAG1; - clock_stat.haveflags|=CLK_HAVEFLAG1; - break; - case CONF_FDG_FLAG2: - c = CLK_FLAG2; - clock_stat.haveflags|=CLK_HAVEFLAG2; - break; - case CONF_FDG_FLAG3: - c = CLK_FLAG3; - clock_stat.haveflags|=CLK_HAVEFLAG3; - break; - case CONF_FDG_FLAG4: - c = CLK_FLAG4; - clock_stat.haveflags|=CLK_HAVEFLAG4; - break; - } - if (fudgeflag == 0) - clock_stat.flags &= ~c; - else - clock_stat.flags |= c; - break; - - case CONFIG_UNKNOWN: - errflg = -1; - break; - } - } - -#ifdef REFCLOCK - /* - * If reference clock support isn't defined the - * fudge line will still be accepted and syntax - * checked, but will essentially do nothing. - */ - if (!errflg) { - refclock_control(&peeraddr, &clock_stat, - (struct refclockstat *)0); - } -#endif - break; - - case CONFIG_STATSDIR: - if (ntokens >= 2) - stats_config(STATS_STATSDIR,tokens[1]); - break; - - case CONFIG_STATISTICS: - for (i = 1; i < ntokens; i++) { - filegen = filegen_get(tokens[i]); - - if (filegen == NULL) { - msyslog(LOG_ERR, - "no statistics named %s available", - tokens[i]); - continue; - } -#ifdef DEBUG - if (debug > 3) - printf("enabling filegen for %s statistics \"%s%s\"\n", - tokens[i], filegen->prefix, filegen->basename); -#endif - filegen->flag |= FGEN_FLAG_ENABLED; - } - break; - - case CONFIG_FILEGEN: - if (ntokens < 2) { - msyslog(LOG_ERR, - "no id for filegen command, line ignored"); - break; - } - - filegen = filegen_get(tokens[1]); - if (filegen == NULL) { - msyslog(LOG_ERR, - "unknown filegen \"%s\" ignored", - tokens[1]); - break; - } - /* - * peerversion is (ab)used for filegen file (index) - * peerkey is (ab)used for filegen type - * peerflags is (ab)used for filegen flags - */ - peerversion = 0; - peerkey = filegen->type; - peerflags = filegen->flag; - errflg = 0; - - for (i = 2; i < ntokens; i++) { - switch (matchkey(tokens[i], - filegen_keywords, 1)) { - case CONF_FGEN_FILE: - if (i >= ntokens - 1) { - msyslog(LOG_ERR, - "filegen %s file requires argument", - tokens[1]); - errflg = i; - break; - } - peerversion = ++i; - break; - case CONF_FGEN_TYPE: - if (i >= ntokens -1) { - msyslog(LOG_ERR, - "filegen %s type requires argument", - tokens[1]); - errflg = i; - break; - } - peerkey = matchkey(tokens[++i], - fgen_types, 1); - if (peerkey == CONFIG_UNKNOWN) { - msyslog(LOG_ERR, - "filegen %s unknown type \"%s\"", - tokens[1], tokens[i]); - errflg = i; - break; - } - break; - - case CONF_FGEN_FLAG_LINK: - peerflags |= FGEN_FLAG_LINK; - break; - - case CONF_FGEN_FLAG_NOLINK: - peerflags &= ~FGEN_FLAG_LINK; - break; - - case CONF_FGEN_FLAG_ENABLE: - peerflags |= FGEN_FLAG_ENABLED; - break; - - case CONF_FGEN_FLAG_DISABLE: - peerflags &= ~FGEN_FLAG_ENABLED; - break; - } - } - if (!errflg) - filegen_config(filegen, tokens[peerversion], - (u_char)peerkey, (u_char)peerflags); - break; - - case CONFIG_SETVAR: - if (ntokens < 2) { - msyslog(LOG_ERR, - "no value for setvar command - line ignored"); - } else { - set_sys_var(tokens[1], strlen(tokens[1])+1, - (u_short) (RW | - ((((ntokens > 2) - && !strcmp(tokens[2], - "default"))) - ? DEF - : 0))); - } - break; - - case CONFIG_ENABLE: - for (i = 1; i < ntokens; i++) { - int flag; - - flag = matchkey(tokens[i], flags_keywords, 1); - if (flag == CONFIG_UNKNOWN) { - msyslog(LOG_ERR, - "enable unknown flag %s", - tokens[i]); - errflg = 1; - break; - } - proto_config(flag, 1, 0., NULL); - } - break; - - case CONFIG_DISABLE: - for (i = 1; i < ntokens; i++) { - int flag; - - flag = matchkey(tokens[i], flags_keywords, 1); - if (flag == CONFIG_UNKNOWN) { - msyslog(LOG_ERR, - "disable unknown flag %s", - tokens[i]); - errflg = 1; - break; - } - proto_config(flag, 0, 0., NULL); - } - break; - - case CONFIG_PHONE: - for (i = 1; i < ntokens && i < MAXPHONE; i++) { - (void)strncpy(sys_phone[i - 1], - tokens[i], MAXDIAL); - } - sys_phone[i - 1][0] = '\0'; - break; - - case CONFIG_ADJ: { - double ftemp; - - sscanf(tokens[1], "%lf", &ftemp); - proto_config(PROTO_ADJ, 0, ftemp, NULL); - } - break; - - } - } - if (fp[0]) - (void)fclose(fp[0]); - -#ifdef HAVE_NETINFO - if (config_netinfo) - free_netinfo_config(config_netinfo); -#endif /* HAVE_NETINFO */ - -#if !defined(VMS) && !defined(SYS_VXWORKS) - /* find a keyid */ - if (info_auth_keyid == 0) - req_keyid = 65535; - else - req_keyid = info_auth_keyid; - - /* if doesn't exist, make up one at random */ - if (!authhavekey(req_keyid)) { - char rankey[9]; - int j; - - for (i = 0; i < 8; i++) - for (j = 1; j < 100; ++j) { - rankey[i] = (char) (RANDOM & 0xff); - if (rankey[i] != 0) break; - } - rankey[8] = 0; - authusekey(req_keyid, KEY_TYPE_MD5, (u_char *)rankey); - authtrust(req_keyid, 1); - if (!authhavekey(req_keyid)) { - msyslog(LOG_ERR, "getconfig: Couldn't generate a valid random key!"); - /* HMS: Should this be fatal? */ - } - } - - /* save keyid so we will accept config requests with it */ - info_auth_keyid = req_keyid; -#endif /* !defined(VMS) && !defined(SYS_VXWORKS) */ - - if (res_fp != NULL) { - if (call_resolver) { - /* - * Need name resolution - */ - do_resolve_internal(); - } - } -} - - -#ifdef HAVE_NETINFO - -/* - * get_netinfo_config - find the nearest NetInfo domain with an ntp - * configuration and initialize the configuration state. - */ -static struct netinfo_config_state * -get_netinfo_config() -{ - ni_status status; - void *domain; - ni_id config_dir; - struct netinfo_config_state *config; - - if (ni_open(NULL, ".", &domain) != NI_OK) return NULL; - - while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) { - void *next_domain; - if (ni_open(domain, "..", &next_domain) != NI_OK) { - ni_free(next_domain); - break; - } - ni_free(domain); - domain = next_domain; - } - if (status != NI_OK) { - ni_free(domain); - return NULL; - } - - config = (struct netinfo_config_state *)malloc(sizeof(struct netinfo_config_state)); - config->domain = domain; - config->config_dir = config_dir; - config->prop_index = 0; - config->val_index = 0; - config->val_list = NULL; - - return config; -} - - - -/* - * free_netinfo_config - release NetInfo configuration state - */ -static void -free_netinfo_config(struct netinfo_config_state *config) -{ - ni_free(config->domain); - free(config); -} - - - -/* - * gettokens_netinfo - return tokens from NetInfo - */ -static int -gettokens_netinfo ( - struct netinfo_config_state *config, - char **tokenlist, - int *ntokens - ) -{ - int prop_index = config->prop_index; - int val_index = config->val_index; - char **val_list = config->val_list; - - /* - * Iterate through each keyword and look for a property that matches it. - */ - again: - if (!val_list) { - for (; prop_index < (sizeof(keywords)/sizeof(keywords[0])); prop_index++) - { - ni_namelist namelist; - struct keyword current_prop = keywords[prop_index]; - - /* - * For each value associated in the property, we're going to return - * a separate line. We squirrel away the values in the config state - * so the next time through, we don't need to do this lookup. - */ - NI_INIT(&namelist); - if (ni_lookupprop(config->domain, &config->config_dir, current_prop.text, &namelist) == NI_OK) { - ni_index index; - - /* Found the property, but it has no values */ - if (namelist.ni_namelist_len == 0) continue; - - if (! (val_list = config->val_list = (char**)malloc(sizeof(char*) * (namelist.ni_namelist_len + 1)))) - { msyslog(LOG_ERR, "out of memory while configuring"); break; } - - for (index = 0; index < namelist.ni_namelist_len; index++) { - char *value = namelist.ni_namelist_val[index]; - - if (! (val_list[index] = (char*)malloc(strlen(value)+1))) - { msyslog(LOG_ERR, "out of memory while configuring"); break; } - - strcpy(val_list[index], value); - } - val_list[index] = NULL; - - break; - } - ni_namelist_free(&namelist); - } - config->prop_index = prop_index; - } - - /* No list; we're done here. */ - if (!val_list) return CONFIG_UNKNOWN; - - /* - * We have a list of values for the current property. - * Iterate through them and return each in order. - */ - if (val_list[val_index]) - { - int ntok = 1; - int quoted = 0; - char *tokens = val_list[val_index]; - - msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]); - - (const char*)tokenlist[0] = keywords[prop_index].text; - for (ntok = 1; ntok < MAXTOKENS; ntok++) { - tokenlist[ntok] = tokens; - while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted)) - quoted ^= (*tokens++ == '"'); - - if (ISEOL(*tokens)) { - *tokens = '\0'; - break; - } else { /* must be space */ - *tokens++ = '\0'; - while (ISSPACE(*tokens)) tokens++; - if (ISEOL(*tokens)) break; - } - } - *ntokens = ntok + 1; - - config->val_index++; - - return keywords[prop_index].keytype; - } - - /* We're done with the current property. */ - prop_index = ++config->prop_index; - - /* Free val_list and reset counters. */ - for (val_index = 0; val_list[val_index]; val_index++) - free(val_list[val_index]); - free(val_list); val_list = config->val_list = NULL; val_index = config->val_index = 0; - - goto again; -} - -#endif /* HAVE_NETINFO */ - - -/* - * gettokens - read a line and return tokens - */ -static int -gettokens ( - FILE *fp, - char *line, - char **tokenlist, - int *ntokens - ) -{ - register char *cp; - register int ntok; - register int quoted = 0; - - /* - * Find start of first token - */ - again: - while ((cp = fgets(line, MAXLINE, fp)) != NULL) { - cp = line; - while (ISSPACE(*cp)) - cp++; - if (!ISEOL(*cp)) - break; - } - if (cp == NULL) { - *ntokens = 0; - return CONFIG_UNKNOWN; /* hack. Is recognized as EOF */ - } - - /* - * Now separate out the tokens - */ - for (ntok = 0; ntok < MAXTOKENS; ntok++) { - tokenlist[ntok] = cp; - while (!ISEOL(*cp) && (!ISSPACE(*cp) || quoted)) - quoted ^= (*cp++ == '"'); - - if (ISEOL(*cp)) { - *cp = '\0'; - break; - } else { /* must be space */ - *cp++ = '\0'; - while (ISSPACE(*cp)) - cp++; - if (ISEOL(*cp)) - break; - } - } - - /* - * Return the match - */ - *ntokens = ntok + 1; - ntok = matchkey(tokenlist[0], keywords, 1); - if (ntok == CONFIG_UNKNOWN) - goto again; - return ntok; -} - - - -/* - * matchkey - match a keyword to a list - */ -static int -matchkey( - register char *word, - register struct keyword *keys, - int complain - ) -{ - for (;;) { - if (keys->keytype == CONFIG_UNKNOWN) { - if (complain) - msyslog(LOG_ERR, - "configure: keyword \"%s\" unknown, line ignored", - word); - return CONFIG_UNKNOWN; - } - if (STRSAME(word, keys->text)) - return keys->keytype; - keys++; - } -} - - -/* - * getnetnum - return a net number (this is crude, but careful) - */ -static int -getnetnum( - const char *num, - struct sockaddr_storage *addr, - int complain - ) -{ - struct addrinfo hints; - struct addrinfo *ptr; - - /* Get host address. Looking for UDP datagram connection */ - memset(&hints, 0, sizeof (hints)); - if (addr->ss_family == AF_INET || addr->ss_family == AF_INET6) - hints.ai_family = addr->ss_family; - else - hints.ai_family = AF_UNSPEC; - - hints.ai_socktype = SOCK_DGRAM; -#ifdef DEBUG - if (debug > 3) - printf("getaddrinfo %s\n", num); -#endif - if (getaddrinfo(num, "ntp", &hints, &ptr)!=0) { - if (complain) - msyslog(LOG_ERR, - "getaddrinfo: \"%s\" invalid host address, line ignored", - num); -#ifdef DEBUG - if (debug > 3) - printf( - "getaddrinfo: \"%s\" invalid host address%s.\n", - num, (complain) - ? ", line ignored" - : ""); -#endif - return 0; - } - - memcpy(addr, ptr->ai_addr, ptr->ai_addrlen); -#ifdef DEBUG - if (debug > 1) - printf("getnetnum given %s, got %s \n", - num, stoa(addr)); -#endif - freeaddrinfo(ptr); - return 1; -} - - -#if !defined(VMS) && !defined(SYS_WINNT) -/* - * catchchild - receive the resolver's exit status - */ -static RETSIGTYPE -catchchild( - int sig - ) -{ - /* - * We only start up one child, and if we're here - * it should have already exited. Hence the following - * shouldn't hang. If it does, please tell me. - */ -#if !defined (SYS_WINNT) && !defined(SYS_VXWORKS) - (void) wait(0); -#endif /* SYS_WINNT && VXWORKS*/ -} -#endif /* VMS */ - - -/* - * save_resolve - save configuration info into a file for later name resolution - */ -static void -save_resolve( - char *name, - int mode, - int version, - int minpoll, - int maxpoll, - u_int flags, - int ttl, - keyid_t keyid, - u_char *keystr - ) -{ -#ifndef SYS_VXWORKS - if (res_fp == NULL) { -#ifndef SYS_WINNT - (void) strcpy(res_file, RES_TEMPFILE); -#else - /* no /tmp directory under NT */ - { - if(!(GetTempPath((DWORD)MAX_PATH, (LPTSTR)res_file))) { - msyslog(LOG_ERR, "cannot get pathname for temporary directory: %m"); - return; - } - (void) strcat(res_file, "ntpdXXXXXX"); - } -#endif /* SYS_WINNT */ -#ifdef HAVE_MKSTEMP - { - int fd; - - res_fp = NULL; - if ((fd = mkstemp(res_file)) != -1) - res_fp = fdopen(fd, "r+"); - } -#else - (void) mktemp(res_file); - res_fp = fopen(res_file, "w"); -#endif - if (res_fp == NULL) { - msyslog(LOG_ERR, "open failed for %s: %m", res_file); - return; - } - } -#ifdef DEBUG - if (debug) { - printf("resolving %s\n", name); - } -#endif - - (void)fprintf(res_fp, "%s %d %d %d %d %d %d %u %s\n", name, - mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr); -#ifdef DEBUG - if (debug > 1) - printf("config: %s %d %d %d %d %x %d %u %s\n", name, mode, - version, minpoll, maxpoll, flags, ttl, keyid, keystr); -#endif - -#else /* SYS_VXWORKS */ - /* save resolve info to a struct */ -#endif /* SYS_VXWORKS */ -} - - -/* - * abort_resolve - terminate the resolver stuff and delete the file - */ -static void -abort_resolve(void) -{ - /* - * In an ideal world we would might reread the file and - * log the hosts which aren't getting configured. Since - * this is too much work, however, just close and delete - * the temp file. - */ - if (res_fp != NULL) - (void) fclose(res_fp); - res_fp = NULL; - -#ifndef SYS_VXWORKS /* we don't open the file to begin with */ -#if !defined(VMS) - (void) unlink(res_file); -#else - (void) delete(res_file); -#endif /* VMS */ -#endif /* SYS_VXWORKS */ -} - - -/* - * do_resolve_internal - start up the resolver function (not program) - */ -/* - * On VMS, this routine will simply refuse to resolve anything. - * - * Possible implementation: keep `res_file' in memory, do async - * name resolution via QIO, update from within completion AST. - * I'm unlikely to find the time for doing this, though. -wjm - */ -static void -do_resolve_internal(void) -{ - int i; - - if (res_fp == NULL) { - /* belch */ - msyslog(LOG_ERR, - "do_resolve_internal: Fatal: res_fp == NULL"); - exit(1); - } - - /* we are done with this now */ - (void) fclose(res_fp); - res_fp = NULL; - -#if !defined(VMS) && !defined (SYS_VXWORKS) - req_file = res_file; /* set up pointer to res file */ -#ifndef SYS_WINNT - (void) signal_no_reset(SIGCHLD, catchchild); - -#ifndef SYS_VXWORKS - i = fork(); - if (i == 0) { - /* - * this used to close everything - * I don't think this is necessary - */ - /* - * To the unknown commenter above: - * Well, I think it's better to clean up - * after oneself. I have had problems with - * refclock-io when intres was running - things - * where fine again when ntpintres was gone. - * So some systems react erratic at least. - * - * Frank Kardel - * - * 94-11-16: - * Further debugging has proven that the above is - * absolutely harmful. The internal resolver - * is still in the SIGIO process group and the lingering - * async io information causes it to process requests from - * all file decriptor causing a race between the NTP daemon - * and the resolver. which then eats data when it wins 8-(. - * It is absolutly necessary to kill any IO associations - * shared with the NTP daemon. - * - * We also block SIGIO (currently no ports means to - * disable the signal handle for IO). - * - * Thanks to wgstuken@informatik.uni-erlangen.de to notice - * that it is the ntp-resolver child running into trouble. - * - * THUS: - */ - - closelog(); - kill_asyncio(0); - - (void) signal_no_reset(SIGCHLD, SIG_DFL); - -#ifdef DEBUG - if (0) - debug = 2; -#endif - -# ifndef LOG_DAEMON - openlog("ntpd_initres", LOG_PID); -# else /* LOG_DAEMON */ - -# ifndef LOG_NTP -# define LOG_NTP LOG_DAEMON -# endif - openlog("ntpd_initres", LOG_PID | LOG_NDELAY, LOG_NTP); -#ifndef SYS_CYGWIN32 -# ifdef DEBUG - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); - else -# endif /* DEBUG */ - setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ -# endif /* LOG_DAEMON */ -#endif - - ntp_intres(); - - /* - * If we got here, the intres code screwed up. - * Print something so we don't die without complaint - */ - msyslog(LOG_ERR, "call to ntp_intres lost"); - abort_resolve(); - exit(1); - } -#else - /* vxWorks spawns a thread... -casey */ - i = sp (ntp_intres); - /*i = taskSpawn("ntp_intres",100,VX_FP_TASK,20000,ntp_intres);*/ -#endif - if (i == -1) { - msyslog(LOG_ERR, "fork() failed, can't start ntp_intres: %m"); - (void) signal_no_reset(SIGCHLD, SIG_DFL); - abort_resolve(); - } -#else /* SYS_WINNT */ - { - /* NT's equivalent of fork() is _spawn(), but the start point - * of the new process is an executable filename rather than - * a function name as desired here. - */ - DWORD dwThreadId; - fflush(stdout); - ResolverThreadHandle = CreateThread( - NULL, /* no security attributes */ - 0, /* use default stack size */ - (LPTHREAD_START_ROUTINE) ntp_intres, /* thread function */ - NULL, /* argument to thread function */ - 0, /* use default creation flags */ - &dwThreadId); /* returns the thread identifier */ - if (ResolverThreadHandle == NULL) { - msyslog(LOG_ERR, "CreateThread() failed, can't start ntp_intres"); - abort_resolve(); - } - } -#endif /* SYS_WINNT */ -#else /* VMS VX_WORKS */ - msyslog(LOG_ERR, - "Name resolution not implemented for VMS - use numeric addresses"); - abort_resolve(); -#endif /* VMS VX_WORKS */ -} |