summaryrefslogtreecommitdiff
path: root/ntpd/ntp_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/ntp_config.c')
-rw-r--r--ntpd/ntp_config.c214
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 */