static DWORD LWNetSrvGetDCNameDiscoverInternal( IN PCSTR pszDnsDomainName, IN OPTIONAL PCSTR pszSiteName, IN OPTIONAL PCSTR pszPrimaryDomain, IN DWORD dwDsFlags, IN DWORD dwBlackListCount, IN OPTIONAL PSTR* ppszAddressBlackList, IN PLWNET_DC_LIST_QUERY_METHOD pfnDCListQuery, OUT PLWNET_DC_INFO* ppDcInfo, OUT OPTIONAL PDNS_SERVER_INFO* ppServerArray, OUT OPTIONAL PDWORD pdwServerCount, OUT PBOOLEAN pbFailedFindWritable ) // // Algorithm: // // - DNS query for desired site & required DC type (pdc, kdc, gc). // - note that if no site is specified, use "un-sited" lookup. // - If no site specified: // - CLDAP to one DC to get actual site // - use new site info that to do DNS query for updated DC list // - CLDAP to DCs in parallel to find the first responder // (meeting any additional criteria -- writable, etc) // { DWORD dwError = 0; PLWNET_DC_INFO pDcInfo = NULL; PDNS_SERVER_INFO pServerArray = NULL; PDNS_SERVER_INFO pServersInPrimaryDomain = NULL; DWORD dwServersInPrimaryDomainCount = 0; DWORD dwServerCount = 0; PLWNET_DC_INFO pSiteDcInfo = NULL; PDNS_SERVER_INFO pSiteServerArray = NULL; DWORD dwSiteServerCount = 0; BOOLEAN bFailedFindWritable = FALSE; // Get server list dwError = pfnDCListQuery(pszDnsDomainName, pszSiteName, dwDsFlags, &pServerArray, &dwServerCount); BAIL_ON_LWNET_ERROR(dwError); LWNetFilterFromBlackList( dwBlackListCount, ppszAddressBlackList, &dwServerCount, pServerArray); if (!dwServerCount) { dwError = ERROR_DOMAIN_BLACKLISTED; BAIL_ON_LWNET_ERROR(dwError); } if (pszPrimaryDomain) { dwError = LWNetFindServersInDomain( pServerArray, dwServerCount, pszPrimaryDomain, &pServersInPrimaryDomain, &dwServersInPrimaryDomainCount); BAIL_ON_LWNET_ERROR(dwError); LWNetFilterFromBlackList( dwBlackListCount, ppszAddressBlackList, &dwServersInPrimaryDomainCount, pServersInPrimaryDomain); if (dwServersInPrimaryDomainCount > 0) { dwError = LWNetSrvPingCLdapArray(pszDnsDomainName, dwDsFlags, pServersInPrimaryDomain, dwServersInPrimaryDomainCount, 0, &pDcInfo, &bFailedFindWritable); } if (dwServersInPrimaryDomainCount == 0 || dwError == NERR_DCNotFound) { dwError = LWNetSrvPingCLdapArray(pszDnsDomainName, dwDsFlags, pServerArray, dwServerCount, 0, &pDcInfo, &bFailedFindWritable); BAIL_ON_LWNET_ERROR(dwError); } } else { // Do CLDAP dwError = LWNetSrvPingCLdapArray(pszDnsDomainName, dwDsFlags, pServerArray, dwServerCount, 0, &pDcInfo, &bFailedFindWritable); BAIL_ON_LWNET_ERROR(dwError); } // If there is no client site, then we are done (though we do not // expect this to ever happen). if (IsNullOrEmptyString(pDcInfo->pszClientSiteName)) { LWNET_LOG_ALWAYS("Missing client site name from " "DC response from %s (%s)", LWNET_SAFE_LOG_STRING(pDcInfo->pszDomainControllerName), LWNET_SAFE_LOG_STRING(pDcInfo->pszDomainControllerAddress)); goto cleanup; } // If a site was passed in, there is nothing more to do. if (!IsNullOrEmptyString(pszSiteName)) { goto cleanup; } // There was no site passed in, so we need to look at the // CLDAP response to get the client site. // If we got the correct site already, we are done. if (LWNetSrvIsInSameSite(pDcInfo)) { if (LWNetIsUpdateKrb5AffinityEnabled(dwDsFlags, pszSiteName, pDcInfo) && !pszSiteName && pDcInfo->pszClientSiteName) { dwError = pfnDCListQuery( pszDnsDomainName, pDcInfo->pszClientSiteName, dwDsFlags, &pSiteServerArray, &dwSiteServerCount); if (dwError == 0) { // Use the site-specific DC. LWNET_SAFE_FREE_MEMORY(pServerArray); dwServerCount = 0; LWNetFilterFromBlackList( dwBlackListCount, ppszAddressBlackList, &dwSiteServerCount, pSiteServerArray); if (!dwSiteServerCount) { dwError = DNS_ERROR_BAD_PACKET; BAIL_ON_LWNET_ERROR(dwError); } pServerArray = pSiteServerArray; dwServerCount = dwSiteServerCount; pSiteServerArray = NULL; dwSiteServerCount = 0; } } dwError = 0; goto cleanup; } // Now we need to use the client site to find a site-specific DC. dwError = LWNetSrvGetDCNameDiscover(pszDnsDomainName, pDcInfo->pszClientSiteName, pszPrimaryDomain, dwDsFlags, dwBlackListCount, ppszAddressBlackList, &pSiteDcInfo, &pSiteServerArray, &dwSiteServerCount, &bFailedFindWritable); if (NERR_DCNotFound == dwError) { if (bFailedFindWritable) { LWNET_LOG_WARNING("No writable DC in client site '%s' for domain '%s'", pDcInfo->pszClientSiteName, pszDnsDomainName); } // Count not find site-specific DC, so use the original DC. dwError = 0; goto cleanup; } BAIL_ON_LWNET_ERROR(dwError); // Use the site-specific DC. LWNET_SAFE_FREE_DC_INFO(pDcInfo); LWNET_SAFE_FREE_MEMORY(pServerArray); dwServerCount = 0; pDcInfo = pSiteDcInfo; pServerArray = pSiteServerArray; dwServerCount = dwSiteServerCount; pSiteDcInfo = NULL; pSiteServerArray = NULL; dwSiteServerCount = 0; error: cleanup: LWNET_SAFE_FREE_DC_INFO(pSiteDcInfo); LWNET_SAFE_FREE_MEMORY(pSiteServerArray); LWNET_SAFE_FREE_MEMORY(pServersInPrimaryDomain); dwSiteServerCount = 0; if (dwError) { LWNET_SAFE_FREE_DC_INFO(pDcInfo); LWNET_SAFE_FREE_MEMORY(pServerArray); dwServerCount = 0; } *ppDcInfo = pDcInfo; if (ppServerArray) { *ppServerArray = pServerArray; *pdwServerCount = dwServerCount; } else { LWNET_SAFE_FREE_MEMORY(pServerArray); } *pbFailedFindWritable = bFailedFindWritable; return dwError; }
DWORD LWNetDnsGetAddressForServer( IN PDLINKEDLIST pAdditionalsList, IN PCSTR pszHostname, OUT PSTR* ppszAddress ) { DWORD dwError = 0; PSTR pszAddress = NULL; PDLINKEDLIST pListMember = NULL; pListMember = pAdditionalsList; while (pListMember) { PDNS_RECORD pRecord = (PDNS_RECORD)pListMember->pItem; if ( (pRecord->wType == ns_t_a ) && !strcasecmp( pRecord->pszName, pszHostname ) ) { dwError = LwAllocateStringPrintf(&pszAddress, "%d.%d.%d.%d", pRecord->pData[0], pRecord->pData[1], pRecord->pData[2], pRecord->pData[3]); BAIL_ON_LWNET_ERROR(dwError); break; } pListMember = pListMember->pNext; } if (IsNullOrEmptyString(pszAddress)) { struct hostent * host; LWNET_LOG_VERBOSE("Getting address for '%s'", pszHostname); host = gethostbyname(pszHostname); if (host && host->h_name) { // ISSUE-2008/07/01-dalmeida -- Need to check that address type is IPv4 dwError = LWNetAllocateString(inet_ntoa(*(struct in_addr*)(host->h_addr_list[0])), &pszAddress); BAIL_ON_LWNET_ERROR(dwError); } } if (IsNullOrEmptyString(pszAddress)) { LWNET_LOG_WARNING("Unable to get IP address for '%s'", pszHostname); dwError = ERROR_NOT_FOUND; BAIL_ON_LWNET_ERROR(dwError); } error: if (dwError) { LWNET_SAFE_FREE_STRING(pszAddress); } *ppszAddress = pszAddress; return dwError; }