Beispiel #1
0
static
VOID
LWNetSrvPingCLdapProcessConnections(
    IN DWORD dwDsFlags,
    IN LWNET_UNIX_MS_TIME_T CurrentTime,
    IN DWORD dwSingleConnTimeoutMilliseconds,
    IN DWORD dwActualConnCount,
    IN struct pollfd *Readfds,
    IN OUT PLWNET_CLDAP_CONNECTION_CONTEXT pConnections,
    OUT PLWNET_DC_INFO* ppDcInfo,
    OUT PBOOLEAN pbFailedFindWritable
)
{
    DWORD dwError = 0;
    DWORD dwIndexConn = dwActualConnCount;
    BOOLEAN bFailedFindWritable = FALSE;
    BOOLEAN bFailed = FALSE;
    PLWNET_DC_INFO pDcInfo = NULL;

    while (dwIndexConn > 0)
    {
        dwIndexConn--;

        if (Readfds[dwIndexConn].revents)
        {
            dwError = LWNetSrvPingCLdapProcess(
                          &pConnections[dwIndexConn],
                          dwDsFlags,
                          CurrentTime,
                          &pDcInfo,
                          &bFailed);
            bFailedFindWritable = bFailed ? TRUE : bFailedFindWritable;
            if (dwError)
            {
                LWNET_LOG_VERBOSE("CLDAP error: %d, %s", dwError, pConnections[dwIndexConn].pServerInfo->pszName);
                dwError = 0;
            }
            else if (pDcInfo)
            {
                break;
            }
        } else if (pConnections[dwIndexConn].StartTime + dwSingleConnTimeoutMilliseconds < CurrentTime)
        {
            LWNET_LOG_VERBOSE("CLDAP timed out: %s", pConnections[dwIndexConn].pServerInfo->pszName);

            LWNetSrvPingCLdapEnd(&pConnections[dwIndexConn]);
        }
    }

    *ppDcInfo = pDcInfo;
}
Beispiel #2
0
NTSTATUS
LWNetSvcmStop(
    PLW_SVCM_INSTANCE pInstance
    )
{
    LWNET_LOG_VERBOSE("LWNet main cleaning up");

    // Post service stopped event to eventlog
    LWNetSrvLogProcessStoppedEvent(ERROR_SUCCESS);

    LWNetSrvStopListenThread();

    LWNetSrvApiShutdown();

    LWNET_LOG_INFO("LWNET Service exiting...");

    return STATUS_SUCCESS;
}
Beispiel #3
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;
}
Beispiel #4
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;
}
Beispiel #5
0
DWORD
LWNetDnsQueryWithBuffer(
    IN PCSTR pszQuestion,
    IN BOOLEAN bReInit,
    IN BOOLEAN bUseTcp,
    OUT PVOID pBuffer,
    IN DWORD dwBufferSize,
    OUT PDWORD pdwResponseSize
    )
{
    DWORD dwError = 0;
    PDNS_RESPONSE_HEADER pHeader = (PDNS_RESPONSE_HEADER)pBuffer;
    int responseSize =  0;
    BOOLEAN bInLock = FALSE;
#if HAVE_DECL_RES_NINIT
    union
    {
        struct __res_state res;
#ifdef __LWI_AIX__
        // struct __res_state was enlarged from 720 in AIX 5.2 to 824 in AIX
        // 5.3. This means calling res_ninit on AIX 5.3 on a structure compiled
        // on AIX 5.2 will result in a buffer overflow. Furthermore, even on
        // AIX 5.3, res_ninit seems to expect 1596 bytes in the structure (1491
        // on AIX 5.2). As a workaround, this padding will ensure enough space
        // is allocated on the stack.
        char buffer[2048];
#endif
    } resLocal = { {0} };
    res_state res = &resLocal.res;
#else
    struct __res_state *res = &_res;
#endif

    LWNET_LOCK_RESOLVER_API(bInLock);

#if HAVE_DECL_RES_NINIT
    if (res_ninit(res) != 0)
#else
    if (res_init() != 0)
#endif
    {
        dwError = ERROR_NOT_FOUND;
        BAIL_ON_LWNET_ERROR(dwError);
    }
    
    if (dwBufferSize < CT_MIN(sizeof(DNS_RESPONSE_HEADER), MAX_DNS_UDP_BUFFER))
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    // TODO: Add lock on calling resolver due to global options, which may or
    // may not be safe depending on the system.
    if (bUseTcp)
    {
        res->options |= RES_USEVC;
    }
    else
    {
        res->options &= ~(RES_USEVC);
    }

    /* Assertion: pResolverContext != NULL && pResolverContext->bLocked == TRUE */
#if HAVE_DECL_RES_NINIT
    responseSize = res_nquery(res, pszQuestion, ns_c_in, ns_t_srv, (PBYTE) pBuffer, dwBufferSize);
#else
    responseSize = res_query(pszQuestion, ns_c_in, ns_t_srv, (PBYTE) pBuffer, dwBufferSize);
#endif
    if (responseSize < 0)
    {
        LWNET_LOG_VERBOSE("DNS lookup for '%s' failed with errno %d, h_errno = %d", pszQuestion, errno, h_errno);
        dwError = DNS_ERROR_BAD_PACKET;
        BAIL_ON_LWNET_ERROR(dwError);
    }
    if (responseSize < CT_FIELD_OFFSET(DNS_RESPONSE_HEADER, data))
    {
        dwError = DNS_ERROR_BAD_PACKET;
        BAIL_ON_LWNET_ERROR(dwError);
    }
    if (responseSize > dwBufferSize)
    {
        dwError = DNS_ERROR_BAD_PACKET;
        BAIL_ON_LWNET_ERROR(dwError);
    }

    LWNetDnsFixHeaderForEndianness(pHeader);

    if (!LWNetDnsIsValidResponse(pHeader))
    {
        dwError = DNS_ERROR_BAD_PACKET;
        BAIL_ON_LWNET_ERROR(dwError);
    }

error:

#if HAVE_DECL_RES_NINIT
    res_nclose(res);
#else
    /* Indicate that we are done with the resolver, except on HPUX which
       does not implement the res_close function. */
#ifndef __LWI_HP_UX__
    res_close();
#endif
#endif

    LWNET_UNLOCK_RESOLVER_API(bInLock);

    if (dwError)
    {
        responseSize = 0;
    }
    *pdwResponseSize = responseSize;
    return dwError;
}