Beispiel #1
0
static
DWORD
LWNetSrvPingCLdapBegin(
    IN PLWNET_CLDAP_CONNECTION_CONTEXT pContext,
    IN PDNS_SERVER_INFO pServerInfo,
    IN PCSTR pszDnsDomainName,
    IN DWORD dwTimeout
)
{
    DWORD dwError = 0;
    PSTR pszQuery = NULL;
    PSTR szAttributeList[] = { NETLOGON_LDAP_ATTRIBUTE_NAME, NULL };
    struct timeval timeout = {0};
    LDAP *ld = NULL;

    pContext->hDirectory = NULL;
    pContext->pServerInfo = pServerInfo;

    dwError = LwAllocateStringPrintf(&pszQuery,
                                     "(&(DnsDomain=%s)(NtVer=\\06\\00\\00\\80))",
                                     pszDnsDomainName);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwCLdapOpenDirectory(pServerInfo->pszAddress, &pContext->hDirectory);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = LwLdapBindDirectoryAnonymous(pContext->hDirectory);
    BAIL_ON_LWNET_ERROR(dwError);

    timeout.tv_sec = 0;
    timeout.tv_usec = dwTimeout;

    dwError = LWNetGetSystemTimeInMs(&pContext->StartTime);
    BAIL_ON_LWNET_ERROR(dwError);

    ld = LwLdapGetSession(pContext->hDirectory);

    dwError = ldap_search_ext(
                  ld,
                  "",
                  LDAP_SCOPE_BASE,
                  pszQuery,
                  szAttributeList,
                  0,
                  NULL,
                  NULL,
                  &timeout,
                  0,
                  &pContext->msgid);
    dwError = LwMapLdapErrorToLwError(dwError);
    BAIL_ON_LWNET_ERROR(dwError);

    dwError = ldap_get_option(
                  ld,
                  LDAP_OPT_DESC,
                  &pContext->fd);
    dwError = LwMapLdapErrorToLwError(dwError);
    BAIL_ON_LWNET_ERROR(dwError);

error:
    if (dwError)
    {
        if (pContext->hDirectory)
        {
            LWNetSrvPingCLdapEnd(pContext);
        }
    }

    LWNET_SAFE_FREE_STRING(pszQuery);

    return dwError;
}
Beispiel #2
0
DWORD
LwLdapOpenDirectoryServerSingleAttempt(
    IN PCSTR pszServerAddress,
    IN PCSTR pszServerName,
    IN DWORD dwTimeoutSec,
    IN DWORD dwFlags,
    OUT PLW_LDAP_DIRECTORY_CONTEXT* ppDirectory
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    LDAP * ld = NULL;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    int rc = LDAP_VERSION3;
    DWORD dwPort = 389;
    struct timeval timeout = {0};
    BOOLEAN bLdapSeal = FALSE;

    timeout.tv_sec = dwTimeoutSec;

    LW_BAIL_ON_INVALID_STRING(pszServerName);
    LW_BAIL_ON_INVALID_STRING(pszServerAddress);

    if (dwFlags & LW_LDAP_OPT_GLOBAL_CATALOG)
    {
       dwPort = 3268;
    }

    // This creates the ld without immediately connecting to the server.
    // That way a connection timeout can be set first.
    ld = (LDAP *)ldap_init(pszServerAddress, dwPort);
    if (!ld) {
        dwError = LwMapErrnoToLwError(errno);
        LW_RTL_LOG_ERROR("Failed to open LDAP connection to domain controller");
        BAIL_ON_LW_ERROR(dwError);
        LW_RTL_LOG_ERROR("Failed to get errno for failed open LDAP connection");
        dwError = LW_ERROR_LDAP_ERROR;
        BAIL_ON_LW_ERROR(dwError);
    }

    dwError = ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
    BAIL_ON_LDAP_ERROR(dwError);

    dwError = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &rc);
    if (dwError) {
        LW_RTL_LOG_ERROR("Failed to set LDAP option protocol version");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    dwError = ldap_set_option( ld, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);
    if (dwError) {
        LW_RTL_LOG_ERROR("Failed to set LDAP option to not follow referrals");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    /* This tells ldap to retry when select returns with EINTR */
    dwError = ldap_set_option( ld, LDAP_OPT_RESTART, (void *)LDAP_OPT_ON);
    if (dwError) {
        LW_RTL_LOG_ERROR("Failed to set LDAP option to auto retry ");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    if (dwFlags & LW_LDAP_OPT_SIGN_AND_SEAL)
    {
        bLdapSeal = TRUE;
    }

    dwError = LwAllocateMemory(sizeof(*pDirectory), OUT_PPVOID(&pDirectory));
    BAIL_ON_LW_ERROR(dwError);

    pDirectory->ld = ld;
    ld = NULL;

    if (dwFlags & LW_LDAP_OPT_ANNONYMOUS)
    {
        dwError = LwLdapBindDirectoryAnonymous((HANDLE)pDirectory);
    }
    else
    {
        dwError = LwLdapBindDirectory(
                      (HANDLE)pDirectory,
                      pszServerName,
                      bLdapSeal);
    }
    // The above functions return -1 when a connection times out.
    if (dwError == (DWORD)-1)
    {
        dwError = ETIMEDOUT;
    }
    BAIL_ON_LW_ERROR(dwError);

    *ppDirectory = pDirectory;

cleanup:

    return(dwError);

error:

    if (pDirectory)
    {
        LwLdapCloseDirectory(pDirectory);
    }
    if (ld)
    {
        ldap_unbind_s(ld);
    }

    *ppDirectory = (HANDLE)NULL;

    goto cleanup;
}