예제 #1
0
static
DWORD
KtLdapBind(
    LDAP  **ppLd,
    PCSTR   pszDc
    )
{
    const int version = LDAP_VERSION3;
    DWORD dwError = ERROR_SUCCESS;
    int lderr = 0;
    PSTR pszUrl = NULL;
    LDAP *pLd = NULL;

    dwError = LwAllocateStringPrintf(&pszUrl,
                                     "ldap://%s",
                                     pszDc);
    BAIL_ON_LSA_ERROR(dwError);

    lderr = ldap_initialize(&pLd,
                            pszUrl);
    BAIL_ON_LDAP_ERROR(lderr);

    lderr = ldap_set_option(pLd,
                            LDAP_OPT_PROTOCOL_VERSION,
                            &version);
    BAIL_ON_LDAP_ERROR(lderr);

    lderr = ldap_set_option(pLd,
                            LDAP_OPT_REFERRALS,
                            LDAP_OPT_OFF);
    BAIL_ON_LDAP_ERROR(lderr);

    dwError = LwLdapBindDirectorySasl(pLd, pszDc, FALSE);
    BAIL_ON_LSA_ERROR(dwError);

    *ppLd = pLd;

cleanup:
    LW_SAFE_FREE_MEMORY(pszUrl);

    if (dwError == ERROR_SUCCESS &&
        lderr != LDAP_SUCCESS)
    {
        dwError = LwMapLdapErrorToLwError(lderr);
    }

    return dwError;

error:
    if (pLd)
    {
        ldap_memfree(pLd);
    }

    *ppLd = NULL;

    goto cleanup;
}
예제 #2
0
DWORD
IDMLdapSaslBind(
    LDAP*        pLd                       /* IN     */
    )
{
    DWORD dwError = 0;
    DWORD dwCleanupError = 0;
    BOOLEAN bLocked = FALSE;
    PSTR  pszCachePath = NULL;

    if (!pLd)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_ERROR(dwError);
    }

    switch (IDMKrbGetState(pgIdmKrbContext))
    {
        case IDM_KRB_CONTEXT_STATE_INITIAL:

            dwError = IDMKrbDetermineJoinState(pgIdmKrbContext);
            BAIL_ON_ERROR(dwError);

        case IDM_KRB_CONTEXT_STATE_JOINED:

            dwError = IDMKrbRenewCredentials(pgIdmKrbContext);
            if (dwError)
            {
               // Refreshing credentials might fail if the system left
               // the domain or there were issues reaching the domain
               // controller.
               IDMKrbSetState(pgIdmKrbContext, IDM_KRB_CONTEXT_STATE_INITIAL);
            }
            BAIL_ON_ERROR(dwError);

            IDM_RWMUTEX_LOCK_SHARED(
                &pgIdmKrbContext->mutex_rw,
                bLocked,
                dwError);
            BAIL_ON_ERROR(dwError);

            dwError = LwKrb5SetThreadDefaultCachePath(
                            pgIdmKrbContext->pszCachePath,
                            &pszCachePath);
            BAIL_ON_ERROR(dwError);

            dwError = LwMapLdapErrorToLwError(
                        ldap_sasl_interactive_bind_s(
                            pLd,
                            NULL,
                            "GSSAPI",
                            NULL,
                            NULL,
                            LDAP_SASL_QUIET,
                            &IDMSASLInteraction,
                            NULL));
            BAIL_ON_ERROR(dwError);

            break;

        default:

            dwError = ERROR_INVALID_STATE;
            BAIL_ON_ERROR(dwError);

            break;
    }

cleanup:

    if (pszCachePath)
    {
        LwKrb5SetThreadDefaultCachePath(pszCachePath, NULL);

        LwFreeMemory(pszCachePath);
    }

    IDM_RWMUTEX_UNLOCK(&pgIdmKrbContext->mutex_rw, bLocked, dwCleanupError);
    if(!dwError)
    {
        dwError = dwCleanupError;
    }
    return dwError;

error:

    goto cleanup;
}
예제 #3
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;
}
예제 #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;
}
예제 #5
0
static
DWORD
KtLdapQuery(
    LDAP  *pLd,
    PCSTR  pszBaseDn,
    DWORD  dwScope,
    PCSTR  pszFilter,
    PCSTR  pszAttrName,
    PSTR  *ppszAttrVal
    )
{
    DWORD dwError = ERROR_SUCCESS;
    int lderr = LDAP_SUCCESS;
    char *attrs[2] = {
        NULL, // This gets filled in later
        NULL  // This null terminates the list of attributes
    };
    LDAPMessage *res = NULL;
    LDAPMessage *entry = NULL;
    char *attr = NULL;
    struct berval **ppBv = NULL;
    BerElement *ptr = NULL;
    struct timeval timeout = { .tv_sec  = 10,
                               .tv_usec = 0 };
    PSTR pszAttrVal = NULL;

    dwError = LwAllocateString(pszAttrName,
                               &attrs[0]);
    BAIL_ON_LSA_ERROR(dwError);

    lderr = ldap_search_ext_s(pLd,
                              pszBaseDn,
                              dwScope,
                              pszFilter,
                              attrs,
                              0,
                              NULL,
                              NULL,
                              &timeout,
                              0,
                              &res);
    BAIL_ON_LDAP_ERROR(lderr);

    if (ldap_count_entries(pLd, res))
    {
        entry = ldap_first_entry(pLd, res);
        if (entry == NULL)
        {
            dwError = ERROR_DS_GENERIC_ERROR;
            BAIL_ON_LSA_ERROR(dwError);
        }

        attr = ldap_first_attribute(pLd, entry, &ptr);
        if (attr)
        {
            ppBv = ldap_get_values_len(pLd, entry, attr);
            if (ldap_count_values_len(ppBv))
            {
                dwError = LwAllocateMemory(ppBv[0]->bv_len + 1,
                                           OUT_PPVOID(&pszAttrVal));
                BAIL_ON_LSA_ERROR(dwError);

                memcpy(pszAttrVal, ppBv[0]->bv_val, ppBv[0]->bv_len);
            }

            ldap_memfree(attr);
        }

        ldap_msgfree(res);
    }

    *ppszAttrVal = pszAttrVal;

cleanup:
    if (ppBv)
    {
        ldap_value_free_len(ppBv);
    }

    if (ptr != NULL)
    {
        ber_free( ptr, 0 );
    }

    LW_SAFE_FREE_STRING(attrs[0]);

    if (dwError == ERROR_SUCCESS &&
        lderr != LDAP_SUCCESS)
    {
        dwError = LwMapLdapErrorToLwError(lderr);
    }

    return dwError;

error:
    *ppszAttrVal = NULL;

    goto cleanup;
}

static
DWORD
KtLdapUnbind(
    LDAP *pLd
    )
{
    DWORD dwError = ERROR_SUCCESS;
    int lderr = LDAP_SUCCESS;

    lderr = ldap_unbind_ext_s(pLd, NULL, NULL);
    BAIL_ON_LDAP_ERROR(lderr);

cleanup:
    if (lderr)
    {
        dwError = LwMapLdapErrorToLwError(lderr);
    }

    return dwError;

error:
    goto cleanup;
}