Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}