diff options
Diffstat (limited to 'ntpd/ntp_config.c')
| -rw-r--r-- | ntpd/ntp_config.c | 214 |
1 files changed, 136 insertions, 78 deletions
diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index c36a21896c6a8..428ab9f467d67 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -361,13 +361,32 @@ static char * normal_dtoa(double); static u_int32 get_pfxmatch(const char **, struct masks *); static u_int32 get_match(const char *, struct masks *); static u_int32 get_logmask(const char *); +static int/*BOOL*/ is_refclk_addr(const address_node * addr); + + #ifndef SIM static int getnetnum(const char *num, sockaddr_u *addr, int complain, enum gnn_type a_type); #endif +#if defined(__GNUC__) /* this covers CLANG, too */ +static void __attribute__((noreturn,format(printf,1,2))) fatal_error(const char *fmt, ...) +#elif defined(_MSC_VER) +static void __declspec(noreturn) fatal_error(const char *fmt, ...) +#else +static void fatal_error(const char *fmt, ...) +#endif +{ + va_list va; + + va_start(va, fmt); + mvsyslog(LOG_EMERG, fmt, va); + va_end(va); + _exit(1); +} + /* FUNCTIONS FOR INITIALIZATION * ---------------------------- */ @@ -1266,7 +1285,10 @@ create_peer_node( break; case T_Ttl: - if (option->value.u >= MAX_TTL) { + if (is_refclk_addr(addr)) { + msyslog(LOG_ERR, "'ttl' does not apply for refclocks"); + errflag = 1; + } else if (option->value.u >= MAX_TTL) { msyslog(LOG_ERR, "ttl: invalid argument"); errflag = 1; } else { @@ -1275,7 +1297,12 @@ create_peer_node( break; case T_Mode: - my_node->ttl = option->value.u; + if (is_refclk_addr(addr)) { + my_node->ttl = option->value.u; + } else { + msyslog(LOG_ERR, "'mode' does not apply for network peers"); + errflag = 1; + } break; case T_Key: @@ -1328,8 +1355,8 @@ create_unpeer_node( ) { unpeer_node * my_node; - u_int u; - char * pch; + u_long u; + const u_char * pch; my_node = emalloc_zero(sizeof(*my_node)); @@ -1338,16 +1365,15 @@ create_unpeer_node( * its generic T_String definition of a name/address "address". * We treat all valid 16-bit numbers as association IDs. */ - pch = addr->address; - while (*pch && isdigit((unsigned char)*pch)) - pch++; - - if (!*pch - && 1 == sscanf(addr->address, "%u", &u) - && u <= ASSOCID_MAX) { + for (u = 0, pch = (u_char*)addr->address; isdigit(*pch); ++pch) { + /* accumulate with overflow retention */ + u = (10 * u + *pch - '0') | (u & 0xFF000000u); + } + + if (!*pch && u <= ASSOCID_MAX) { my_node->assocID = (associd_t)u; - destroy_address_node(addr); my_node->addr = NULL; + destroy_address_node(addr); } else { my_node->assocID = 0; my_node->addr = addr; @@ -1841,16 +1867,12 @@ config_auth( /* Crypto Command */ #ifdef AUTOKEY -# ifdef __GNUC__ - item = -1; /* quiet warning */ -# endif my_val = HEAD_PFIFO(ptree->auth.crypto_cmd_list); for (; my_val != NULL; my_val = my_val->link) { switch (my_val->attr) { default: - INSIST(0); - break; + fatal_error("config_auth: attr-token=%d", my_val->attr); case T_Host: item = CRYPTO_CONF_PRIV; @@ -1996,40 +2018,96 @@ config_tos( int item; double val; -#ifdef __GNUC__ - item = -1; /* quiet warning */ -#endif + /* [Bug 2896] For the daemon to work properly it is essential + * that minsane < minclock <= maxclock. + * + * If either constraint is violated, the daemon will be or might + * become dysfunctional. Fixing the values is too fragile here, + * since three variables with interdependecies are involved. We + * just log an error but do not stop: This might be caused by + * remote config, and it might be fixed by remote config, too. + */ + int l_maxclock = sys_maxclock; + int l_minclock = sys_minclock; + int l_minsane = sys_minsane; + + /* -*- phase one: inspect / sanitize the values */ tos = HEAD_PFIFO(ptree->orphan_cmds); for (; tos != NULL; tos = tos->link) { val = tos->value.d; switch(tos->attr) { - default: - INSIST(0); break; case T_Bcpollbstep: if (val > 4) { msyslog(LOG_WARNING, - "Using maximum bcpollbstep ceiling %d, %g requested", - 4, val); - val = 4; + "Using maximum bcpollbstep ceiling %d, %d requested", + 4, (int)val); + tos->value.d = 4; } else if (val < 0) { msyslog(LOG_WARNING, - "Using minimum bcpollbstep floor %d, %g requested", - 0, val); - val = 0; + "Using minimum bcpollbstep floor %d, %d requested", + 0, (int)val); + tos->value.d = 0; } - item = PROTO_BCPOLLBSTEP; break; - + case T_Ceiling: if (val > STRATUM_UNSPEC - 1) { msyslog(LOG_WARNING, - "Using maximum tos ceiling %d, %g requested", - STRATUM_UNSPEC - 1, val); - val = STRATUM_UNSPEC - 1; + "Using maximum tos ceiling %d, %d requested", + STRATUM_UNSPEC - 1, (int)val); + tos->value.d = STRATUM_UNSPEC - 1; + } else if (val < 1) { + msyslog(LOG_WARNING, + "Using minimum tos floor %d, %d requested", + 1, (int)val); + tos->value.d = 1; } + break; + + case T_Minclock: + if ((int)tos->value.d < 1) + tos->value.d = 1; + l_minclock = (int)tos->value.d; + break; + + case T_Maxclock: + if ((int)tos->value.d < 1) + tos->value.d = 1; + l_maxclock = (int)tos->value.d; + break; + + case T_Minsane: + if ((int)tos->value.d < 1) + tos->value.d = 1; + l_minsane = (int)tos->value.d; + break; + } + } + + if ( ! (l_minsane < l_minclock && l_minclock <= l_maxclock)) { + msyslog(LOG_ERR, + "tos error: must have minsane (%d) < minclock (%d) <= maxclock (%d)" + " - daemon will not operate properly!", + l_minsane, l_minclock, l_maxclock); + } + + /* -*- phase two: forward the values to the protocol machinery */ + tos = HEAD_PFIFO(ptree->orphan_cmds); + for (; tos != NULL; tos = tos->link) { + val = tos->value.d; + switch(tos->attr) { + + default: + fatal_error("config-tos: attr-token=%d", tos->attr); + + case T_Bcpollbstep: + item = PROTO_BCPOLLBSTEP; + break; + + case T_Ceiling: item = PROTO_CEILING; break; @@ -2172,8 +2250,7 @@ config_monitor( switch (my_opts->value.i) { default: - INSIST(0); - break; + fatal_error("config-monitor: type-token=%d", my_opts->value.i); case T_None: filegen_type = FILEGEN_NONE; @@ -2409,8 +2486,7 @@ config_access( switch (curr_flag->i) { default: - INSIST(0); - break; + fatal_error("config-access: flag-type-token=%d", curr_flag->i); case T_Ntpport: mflags |= RESM_NTPONLY; @@ -2640,8 +2716,7 @@ config_rlimit( switch (rlimit_av->attr) { default: - INSIST(0); - break; + fatal_error("config-rlimit: value-token=%d", rlimit_av->attr); case T_Memlock: /* What if we HAVE_OPT(SAVECONFIGQUIT) ? */ @@ -2714,16 +2789,12 @@ config_tinker( attr_val * tinker; int item; -#ifdef __GNUC__ - item = -1; /* quiet warning */ -#endif tinker = HEAD_PFIFO(ptree->tinker); for (; tinker != NULL; tinker = tinker->link) { switch (tinker->attr) { default: - INSIST(0); - break; + fatal_error("config_tinker: attr-token=%d", tinker->attr); case T_Allan: item = LOOP_ALLAN; @@ -2830,16 +2901,7 @@ config_nic_rules( switch (curr_node->match_class) { default: -#ifdef __GNUC__ - /* - * this assignment quiets a gcc "may be used - * uninitialized" warning and is here for no - * other reason. - */ - match_type = MATCH_ALL; -#endif - INSIST(FALSE); - break; + fatal_error("config_nic_rules: match-class-token=%d", curr_node->match_class); case 0: /* @@ -2890,16 +2952,7 @@ config_nic_rules( switch (curr_node->action) { default: -#ifdef __GNUC__ - /* - * this assignment quiets a gcc "may be used - * uninitialized" warning and is here for no - * other reason. - */ - action = ACTION_LISTEN; -#endif - INSIST(FALSE); - break; + fatal_error("config_nic_rules: action-token=%d", curr_node->action); case T_Listen: action = ACTION_LISTEN; @@ -3087,8 +3140,7 @@ config_logconfig( ntp_syslogmask = get_logmask(my_lc->value.s); break; default: - INSIST(0); - break; + fatal_error("config-logconfig: modifier='%c'", my_lc->attr); } } } @@ -3210,7 +3262,7 @@ config_ttl( "ttl: Number of TTL entries exceeds %zu. Ignoring TTL %d...", COUNTOF(sys_ttl), curr_ttl->i); } - sys_ttlmax = i - 1; + sys_ttlmax = (i) ? (i - 1) : 0; } #endif /* !SIM */ @@ -3738,8 +3790,7 @@ peerflag_bits( switch (option->value.i) { default: - INSIST(0); - break; + fatal_error("peerflag_bits: option-token=%d", option->value.i); case T_Autokey: peerflags |= FLAG_SKEY; @@ -4040,10 +4091,10 @@ config_unpeers( curr_unpeer = HEAD_PFIFO(ptree->unpeers); for (; curr_unpeer != NULL; curr_unpeer = curr_unpeer->link) { /* - * Either AssocID will be zero, and we unpeer by name/ - * address addr, or it is nonzero and addr NULL. + * If we have no address attached, assume we have to + * unpeer by AssocID. */ - if (curr_unpeer->assocID) { + if (!curr_unpeer->addr) { p = findpeerbyassoc(curr_unpeer->assocID); if (p != NULL) { msyslog(LOG_NOTICE, "unpeered %s", @@ -4051,7 +4102,6 @@ config_unpeers( peer_clear(p, "GONE"); unpeer(p); } - continue; } @@ -4070,7 +4120,6 @@ config_unpeers( peer_clear(p, "GONE"); unpeer(p); } - continue; } /* @@ -4384,11 +4433,11 @@ config_ntpd( config_mdnstries(ptree); config_setvar(ptree); config_ttl(ptree); - config_trap(ptree); config_vars(ptree); - io_open_sockets(); + io_open_sockets(); /* [bug 2837] dep. on config_vars() */ + config_trap(ptree); /* [bug 2923] dep. on io_open_sockets() */ config_other_modes(ptree); config_peers(ptree); config_unpeers(ptree); @@ -4636,6 +4685,16 @@ save_and_apply_config_tree(int/*BOOL*/ input_from_file) #endif } +/* Hack to disambiguate 'server' statements for refclocks and network peers. + * Please note the qualification 'hack'. It's just that. + */ +static int/*BOOL*/ +is_refclk_addr( + const address_node * addr + ) +{ + return addr && addr->address && !strncmp(addr->address, "127.127.", 6); +} static void ntpd_set_tod_using( @@ -5041,8 +5100,7 @@ ntp_rlimit( # endif /* RLIMIT_STACK */ default: - INSIST(!"Unexpected setrlimit() case!"); - break; + fatal_error("ntp_rlimit: unexpected RLIMIT case: %d", rl_what); } } #endif /* HAVE_SETRLIMIT */ |
