--- prnetdb.c 2007-05-06 23:57:09.171405505 -0700 +++ prnetdb.c.good 2007-05-07 00:08:44.493617592 -0700 @@ -669,7 +669,8 @@ static PRStatus CopyProtoent( #endif /* definition of GETHOSTBYXXX */ -PR_IMPLEMENT(PRStatus) PR_GetHostByName( +/* DNS POLICY */ +PR_IMPLEMENT(PRStatus) PR_GetHostByName_Policy( const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp) { struct hostent *h; @@ -723,6 +724,53 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName( return rv; } +static PRStatus pr_CheckPolicy(const char *name, const char *addr) { + char query[PR_NETDB_BUF_SIZE]; + char tmpbuf[PR_NETDB_BUF_SIZE]; + PRHostEnt hostEntry; + + unsigned char *byte = (unsigned char*)addr; + PR_snprintf(query, sizeof(query), "auth.%u.%u.%u.%u.in-addr.arpa", byte[3], byte[2], byte[1], byte[0]); + + if ((PR_GetHostByName_Policy(query, tmpbuf, sizeof(tmpbuf), &hostEntry) != PR_SUCCESS) || hostEntry.h_length == 0) + return PR_SUCCESS; + + PR_snprintf(query, sizeof(query), "%s.auth.%u.%u.%u.%u.in-addr.arpa", name, byte[3], byte[2], byte[1], byte[0]); + + if ((PR_GetHostByName_Policy(query, tmpbuf, sizeof(tmpbuf), &hostEntry) != PR_SUCCESS) || hostEntry.h_length == 0) + return PR_FAILURE; + + return PR_SUCCESS; +} + +static PRStatus pr_CheckPolicyHostEnt(const char *name, PRHostEnt *hp) { + int hostIndex = 0; + PRNetAddr addr; + while ((hostIndex = PR_EnumerateHostEnt(hostIndex, hp, 0, &addr)) != 0) { + if (addr.raw.family != AF_INET) + continue; + + if (pr_CheckPolicy(name, (char *)&(addr.inet.ip)) != PR_SUCCESS) + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +PR_IMPLEMENT(PRStatus) PR_GetHostByName( + const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp) +{ + PRStatus rv; + rv = PR_GetHostByName_Policy(name, buf, bufsize, hp); + if (rv != PR_SUCCESS) + return rv; + + if (pr_CheckPolicyHostEnt(name, hp) != PR_SUCCESS) + return PR_FAILURE; + + return rv; +} + #if !defined(_PR_INET6) && \ defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) typedef struct hostent * (*_pr_getipnodebyname_t)(const char *, int, @@ -957,6 +1005,14 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByNam if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped; rv = CopyHostent(h, &buf, &bufsize, conversion, hp); + + /* DNS POLICY */ + if (rv == PR_SUCCESS && (pr_CheckPolicyHostEnt(name, hp) != PR_SUCCESS)) + { + rv = PR_FAILURE; + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, 0); + } + if (PR_SUCCESS != rv) PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) @@ -966,7 +1022,9 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByNam (*((_pr_freehostent_t)_pr_freehostent_fp))(h); #endif #if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED) + + + if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED) && ((flags & PR_AI_ALL) || ((flags & PR_AI_ADDRCONFIG) && _pr_have_inet_if)) && !did_af_inet && (h = GETHOSTBYNAME2(name, AF_INET)) != 0) { @@ -2037,6 +2095,21 @@ _pr_find_getaddrinfo(void) #endif /* _PR_HAVE_GETADDRINFO */ +/* DNS POLICY */ +static PRStatus pr_CheckPolicyAddrInfo(const char *name, PRAddrInfo *addrinfo) { + PRNetAddr addr; + void *iter = NULL; + while ((iter = PR_EnumerateAddrInfo(iter, addrinfo, 0, &addr)) != NULL) { + if (addr.raw.family != AF_INET) + continue; + + if (pr_CheckPolicy(name, (char *)&(addr.inet.ip)) != PR_SUCCESS) + return PR_FAILURE; + } + + return PR_SUCCESS; +} + /* * If getaddrinfo does not exist, then we will fall back on * PR_GetHostByName, which requires that we allocate a buffer for the @@ -2116,7 +2189,9 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInf hints.ai_socktype = SOCK_STREAM; rv = GETADDRINFO(hostname, NULL, &hints, &res); - if (rv == 0) + + /* DNS POLICY */ + if (rv == 0 && (pr_CheckPolicyAddrInfo(hostname, (PRAddrInfo *)res) == PR_SUCCESS)) return (PRAddrInfo *) res; PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv);