From: Martin Burnicki Date: Tue, 19 Jun 2018 11:00:54 +0000 (+0200) Subject: Fixes for ntpdate as discussed in bug #3442. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa44452edfe001aa7b07fdf79fa3c7b2aa29ed12;p=thirdparty%2Fntp.git Fixes for ntpdate as discussed in bug #3442. bk: 5b28e266Iv8CnIp2uGuMQqZG3fp3OA --- diff --git a/ChangeLog b/ChangeLog index 61e886ebd..6a8bbce3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +* [Bug 3442] Fixes for ntpdate as suggested by Gerry Garvey, + with modifications New macro REFID_ISTEXT() which is also used in ntpd/ntp_control.c. --- diff --git a/ntpdate/ntpdate.c b/ntpdate/ntpdate.c index 8d80767b9..03d9552dd 100644 --- a/ntpdate/ntpdate.c +++ b/ntpdate/ntpdate.c @@ -154,7 +154,7 @@ char const *progname; /* * Systemwide parameters and flags */ -int sys_samples = DEFSAMPLES; /* number of samples/server */ +int sys_samples = 0; /* number of samples/server, will be modified later */ u_long sys_timeout = DEFTIMEOUT; /* timeout time, in TIMER_HZ units */ struct server *sys_servers; /* the server list */ int sys_numservers = 0; /* number of servers to poll */ @@ -220,7 +220,7 @@ void input_handler (void); static int l_adj_systime (l_fp *); static int l_step_systime (l_fp *); -static void printserver (struct server *, FILE *); +static void print_server (struct server *, FILE *); #ifdef SYS_WINNT int on = 1; @@ -437,6 +437,14 @@ ntpdatemain ( exit(2); } + /* + * If number of Samples (-p) not specified by user: + * - if a simple_query (-q) just ONE will do + * - otherwise the normal is DEFSAMPLES + */ + if (sys_samples == 0) + sys_samples = (simple_query ? 1 : DEFSAMPLES); + if (debug || simple_query) { #ifdef HAVE_SETVBUF static char buf[BUFSIZ]; @@ -651,9 +659,6 @@ transmit( { struct pkt xpkt; - if (debug) - printf("transmit(%s)\n", stoa(&server->srcadr)); - if (server->filter_nextpt < server->xmtcnt) { l_fp ts; /* @@ -674,6 +679,9 @@ transmit( return; } + if (debug) + printf("transmit(%s)\n", stoa(&server->srcadr)); + /* * If we're here, send another message to the server. Fill in * the packet and let 'er rip. @@ -849,7 +857,7 @@ receive( NTOHL_FP(&rpkt->xmt, &server->org); /* - * Make sure the server is at least somewhat sane. If not, try + * Make sure the server is at least somewhat sane. If not, try * again. */ if (L_ISZERO(&rec) || !L_ISHIS(&server->org, &rec)) { @@ -1042,15 +1050,15 @@ clock_select(void) /* * This first chunk of code is supposed to go through all * servers we know about to find the NTP_MAXLIST servers which - * are most likely to succeed. We run through the list + * are most likely to succeed. We run through the list * doing the sanity checks and trying to insert anyone who - * looks okay. We are at all times aware that we should + * looks okay. We are at all times aware that we should * only keep samples from the top two strata and we only need * NTP_MAXLIST of them. */ nlist = 0; /* none yet */ for (server = sys_servers; server != NULL; server = server->next_server) { - if (server->delay == 0) { + if (server->stratum == 0) { if (debug) printf("%s: Server dropped: no data\n", ntoa(&server->srcadr)); continue; /* no data */ @@ -1068,7 +1076,7 @@ clock_select(void) } if (server->leap == LEAP_NOTINSYNC) { if (debug) - printf("%s: Server dropped: Leap not in sync\n", ntoa(&server->srcadr)); + printf("%s: Server dropped: leap not in sync\n", ntoa(&server->srcadr)); continue; /* he's in trouble */ } if (!L_ISHIS(&server->org, &server->reftime)) { @@ -1080,7 +1088,7 @@ clock_select(void) if ((server->org.l_ui - server->reftime.l_ui) >= NTP_MAXAGE) { if (debug) - printf("%s: Server dropped: Server has gone too long without sync\n", + printf("%s: Server dropped: server has gone too long without sync\n", ntoa(&server->srcadr)); continue; /* too long without sync */ } @@ -1256,8 +1264,10 @@ clock_adjust(void) server = clock_select(); if (debug || simple_query) { + if (debug) + printf ("\n"); for (sp = sys_servers; sp != NULL; sp = sp->next_server) - printserver(sp, stdout); + print_server(sp, stdout); } if (server == 0) { @@ -1283,31 +1293,17 @@ clock_adjust(void) } if (dostep) { - if (simple_query || debug || l_step_systime(&server->offset)){ + if (simple_query || l_step_systime(&server->offset)){ msyslog(LOG_NOTICE, "step time server %s offset %s sec", stoa(&server->srcadr), lfptoa(&server->offset, 6)); } } else { -#ifndef SYS_WINNT if (simple_query || l_adj_systime(&server->offset)) { msyslog(LOG_NOTICE, "adjust time server %s offset %s sec", stoa(&server->srcadr), lfptoa(&server->offset, 6)); } -#else - /* The NT SetSystemTimeAdjustment() call achieves slewing by - * changing the clock frequency. This means that we cannot specify - * it to slew the clock by a definite amount and then stop like - * the Unix adjtime() routine. We can technically adjust the clock - * frequency, have ntpdate sleep for a while, and then wake - * up and reset the clock frequency, but this might cause some - * grief if the user attempts to run ntpd immediately after - * ntpdate and the socket is in use. - */ - printf("\nThe -b option is required by ntpdate on Windows NT platforms\n"); - exit(1); -#endif /* SYS_WINNT */ } return(0); } @@ -1605,24 +1601,26 @@ init_alarm(void) #else /* SYS_WINNT follows */ _tzset(); - /* - * Get privileges needed for fiddling with the clock - */ + if (!simple_query && !debug) { + /* + * Get privileges needed for fiddling with the clock + */ - /* get the current process token handle */ - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { - msyslog(LOG_ERR, "OpenProcessToken failed: %m"); - exit(1); + /* get the current process token handle */ + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + msyslog(LOG_ERR, "OpenProcessToken failed: %m"); + exit(1); + } + /* get the LUID for system-time privilege. */ + LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); + tkp.PrivilegeCount = 1; /* one privilege to set */ + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + /* get set-time privilege for this process. */ + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); + /* cannot test return value of AdjustTokenPrivileges. */ + if (GetLastError() != ERROR_SUCCESS) + msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); } - /* get the LUID for system-time privilege. */ - LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); - tkp.PrivilegeCount = 1; /* one privilege to set */ - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - /* get set-time privilege for this process. */ - AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); - /* cannot test return value of AdjustTokenPrivileges. */ - if (GetLastError() != ERROR_SUCCESS) - msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); /* * Set up timer interrupts for every 2**EVENT_TIMEOUT seconds @@ -1996,7 +1994,6 @@ input_handler(void) } -#if !defined SYS_WINNT && !defined SYS_CYGWIN32 /* * adj_systime - do a big long slew of the system time */ @@ -2041,15 +2038,30 @@ l_adj_systime( adjtv.tv_usec = -adjtv.tv_usec; } - if (adjtv.tv_usec != 0 && !debug) { + if (!debug && (adjtv.tv_usec != 0)) { + /* A time correction needs to be applied. */ +#if !defined SYS_WINNT && !defined SYS_CYGWIN32 + /* Slew the time on systems that support this. */ if (adjtime(&adjtv, &oadjtv) < 0) { msyslog(LOG_ERR, "Can't adjust the time of day: %m"); exit(1); } +#else /* SYS_WINNT or SYS_CYGWIN32 is defined */ + /* + * The NT SetSystemTimeAdjustment() call achieves slewing by + * changing the clock frequency. This means that we cannot specify + * it to slew the clock by a definite amount and then stop like + * the Unix adjtime() routine. We can technically adjust the clock + * frequency, have ntpdate sleep for a while, and then wake + * up and reset the clock frequency, but this might cause some + * grief if the user attempts to run ntpd immediately after + * ntpdate and the socket is in use. + */ + printf("\nSlewing the system time is not supported on Windows. Use the -b option to step the time.\n"); +#endif /* defined SYS_WINNT || defined SYS_CYGWIN32 */ } return 1; } -#endif /* SYS_WINNT */ /* @@ -2068,11 +2080,14 @@ l_step_systime( int isneg; int n; - if (debug) return 1; + if (debug) + return 1; + /* * Take the absolute value of the offset */ ftmp = *ts; + if (L_ISNEG(&ftmp)) { L_NEG(&ftmp); isneg = 1; @@ -2082,9 +2097,9 @@ l_step_systime( if (ftmp.l_ui >= 3) { /* Step it and slew - we might win */ LFPTOD(ts, dtemp); n = step_systime(dtemp); - if (!n) - return n; - if (isneg) + if (n == 0) + return 0; + if (isneg) /* WTF! */ ts->l_ui = ~0; else ts->l_ui = ~0; @@ -2113,12 +2128,12 @@ l_step_systime( } -/* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c */ +/* XXX ELIMINATE print_server similar in ntptrace.c, ntpdate.c */ /* - * printserver - print detail information for a server + * print_server - print detail information for a server */ static void -printserver( +print_server( register struct server *pp, FILE *fp ) @@ -2127,6 +2142,9 @@ printserver( char junk[5]; const char *str; + if (pp->stratum == 0) /* Nothing received => nothing to print */ + return; + if (!debug) { (void) fprintf(fp, "server %s, stratum %d, offset %s, delay %s\n", stoa(&pp->srcadr), pp->stratum, @@ -2143,17 +2161,20 @@ printserver( pp->leap & 0x1 ? '1' : '0', pp->trust); - if (pp->stratum == 1) { - junk[4] = 0; - memmove(junk, (char *)&pp->refid, 4); + if (REFID_ISTEXT(pp->stratum)) { + str = (char *) &pp->refid; + for (i=0; i<4 && str[i]; i++) { + junk[i] = (isprint(str[i]) ? str[i] : '.'); + } + junk[i] = 0; // force terminating 0 str = junk; } else { - str = stoa(&pp->srcadr); + str = numtoa(pp->refid); } (void) fprintf(fp, - "refid [%s], delay %s, dispersion %s\n", - str, fptoa((s_fp)pp->delay, 5), - ufptoa(pp->dispersion, 5)); + "refid [%s], root delay %s, root dispersion %s\n", + str, fptoa((s_fp)pp->rootdelay, 6), + ufptoa(pp->rootdisp, 6)); (void) fprintf(fp, "transmitted %d, in filter %d\n", pp->xmtcnt, pp->filter_nextpt); @@ -2165,21 +2186,23 @@ printserver( (void) fprintf(fp, "transmit timestamp: %s\n", prettydate(&pp->xmt)); - (void) fprintf(fp, "filter delay: "); - for (i = 0; i < NTP_SHIFT; i++) { - (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5)); - if (i == (NTP_SHIFT>>1)-1) - (void) fprintf(fp, "\n "); - } - (void) fprintf(fp, "\n"); + if (sys_samples > 1) { + (void) fprintf(fp, "filter delay: "); + for (i = 0; i < NTP_SHIFT; i++) { + (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5)); + if (i == (NTP_SHIFT>>1)-1) + (void) fprintf(fp, "\n "); + } + (void) fprintf(fp, "\n"); - (void) fprintf(fp, "filter offset:"); - for (i = 0; i < PEER_SHIFT; i++) { - (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6)); - if (i == (PEER_SHIFT>>1)-1) - (void) fprintf(fp, "\n "); + (void) fprintf(fp, "filter offset:"); + for (i = 0; i < PEER_SHIFT; i++) { + (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6)); + if (i == (PEER_SHIFT>>1)-1) + (void) fprintf(fp, "\n "); + } + (void) fprintf(fp, "\n"); } - (void) fprintf(fp, "\n"); (void) fprintf(fp, "delay %s, dispersion %s\n", fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5));