diff options
Diffstat (limited to 'ntpd/ntp_config.c')
-rw-r--r-- | ntpd/ntp_config.c | 493 |
1 files changed, 431 insertions, 62 deletions
diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 428ab9f467d6..003b1534a9c4 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -149,9 +149,9 @@ typedef struct peer_resolved_ctx_tag { extern int yydebug; /* ntp_parser.c (.y) */ config_tree cfgt; /* Parser output stored here */ struct config_tree_tag *cfg_tree_history; /* History of configs */ -char *sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */ +char * sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */ char default_keysdir[] = NTP_KEYSDIR; -char *keysdir = default_keysdir; /* crypto keys directory */ +char * keysdir = default_keysdir; /* crypto keys directory */ char * saveconfigdir; #if defined(HAVE_SCHED_SETSCHEDULER) int config_priority_override = 0; @@ -312,6 +312,7 @@ static void config_monitor(config_tree *); static void config_rlimit(config_tree *); static void config_system_opts(config_tree *); static void config_tinker(config_tree *); +static int config_tos_clock(config_tree *); static void config_tos(config_tree *); static void config_vars(config_tree *); @@ -363,6 +364,8 @@ 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); +static void appendstr(char *, size_t, char *); + #ifndef SIM static int getnetnum(const char *num, sockaddr_u *addr, int complain, @@ -528,7 +531,7 @@ dump_config_tree( setvar_node *setv_node; nic_rule_node *rule_node; int_node *i_n; - int_node *flags; + int_node *flag_tok_fifo; int_node *counter_set; string_node *str_node; @@ -554,7 +557,10 @@ dump_config_tree( ptree->source.value.s); } - /* For options I didn't find documentation I'll just output its name and the cor. value */ + /* + * For options without documentation we just output the name + * and its data value + */ atrv = HEAD_PFIFO(ptree->vars); for ( ; atrv != NULL; atrv = atrv->link) { switch (atrv->type) { @@ -722,6 +728,21 @@ dump_config_tree( token_name(atrv->type)); break; #endif + case T_Integer: + if (atrv->attr == T_Basedate) { + struct calendar jd; + ntpcal_rd_to_date(&jd, atrv->value.i + DAY_NTP_STARTS); + fprintf(df, " %s \"%04hu-%02hu-%02hu\"", + keyword(atrv->attr), jd.year, + (u_short)jd.month, + (u_short)jd.monthday); + } else { + fprintf(df, " %s %d", + keyword(atrv->attr), + atrv->value.i); + } + break; + case T_Double: fprintf(df, " %s %s", keyword(atrv->attr), @@ -904,30 +925,52 @@ dump_config_tree( fprintf(df, "\n"); } - for (rest_node = HEAD_PFIFO(ptree->restrict_opts); rest_node != NULL; rest_node = rest_node->link) { + int is_default = 0; if (NULL == rest_node->addr) { s = "default"; - flags = HEAD_PFIFO(rest_node->flags); - for ( ; flags != NULL; flags = flags->link) - if (T_Source == flags->i) { + /* Don't need to set is_default=1 here */ + flag_tok_fifo = HEAD_PFIFO(rest_node->flag_tok_fifo); + for ( ; flag_tok_fifo != NULL; flag_tok_fifo = flag_tok_fifo->link) { + if (T_Source == flag_tok_fifo->i) { s = "source"; break; - } + } + } } else { - s = rest_node->addr->address; + const char *ap = rest_node->addr->address; + const char *mp = ""; + + if (rest_node->mask) + mp = rest_node->mask->address; + + if ( rest_node->addr->type == AF_INET + && !strcmp(ap, "0.0.0.0") + && !strcmp(mp, "0.0.0.0")) { + is_default = 1; + s = "-4 default"; + } else if ( rest_node->mask + && rest_node->mask->type == AF_INET6 + && !strcmp(ap, "::") + && !strcmp(mp, "::")) { + is_default = 1; + s = "-6 default"; + } else { + s = ap; + } } fprintf(df, "restrict %s", s); - if (rest_node->mask != NULL) + if (rest_node->mask != NULL && !is_default) fprintf(df, " mask %s", rest_node->mask->address); - flags = HEAD_PFIFO(rest_node->flags); - for ( ; flags != NULL; flags = flags->link) - if (T_Source != flags->i) - fprintf(df, " %s", keyword(flags->i)); + fprintf(df, " ippeerlimit %d", rest_node->ippeerlimit); + flag_tok_fifo = HEAD_PFIFO(rest_node->flag_tok_fifo); + for ( ; flag_tok_fifo != NULL; flag_tok_fifo = flag_tok_fifo->link) + if (T_Source != flag_tok_fifo->i) + fprintf(df, " %s", keyword(flag_tok_fifo->i)); fprintf(df, "\n"); } @@ -1057,11 +1100,45 @@ concat_gen_fifos( return pf1; } +void* +destroy_gen_fifo( + void *fifo, + fifo_deleter func + ) +{ + any_node * np = NULL; + any_node_fifo * pf1 = fifo; + + if (pf1 != NULL) { + if (!func) + func = free; + for (;;) { + UNLINK_FIFO(np, *pf1, link); + if (np == NULL) + break; + (*func)(np); + } + free(pf1); + } + return NULL; +} /* FUNCTIONS FOR CREATING NODES ON THE SYNTAX TREE * ----------------------------------------------- */ +void +destroy_attr_val( + attr_val * av + ) +{ + if (av) { + if (T_String == av->type) + free(av->value.s); + free(av); + } +} + attr_val * create_attr_dval( int attr, @@ -1402,7 +1479,8 @@ restrict_node * create_restrict_node( address_node * addr, address_node * mask, - int_fifo * flags, + short ippeerlimit, + int_fifo * flag_tok_fifo, int line_no ) { @@ -1411,7 +1489,8 @@ create_restrict_node( my_node = emalloc_zero(sizeof(*my_node)); my_node->addr = addr; my_node->mask = mask; - my_node->flags = flags; + my_node->ippeerlimit = ippeerlimit; + my_node->flag_tok_fifo = flag_tok_fifo; my_node->line_no = line_no; return my_node; @@ -1428,7 +1507,7 @@ destroy_restrict_node( */ destroy_address_node(my_node->addr); destroy_address_node(my_node->mask); - destroy_int_fifo(my_node->flags); + destroy_int_fifo(my_node->flag_tok_fifo); free(my_node); } @@ -1484,9 +1563,7 @@ destroy_attr_val_fifo( UNLINK_FIFO(av, *av_fifo, link); if (av == NULL) break; - if (T_String == av->type) - free(av->value.s); - free(av); + destroy_attr_val(av); } free(av_fifo); } @@ -2009,6 +2086,35 @@ free_config_auth( #endif /* FREE_CFG_T */ +/* Configure low-level clock-related parameters. Return TRUE if the + * clock might need adjustment like era-checking after the call, FALSE + * otherwise. + */ +static int/*BOOL*/ +config_tos_clock( + config_tree *ptree + ) +{ + int ret; + attr_val * tos; + + ret = FALSE; + tos = HEAD_PFIFO(ptree->orphan_cmds); + for (; tos != NULL; tos = tos->link) { + switch(tos->attr) { + + default: + break; + + case T_Basedate: + basedate_set_day(tos->value.i); + ret = TRUE; + break; + } + } + return ret; +} + static void config_tos( config_tree *ptree @@ -2034,12 +2140,16 @@ config_tos( /* -*- phase one: inspect / sanitize the values */ tos = HEAD_PFIFO(ptree->orphan_cmds); for (; tos != NULL; tos = tos->link) { - val = tos->value.d; + /* not all attributes are doubles (any more), so loading + * 'val' in all cases is not a good idea: It should be + * done as needed in every case processed here. + */ switch(tos->attr) { default: break; case T_Bcpollbstep: + val = tos->value.d; if (val > 4) { msyslog(LOG_WARNING, "Using maximum bcpollbstep ceiling %d, %d requested", @@ -2054,6 +2164,7 @@ config_tos( break; case T_Ceiling: + val = tos->value.d; if (val > STRATUM_UNSPEC - 1) { msyslog(LOG_WARNING, "Using maximum tos ceiling %d, %d requested", @@ -2068,18 +2179,21 @@ config_tos( break; case T_Minclock: + val = tos->value.d; if ((int)tos->value.d < 1) tos->value.d = 1; l_minclock = (int)tos->value.d; break; case T_Maxclock: + val = tos->value.d; if ((int)tos->value.d < 1) tos->value.d = 1; l_maxclock = (int)tos->value.d; break; case T_Minsane: + val = tos->value.d; if ((int)tos->value.d < 1) tos->value.d = 1; l_minsane = (int)tos->value.d; @@ -2097,7 +2211,6 @@ config_tos( /* -*- 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: @@ -2150,8 +2263,11 @@ config_tos( case T_Beacon: item = PROTO_BEACON; break; + + case T_Basedate: + continue; /* SKIP proto-config for this! */ } - proto_config(item, 0, val, NULL); + proto_config(item, 0, tos->value.d, NULL); } } @@ -2348,7 +2464,7 @@ config_access( static int warned_signd; attr_val * my_opt; restrict_node * my_node; - int_node * curr_flag; + int_node * curr_tok_fifo; sockaddr_u addr; sockaddr_u mask; struct addrinfo hints; @@ -2356,8 +2472,9 @@ config_access( struct addrinfo * pai; int rc; int restrict_default; - u_short flags; + u_short rflags; u_short mflags; + short ippeerlimit; int range_err; const char * signd_warning = #ifdef HAVE_NTP_SIGND @@ -2476,17 +2593,23 @@ config_access( /* Configure the restrict options */ my_node = HEAD_PFIFO(ptree->restrict_opts); + for (; my_node != NULL; my_node = my_node->link) { + /* Grab the ippeerlmit */ + ippeerlimit = my_node->ippeerlimit; + +DPRINTF(1, ("config_access: top-level node %p: ippeerlimit %d\n", my_node, ippeerlimit)); + /* Parse the flags */ - flags = 0; + rflags = 0; mflags = 0; - curr_flag = HEAD_PFIFO(my_node->flags); - for (; curr_flag != NULL; curr_flag = curr_flag->link) { - switch (curr_flag->i) { + curr_tok_fifo = HEAD_PFIFO(my_node->flag_tok_fifo); + for (; curr_tok_fifo != NULL; curr_tok_fifo = curr_tok_fifo->link) { + switch (curr_tok_fifo->i) { default: - fatal_error("config-access: flag-type-token=%d", curr_flag->i); + fatal_error("config_access: flag-type-token=%d", curr_tok_fifo->i); case T_Ntpport: mflags |= RESM_NTPONLY; @@ -2497,71 +2620,75 @@ config_access( break; case T_Flake: - flags |= RES_FLAKE; + rflags |= RES_FLAKE; break; case T_Ignore: - flags |= RES_IGNORE; + rflags |= RES_IGNORE; break; case T_Kod: - flags |= RES_KOD; + rflags |= RES_KOD; break; case T_Mssntp: - flags |= RES_MSSNTP; + rflags |= RES_MSSNTP; break; case T_Limited: - flags |= RES_LIMITED; + rflags |= RES_LIMITED; break; case T_Lowpriotrap: - flags |= RES_LPTRAP; + rflags |= RES_LPTRAP; break; case T_Nomodify: - flags |= RES_NOMODIFY; + rflags |= RES_NOMODIFY; break; case T_Nomrulist: - flags |= RES_NOMRULIST; + rflags |= RES_NOMRULIST; + break; + + case T_Noepeer: + rflags |= RES_NOEPEER; break; case T_Nopeer: - flags |= RES_NOPEER; + rflags |= RES_NOPEER; break; case T_Noquery: - flags |= RES_NOQUERY; + rflags |= RES_NOQUERY; break; case T_Noserve: - flags |= RES_DONTSERVE; + rflags |= RES_DONTSERVE; break; case T_Notrap: - flags |= RES_NOTRAP; + rflags |= RES_NOTRAP; break; case T_Notrust: - flags |= RES_DONTTRUST; + rflags |= RES_DONTTRUST; break; case T_Version: - flags |= RES_VERSION; + rflags |= RES_VERSION; break; } } - if ((RES_MSSNTP & flags) && !warned_signd) { + if ((RES_MSSNTP & rflags) && !warned_signd) { warned_signd = 1; fprintf(stderr, "%s\n", signd_warning); msyslog(LOG_WARNING, "%s", signd_warning); } /* It would be swell if we could identify the line number */ - if ((RES_KOD & flags) && !(RES_LIMITED & flags)) { + if ((RES_KOD & rflags) && !(RES_LIMITED & rflags)) { const char *kod_where = (my_node->addr) ? my_node->addr->address : (mflags & RESM_SOURCE) @@ -2589,10 +2716,10 @@ config_access( restrict_default = 1; } else { /* apply "restrict source ..." */ - DPRINTF(1, ("restrict source template mflags %x flags %x\n", - mflags, flags)); - hack_restrict(RESTRICT_FLAGS, NULL, - NULL, mflags, flags, 0); + DPRINTF(1, ("restrict source template ippeerlimit %d mflags %x rflags %x\n", + ippeerlimit, mflags, rflags)); + hack_restrict(RESTRICT_FLAGS, NULL, NULL, + ippeerlimit, mflags, rflags, 0); continue; } } else { @@ -2661,15 +2788,15 @@ config_access( if (restrict_default) { AF(&addr) = AF_INET; AF(&mask) = AF_INET; - hack_restrict(RESTRICT_FLAGS, &addr, - &mask, mflags, flags, 0); + hack_restrict(RESTRICT_FLAGS, &addr, &mask, + ippeerlimit, mflags, rflags, 0); AF(&addr) = AF_INET6; AF(&mask) = AF_INET6; } do { - hack_restrict(RESTRICT_FLAGS, &addr, - &mask, mflags, flags, 0); + hack_restrict(RESTRICT_FLAGS, &addr, &mask, + ippeerlimit, mflags, rflags, 0); if (pai != NULL && NULL != (pai = pai->ai_next)) { INSIST(pai->ai_addr != NULL); @@ -2720,6 +2847,9 @@ config_rlimit( case T_Memlock: /* What if we HAVE_OPT(SAVECONFIGQUIT) ? */ + if (HAVE_OPT( SAVECONFIGQUIT )) { + break; + } if (rlimit_av->value.i == -1) { # if defined(HAVE_MLOCKALL) if (cur_memlock != 0) { @@ -3006,17 +3136,17 @@ apply_enable_disable( int enable ) { - attr_val *curr_flag; + attr_val *curr_tok_fifo; int option; #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED bc_entry *pentry; #endif - for (curr_flag = HEAD_PFIFO(fifo); - curr_flag != NULL; - curr_flag = curr_flag->link) { + for (curr_tok_fifo = HEAD_PFIFO(fifo); + curr_tok_fifo != NULL; + curr_tok_fifo = curr_tok_fifo->link) { - option = curr_flag->value.i; + option = curr_tok_fifo->value.i; switch (option) { default: @@ -3851,6 +3981,9 @@ config_peers( * If we have a numeric address, we can safely * proceed in the mainline with it. Otherwise, hand * the hostname off to the blocking child. + * + * Note that if we're told to add the peer here, we + * do that regardless of ippeerlimit. */ if (is_ip_address(*cmdline_servers, AF_UNSPEC, &peeraddr)) { @@ -3862,6 +3995,7 @@ config_peers( &peeraddr, NULL, NULL, + -1, MODE_CLIENT, NTP_VERSION, 0, @@ -3912,6 +4046,7 @@ config_peers( &peeraddr, curr_peer->addr->address, NULL, + -1, hmode, curr_peer->peerversion, curr_peer->minpoll, @@ -3935,6 +4070,7 @@ config_peers( &peeraddr, NULL, NULL, + -1, hmode, curr_peer->peerversion, curr_peer->minpoll, @@ -4035,6 +4171,7 @@ peer_name_resolved( &peeraddr, NULL, NULL, + -1, ctx->hmode, ctx->version, ctx->minpoll, @@ -4113,7 +4250,7 @@ config_unpeers( if (rc > 0) { DPRINTF(1, ("unpeer: searching for %s\n", stoa(&peeraddr))); - p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0); + p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL); if (p != NULL) { msyslog(LOG_NOTICE, "unpeered %s", stoa(&peeraddr)); @@ -4193,7 +4330,7 @@ unpeer_name_resolved( memcpy(&peeraddr, res->ai_addr, res->ai_addrlen); DPRINTF(1, ("unpeer: searching for peer %s\n", stoa(&peeraddr))); - peer = findexistingpeer(&peeraddr, NULL, NULL, -1, 0); + peer = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL); if (peer != NULL) { af = AF(&peeraddr); fam_spec = (AF_INET6 == af) @@ -4420,6 +4557,15 @@ config_ntpd( int/*BOOL*/ input_from_files ) { + /* [Bug 3435] check and esure clock sanity if configured from + * file and clock sanity parameters (-> basedate) are given. Do + * this ASAP, so we don't disturb the closed loop controller. + */ + if (input_from_files) { + if (config_tos_clock(ptree)) + clamp_systime(); + } + config_nic_rules(ptree, input_from_files); config_monitor(ptree); config_auth(ptree); @@ -4444,6 +4590,12 @@ config_ntpd( config_fudge(ptree); config_reset_counters(ptree); +#ifdef DEBUG + if (debug > 1) { + dump_restricts(); + } +#endif + #ifdef TEST_BLOCKING_WORKER { struct addrinfo hints; @@ -5043,6 +5195,9 @@ ntp_rlimit( switch (rl_what) { # ifdef RLIMIT_MEMLOCK case RLIMIT_MEMLOCK: + if (HAVE_OPT( SAVECONFIGQUIT )) { + break; + } /* * The default RLIMIT_MEMLOCK is very low on Linux systems. * Unless we increase this limit malloc calls are likely to @@ -5104,3 +5259,217 @@ ntp_rlimit( } } #endif /* HAVE_SETRLIMIT */ + + +char * +build_iflags(u_int32 iflags) +{ + static char ifs[1024]; + + ifs[0] = '\0'; + + if (iflags & INT_UP) { + iflags &= ~INT_UP; + appendstr(ifs, sizeof ifs, "up"); + } + + if (iflags & INT_PPP) { + iflags &= ~INT_PPP; + appendstr(ifs, sizeof ifs, "ppp"); + } + + if (iflags & INT_LOOPBACK) { + iflags &= ~INT_LOOPBACK; + appendstr(ifs, sizeof ifs, "loopback"); + } + + if (iflags & INT_BROADCAST) { + iflags &= ~INT_BROADCAST; + appendstr(ifs, sizeof ifs, "broadcast"); + } + + if (iflags & INT_MULTICAST) { + iflags &= ~INT_MULTICAST; + appendstr(ifs, sizeof ifs, "multicast"); + } + + if (iflags & INT_BCASTOPEN) { + iflags &= ~INT_BCASTOPEN; + appendstr(ifs, sizeof ifs, "bcastopen"); + } + + if (iflags & INT_MCASTOPEN) { + iflags &= ~INT_MCASTOPEN; + appendstr(ifs, sizeof ifs, "mcastopen"); + } + + if (iflags & INT_WILDCARD) { + iflags &= ~INT_WILDCARD; + appendstr(ifs, sizeof ifs, "wildcard"); + } + + if (iflags & INT_MCASTIF) { + iflags &= ~INT_MCASTIF; + appendstr(ifs, sizeof ifs, "MCASTif"); + } + + if (iflags & INT_PRIVACY) { + iflags &= ~INT_PRIVACY; + appendstr(ifs, sizeof ifs, "IPv6privacy"); + } + + if (iflags & INT_BCASTXMIT) { + iflags &= ~INT_BCASTXMIT; + appendstr(ifs, sizeof ifs, "bcastxmit"); + } + + if (iflags) { + char string[10]; + + snprintf(string, sizeof string, "%0x", iflags); + appendstr(ifs, sizeof ifs, string); + } + + return ifs; +} + + +char * +build_mflags(u_short mflags) +{ + static char mfs[1024]; + + mfs[0] = '\0'; + + if (mflags & RESM_NTPONLY) { + mflags &= ~RESM_NTPONLY; + appendstr(mfs, sizeof mfs, "ntponly"); + } + + if (mflags & RESM_SOURCE) { + mflags &= ~RESM_SOURCE; + appendstr(mfs, sizeof mfs, "source"); + } + + if (mflags) { + char string[10]; + + snprintf(string, sizeof string, "%0x", mflags); + appendstr(mfs, sizeof mfs, string); + } + + return mfs; +} + + +char * +build_rflags(u_short rflags) +{ + static char rfs[1024]; + + rfs[0] = '\0'; + + if (rflags & RES_FLAKE) { + rflags &= ~RES_FLAKE; + appendstr(rfs, sizeof rfs, "flake"); + } + + if (rflags & RES_IGNORE) { + rflags &= ~RES_IGNORE; + appendstr(rfs, sizeof rfs, "ignore"); + } + + if (rflags & RES_KOD) { + rflags &= ~RES_KOD; + appendstr(rfs, sizeof rfs, "kod"); + } + + if (rflags & RES_MSSNTP) { + rflags &= ~RES_MSSNTP; + appendstr(rfs, sizeof rfs, "mssntp"); + } + + if (rflags & RES_LIMITED) { + rflags &= ~RES_LIMITED; + appendstr(rfs, sizeof rfs, "limited"); + } + + if (rflags & RES_LPTRAP) { + rflags &= ~RES_LPTRAP; + appendstr(rfs, sizeof rfs, "lptrap"); + } + + if (rflags & RES_NOMODIFY) { + rflags &= ~RES_NOMODIFY; + appendstr(rfs, sizeof rfs, "nomodify"); + } + + if (rflags & RES_NOMRULIST) { + rflags &= ~RES_NOMRULIST; + appendstr(rfs, sizeof rfs, "nomrulist"); + } + + if (rflags & RES_NOEPEER) { + rflags &= ~RES_NOEPEER; + appendstr(rfs, sizeof rfs, "noepeer"); + } + + if (rflags & RES_NOPEER) { + rflags &= ~RES_NOPEER; + appendstr(rfs, sizeof rfs, "nopeer"); + } + + if (rflags & RES_NOQUERY) { + rflags &= ~RES_NOQUERY; + appendstr(rfs, sizeof rfs, "noquery"); + } + + if (rflags & RES_DONTSERVE) { + rflags &= ~RES_DONTSERVE; + appendstr(rfs, sizeof rfs, "dontserve"); + } + + if (rflags & RES_NOTRAP) { + rflags &= ~RES_NOTRAP; + appendstr(rfs, sizeof rfs, "notrap"); + } + + if (rflags & RES_DONTTRUST) { + rflags &= ~RES_DONTTRUST; + appendstr(rfs, sizeof rfs, "notrust"); + } + + if (rflags & RES_VERSION) { + rflags &= ~RES_VERSION; + appendstr(rfs, sizeof rfs, "version"); + } + + if (rflags) { + char string[10]; + + snprintf(string, sizeof string, "%0x", rflags); + appendstr(rfs, sizeof rfs, string); + } + + if ('\0' == rfs[0]) { + appendstr(rfs, sizeof rfs, "(none)"); + } + + return rfs; +} + + +static void +appendstr( + char *string, + size_t s, + char *new + ) +{ + if (*string != '\0') { + (void)strlcat(string, ",", s); + } + (void)strlcat(string, new, s); + + return; +} |