Example #1
0
/* Decompose a NetBIOS Second Layer name into an array of name components */
DWORD
LWNetNbName2ToParts(
    PBYTE NbNameL2,
    PSTR **retNbNameParts,
    PDWORD retNbNamePartsLen)
{
    DWORD dwError = 0;
    DWORD numParts = 0;
    DWORD len = 0;
    DWORD i = 0;
    UINT8 *ptr = NULL;
    PSTR *NBNameParts = NULL;

    /* Count number of parts in NetBIOS name */
    ptr = NbNameL2;
    while (*ptr)
    {
        len = (int) *ptr++;
        ptr += len;
        numParts++;
    }
    len++;

    dwError = LWNetAllocateMemory((numParts+1) * sizeof(*NBNameParts),
                                  (PVOID*)&NBNameParts);
    BAIL_ON_LWNET_ERROR(dwError);

    /* Reset and allocate strings for the various parts */
    ptr = NbNameL2;
    i = 0;
    while (*ptr)
    {
        len = (int) *ptr++;

        dwError = LWNetAllocateMemory((len + 1) * sizeof(char),
                      (PVOID*)&NBNameParts[i]);
        BAIL_ON_LWNET_ERROR(dwError);

        strncat(NBNameParts[i++], (char *) ptr, len);
        ptr += len;
    }
    ptr++;
    *retNbNameParts = NBNameParts;
    *retNbNamePartsLen = ptr - NbNameL2;

cleanup:
    return dwError;

error:
    if (NBNameParts)
    {
        for (i=0; NBNameParts[i]; i++)
        {
            LWNET_SAFE_FREE_MEMORY(NBNameParts[i]);
        }
        LWNET_SAFE_FREE_MEMORY(NBNameParts);
    }
    goto cleanup;
}
Example #2
0
static
DWORD
LWNetFindServersInDomain(
    IN PDNS_SERVER_INFO pServerArray,
    IN DWORD dwServerCount,
    IN PCSTR pszDomainName,
    OUT PDNS_SERVER_INFO* ppServersInDomain,
    OUT PDWORD pdwServersInDomainCount
)
{
    DWORD dwError = 0;
    DWORD i = 0;
    DWORD dwServersInDomainCount = 0;
    DWORD dwServerIndex = 0;
    PDNS_SERVER_INFO pServersInDomain = NULL;

    for (i = 0; i < dwServerCount; i++)
    {
        if (LWNetServerIsInDomain(&pServerArray[i], pszDomainName))
        {
            dwServersInDomainCount++;
        }
    }

    if (dwServersInDomainCount)
    {
        dwError = LWNetAllocateMemory(dwServersInDomainCount * sizeof(*pServerArray), OUT_PPVOID(&pServersInDomain));
        BAIL_ON_LWNET_ERROR(dwError);

        for (i = 0; i < dwServerCount; i++)
        {
            if (LWNetServerIsInDomain(&pServerArray[i], pszDomainName))
            {
                pServersInDomain[dwServerIndex++] = pServerArray[i];
            }
        }
    }

    *ppServersInDomain = pServersInDomain;
    *pdwServersInDomainCount = dwServersInDomainCount;

cleanup:

    return dwError;

error:

    *ppServersInDomain = NULL;
    *pdwServersInDomainCount = 0;

    LWNET_SAFE_FREE_MEMORY(pServersInDomain);

    goto cleanup;
}
Example #3
0
DWORD
LWNetNbConstructNameQuery(
    IN PSTR pszNetBiosHost,
    IN UINT8 bBroadcast,
    IN UINT8 queryType,
    OUT UINT16 *RetTransactionId,
    OUT UINT8 *NetBiosQuery,
    OUT PDWORD NetBiosQueryLen)
{
    DWORD dwError = 0;
    DWORD len = 0;
    DWORD NbNameLevel2Len = 0;
    UINT8 *NbNameLevel2 = NULL;
    UINT8 BuiltNBHeader[LWNB_NAME_MAX_LENGTH] = {0};
    UINT16 TransactionId = 0;

    dwError = LWNetNbStrToNbName2(
                  pszNetBiosHost,
                  queryType,
                  &NbNameLevel2,
                  &NbNameLevel2Len);
    BAIL_ON_LWNET_ERROR(dwError);

    TransactionId = LWNetNbNextTransactionId(gpNbCtx);
    dwError = LWNetNbConstructNameQueryHeader(
              TransactionId,
              bBroadcast ? LWNB_QUERY_BROADCAST : LWNB_QUERY_WINS,
              LWNB_OPCODE_QUERY,
              1,           // QDCOUNT: Number of names being looked up
              sizeof(BuiltNBHeader),
              BuiltNBHeader);
    BAIL_ON_LWNET_ERROR(dwError);

    /* Assemble the complete marshaled NetBIOS query packet */
    memcpy(&NetBiosQuery[len], BuiltNBHeader, LWNB_NAME_QUERY_HEADER_SIZE);
    len += LWNB_NAME_QUERY_HEADER_SIZE;
    memcpy(&NetBiosQuery[len], NbNameLevel2, NbNameLevel2Len);
    len += NbNameLevel2Len;
    memcpy(&NetBiosQuery[len], NetBiosQueryFooter, sizeof(NetBiosQueryFooter));
    len += sizeof(NetBiosQueryFooter);

    *NetBiosQueryLen = len;
    *RetTransactionId = TransactionId;

cleanup:
    LWNET_SAFE_FREE_MEMORY(NbNameLevel2);
    return dwError;

error:
    goto cleanup;
}
Example #4
0
VOID
LWNetSrvNetBiosCleanup(
    VOID
    )
{
    if (!gpNbCtx)
    {
        return;
    }
    pthread_mutex_destroy(&gpNbCtx->mutex);
    pthread_mutex_destroy(&gpNbCtx->mutexAck);
    pthread_cond_destroy(&gpNbCtx->cv);
    pthread_cond_destroy(&gpNbCtx->cvAck);
    LWNET_SAFE_FREE_MEMORY(gpNbCtx);
}
Example #5
0
DWORD
LWNetDnsParseName(
    IN PDNS_RESPONSE_HEADER pHeader,
    IN PBYTE pData,
    OUT PDWORD pdwBytesToAdvance,
    OUT OPTIONAL PSTR* ppszName
    )
{
    DWORD dwError = 0;
    DWORD dwBytesToAdvance = 0;
    DWORD dwNameLen = 0;
    PSTR pszName = NULL;

    /* Figure out the size and how many bytes the parse will advance */
    LWNetDnsParseNameWorker(pHeader, pData, &dwBytesToAdvance, &dwNameLen, NULL);

    if (ppszName)
    {
        /* Now allocate the memory, overallocating to ensure NULL termination in case
           the DNS packet does not termiante */
        dwError = LWNetAllocateMemory((dwNameLen+3) * sizeof(CHAR), (PVOID*)&pszName);
        BAIL_ON_LWNET_ERROR(dwError);

        /* Fill in the name */
        LWNetDnsParseNameWorker(pHeader, pData, NULL, NULL, pszName);

        /* Ensure NULL termination */
        pszName[dwNameLen] = 0;
    }
    
error:
    if (dwError)
    {
        LWNET_SAFE_FREE_MEMORY(pszName);
    }

    *pdwBytesToAdvance = dwBytesToAdvance;

    if (ppszName)
    {
        *ppszName = pszName;
    }

    return dwError;
}
Example #6
0
VOID
LWNetNbAddressListFree(
    IN struct in_addr *retAddrs)
{
    LWNET_SAFE_FREE_MEMORY(retAddrs);
}
Example #7
0
DWORD
LWNetNbParseNameQueryResponse(
    IN PBYTE buf,
    IN DWORD len,
    IN UINT16 TransactionId,
    OUT UINT16 *retTransactionId,
    OUT PSTR *retNbName,
    OUT UINT32 *retTTL,
    OUT UINT8 *retFlags,
    OUT struct in_addr **retAddrs,
    OUT PDWORD retAddrsLen)
{
    DWORD dwError = 0;
    DWORD i = 0;
    DWORD j = 0;
    UINT16 parseTransactionId = 0;
    UINT16 opCodeFlags = 0;
    UINT16 bResponse = 0;
    UINT16 nbQDCount = 0;
    UINT16 nbANCount = 0;
    UINT16 nbNSCount = 0;
    UINT16 nbARCount = 0;
    UINT16 nbNB = 0;
    UINT16 nbIN = 0;
    UINT32 nbTTL = 0;
    UINT16 nbNB_Flags = 0;
    UINT32 IpAddress = 0;
    UINT16 RDLength = 0;
    UINT8 queryType = 0;
    PSTR NetBiosName = NULL;
    PSTR NbName = NULL;
    DWORD numAddrs = 0;
    DWORD nbNameLen = 0;
    struct in_addr *addrs = NULL;

    memcpy(&parseTransactionId, &buf[i], sizeof(parseTransactionId));
    i += sizeof(parseTransactionId);

    parseTransactionId = ntohs(parseTransactionId);
    if (retTransactionId)
    {
        *retTransactionId = parseTransactionId;
    }

    memcpy(&opCodeFlags, &buf[i], sizeof(opCodeFlags));
    i += sizeof(opCodeFlags);

    opCodeFlags = ntohs(opCodeFlags);
    bResponse = opCodeFlags & (1 << LWNB_SHIFT_REQUEST_TYPE) ? 1 : 0;

#if 0
    /* Deal with other flags later... Not sure it matters at this point */

    opCodeFlags |= (bBroadcast & 1) << LWNB_SHIFT_FLAG_BROADCAST;
    opCodeFlags |= 1                << LWNB_SHIFT_FLAG_RECURSION_DESIRED;
    opCodeFlags |= (opcode & 4)     << LWNB_SHIFT_OPCODE;
#endif

    if (bResponse != LWNB_OPCODE_RESPONSE)
    {
        /* Something is seriously wrong if this is not a NetBIOS response */
        dwError = ERROR_BAD_NET_RESP;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    memcpy(&nbQDCount, &buf[i], sizeof(nbQDCount));
    i += sizeof(nbQDCount);
    nbQDCount = ntohs(nbQDCount);

    memcpy(&nbANCount, &buf[i], sizeof(nbANCount));
    i += sizeof(nbANCount);
    nbANCount = ntohs(nbANCount);
    if (nbANCount != 1)
    {
        /* There must be exactly 1 answer to the sent query */
        dwError = ERROR_BAD_NET_RESP;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    memcpy(&nbNSCount, &buf[i], sizeof(nbNSCount));
    i += sizeof(nbNSCount);
    nbNSCount = ntohs(nbNSCount);

    memcpy(&nbARCount, &buf[i], sizeof(nbARCount));
    i += sizeof(nbARCount);
    nbARCount = ntohs(nbARCount);

    dwError = LWNetNbName2ToStr(
                 &buf[i],
                 &NetBiosName,
                 &queryType,
                 &nbNameLen);
    BAIL_ON_LWNET_ERROR(dwError);
    i += nbNameLen;

    memcpy(&nbNB, &buf[i], sizeof(nbNB));
    i += sizeof(nbNB);
    nbNB = ntohs(nbNB);

    memcpy(&nbIN, &buf[i], sizeof(nbIN));
    i += sizeof(nbIN);
    nbIN = ntohs(nbIN);

    if (nbNB != 0x0020 || nbIN != 0x0001)
    {
        /* RFC 1002 says these must be the values for these fields */
        dwError = ERROR_BAD_NET_RESP;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    memcpy(&nbTTL, &buf[i], sizeof(nbTTL));
    i += sizeof(nbTTL);
    nbTTL = ntohl(nbTTL);
    if (retTTL)
    {
        *retTTL = nbTTL;
    }

    memcpy(&RDLength, &buf[i], sizeof(RDLength));
    i += sizeof(RDLength);
    RDLength = ntohs(RDLength);
    numAddrs = RDLength / (sizeof(nbNB_Flags) + sizeof(IpAddress));
    dwError = LWNetAllocateMemory(
                  numAddrs * sizeof(struct in_addr),
                  (PVOID*) &addrs);
    BAIL_ON_LWNET_ERROR(dwError);

    j = 0;
    do
    {
        memcpy(&nbNB_Flags, &buf[i], sizeof(nbNB_Flags));
        i += sizeof(nbNB_Flags);
        nbNB_Flags = ntohs(nbNB_Flags);
        nbNB_Flags >>= 13;
        *retFlags = nbNB_Flags;

        memcpy(&IpAddress, &buf[i], sizeof(IpAddress));
        i += sizeof(IpAddress);
        addrs[j++].s_addr = IpAddress;
        RDLength -= sizeof(nbNB_Flags) + sizeof(IpAddress);
    }
    while (RDLength > 0);
    *retNbName = NetBiosName;
    *retAddrs = addrs;
    *retAddrsLen = j;

cleanup:
    return dwError;

error:
    LWNET_SAFE_FREE_MEMORY(NetBiosName);
    LWNET_SAFE_FREE_MEMORY(NbName);
    LWNET_SAFE_FREE_MEMORY(addrs);
    goto cleanup;
}
Example #8
0
/* Convert NetBIOS level 2 encoded name to a string */
DWORD
LWNetNbName2ToStr(
    IN PBYTE buf,
    OUT PSTR *ppNbName,
    OUT PUINT8 pSuffix,
    OUT PDWORD dwBytesConsumed)
{
    DWORD dwError = 0;
    PSTR *NbNameParts2 = NULL;
    PSTR NbName = NULL;
    CHAR netBiosName[LWNB_NAME_MAX_LENGTH] = {0};
    DWORD addrsLen = 0;
    DWORD nbNameOffset = 0;
    DWORD i = 0;

    dwError = LWNetNbName2ToParts(&buf[i], &NbNameParts2, &addrsLen);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LWNetAllocateMemory(
                  addrsLen * sizeof(char),
                  (PVOID*) &NbName);
    BAIL_ON_LWNET_ERROR(dwError);

    nbNameOffset = 0;
    for (i=0; NbNameParts2[i]; i++)
    {
        if (i==0)
        {
            /*
             * Convert first part of name, which is in NetBIOS layer 1 encoding
             * to a null-terminated string.
             */
            LWNetNbNameToStr((UINT8 *) NbNameParts2[i], netBiosName, pSuffix);
            strncat(NbName, netBiosName, addrsLen - nbNameOffset);
            nbNameOffset += strlen(netBiosName);
        }
        else
        {
            /* The rest of the name is just text, so copy it */
            strncat(NbName, ".", addrsLen - nbNameOffset);
            nbNameOffset++;

            strncat(NbName,
                    NbNameParts2[i],
                    addrsLen - nbNameOffset);
            nbNameOffset += strlen(NbNameParts2[i]);
        }
    }
    *ppNbName = NbName;
    *dwBytesConsumed = addrsLen;

cleanup:
    for (i=0; NbNameParts2[i]; i++)
    {
        LWNET_SAFE_FREE_MEMORY(NbNameParts2[i]);
    }
    LWNET_SAFE_FREE_MEMORY(NbNameParts2);
    return dwError;

error:
    LW_SAFE_FREE_MEMORY(NbName);
    goto cleanup;
}
Example #9
0
static DWORD
LWNetNbResolveNameUdp(
    PSTR pszHostName,
    PSTR winsServer,
    UINT8 queryType,
    OUT struct in_addr **retAddrs,
    OUT PDWORD retAddrsLen)
{
    DWORD dwError = 0;
    UINT16 transactionId = 0;
    UINT8 *NetBiosQuery = NULL;
    DWORD NetBiosQueryLen = 0;
    struct sockaddr_in dgAddr;
    struct timespec cvTimeout = {0};
    struct timeval  tp = {0};
    struct in_addr *resAddrs = NULL;
    struct in_addr *tmpResAddrs = NULL;
    int sts = 0;
    DWORD i = 0;
    DWORD resAddrsLen = 0;
    DWORD resAddrsAllocLen = 128;
    DWORD commType = 0;
    BOOLEAN bLocked = FALSE;

    dwError = LWNetAllocateMemory(
                  LWNB_NETBIOS_UDP_MAX,
                  (PVOID*) &NetBiosQuery);
    BAIL_ON_LWNET_ERROR(dwError);

    memset(&dgAddr, 0, sizeof(dgAddr));
    dgAddr.sin_family = AF_INET;
    dgAddr.sin_port = htons(137);

    if (winsServer && *winsServer)
    {
        sts = inet_aton(winsServer, &dgAddr.sin_addr);
        if (sts == -1)
        {
            dwError = LwErrnoToWin32Error(ERROR_INCORRECT_ADDRESS);
            BAIL_ON_LWNET_ERROR(dwError);
        }

        commType = LWNB_QUERY_WINS;
        dwError = LWNetNbConstructNameQuery(
                      pszHostName,
                      commType,
                      queryType,
                      &transactionId,
                      NetBiosQuery,
                      &NetBiosQueryLen);
        BAIL_ON_LWNET_ERROR(dwError);
    }
    else
    {
        dgAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
        commType = LWNB_QUERY_BROADCAST;
        dwError = LWNetNbConstructNameQuery(
                      pszHostName,
                      commType,
                      queryType,
                      &transactionId,
                      NetBiosQuery,
                      &NetBiosQueryLen);
        BAIL_ON_LWNET_ERROR(dwError);
    }


    // If this is not enough memory, realloc below fixes that
    dwError = LWNetAllocateMemory(
                  resAddrsAllocLen * sizeof(struct in_addr),
                  (PVOID*) &resAddrs);
    BAIL_ON_LWNET_ERROR(dwError);

    pthread_mutex_lock(&gpNbCtx->mutex);
    bLocked = TRUE;
    sts = sendto(gpNbCtx->sock,
                 NetBiosQuery,
                 NetBiosQueryLen,
                 0,  /* flags */
                 (struct sockaddr *) &dgAddr,
                 sizeof(dgAddr));
    if (sts == -1)
    {
        dwError = ERROR_NET_WRITE_FAULT;
        BAIL_ON_LWNET_ERROR(dwError);
    }
    do
    {
        gettimeofday(&tp, NULL);
        cvTimeout.tv_sec = tp.tv_sec + gpNbCtx->udpTimeout;
        cvTimeout.tv_nsec = tp.tv_usec * 1000;
        do {
            sts = pthread_cond_timedwait(
                      &gpNbCtx->cv,
                      &gpNbCtx->mutex,
                      &cvTimeout);
        } while (!gpNbCtx->bNbRepsponse && sts != ETIMEDOUT);

        if (sts == 0 && gpNbCtx->transactionId == transactionId)
        {
            gpNbCtx->bNbRepsponse = FALSE;


            if ((commType == LWNB_QUERY_WINS && gpNbCtx->respError == 0) ||
                (commType == LWNB_QUERY_BROADCAST))
            {
                if ((gpNbCtx->addrsLen + resAddrsLen) > resAddrsAllocLen)
                {
                    resAddrsAllocLen = resAddrsAllocLen * 2 + gpNbCtx->addrsLen;
                    tmpResAddrs = LwRtlMemoryRealloc(
                                      resAddrs,
                                      resAddrsAllocLen);
                    if (!tmpResAddrs)
                    {
                        dwError = ERROR_NOT_ENOUGH_MEMORY;
                        BAIL_ON_LWNET_ERROR(dwError);
                    }
                    resAddrs = tmpResAddrs;
                    tmpResAddrs = NULL;
                }
                for (i=0; i<gpNbCtx->addrsLen; i++)
                {
                    memcpy(&resAddrs[resAddrsLen++],
                           &gpNbCtx->addrs[i],
                           sizeof(struct in_addr));
                }
            }
            pthread_mutex_lock(&gpNbCtx->mutexAck);
            gpNbCtx->bAck = TRUE;
            pthread_mutex_unlock(&gpNbCtx->mutexAck);
            pthread_cond_signal(&gpNbCtx->cvAck);

            if (commType == LWNB_QUERY_WINS && gpNbCtx->respError)
            {
                // Bail when WINS query fails to resolve the hostname
                dwError = gpNbCtx->respError;
                BAIL_ON_LWNET_ERROR(dwError);
            }
        }
    } while (commType == LWNB_QUERY_BROADCAST && sts != ETIMEDOUT);
    bLocked = FALSE;
    pthread_mutex_unlock(&gpNbCtx->mutex);

    if (resAddrsLen == 0)
    {
        dwError = ERROR_BAD_NET_NAME;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    *retAddrs = resAddrs;
    *retAddrsLen = resAddrsLen;

cleanup:
    if (bLocked)
    {
        pthread_mutex_unlock(&gpNbCtx->mutex);
    }
    LWNET_SAFE_FREE_MEMORY(NetBiosQuery);
    return dwError;

error:
    LWNET_SAFE_FREE_MEMORY(resAddrs);
    goto cleanup;
}
Example #10
0
DWORD
LWNetDnsBuildServerArray(
    IN PDLINKEDLIST pSrvRecordList,
    OUT PDNS_SERVER_INFO* ppServerArray,
    OUT PDWORD pdwServerCount
    )
{
    DWORD dwError = 0;
    DWORD dwServerCount = 0;
    PDNS_SERVER_INFO pServerArray = NULL;
    PDLINKEDLIST pListMember = NULL;
    PDNS_SRV_INFO_RECORD pSrvRecord = NULL;
    DWORD dwServerIndex = 0;
    DWORD dwStringSize = 0;
    DWORD dwRequiredSize = 0;
    PSTR pStringLocation = NULL;

    for (pListMember = pSrvRecordList; pListMember; pListMember = pListMember->pNext)
    {
        pSrvRecord = (PDNS_SRV_INFO_RECORD)pListMember->pItem;

        dwStringSize += strlen(pSrvRecord->pszAddress) + 1;
        dwStringSize += strlen(pSrvRecord->pszTarget) + 1;

        dwServerCount++;
    }

    if (dwServerCount < 1)
    {
        // nothing to do, so we are done
        dwError = 0;
        goto error;
    }

    dwRequiredSize = dwServerCount * sizeof(DNS_SERVER_INFO) + dwStringSize;

    dwError = LWNetAllocateMemory(dwRequiredSize, (PVOID*)&pServerArray);
    BAIL_ON_LWNET_ERROR(dwError);

    pStringLocation = CT_PTR_ADD(pServerArray, dwServerCount * sizeof(DNS_SERVER_INFO));
    dwServerIndex = 0;
    for (pListMember = pSrvRecordList; pListMember; pListMember = pListMember->pNext)
    {
        PSTR source;

        pSrvRecord = (PDNS_SRV_INFO_RECORD)pListMember->pItem;
        
        // Copy the strings into the buffer
        pServerArray[dwServerIndex].pszAddress = pStringLocation;
        for (source = pSrvRecord->pszAddress; source[0]; source++)
        {
            pStringLocation[0] = source[0];
            pStringLocation++;
        }
        pStringLocation[0] = source[0];
        pStringLocation++;

        pServerArray[dwServerIndex].pszName = pStringLocation;
        for (source = pSrvRecord->pszTarget; source[0]; source++)
        {
            pStringLocation[0] = source[0];
            pStringLocation++;
        }
        pStringLocation[0] = source[0];
        pStringLocation++;

        dwServerIndex++;
    }

    // TODO: Turns this into ASSERT
    if (CT_PTR_OFFSET(pServerArray, pStringLocation) != dwRequiredSize)
    {
        LWNET_LOG_ERROR("ASSERT - potential buffer overflow");
    }

error:    
    if (dwError)
    {
        LWNET_SAFE_FREE_MEMORY(pServerArray);
        dwServerCount = 0;
    }

    *ppServerArray = pServerArray;
    *pdwServerCount = dwServerCount;

    return dwError;
}
Example #11
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;
}
Example #12
0
static
DWORD
LWNetSrvPingCLdapProcess(
    IN PLWNET_CLDAP_CONNECTION_CONTEXT pContext,
    IN DWORD dwDsFlags,
    IN LWNET_UNIX_MS_TIME_T StopTime,
    OUT PLWNET_DC_INFO* ppDcInfo,
    OUT PBOOLEAN pbFailedFindWritable
)
{
    DWORD dwError = 0;
    DWORD dwResultType = 0;
    LDAPMessage* pMessage = NULL;
    PBYTE pNetlogonAttributeValue = NULL;
    DWORD dwNetlogonAttributeSize = 0;
    PLWNET_DC_INFO pDcInfo = NULL;
    BOOLEAN bFailedFindWritable = FALSE;
    struct timeval timeout = {0};
    LDAP *ld = NULL;

    ld = LwLdapGetSession(pContext->hDirectory);

    dwResultType =  ldap_result(
                        ld,
                        pContext->msgid,
                        0,
                        &timeout,
                        &pMessage);
    if (dwResultType == 0)
    {
        // timed out
        goto error;
    }
    else if (dwResultType == -1)
    {
        // -1 = problem
        dwError = LDAP_NO_SUCH_OBJECT;
        LWNET_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search");
    }
    else
    {
        // returns result type
        if (dwResultType != LDAP_RES_SEARCH_ENTRY)
        {
            dwError = LDAP_NO_SUCH_OBJECT;
            LWNET_LOG_DEBUG("Caught incorrect result type on ldap search: %d", dwError);
        }
    }
    dwError = LwMapLdapErrorToLwError(dwError);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwLdapGetBytes(
                  pContext->hDirectory,
                  pMessage,
                  NETLOGON_LDAP_ATTRIBUTE_NAME,
                  &pNetlogonAttributeValue,
                  &dwNetlogonAttributeSize);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LWNetBuildDCInfo(pNetlogonAttributeValue,
                               dwNetlogonAttributeSize,
                               &pDcInfo);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LWNetAllocateString(pContext->pServerInfo->pszAddress, &pDcInfo->pszDomainControllerAddress);
    BAIL_ON_LWNET_ERROR(dwError);

    pDcInfo->dwPingTime = (DWORD)(StopTime - pContext->StartTime);
    if (StopTime < pContext->StartTime)
    {
        LWNET_LOG_ERROR("Stop time is earlier than start time");
    }

    if (!LWNetSrvIsMatchingDcInfo(pDcInfo, dwDsFlags))
    {
        dwError = LW_ERROR_NO_SUCH_OBJECT;

        if (LWNetSrvIsMatchingDcInfo(pDcInfo, dwDsFlags & ~DS_WRITABLE_REQUIRED))
        {
            // We found something, but it failed only because it did
            // not satisfy writability.
            bFailedFindWritable = TRUE;
        }
    }

error:
    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    LWNET_SAFE_FREE_MEMORY(pNetlogonAttributeValue);

    if (dwError)
    {
        LWNET_SAFE_FREE_DC_INFO(pDcInfo);

        LWNetSrvPingCLdapEnd(pContext);
    }

    *ppDcInfo = pDcInfo;
    *pbFailedFindWritable = bFailedFindWritable;

    return dwError;
}
Example #13
0
DWORD
LWNetDnsSrvQuery(
    IN PCSTR pszDnsDomainName,
    IN OPTIONAL PCSTR pszSiteName,
    IN DWORD dwDsFlags,
    OUT PDNS_SERVER_INFO* ppServerArray,
    OUT PDWORD pdwServerCount
    )
// Call LWNET_SAFE_FREE_MEMORY on returned server array
{
    DWORD dwError = 0;
    PSTR pszQuestion = NULL;
    const size_t dwBufferSize = (64 * 1024);
    PVOID pBuffer = NULL;
    PDNS_RESPONSE_HEADER pResponse = NULL;
    DWORD dwResponseSize = 0;
    PDLINKEDLIST pAnswersList = NULL;
    PDLINKEDLIST pAdditionalsList = NULL;
    PDLINKEDLIST pSRVRecordList = NULL;
    PDNS_SERVER_INFO pServerArray = NULL;
    DWORD dwServerCount = 0;

    // TODO - Handle trailing dot in domain; handle no dots in domain

    dwError = LWNetDnsGetSrvRecordQuestion(&pszQuestion, pszDnsDomainName,
                                           pszSiteName, dwDsFlags);
    BAIL_ON_LWNET_ERROR(dwError);
   
    dwError = LWNetAllocateMemory(dwBufferSize, &pBuffer);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LWNetDnsQueryWithBuffer(pszQuestion, TRUE, FALSE,
                                      pBuffer, dwBufferSize,
                                      &dwResponseSize);
    BAIL_ON_LWNET_ERROR(dwError);

    pResponse = (PDNS_RESPONSE_HEADER) pBuffer;
    if (LWNetDnsIsTruncatedResponse(pResponse))
    {
        dwError = LWNetDnsQueryWithBuffer(pszQuestion, FALSE, TRUE,
                                          pBuffer, dwBufferSize,
                                          &dwResponseSize);
        BAIL_ON_LWNET_ERROR(dwError);
    }

    // TODO: Add dwResponseSize validation to parsing.

    // Decode DNS response w/o taking into account record type
    dwError = LWNetDnsParseQueryResponse(pResponse,
                                         &pAnswersList,
                                         NULL,
                                         &pAdditionalsList);
    BAIL_ON_LWNET_ERROR(dwError);

    // Decode SRV records
    dwError = LWNetDnsBuildSRVRecordList(pResponse,
                                         pAnswersList,
                                         pAdditionalsList,
                                         &pSRVRecordList);
    BAIL_ON_LWNET_ERROR(dwError);

    // Create list of server names and addresses
    dwError = LWNetDnsBuildServerArray(pSRVRecordList,
                                       &pServerArray, &dwServerCount);
    BAIL_ON_LWNET_ERROR(dwError);

error:
    LWNET_SAFE_FREE_STRING(pszQuestion);
    LWNET_SAFE_FREE_MEMORY(pBuffer);
    LWNET_SAFE_FREE_DNS_RECORD_LINKED_LIST(pAnswersList);
    LWNET_SAFE_FREE_DNS_RECORD_LINKED_LIST(pAdditionalsList);
    LWNET_SAFE_FREE_SRV_INFO_LINKED_LIST(pSRVRecordList);

    if (dwError)
    {
        LWNET_SAFE_FREE_MEMORY(pServerArray);
        dwServerCount = 0;
    }

    *ppServerArray= pServerArray;
    *pdwServerCount = dwServerCount;

    return dwError;
}
Example #14
0
VOID *LWNetSrvStartNetBiosThreadRoutine(VOID *ctx)
{
    DWORD dwError = 0;
    struct pollfd pollfds[1];
    int sts = 0;
    int sock = 0;
    UINT8 *NetBiosReply = NULL;
    struct sockaddr_in dgAddr;
    int NetBiosReplyAddrLen = 0;
    void *pNetBiosReplyAddrLen = &NetBiosReplyAddrLen;
    PLWNET_SRV_NETBIOS_CONTEXT pNbCtx = (PLWNET_SRV_NETBIOS_CONTEXT) ctx;
    int allowBroadcast = 1;
    UINT8 Flags = 0;
    UINT16 respTransactionId = 0;
    PSTR NbName = NULL;
    struct in_addr *addrs = NULL;
    DWORD addrsLen = 0;
    struct timeval  tp = {0};
    struct timespec cvTimeout = {0};

    dwError = LWNetAllocateMemory(
                  LWNB_NETBIOS_UDP_MAX,
                  (PVOID*) &NetBiosReply);

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock == -1)
    {
        dwError = ERROR_INVALID_HANDLE;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    sts = setsockopt(sock,
              SOL_SOCKET,
              SO_BROADCAST,
              &allowBroadcast,
              sizeof(allowBroadcast));
    if (sts == -1)
    {
        dwError = ERROR_INVALID_HANDLE;
        BAIL_ON_LWNET_ERROR(dwError);
    }


    pthread_mutex_lock(&pNbCtx->mutex);
    pNbCtx->sock = sock;
    pthread_mutex_unlock(&pNbCtx->mutex);

    do
    {
        memset(pollfds, 0, sizeof(pollfds));
        pollfds[0].fd = sock;
        pollfds[0].events = POLLIN;

        sts = poll(pollfds, 1, -1);
        if (sts > 0 && pollfds[0].revents)
        {
            sts = recvfrom(
                  sock,
                  NetBiosReply,
                  LWNB_NETBIOS_UDP_MAX,
                  0,  /* flags */
                  (struct sockaddr *) &dgAddr,
                  pNetBiosReplyAddrLen);
            if (sts > 0)
            {
                dwError = LWNetNbParseNameQueryResponse(
                              NetBiosReply,
                              sts,
                              0, // remove this argument
                              &respTransactionId,
                              &NbName,
                              NULL,
                              &Flags,
                              &addrs,
                              &addrsLen);
                pthread_mutex_lock(&pNbCtx->mutex);
                pNbCtx->respError = dwError;
                pNbCtx->transactionId = respTransactionId;
                pNbCtx->addrs = addrs;
                pNbCtx->addrsLen = addrsLen;
                pNbCtx->bNbRepsponse = TRUE;
                pthread_mutex_lock(&pNbCtx->mutexAck);
                pthread_mutex_unlock(&pNbCtx->mutex);
                pthread_cond_broadcast(&pNbCtx->cv);

                // Wait for LWNetNbResolveName ack address received
                do
                {
                    gettimeofday(&tp, NULL);
                    cvTimeout.tv_sec =
                        tp.tv_sec + pNbCtx->udpTimeout;
                    cvTimeout.tv_nsec = tp.tv_usec * 1000;
                    sts = pthread_cond_timedwait(
                              &pNbCtx->cvAck,
                              &pNbCtx->mutexAck,
                              &cvTimeout);
                } while (!pNbCtx->bAck && sts != ETIMEDOUT);
                pNbCtx->bAck = FALSE;
                pthread_mutex_unlock(&pNbCtx->mutexAck);
            }
        }
    } while (!pNbCtx->bShutdown);
    LWNET_LOG_INFO("Stopping NetBIOS listener thread");

cleanup:
    LWNET_SAFE_FREE_MEMORY(NetBiosReply);
    LWNET_SAFE_FREE_STRING(NbName);
    if (sock != -1)
    {
        close(sock);
    }
    return NULL;

error:
    goto cleanup;
}
Example #15
0
/* "Second Level" NetBIOS name encoding */
DWORD
LWNetNbStrToNbName2(
    PSTR Fqdn,
    UINT8 suffix,
    PBYTE *retNbNameL2,
    PDWORD retNbNameL2Len)
{
    DWORD dwError = 0;
    DWORD len = 0;
    PSTR p = NULL;
    PSTR token = NULL;
    PSTR tokenPtr = NULL;
    UINT8 *retName = NULL;
    UINT8 *up = NULL;

    /*
     * 32=Max NetBIOS First Level encoding length
     * All . separators are replaced by 1 byte count, so
     * don't need to count number of dots to determine buffer length
     * 2=FirstLevel encoding length + ending length (by definition 0)
     */
    len = LWNB_NETBIOS_ENCNAME_LEN + strlen(Fqdn) + 2;
    dwError = LWNetAllocateMemory(sizeof(CHAR) * len,
                                  (PVOID*)&retName);
    BAIL_ON_LWNET_ERROR(dwError);

    up = retName;

    dwError = LWNetAllocateString(
                  Fqdn,
                  &token);
    BAIL_ON_LWNET_ERROR(dwError);

    p = strchr(token, '.');
    if (p)
    {
        *p++ = '\0';
        Fqdn = token;
    }

    /* Store length of NetBIOS name component before that name */
    *up++ = (UINT8) LWNB_NETBIOS_ENCNAME_LEN;
    LWNetNbStrToNbName(Fqdn, suffix, up);
    up += LWNB_NETBIOS_ENCNAME_LEN;

    /* Work through rest of Fqdn, replacing . with length of stuff before . */
    if (p)
    {
        p = strtok_r(p, ".", &tokenPtr);
    }
    while (p)
    {
        len = strlen(p);
        *up++ = (UINT8) len;
        strncat((char *) up, p, sizeof(CHAR)*len - (up-retName));
        up += len;
        p = strtok_r(NULL, ".", &tokenPtr);
    }
    *up++ = '\0';

    *retNbNameL2 = (UINT8 *) retName;
    *retNbNameL2Len = up - retName;

cleanup:
    LWNET_SAFE_FREE_MEMORY(token);
    return dwError;

error:
    LWNET_SAFE_FREE_MEMORY(retName);
    goto cleanup;
}
Example #16
0
DWORD
LWNetSrvNetBiosInit(VOID)
{
    struct {
        unsigned mutexInit : 1;
        unsigned mutexAckInit : 1;
        unsigned cvInit : 1;
        unsigned cvAckInit : 1;
    } initialized = {0};

    DWORD dwError = 0;
    PLWNET_SRV_NETBIOS_CONTEXT pNbCtx = NULL;

    dwError = LWNetAllocateMemory(
                  sizeof(*pNbCtx),
                  (PVOID*) &pNbCtx);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwErrnoToWin32Error(pthread_mutex_init(&pNbCtx->mutex, NULL));
    BAIL_ON_LWNET_ERROR(dwError);
    initialized.mutexInit = TRUE;

    dwError = LwErrnoToWin32Error(pthread_cond_init(&pNbCtx->cv, NULL));
    BAIL_ON_LWNET_ERROR(dwError);
    initialized.cvInit = TRUE;

    dwError = LwErrnoToWin32Error(pthread_mutex_init(&pNbCtx->mutexAck, NULL));
    BAIL_ON_LWNET_ERROR(dwError);
    initialized.mutexAckInit = TRUE;

    dwError = LwErrnoToWin32Error(pthread_cond_init(&pNbCtx->cvAck, NULL));
    BAIL_ON_LWNET_ERROR(dwError);
    initialized.cvAckInit = TRUE;

    dwError = LwErrnoToWin32Error(pthread_mutex_init(
                  &pNbCtx->mutexTransactionId, NULL));
    BAIL_ON_LWNET_ERROR(dwError);

    gpNbCtx = pNbCtx;

cleanup:
    return dwError;

error:
    if (initialized.mutexInit)
    {
        pthread_mutex_destroy(&pNbCtx->mutex);
    }
    if (initialized.mutexAckInit)
    {
        pthread_mutex_destroy(&pNbCtx->mutexAck);
    }
    if (initialized.cvInit)
    {
        pthread_cond_destroy(&pNbCtx->cv);
    }
    if (initialized.cvAckInit)
    {
        pthread_cond_destroy(&pNbCtx->cvAck);
    }
    LWNET_SAFE_FREE_MEMORY(pNbCtx);
    goto cleanup;
}
Example #17
0
int
main(
    int argc,
    char* argv[]
    )
{
    DWORD dwError = 0;
    PSTR pszHostName = NULL;
    PWSTR pwszHostName = NULL;
    PWSTR pwszCanonName = NULL;
    PSTR pszCanonName = NULL;
    PLWNET_RESOLVE_ADDR *ppAddressList = NULL;
    DWORD dwAddressListLen = 0;
    DWORD i = 0;
    CHAR ipAddressBuf[INET_ADDRSTRLEN];
    PCSTR pszAddress = NULL;
    DWORD ipAddressLen = 0;
    DWORD ipAddrFamily = 0;
    PBYTE pIpAddr = NULL;

    lwnet_init_logging_to_file(LWNET_LOG_LEVEL_VERBOSE, TRUE, "");

    ParseArgs(argc, argv);

    if (argc == 1)
    {
        printf("usage: %s hostname\n", argv[0]);
        return 0;
    }

    pszHostName = argv[1];
    dwError = LwRtlWC16StringAllocateFromCString(&pwszHostName,
                                                 pszHostName);
    BAIL_ON_LWNET_ERROR(dwError);
    dwError = LWNetResolveName(
                  (PCWSTR) pwszHostName,
                  &pwszCanonName,
                  &ppAddressList,
                  &dwAddressListLen);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwRtlCStringAllocateFromWC16String(&pszCanonName,
                                                 pwszCanonName);
    BAIL_ON_LWNET_ERROR(dwError);
 
    for (i=0; i<dwAddressListLen; i++)
    {
        if (ppAddressList[i]->AddressType == LWNET_IP_ADDR_V4)
        {
            ipAddressLen = 4; 
            ipAddrFamily = PF_INET;
            pIpAddr = ppAddressList[i]->Address.Ip4Addr;
        }
        else if (ppAddressList[i]->AddressType == LWNET_IP_ADDR_V6)
        {
            ipAddressLen = 16; 
            ipAddrFamily = PF_INET6;
            pIpAddr = ppAddressList[i]->Address.Ip4Addr;
        }
        pszAddress = inet_ntop(ipAddrFamily,
                               pIpAddr,
                               ipAddressBuf,
                               sizeof(ipAddressBuf));
        if (pszAddress)
        {
            printf("IP Address = %s\n", pszAddress);
        }
    }
    printf("Responses = %d Host: '%s'\n", dwAddressListLen, pszCanonName);

cleanup:
    LWNetResolveNameFree(pwszCanonName, ppAddressList, dwAddressListLen);
    LWNET_SAFE_FREE_MEMORY(pwszHostName);
    LWNET_SAFE_FREE_STRING(pszCanonName);
    return (dwError);
error:
 
    if (dwError == ERROR_BAD_NET_NAME)
    {
        printf("LWNetResolveName() failed DNS/NetBIOS name resolution\n");
    }
    else
    {
        LWNET_LOG_ERROR("Failed communication with likewise-netlogond. "
                        "Error code [%d]\n", dwError);
    } 
    goto cleanup;

}