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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }