DWORD DefaultModeNonSchemaEnumNSSArtefacts( PLSA_DM_LDAP_CONNECTION pConn, PCSTR pszCellDN, PCSTR pszNetBIOSDomainName, PAD_ENUM_STATE pEnumState, DWORD dwMaxNumNSSArtefacts, PDWORD pdwNumNSSArtefactsFound, PVOID** pppNSSArtefactInfoList ) { DWORD dwError = 0; DWORD dwCount = 0; PCSTR pszQuery = "(&(objectClass=serviceConnectionPoint)(keywords=objectClass=centerisLikewiseMapEntry))"; PSTR pszDN = NULL; PSTR pszEscapedDN = NULL; PVOID* ppNSSArtefactInfoList = NULL; PVOID* ppNSSArtefactInfoList_accumulate = NULL; DWORD dwTotalNumNSSArtefactsFound = 0; DWORD dwNumNSSArtefactsFound = 0; DWORD dwNSSArtefactInfoLevel = 0; PSTR szAttributeList[] = { AD_LDAP_NAME_TAG, AD_LDAP_KEYWORDS_TAG, NULL }; LDAPMessage *pMessagePseudo = NULL; LDAP *pLd = NULL; HANDLE hDirectory = NULL; DWORD dwNumNSSArtefactsWanted = dwMaxNumNSSArtefacts; dwNSSArtefactInfoLevel = pEnumState->dwInfoLevel; BAIL_ON_INVALID_STRING(pEnumState->pszMapName); dwError = LwAllocateStringPrintf( &pszDN, "CN=%s,CN=Maps,%s", pEnumState->pszMapName, pszCellDN); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapEscapeString( &pszEscapedDN, pszDN); BAIL_ON_LSA_ERROR(dwError); if (pEnumState->Cookie.bSearchFinished){ dwError = LW_ERROR_NO_MORE_NSS_ARTEFACTS; BAIL_ON_LSA_ERROR(dwError); } do { dwError = LsaDmLdapDirectoryOnePagedSearch( pConn, pszEscapedDN, pszQuery, szAttributeList, dwNumNSSArtefactsWanted, &pEnumState->Cookie, LDAP_SCOPE_ONELEVEL, &hDirectory, &pMessagePseudo); BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); dwCount = ldap_count_entries( pLd, pMessagePseudo); if (dwCount < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (dwCount == 0) { dwError = LW_ERROR_NO_MORE_NSS_ARTEFACTS; } BAIL_ON_LSA_ERROR(dwError); dwError = ADNonSchemaMarshalNSSArtefactInfoList( hDirectory, pszNetBIOSDomainName, pMessagePseudo, pEnumState->dwMapFlags, dwNSSArtefactInfoLevel, &ppNSSArtefactInfoList, &dwNumNSSArtefactsFound ); BAIL_ON_LSA_ERROR(dwError); dwNumNSSArtefactsWanted -= dwNumNSSArtefactsFound; dwError = LsaAppendAndFreePtrs( &dwTotalNumNSSArtefactsFound, &ppNSSArtefactInfoList_accumulate, &dwNumNSSArtefactsFound, &ppNSSArtefactInfoList); BAIL_ON_LSA_ERROR(dwError); if (pMessagePseudo) { ldap_msgfree(pMessagePseudo); pMessagePseudo = NULL; } } while (!pEnumState->Cookie.bSearchFinished && dwNumNSSArtefactsWanted); *pppNSSArtefactInfoList = ppNSSArtefactInfoList_accumulate; *pdwNumNSSArtefactsFound = dwTotalNumNSSArtefactsFound; cleanup: LW_SAFE_FREE_STRING(pszDN); LW_SAFE_FREE_STRING(pszEscapedDN); return dwError; error: *pppNSSArtefactInfoList = NULL; *pdwNumNSSArtefactsFound = 0; if (ppNSSArtefactInfoList) { LsaFreeNSSArtefactInfoList(dwNSSArtefactInfoLevel, ppNSSArtefactInfoList, dwNumNSSArtefactsFound); } if (ppNSSArtefactInfoList_accumulate) { LsaFreeNSSArtefactInfoList(dwNSSArtefactInfoLevel, ppNSSArtefactInfoList_accumulate, dwTotalNumNSSArtefactsFound); } if (dwError == LW_ERROR_LDAP_NO_SUCH_OBJECT) { dwError = LW_ERROR_NO_MORE_NSS_ARTEFACTS; } goto cleanup; }
static DWORD AD_RawFindComputerDn( IN HANDLE hDirectory, IN PCSTR pszDnsDomainName, IN PCSTR pszSamAccountName, OUT PSTR* ppszComputerDn ) { DWORD dwError = 0; LDAP* pLd = NULL; PSTR pszDirectoryRoot = NULL; PSTR pszEscapedSamAccountName = NULL; PSTR szAttributeList[] = {"*", NULL}; PSTR pszQuery = NULL; LDAPMessage *pMessage = NULL; int count = 0; PSTR pszComputerDn = NULL; pLd = LwLdapGetSession(hDirectory); dwError = LwLdapConvertDomainToDN( pszDnsDomainName, &pszDirectoryRoot); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapEscapeString( &pszEscapedSamAccountName, pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); LwStrToUpper(pszEscapedSamAccountName); dwError = LwAllocateStringPrintf( &pszQuery, "(sAMAccountName=%s)", pszEscapedSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapDirectorySearch( hDirectory, pszDirectoryRoot, LDAP_SCOPE_SUBTREE, pszQuery, szAttributeList, &pMessage); BAIL_ON_LSA_ERROR(dwError); count = ldap_count_entries(pLd, pMessage); if (count < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (count == 0) { dwError = LW_ERROR_NO_SUCH_DOMAIN; } else if (count > 1) { dwError = LW_ERROR_DUPLICATE_DOMAINNAME; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetDN(hDirectory, pMessage, &pszComputerDn); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pszComputerDn)) { dwError = LW_ERROR_LDAP_FAILED_GETDN; BAIL_ON_LSA_ERROR(dwError); } error: if (dwError) { LW_SAFE_FREE_STRING(pszComputerDn); } LW_SAFE_FREE_STRING(pszDirectoryRoot); LW_SAFE_FREE_STRING(pszEscapedSamAccountName); LW_SAFE_FREE_STRING(pszQuery); if (pMessage) { ldap_msgfree(pMessage); } *ppszComputerDn = pszComputerDn; return dwError; }
DWORD DefaultModeNonSchemaFindNSSArtefactByKey( IN PLSA_DM_LDAP_CONNECTION pConn, PCSTR pszCellDN, PCSTR pszNetBIOSDomainName, PCSTR pszKeyName, PCSTR pszMapName, DWORD dwInfoLevel, LSA_NIS_MAP_QUERY_FLAGS dwFlags, PVOID* ppNSSArtefactInfo ) { DWORD dwError = 0; DWORD dwCount = 0; PSTR pszQuery = NULL; PSTR pszDN = NULL; PSTR pszEscapedDN = NULL; PSTR szAttributeList[] = { AD_LDAP_NAME_TAG, AD_LDAP_KEYWORDS_TAG, NULL }; LDAPMessage *pMessagePseudo = NULL; PVOID* ppArtefactInfos = NULL; DWORD dwNumInfos = 0; BOOLEAN bMapExists = FALSE; LDAP *pLd = NULL; HANDLE hDirectory = NULL; BAIL_ON_INVALID_STRING(pszMapName); BAIL_ON_INVALID_STRING(pszKeyName); dwError = LwAllocateStringPrintf( &pszDN, "CN=%s,CN=Maps,%s", pszMapName, pszCellDN); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapEscapeString( &pszEscapedDN, pszDN); BAIL_ON_LSA_ERROR(dwError); dwError = ADLdap_IsValidDN( pConn, pszEscapedDN, &bMapExists); BAIL_ON_LSA_ERROR(dwError); if (!bMapExists) { dwError = LW_ERROR_NO_SUCH_NSS_MAP; BAIL_ON_LSA_ERROR(dwError); } dwError = LwAllocateStringPrintf( &pszQuery, "(&(objectClass=serviceConnectionPoint)(keywords=objectClass=centerisLikewiseMapEntry)(name=%s))", pszKeyName); BAIL_ON_LSA_ERROR(dwError); dwError = LsaDmLdapDirectorySearch( pConn, pszEscapedDN, LDAP_SCOPE_ONELEVEL, pszQuery, szAttributeList, &hDirectory, &pMessagePseudo); BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); dwCount = ldap_count_entries( pLd, pMessagePseudo); if (dwCount < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (dwCount == 0) { dwError = LW_ERROR_NO_SUCH_NSS_KEY; } BAIL_ON_LSA_ERROR(dwError); dwError = ADNonSchemaMarshalNSSArtefactInfoList( hDirectory, pszNetBIOSDomainName, pMessagePseudo, dwFlags, dwInfoLevel, &ppArtefactInfos, &dwNumInfos); BAIL_ON_LSA_ERROR(dwError); *ppNSSArtefactInfo = *ppArtefactInfos; *ppArtefactInfos = NULL; cleanup: if (pMessagePseudo) { ldap_msgfree(pMessagePseudo); } if (ppArtefactInfos) { LsaFreeNSSArtefactInfoList(dwInfoLevel, ppArtefactInfos, dwNumInfos); } LW_SAFE_FREE_STRING(pszDN); LW_SAFE_FREE_STRING(pszEscapedDN); LW_SAFE_FREE_STRING(pszQuery); return dwError; error: *ppNSSArtefactInfo = NULL; if (dwError == LW_ERROR_LDAP_NO_SUCH_OBJECT) { dwError = LW_ERROR_NO_SUCH_NSS_KEY; } goto cleanup; }
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; }
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; }
DWORD ADGetConfigurationMode( IN PLSA_DM_LDAP_CONNECTION pConn, PCSTR pszDN, ADConfigurationMode* pADConfMode ) { DWORD dwError = 0; LDAP *pLd = NULL; PSTR szAttributeList[] = {AD_LDAP_DESCRIPTION_TAG, NULL}; LDAPMessage *pMessage = NULL; DWORD dwCount = 0; ADConfigurationMode adConfMode = NonSchemaMode; HANDLE hDirectory = NULL; PSTR* ppszValues = NULL; DWORD dwNumValues = 0; DWORD i = 0; BAIL_ON_INVALID_POINTER(pConn); dwError = LsaDmLdapDirectorySearch( pConn, pszDN, LDAP_SCOPE_BASE, "(objectClass=*)", szAttributeList, &hDirectory, &pMessage); if (dwError == LW_ERROR_LDAP_NO_SUCH_OBJECT){ dwError = LW_ERROR_INCOMPATIBLE_MODES_BETWEEN_TRUSTEDDOMAINS; } BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); dwCount = ldap_count_entries( pLd, pMessage ); if (dwCount < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (dwCount == 0) { dwError = LW_ERROR_NO_SUCH_CELL; } else if (dwCount > 1) { dwError = LW_ERROR_INTERNAL; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetStrings( hDirectory, pMessage, AD_LDAP_DESCRIPTION_TAG, &ppszValues, &dwNumValues); BAIL_ON_LSA_ERROR(dwError); for (i = 0; i < dwNumValues; i++) { if (!strncasecmp(ppszValues[i], "use2307Attrs=", sizeof("use2307Attrs=")-1)) { PSTR pszValue = ppszValues[i] + sizeof("use2307Attrs=") - 1; if (!LW_IS_NULL_OR_EMPTY_STR(pszValue) && !strcasecmp(pszValue, "true")) { adConfMode = SchemaMode; break; } } } *pADConfMode = adConfMode; cleanup: if (pMessage) { ldap_msgfree(pMessage); } if (ppszValues) { LwFreeStringArray(ppszValues, dwNumValues); } return dwError; error: *pADConfMode = UnknownMode; goto cleanup; }
// Give an attribute name "pszAttributeName" // Return all the values of the attribute for a given DN "pszDN" // The number of values can be more than 1500 since "ranging" is handled correctly in the routine // Now accept whether to do an extended DN search and whether to parse result to get Sids DWORD ADLdap_GetAttributeValuesList( IN PLSA_DM_LDAP_CONNECTION pConn, IN PCSTR pszDN, IN PCSTR pszAttributeName, IN BOOLEAN bDoExtDnSearch, IN BOOLEAN bDoSidParsing, OUT PDWORD pdwTotalCount, OUT PSTR** pppszValues ) { DWORD dwError = 0; // Do not free "szAttributeList" PSTR szAttributeList[2] = {NULL,NULL}; PSTR* ppszValuesTotal = NULL; PSTR* ppszValues = NULL; LDAPMessage* pMessage = NULL; DWORD dwCount = 0; DWORD dwTotalCount = 0; PLW_DLINKED_LIST pList = NULL; PLW_DLINKED_LIST pNode = NULL; PLSA_AD_QUERY_LISTS_ENTRY pEntry = NULL; PSTR pszRangeAttr = NULL; LDAP* pLd = NULL; BerElement* pBer = NULL; PSTR pszRetrievedAttr = NULL; //Do Not free "pszRetrievedRangeAttr" PSTR pszRetrievedRangeAttr = NULL; BOOLEAN bIsEnd = FALSE; DWORD iValues = 0; DWORD iValuesTotal = 0; PSTR pszAttributeRangedName = NULL; HANDLE hDirectory = NULL; BAIL_ON_INVALID_STRING(pszAttributeName); szAttributeList[0] = (PSTR)pszAttributeName; for (;;) { if (pMessage) { ldap_msgfree(pMessage); pMessage = NULL; } if (!bDoExtDnSearch && bDoSidParsing) { dwError = LW_ERROR_INVALID_PARAMETER; BAIL_ON_LSA_ERROR(dwError); } if (bDoExtDnSearch) { dwError = LsaDmLdapDirectoryExtendedDNSearch( pConn, pszDN, "(objectClass=*)", szAttributeList, LDAP_SCOPE_BASE, &hDirectory, &pMessage); BAIL_ON_LSA_ERROR(dwError); } else { dwError = LsaDmLdapDirectorySearch( pConn, pszDN, LDAP_SCOPE_BASE, "(objectClass=*)", szAttributeList, &hDirectory, &pMessage); BAIL_ON_LSA_ERROR(dwError); } pLd = LwLdapGetSession(hDirectory); dwError = LwLdapGetStringsWithExtDnResult( hDirectory, pMessage, pszAttributeName, bDoSidParsing, &ppszValues, &dwCount); BAIL_ON_LSA_ERROR(dwError); if (ppszValues && dwCount) { if (pList) { // This is the case where we started out getting // ranged info but the info became non-ranged. // We might actually want to allow this to handle // a case where the membership list is trimmed // while we are enumerating. dwError = LW_ERROR_LDAP_ERROR; BAIL_ON_LSA_ERROR(dwError); } dwTotalCount = dwCount; ppszValuesTotal = ppszValues; dwCount = 0; ppszValues = NULL; break; } if (pszRetrievedAttr) { ldap_memfree(pszRetrievedAttr); pszRetrievedAttr = NULL; } if (pBer) { ber_free(pBer, 0); } LW_SAFE_FREE_STRING(pszAttributeRangedName); dwError = LwAllocateStringPrintf( &pszAttributeRangedName, "%s;Range=", pszAttributeName); BAIL_ON_LSA_ERROR(dwError); pszRetrievedAttr = ldap_first_attribute(pLd, pMessage, &pBer); while (pszRetrievedAttr) { if (!strncasecmp(pszRetrievedAttr, pszAttributeRangedName, strlen(pszAttributeRangedName))) { pszRetrievedRangeAttr = pszRetrievedAttr; break; } ldap_memfree(pszRetrievedAttr); pszRetrievedAttr = NULL; pszRetrievedAttr = ldap_next_attribute(pLd, pMessage, pBer); } if (!pszRetrievedRangeAttr) { // This happens when we have an group with no members, break; } if ('*' == pszRetrievedRangeAttr[strlen(pszRetrievedRangeAttr)-1]) { bIsEnd = TRUE; } dwError = LwLdapGetStringsWithExtDnResult( hDirectory, pMessage, pszRetrievedRangeAttr, bDoSidParsing, &ppszValues, &dwCount); BAIL_ON_LSA_ERROR(dwError); dwTotalCount += dwCount; dwError = CreateQueryListEntry( &pEntry, dwCount, ppszValues); BAIL_ON_LSA_ERROR(dwError); ppszValues = NULL; dwCount = 0; dwError = LwDLinkedListPrepend(&pList, pEntry); BAIL_ON_LSA_ERROR(dwError); pEntry = NULL; if (bIsEnd) { break; } LW_SAFE_FREE_STRING(pszRangeAttr); dwError = LwAllocateStringPrintf( &pszRangeAttr, "%s%u-*", pszAttributeRangedName, dwTotalCount); BAIL_ON_LSA_ERROR(dwError); szAttributeList[0] = pszRangeAttr; } if (pList && !ppszValuesTotal) { dwError = LwAllocateMemory( sizeof(*ppszValuesTotal) * dwTotalCount, (PVOID*)&ppszValuesTotal); BAIL_ON_LSA_ERROR(dwError); for (pNode = pList; pNode; pNode = pNode->pNext) { PLSA_AD_QUERY_LISTS_ENTRY pEntry = (PLSA_AD_QUERY_LISTS_ENTRY)pNode->pItem; for (iValues = 0; iValues < pEntry->dwQueryCount; iValues++) { ppszValuesTotal[iValuesTotal] = pEntry->ppszQueryValues[iValues]; pEntry->ppszQueryValues[iValues] = NULL; iValuesTotal++; } } } *pdwTotalCount = dwTotalCount; *pppszValues = ppszValuesTotal; cleanup: if (pMessage) { ldap_msgfree(pMessage); } if (pszRetrievedAttr) { ldap_memfree(pszRetrievedAttr); } if (pBer) { ber_free(pBer, 0); } LwFreeStringArray(ppszValues, dwCount); DestroyQueryListEntry(&pEntry); LW_SAFE_FREE_STRING(pszAttributeRangedName); LW_SAFE_FREE_STRING(pszRangeAttr); for (pNode = pList; pNode; pNode = pNode->pNext) { PLSA_AD_QUERY_LISTS_ENTRY pEntry = (PLSA_AD_QUERY_LISTS_ENTRY)pNode->pItem; DestroyQueryListEntry(&pEntry); } LwDLinkedListFree(pList); return dwError; error: LwFreeStringArray(ppszValuesTotal, iValuesTotal); *pdwTotalCount = 0; *pppszValues = NULL; goto cleanup; }
DWORD ADGetDomainMaxPwdAge( IN PLSA_DM_LDAP_CONNECTION pConn, PCSTR pszDomainName, PUINT64 pMaxPwdAge) { DWORD dwError = 0; LDAP *pLd = NULL; PSTR szAttributeList[] = { AD_LDAP_MAX_PWDAGE_TAG, NULL}; LDAPMessage *pMessage = NULL; DWORD dwCount = 0; PSTR pszDirectoryRoot = NULL; int64_t int64MaxPwdAge = 0; HANDLE hDirectory = NULL; dwError = LwLdapConvertDomainToDN( pszDomainName, &pszDirectoryRoot); BAIL_ON_LSA_ERROR(dwError); dwError = LsaDmLdapDirectorySearch( pConn, pszDirectoryRoot, LDAP_SCOPE_BASE, "(objectClass=*)", szAttributeList, &hDirectory, &pMessage); BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); dwCount = ldap_count_entries( pLd, pMessage ); if (dwCount < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (dwCount == 0) { dwError = LW_ERROR_NO_SUCH_DOMAIN; } else if (dwCount > 1) { dwError = LW_ERROR_DUPLICATE_DOMAINNAME; } BAIL_ON_LSA_ERROR(dwError); //process "maxPwdAge" dwError = LwLdapGetInt64( hDirectory, pMessage, AD_LDAP_MAX_PWDAGE_TAG, &int64MaxPwdAge); BAIL_ON_LSA_ERROR(dwError); if (int64MaxPwdAge == 0x8000000000000000LL) { *pMaxPwdAge = 0; } else { *pMaxPwdAge = (UINT64) (int64MaxPwdAge < 0 ? -int64MaxPwdAge : int64MaxPwdAge); } cleanup: LW_SAFE_FREE_STRING(pszDirectoryRoot); if (pMessage) { ldap_msgfree(pMessage); } return dwError; error: goto cleanup; }
DWORD ADGetCellInformation( IN PLSA_DM_LDAP_CONNECTION pConn, PCSTR pszDN, PSTR* ppszCellDN ) { DWORD dwError = 0; LDAP *pLd = NULL; PSTR szAttributeList[] = {"*", NULL}; LDAPMessage *pMessage = NULL; DWORD dwCount = 0; PSTR pszCellDN = NULL; HANDLE hDirectory = NULL; dwError = LsaDmLdapDirectorySearch( pConn, pszDN, LDAP_SCOPE_ONELEVEL, "(name=$LikewiseIdentityCell)", szAttributeList, &hDirectory, &pMessage); BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); dwCount = ldap_count_entries( pLd, pMessage ); if (dwCount < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (dwCount == 0) { dwError = LW_ERROR_NO_SUCH_CELL; } else if (dwCount > 1) { dwError = LW_ERROR_INTERNAL; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetDN( hDirectory, pMessage, &pszCellDN); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pszCellDN)) { dwError = LW_ERROR_LDAP_FAILED_GETDN; BAIL_ON_LSA_ERROR(dwError); } *ppszCellDN = pszCellDN; cleanup: if (pMessage) { ldap_msgfree(pMessage); } return dwError; error: *ppszCellDN = NULL; LW_SAFE_FREE_STRING(pszCellDN); goto cleanup; }
DWORD ADFindComputerDN( IN PLSA_DM_LDAP_CONNECTION pConn, PCSTR pszSamAccountName, PCSTR pszDomainName, PSTR* ppszComputerDN ) { DWORD dwError = 0; LDAP *pLd = NULL; PSTR pszDirectoryRoot = NULL; PSTR szAttributeList[] = {"*", NULL}; PSTR pszQuery = NULL; LDAPMessage *pMessage = NULL; DWORD dwCount = 0; PSTR pszComputerDN = NULL; PSTR pszEscapedUpperSamAccountName = NULL; HANDLE hDirectory = NULL; dwError = LwLdapConvertDomainToDN(pszDomainName, &pszDirectoryRoot); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapEscapeString( &pszEscapedUpperSamAccountName, pszSamAccountName); BAIL_ON_LSA_ERROR(dwError); LwStrToUpper(pszEscapedUpperSamAccountName); dwError = LwAllocateStringPrintf(&pszQuery, "(sAMAccountName=%s)", pszEscapedUpperSamAccountName); BAIL_ON_LSA_ERROR(dwError); dwError = LsaDmLdapDirectorySearch( pConn, pszDirectoryRoot, LDAP_SCOPE_SUBTREE, pszQuery, szAttributeList, &hDirectory, &pMessage); BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); dwCount = ldap_count_entries( pLd, pMessage ); if (dwCount < 0) { dwError = LW_ERROR_LDAP_ERROR; } else if (dwCount == 0) { dwError = LW_ERROR_NO_SUCH_DOMAIN; } else if (dwCount > 1) { dwError = LW_ERROR_DUPLICATE_DOMAINNAME; } BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapGetDN( hDirectory, pMessage, &pszComputerDN); BAIL_ON_LSA_ERROR(dwError); if (LW_IS_NULL_OR_EMPTY_STR(pszComputerDN)) { dwError = LW_ERROR_LDAP_FAILED_GETDN; BAIL_ON_LSA_ERROR(dwError); } *ppszComputerDN = pszComputerDN; cleanup: LW_SAFE_FREE_STRING(pszEscapedUpperSamAccountName); LW_SAFE_FREE_STRING(pszDirectoryRoot); LW_SAFE_FREE_STRING(pszQuery); if (pMessage) { ldap_msgfree(pMessage); } return dwError; error: *ppszComputerDN = NULL; LW_SAFE_FREE_STRING(pszComputerDN); goto cleanup; }
DWORD ADGetLDAPUPNString( IN OPTIONAL HANDLE hDirectory, IN OPTIONAL LDAPMessage* pMessage, IN PCSTR pszDnsDomainName, IN PCSTR pszSamaccountName, OUT PSTR* ppszUPN, OUT PBOOLEAN pbIsGeneratedUPN ) { DWORD dwError = LW_ERROR_SUCCESS; LDAP *pLd = NULL; PSTR *ppszValues = NULL; PSTR pszUPN = NULL; BOOLEAN bIsGeneratedUPN = FALSE; if (hDirectory && pMessage) { pLd = LwLdapGetSession(hDirectory); ppszValues = (PSTR*)ldap_get_values(pLd, pMessage, AD_LDAP_UPN_TAG); if (ppszValues && ppszValues[0]) { dwError = LwAllocateString(ppszValues[0], &pszUPN); BAIL_ON_LSA_ERROR(dwError); if (!index(pszUPN, '@')) { // Some domain users might have invalid UPNs in AD. // Fix it for them. LW_SAFE_FREE_STRING(pszUPN); dwError = LW_ERROR_DATA_ERROR; BAIL_ON_LSA_ERROR(dwError); } else { // Do not touch the non-realm part, just the realm part // to make sure the realm conforms to spec. LsaPrincipalRealmToUpper(pszUPN); } } } if (!pszUPN) { dwError = LwAllocateStringPrintf( &pszUPN, "%s@%s", pszSamaccountName, pszDnsDomainName); BAIL_ON_LSA_ERROR(dwError); bIsGeneratedUPN = TRUE; // If we genereate, we do lower@UPPER regardless of whatever // SAM account name case was provided. (Note: It may be that // we should preseve case from the SAM account name, but we // would need to make sure that the SAM account name provided // to this function is matches the case in AD and is not derived // from something the user typed in locally. LsaPrincipalNonRealmToLower(pszUPN); LsaPrincipalRealmToUpper(pszUPN); } *ppszUPN = pszUPN; *pbIsGeneratedUPN = bIsGeneratedUPN; cleanup: if (ppszValues) { ldap_value_free(ppszValues); } return dwError; error: *ppszUPN = NULL; LW_SAFE_FREE_STRING(pszUPN); goto cleanup; }
DWORD ADLdap_AddDomainLocalGroups( IN PAD_PROVIDER_CONTEXT pContext, IN PLSA_SECURITY_OBJECT pObject, IN OUT PLW_HASH_TABLE pGroupHash ) { DWORD dwError = 0; PLSA_DM_LDAP_CONNECTION pConn = NULL; PSTR szAttributeList[] = { AD_LDAP_OBJECTSID_TAG, NULL }; PSTR pDomainDN = NULL; PSTR pszEscapedDN = NULL; // Do not free. This is owned by pConn HANDLE hDirectory = NULL; LDAPMessage* pMessage = NULL; // Do not free. This is owned by pConn LDAP* pLd = NULL; PSTR pGroupSid = NULL; PSTR pFilter = NULL; // Do not free LDAPMessage* pCurrentMessage = NULL; dwError = LsaDmLdapOpenDc( pContext, pContext->pState->pszDomainName, &pConn); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapConvertDomainToDN( pContext->pState->pszDomainName, &pDomainDN); BAIL_ON_LSA_ERROR(dwError); dwError = LwLdapEscapeString(&pszEscapedDN, pObject->pszDN); BAIL_ON_LSA_ERROR(dwError); // groupType: 2147483652 = 0x80000004 = ( GROUP_TYPE_RESOURCE_GROUP | // GROUP_TYPE_SECURITY_ENABLED ) = domain local security group dwError = LwAllocateStringPrintf( &pFilter, "(&(|(member=%s)(member=CN=%s,CN=ForeignSecurityPrincipals,%s))(groupType=2147483652))", pszEscapedDN, pObject->pszObjectSid, pDomainDN); BAIL_ON_LSA_ERROR(dwError); dwError = LsaDmLdapDirectorySearch( pConn, pDomainDN, LDAP_SCOPE_SUBTREE, pFilter, szAttributeList, &hDirectory, &pMessage); BAIL_ON_LSA_ERROR(dwError); pLd = LwLdapGetSession(hDirectory); pCurrentMessage = ldap_first_entry(pLd, pMessage); while (pCurrentMessage) { LW_SAFE_FREE_STRING(pGroupSid); dwError = ADLdap_GetObjectSid( hDirectory, pCurrentMessage, &pGroupSid); BAIL_ON_LSA_ERROR(dwError); if (!LwHashExists(pGroupHash, pGroupSid)) { // Set the value of the hash entry so this string gets freed with // the hash. dwError = LwHashSetValue(pGroupHash, pGroupSid, pGroupSid); BAIL_ON_LSA_ERROR(dwError); pGroupSid = NULL; } pCurrentMessage = ldap_next_entry(pLd, pCurrentMessage); } cleanup: LsaDmLdapClose(pConn); LW_SAFE_FREE_STRING(pszEscapedDN); LW_SAFE_FREE_STRING(pDomainDN); LW_SAFE_FREE_STRING(pFilter); LW_SAFE_FREE_STRING(pGroupSid); if (pMessage) { ldap_msgfree(pMessage); } return dwError; error: goto cleanup; }