[Bug 1517] ntpq and ntpdc should verify reverse DNS before use.
ntpq and ntpdc now use the following format for showing purported
DNS names from IP address "reverse" DNS lookups when the DNS name
does not exist or does not include the original IP address among
the results: "192.168.1.2 (fake.dns.local)".
bk: 4bb8108cauaG1mslKFv9Hy_H9hvGNg
+* [Bug 1516] unpeer by IP address fails, DNS name works.
+* [Bug 1517] ntpq and ntpdc should verify reverse DNS before use.
+ ntpq and ntpdc now use the following format for showing purported
+ DNS names from IP address "reverse" DNS lookups when the DNS name
+ does not exist or does not include the original IP address among
+ the results: "192.168.1.2 (fake.dns.local)".
(4.2.7p22) 2010/04/02 Released by Harlan Stenn <stenn@ntp.org>
* [Bug 1432] Don't set inheritable flag for linux capabilities.
* [Bug 1465] Make sure time from TS2100 is not invalid.
#include "lib_strbuf.h"
#include "ntp_stdlib.h"
#include "ntp.h"
+#include "ntp_debug.h"
char *
sockaddr_u *sock
)
{
- register char *buffer;
+ const char svc[] = "ntp";
+ char * pbuf;
+ char * pliar;
+ int gni_flags;
+ struct addrinfo hints;
+ struct addrinfo * alist;
+ struct addrinfo * ai;
+ int a_info;
- LIB_GETBUF(buffer);
- if (getnameinfo(&sock->sa, SOCKLEN(sock), buffer,
- LIB_BUFLENGTH, NULL, 0, 0))
- return stoa(sock);
+ /* reverse the address to purported DNS name */
+ LIB_GETBUF(pbuf);
+ gni_flags = NI_DGRAM | NI_NAMEREQD;
+ if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH,
+ NULL, 0, gni_flags))
+ return stoa(sock); /* use address */
- return buffer;
+ DPRINTF(1, ("%s reversed to %s\n", stoa(sock), pbuf));
+
+ /*
+ * Resolve the reversed name and make sure the reversed address
+ * is among the results.
+ */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF(sock);
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_flags = 0;
+ alist = NULL;
+
+ a_info = getaddrinfo(pbuf, svc, &hints, &alist);
+ if (a_info == EAI_NONAME
+#ifdef EAI_NODATA
+ || a_info == EAI_NODATA
+#endif
+ ) {
+ hints.ai_flags = AI_CANONNAME;
+#ifdef AI_ADDRCONFIG
+ hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+ a_info = getaddrinfo(pbuf, svc, &hints, &alist);
+ }
+#ifdef AI_ADDRCONFIG
+ /* Some older implementations don't like AI_ADDRCONFIG. */
+ if (a_info == EAI_BADFLAGS) {
+ hints.ai_flags &= ~AI_ADDRCONFIG;
+ a_info = getaddrinfo(pbuf, svc, &hints, &alist);
+ }
+#endif
+ if (a_info)
+ goto forward_fail;
+
+ NTP_INSIST(alist != NULL);
+
+ for (ai = alist; ai != NULL; ai = ai->ai_next)
+ if (SOCK_EQ(sock, (sockaddr_u *)ai->ai_addr))
+ break;
+ freeaddrinfo(alist);
+
+ if (ai != NULL)
+ return pbuf; /* forward check passed */
+
+ forward_fail:
+ DPRINTF(1, ("forward check lookup fail: %s\n", pbuf));
+ LIB_GETBUF(pliar);
+ snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf);
+
+ return pliar;
}
{
sockaddr_u peeraddr;
struct addrinfo hints;
- isc_netaddr_t i_netaddr;
struct unpeer_node * curr_unpeer;
struct peer * p;
const char * name;
- u_short af;
+ int rc;
for (curr_unpeer = queue_head(ptree->unpeers);
curr_unpeer != NULL;
continue;
}
+ memset(&peeraddr, 0, sizeof(peeraddr));
+ AF(&peeraddr) = curr_unpeer->addr->type;
name = curr_unpeer->addr->address;
- af = curr_unpeer->addr->type;
+ rc = getnetnum(name, &peeraddr, 0, t_UNK);
/* Do we have a numeric address? */
- if (is_ip_address(name, af, &i_netaddr)) {
- AF(&peeraddr) = (u_short)i_netaddr.family;
- if (AF_INET6 == i_netaddr.family)
- SET_ADDR6N(&peeraddr,
- i_netaddr.type.in6);
- else
- SET_ADDR4N(&peeraddr,
- i_netaddr.type.in.s_addr);
-
+ if (rc > 0) {
DPRINTF(1, ("unpeer: searching for %s\n",
stoa(&peeraddr)));
p = findexistingpeer(&peeraddr, NULL, NULL, -1);
/* Resolve the hostname to address(es). */
#ifdef WORKER
memset(&hints, 0, sizeof(hints));
- hints.ai_family = af;
+ hints.ai_family = curr_unpeer->addr->type;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
getaddrinfo_sometime(name, "ntp", &hints,
const char *num,
sockaddr_u *addr,
int complain,
- enum gnn_type a_type
+ enum gnn_type a_type /* ignored */
)
{
isc_netaddr_t ipaddr;
const char *hname
)
{
+ const char svc[] = "ntp";
char temphost[LENHOSTNAME];
int a_info, i;
- struct addrinfo hints, *ai = NULL;
+ struct addrinfo hints, *ai;
register const char *cp;
char name[LENHOSTNAME];
- char service[5];
/*
* We need to get by the [] if they were entered
* will return an "IPv4-mapped IPv6 address" address if you
* give it an IPv4 address to lookup.
*/
- strcpy(service, "ntp");
- memset((char *)&hints, 0, sizeof(struct addrinfo));
+ memset(&hints, 0, sizeof(hints));
hints.ai_family = ai_fam_templ;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = Z_AI_NUMERICHOST;
+ ai = NULL;
- a_info = getaddrinfo(hname, service, &hints, &ai);
+ a_info = getaddrinfo(hname, svc, &hints, &ai);
if (a_info == EAI_NONAME
#ifdef EAI_NODATA
|| a_info == EAI_NODATA
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif
- a_info = getaddrinfo(hname, service, &hints, &ai);
+ a_info = getaddrinfo(hname, svc, &hints, &ai);
}
#ifdef AI_ADDRCONFIG
/* Some older implementations don't like AI_ADDRCONFIG. */
if (a_info == EAI_BADFLAGS) {
hints.ai_flags &= ~AI_ADDRCONFIG;
- a_info = getaddrinfo(hname, service, &hints, &ai);
+ a_info = getaddrinfo(hname, svc, &hints, &ai);
}
#endif
if (a_info != 0) {