Beispiel #1
0
DWORD
LwLdapCountEntries(
    HANDLE hDirectory,
    LDAPMessage* pMessage,
    PDWORD pdwCount
    )
{
    int iCount = 0;
    int err = 0;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    DWORD dwError = 0;

    pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;
    iCount = ldap_count_entries(pDirectory->ld, pMessage);

    if (iCount < 0)
    {
        dwError = ldap_get_option(
                        pDirectory->ld,
                        LDAP_OPT_ERROR_NUMBER,
                        &err);
        BAIL_ON_LDAP_ERROR(dwError);
        dwError = err;
        BAIL_ON_LDAP_ERROR(dwError);
    }

    *pdwCount = iCount;

cleanup:
    return dwError;

error:
    *pdwCount = 0;
    goto cleanup;
}
Beispiel #2
0
DWORD
LwLdapBindDirectorySasl(
    LDAP *ld,
    PCSTR pszServerName,
    BOOLEAN bSeal
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;

    // Do not attempt to canonicalize the server
    // name which isn't necessary since we used
    // the server's FQDN or address.

    dwError = ldap_set_option(
                  ld,
                  LDAP_OPT_X_SASL_NOCANON,
                  LDAP_OPT_ON);
    BAIL_ON_LDAP_ERROR(dwError);

    // ssf=1 is sign, ssf>1 is seal.  By default
    // it will use the maximum available ssf level
    // so setting minssf isn't strictly necessary.
    // Setting minssf guarantees an error if it
    // cannot provide the minimum level.

    if (bSeal)
    {
        dwError = ldap_set_option(
                      ld,
                      LDAP_OPT_X_SASL_SECPROPS,
                      (void *)"minssf=2");
        BAIL_ON_LDAP_ERROR(dwError);
    }
    else
    {
        dwError = ldap_set_option(
                      ld,
                      LDAP_OPT_X_SASL_SECPROPS,
                      (void *)"minssf=1,maxssf=1");
        BAIL_ON_LDAP_ERROR(dwError);
    }

    dwError = ldap_sasl_interactive_bind_s(
                  ld,
                  NULL,
                  "GSS-SPNEGO",
                  NULL,
                  NULL,
                  LDAP_SASL_QUIET,
                  LwLdapGssSpnegoInteract,
                  (void *)pszServerName);
    if (dwError != 0) {
        LW_RTL_LOG_ERROR("ldap_sasl_interactive_bind_s failed with error code %d", dwError);
        BAIL_ON_LDAP_ERROR(dwError);
    }

error:

    return dwError;
}
Beispiel #3
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;
}
Beispiel #4
0
DWORD
LwLdapEnablePageControlOption(
    HANDLE hDirectory
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    LDAPControl serverControl = {0};
    LDAPControl *ppServerPageCtrls[2] = {NULL, NULL};

    serverControl.ldctl_value.bv_val = NULL;
    serverControl.ldctl_value.bv_len = 0;
    serverControl.ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
    serverControl.ldctl_iscritical = 'T';

    ppServerPageCtrls[0] = &serverControl;

    pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;

    dwError = ldap_set_option(pDirectory->ld,
                              LDAP_OPT_SERVER_CONTROLS,
                              OUT_PPVOID(&ppServerPageCtrls));
    BAIL_ON_LDAP_ERROR(dwError);

cleanup:

    return dwError;

error:

    goto cleanup;
}
Beispiel #5
0
DWORD
LwLdapBindDirectoryAnonymous(
    HANDLE hDirectory
    )
{
    DWORD dwError = 0;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;

    LW_BAIL_ON_INVALID_HANDLE(hDirectory);

    dwError = ldap_bind_s(
                    pDirectory->ld,
                    NULL,
                    NULL,
                    LDAP_AUTH_SIMPLE);
    BAIL_ON_LDAP_ERROR(dwError);

cleanup:

    return dwError;

error:

    LW_RTL_LOG_ERROR("Failed on LDAP simple bind (Error code: %u)", dwError);

    if(pDirectory->ld != NULL)
    {
        ldap_unbind_s(pDirectory->ld);
        pDirectory->ld = NULL;
    }

    goto cleanup;
}
Beispiel #6
0
DWORD
LwCLdapOpenDirectory(
    IN PCSTR pszServerName,
    OUT PHANDLE phDirectory
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    LDAP * ld = NULL;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    int rc = LDAP_VERSION3;
    PSTR pszURL = NULL;

    LW_BAIL_ON_INVALID_STRING(pszServerName);

    dwError = LwAllocateStringPrintf(&pszURL, "cldap://%s",
                                        pszServerName);
    BAIL_ON_LW_ERROR(dwError);

    dwError = ldap_initialize(&ld, pszURL);
    BAIL_ON_LDAP_ERROR(dwError);

    dwError = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &rc);
    BAIL_ON_LDAP_ERROR(dwError);

    dwError = ldap_set_option(ld, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);
    BAIL_ON_LDAP_ERROR(dwError);

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

    pDirectory->ld = ld;

error:
    LW_SAFE_FREE_STRING(pszURL);
    if (dwError)
    {
        if (pDirectory)
        {
            LwLdapCloseDirectory(pDirectory);
            pDirectory = NULL;
        }
    }

    *phDirectory = (HANDLE)pDirectory;

    return dwError;
}
Beispiel #7
0
DWORD
LwLdapDisablePageControlOption(
    HANDLE hDirectory
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;
    LDAPControl *ppServerPageCtrls[1] = {NULL};

    dwError = ldap_set_option(pDirectory->ld,
                              LDAP_OPT_SERVER_CONTROLS,
                              OUT_PPVOID(&ppServerPageCtrls));
    BAIL_ON_LDAP_ERROR(dwError);

cleanup:

    return dwError;

error:

    goto cleanup;
}
Beispiel #8
0
DWORD
LwLdapModify(
    HANDLE hDirectory,
    PCSTR pszDN,
    LDAPMod** ppMods
    )
{
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    DWORD dwError = 0;

    pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;

    dwError = ldap_modify_s(
                  pDirectory->ld,
                  pszDN,
                  ppMods);
    BAIL_ON_LDAP_ERROR(dwError);

cleanup:
    return dwError;

error:
    goto cleanup;
}
Beispiel #9
0
int
VmDirReplResolveConflicts(
    PVDIR_OPERATION     pOperation,
    PVDIR_ENTRY         pEntry,
    PLW_HASHMAP         pMetaDataMap
    )
{
    int                          retVal = LDAP_SUCCESS;
    int                          dbRetVal = 0;
    PSTR                         pszAttrType = NULL;
    DWORD                        dwConflictCnt = 0;
    LW_HASHMAP_ITER              iter = LW_HASHMAP_ITER_INIT;
    LW_HASHMAP_PAIR              pair = {NULL, NULL};
    PVDIR_ATTRIBUTE              pConsumerAttr = NULL;
    PVMDIR_ATTRIBUTE_METADATA    pSupplierMetaData = NULL;
    PVMDIR_REPLICATION_METRICS   pReplMetrics = NULL;

    if (!pOperation || !pEntry || !pMetaDataMap)
    {
        BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER);
    }

    while (LwRtlHashMapIterate(pMetaDataMap, &iter, &pair))
    {
        pszAttrType = (PSTR) pair.pKey;
        pSupplierMetaData = (PVMDIR_ATTRIBUTE_METADATA) pair.pValue;

        if (VmDirStringCompareA(pszAttrType, ATTR_OBJECT_GUID, FALSE) == 0)
        {
            continue;
        }

        VmDirFreeAttribute(pConsumerAttr);
        pConsumerAttr = NULL;

        retVal = VmDirAttributeAllocate(pszAttrType, 0, pOperation->pSchemaCtx, &pConsumerAttr);
        BAIL_ON_LDAP_ERROR(
                retVal,
                LDAP_OPERATIONS_ERROR,
                (pOperation->ldapResult.pszErrMsg),
                "VmDirAttributeAllocate failed", VDIR_SAFE_STRING(pOperation->pBEErrorMsg));

        dbRetVal = pOperation->pBEIF->pfnBEGetAttrMetaData(
                pOperation->pBECtx, pConsumerAttr, pEntry->eId);

        if (dbRetVal)
        {
            switch (dbRetVal)
            {
                case ERROR_BACKEND_ATTR_META_DATA_NOTFOUND: //When a new attribute is being added
                    // => Supplier attribute meta data WINS against consumer attribute meta data
                    break;

                default:
                     BAIL_ON_LDAP_ERROR(
                             retVal,
                             LDAP_OPERATIONS_ERROR,
                             (pOperation->ldapResult.pszErrMsg),
                             "pfnBEGetAttrMetaData failed - (%d)(%s)",
                             dbRetVal,
                             VDIR_SAFE_STRING(pOperation->pBEErrorMsg));
            }
        }
        else
        {
            BOOLEAN             bSupplierWon = FALSE;
            BOOLEAN             bIsSameAttrValue = FALSE;
            PSZ_METADATA_BUF    pszSupplierMetaData = {'\0'};
            PSZ_METADATA_BUF    pszConsumerMetaData = {'\0'};

            bSupplierWon = _VmDirReplAttrConflictCheck(
                    pSupplierMetaData, pConsumerAttr->pMetaData);

            bIsSameAttrValue = _VmDirIsBenignReplConflict(
                    pEntry, pConsumerAttr);

            //Ignore error - used only for logging
            VmDirMetaDataSerialize(pSupplierMetaData, &pszSupplierMetaData[0]);
            VmDirMetaDataSerialize(pConsumerAttr->pMetaData, &pszConsumerMetaData[0]);

            if (bSupplierWon == FALSE)
            {
                if (VmDirStringCompareA(pszAttrType, ATTR_USN_CHANGED, FALSE) == 0)
                {
                    // Need to keep usnChanged to advance localUSN for this replication change.
                    retVal = VmDirMetaDataCopyContent(pConsumerAttr->pMetaData, pSupplierMetaData);
                    BAIL_ON_VMDIR_ERROR(retVal);
                }
                else
                {
                    VMDIR_FREE_REPL_ATTR_IN_CONFLICT(pSupplierMetaData);
                }

                dwConflictCnt++;

                if (!bIsSameAttrValue)
                {
                    VMDIR_LOG_WARNING(
                            VMDIR_LOG_MASK_ALL,
                            "%s: supplier version loses."
                            " pszAttrType: %s supplier attr meta: %s, consumer attr meta: %s ",
                            __FUNCTION__,
                            pEntry->dn.lberbv.bv_val,
                            pszAttrType,
                            pszSupplierMetaData,
                            pszConsumerMetaData);
                }
            }
            else
            {
                VMDIR_LOG_VERBOSE(
                        VMDIR_LOG_MASK_ALL,
                        "%s: supplier version wins."
                        " pszAttrType: %s supplier attr meta: %s, consumer attr meta: %s ",
                        __FUNCTION__,
                        pEntry->dn.lberbv.bv_val,
                        pszAttrType,
                        pszSupplierMetaData,
                        pszConsumerMetaData);
            }
        }
    }

    if (dwConflictCnt > 0)
    {
        if (VmDirReplMetricsCacheFind(pOperation->pszPartner, &pReplMetrics) == 0)
        {
            VmMetricsCounterAdd(pReplMetrics->pCountConflictResolved, dwConflictCnt);
        }
    }

cleanup:
    VmDirFreeAttribute(pConsumerAttr);
    return retVal;

ldaperror:
error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", retVal);
    goto cleanup;
}
Beispiel #10
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;
}
Beispiel #11
0
DWORD
LwLdapDirectoryOnePagedSearch(
    HANDLE         hDirectory,
    PCSTR          pszObjectDN,
    PCSTR          pszQuery,
    PSTR*          ppszAttributeList,
    DWORD          dwPageSize,
    PLW_SEARCH_COOKIE pCookie,
    int            scope,
    LDAPMessage**  ppMessage
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = NULL;
    ber_int_t pageCount = 0;
    CHAR pagingCriticality = 'T';
    LDAPControl *pPageControl = NULL;
    LDAPControl *ppInputControls[2] = { NULL, NULL };
    LDAPControl **ppReturnedControls = NULL;
    int errorcodep = 0;
    LDAPMessage* pMessage = NULL;
    BOOLEAN bSearchFinished = FALSE;
    struct berval * pBerCookie = (struct berval *)pCookie->pvData;

    LW_ASSERT(pCookie->pfnFree == NULL || pCookie->pfnFree == LwLdapFreeCookie);
    pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;

   // dwError = ADEnablePageControlOption(hDirectory);
   // BAIL_ON_LW_ERROR(dwError);

    dwError = ldap_create_page_control(pDirectory->ld,
                                       dwPageSize,
                                       pBerCookie,
                                       pagingCriticality,
                                       &pPageControl);
    BAIL_ON_LDAP_ERROR(dwError);

    ppInputControls[0] = pPageControl;

    dwError = LwLdapDirectorySearchEx(
               hDirectory,
               pszObjectDN,
               scope,
               pszQuery,
               ppszAttributeList,
               ppInputControls,
               0,
               &pMessage);
    BAIL_ON_LW_ERROR(dwError);

    dwError = ldap_parse_result(pDirectory->ld,
                                pMessage,
                                &errorcodep,
                                NULL,
                                NULL,
                                NULL,
                                &ppReturnedControls,
                                0);
    BAIL_ON_LDAP_ERROR(dwError);

    if (pBerCookie != NULL)
    {
        ber_bvfree(pBerCookie);
        pBerCookie = NULL;
    }

    dwError = ldap_parse_page_control(pDirectory->ld,
                                      ppReturnedControls,
                                      &pageCount,
                                      &pBerCookie);
    BAIL_ON_LDAP_ERROR(dwError);

    if (pBerCookie == NULL || pBerCookie->bv_len < 1)
    {
        bSearchFinished = TRUE;
    }

    if (ppReturnedControls)
    {
       ldap_controls_free(ppReturnedControls);
       ppReturnedControls = NULL;
    }

    ppInputControls[0] = NULL;
    ldap_control_free(pPageControl);
    pPageControl = NULL;

    pCookie->bSearchFinished = bSearchFinished;
    *ppMessage = pMessage;
    pCookie->pvData = pBerCookie;
    pCookie->pfnFree = LwLdapFreeCookie;

cleanup:
  /*  dwError_disable = ADDisablePageControlOption(hDirectory);
    if (dwError_disable)
        LW_RTL_LOG_ERROR("Error: LDAP Disable PageControl Info: failed");*/

    if (ppReturnedControls) {
        ldap_controls_free(ppReturnedControls);
    }

    ppInputControls[0] = NULL;

    if (pPageControl) {
        ldap_control_free(pPageControl);
    }

    return (dwError);

error:

    *ppMessage = NULL;
    pCookie->pvData = NULL;
    pCookie->pfnFree = NULL;
    pCookie->bSearchFinished = TRUE;

    if (pBerCookie != NULL)
    {
        ber_bvfree(pBerCookie);
        pBerCookie = NULL;
    }

    goto cleanup;
}
Beispiel #12
0
DWORD
LwLdapDirectorySearchEx(
    HANDLE hDirectory,
    PCSTR  pszObjectDN,
    int    scope,
    PCSTR  pszQuery,
    PSTR*  ppszAttributeList,
    LDAPControl** ppServerControls,
    DWORD  dwNumMaxEntries,
    LDAPMessage** ppMessage
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;
    struct timeval timeout = {0};
    LDAPMessage* pMessage = NULL;

    // Set timeout to 60 seconds to be able to deal with large group
    // Instead of bailing on errors
    timeout.tv_sec = 60;
    timeout.tv_usec = 0;

    dwError = ldap_search_ext_s(
                    pDirectory->ld,
                    pszObjectDN,
                    scope,
                    pszQuery,
                    ppszAttributeList,
                    0,
                    ppServerControls,
                    NULL,
                    &timeout,
                    dwNumMaxEntries,
                    &pMessage);
    if (dwError) {
        if (dwError == LDAP_NO_SUCH_OBJECT) {
            LW_RTL_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search");
            BAIL_ON_LDAP_ERROR(dwError);
        }
        if (dwError == LDAP_REFERRAL) {
            LW_RTL_LOG_ERROR("Caught LDAP_REFERRAL Error on ldap search");
            LW_RTL_LOG_ERROR("LDAP Search Info: DN: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszObjectDN) ? "<null>" : pszObjectDN);
            LW_RTL_LOG_ERROR("LDAP Search Info: scope: [%d]", scope);
            LW_RTL_LOG_ERROR("LDAP Search Info: query: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszQuery) ? "<null>" : pszQuery);
            if (ppszAttributeList) {
                size_t i;
                for (i = 0; ppszAttributeList[i] != NULL; i++) {
                    LW_RTL_LOG_ERROR("LDAP Search Info: attribute: [%s]", ppszAttributeList[i]);
                }
            }
            else {
                LW_RTL_LOG_ERROR("Error: LDAP Search Info: no attributes were specified");
            }
        }
        BAIL_ON_LDAP_ERROR(dwError);
    }

    *ppMessage = pMessage;

cleanup:

    return(dwError);

error:

    *ppMessage = NULL;

    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    goto cleanup;
}
Beispiel #13
0
DWORD
LwLdapDirectorySearch(
    HANDLE hDirectory,
    PCSTR  pszObjectDN,
    int    scope,
    PCSTR  pszQuery,
    PSTR*  ppszAttributeList,
    LDAPMessage** ppMessage
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;
    struct timeval timeout = {0};
    LDAPMessage* pMessage = NULL;

    timeout.tv_sec = 15;
    timeout.tv_usec = 0;

    dwError = ldap_search_st(pDirectory->ld,
                             pszObjectDN,
                             scope,
                             pszQuery,
                             ppszAttributeList,
                             0,
                             &timeout,
                             &pMessage);
    if (dwError) {
        if (dwError == LDAP_NO_SUCH_OBJECT) {
            LW_RTL_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search");
            BAIL_ON_LDAP_ERROR(dwError);
        }
        if (dwError == LDAP_REFERRAL) {
            LW_RTL_LOG_ERROR("Caught LDAP_REFERRAL Error on ldap search");
            LW_RTL_LOG_ERROR("LDAP Search Info: DN: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszObjectDN) ? "<null>" : pszObjectDN);
            LW_RTL_LOG_ERROR("LDAP Search Info: scope: [%d]", scope);
            LW_RTL_LOG_ERROR("LDAP Search Info: query: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszQuery) ? "<null>" : pszQuery);
            if (ppszAttributeList) {
                size_t i;
                for (i = 0; ppszAttributeList[i] != NULL; i++) {
                    LW_RTL_LOG_ERROR("LDAP Search Info: attribute: [%s]", ppszAttributeList[i]);
                }
            }
            else {
                LW_RTL_LOG_ERROR("Error: LDAP Search Info: no attributes were specified");
            }
        }
        BAIL_ON_LDAP_ERROR(dwError);
    }

    *ppMessage = pMessage;

cleanup:

    return(dwError);

error:

    *ppMessage = NULL;

    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    goto cleanup;
}
Beispiel #14
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;
}
Beispiel #15
0
DWORD
LwLdapDirectoryExtendedDNSearch(
    IN HANDLE hDirectory,
    IN PCSTR pszObjectDN,
    IN PCSTR pszQuery,
    IN PSTR* ppszAttributeList,
    IN int scope,
    OUT LDAPMessage** ppMessage
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    CHAR ExtDNCriticality = 'T';
    LDAPControl *pExtDNControl = NULL;
    LDAPControl *ppInputControls[2] = { NULL, NULL };
    LDAPMessage* pMessage = NULL;
    struct berval value = {0};

    // Setup the extended DN control, in order to be windows 2000 compatible,
    // Do not specify control value, hence, the return result will always be in hexadecimal string format.
    value.bv_len = 0;
    value.bv_val = NULL;
    dwError = ldap_control_create(LDAP_CONTROL_X_EXTENDED_DN,
                                  ExtDNCriticality,
                                  &value,
                                  0,
                                  &pExtDNControl);
    BAIL_ON_LDAP_ERROR(dwError);

    ppInputControls[0] = pExtDNControl;

    dwError = LwLdapDirectorySearchEx(
               hDirectory,
               pszObjectDN,
               scope,
               pszQuery,
               ppszAttributeList,
               ppInputControls,
               0,
               &pMessage);
    BAIL_ON_LW_ERROR(dwError);

    LW_ASSERT(pMessage != NULL);
    *ppMessage = pMessage;

cleanup:
    ppInputControls[0] = NULL;

    if (pExtDNControl)
    {
        ldap_control_free(pExtDNControl);
    }

    return (dwError);

error:
    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }
    *ppMessage = NULL;

    goto cleanup;
}