DWORD VmAfdQueryCACerts( LDAP* pLotus, PCSTR pszCACN, BOOL bDetail, PVMAFD_CA_CERT_ARRAY* ppCACertificates ) { DWORD dwError = 0; PSTR pszClassFilter = "(objectClass=vmwCertificationAuthority)"; PSTR pszAttrEntryDN = "entryDN"; PSTR pszAttrCADN = "cACertificateDN"; PSTR pszAttrCert = "cACertificate"; PSTR pszAttrCrl = "certificateRevocationList"; PSTR pszFilter = NULL; PSTR pszComboFilter = NULL; PSTR pszSearchBaseDN= NULL; PSTR pszDomainName = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pCAResult = NULL; PVMAFD_CA_CERT_ARRAY pCertArray = NULL; PCHAR attrs[] = { pszAttrEntryDN, pszAttrCADN, pszAttrCert, pszAttrCrl, NULL}; struct berval** ppValues = NULL; int nCertCount = 0; int certIndex = 0; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CA_CERT_ARRAY), (PVOID*)&pCertArray); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdGetDefaultDomainName( pLotus, &pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszSearchBaseDN, "cn=Configuration,%s", pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); if (pszCACN) { dwError = VmAfdAllocateStringPrintf( &pszComboFilter, "(&(CN=%s)%s)", pszCACN, pszClassFilter); BAIL_ON_VMAFD_ERROR(dwError); pszFilter = pszComboFilter; } else { pszFilter = pszClassFilter; } dwError = ldap_search_ext_s( pLotus, pszSearchBaseDN, LDAP_SCOPE_SUBTREE, pszFilter, attrs, 0, /* get values and attrs */ NULL, NULL, NULL, 0, &pSearchResult); BAIL_ON_VMAFD_ERROR(dwError); nCertCount = ldap_count_entries(pLotus, pSearchResult); if (nCertCount > 0) { pCertArray->dwCount = nCertCount; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CA_CERT) * nCertCount, (PVOID*)&pCertArray->pCACerts); BAIL_ON_VMAFD_ERROR(dwError); for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult), ++certIndex) { // The following assumes there's only one certificate for each CA // object. In the future if the whole chain is store, we will // update accordingly. // Copy CN dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrEntryDN, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pCN); BAIL_ON_VMAFD_ERROR(dwError); // Copy subject DN dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCADN, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pSubjectDN); BAIL_ON_VMAFD_ERROR(dwError); if (bDetail) { // Copy certificate dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCert, FALSE, (PSTR*)&pCertArray->pCACerts[certIndex].pCert); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdCopyQueryResultAttributeString( pLotus, pCAResult, pszAttrCrl, TRUE, (PSTR*)&pCertArray->pCACerts[certIndex].pCrl); BAIL_ON_VMAFD_ERROR(dwError); } } } *ppCACertificates = pCertArray; cleanup: VMAFD_SAFE_FREE_MEMORY(pszSearchBaseDN); VMAFD_SAFE_FREE_MEMORY(pszDomainName); VMAFD_SAFE_FREE_MEMORY(pszComboFilter); if (ppValues != NULL) { ldap_value_free_len(ppValues); ppValues = NULL; } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; error: if (pCertArray ) { VecsFreeCACertArray(pCertArray); } if (ppCACertificates) { *ppCACertificates = NULL; } goto cleanup; }
static DWORD VmAfSrvCheckDC( PDNS_SERVER_INFO pServerInfo, PCSTR pszDomain, PCSTR pszUPN, PCSTR pszPassword, PSTR* ppszHostname, PSTR* ppszNetworkAddress ) { DWORD dwError = 0; PSTR pszHostname = NULL; PSTR pszNetworkAddress = NULL; PSTR pszDomainOther = NULL; LDAP* pLd = NULL; dwError = VmAfdLDAPConnect( pServerInfo->pszAddress, 0, pszUPN, pszPassword, &pLd); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdGetDefaultDomainName(pLd, &pszDomainOther); BAIL_ON_VMAFD_ERROR(dwError); if (VmAfdStringCompareA(pszDomain, pszDomainOther, FALSE) != 0) { dwError = ERROR_DC_NOT_FOUND; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdAllocateStringA(pServerInfo->pszName, &pszHostname); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringA(pServerInfo->pszAddress, &pszNetworkAddress); BAIL_ON_VMAFD_ERROR(dwError); *ppszHostname = pszHostname; *ppszNetworkAddress = pszNetworkAddress; cleanup: if (pLd) { VmAfdLdapClose(pLd); } VMAFD_SAFE_FREE_MEMORY(pszDomainOther); return dwError; error: *ppszNetworkAddress = NULL; *ppszHostname = NULL; VMAFD_SAFE_FREE_MEMORY(pszHostname); VMAFD_SAFE_FREE_MEMORY(pszNetworkAddress); goto cleanup; }
DWORD VmAfdQueryCACertAndCrlAttributes( LDAP* pLotus, PVMAFD_CERT_ARRAY* ppCertificates, PVMAFD_CRL_FILE_CONTAINER* ppCrls ) { DWORD dwError = 0; PSTR pszFilter = "(objectClass=vmwCertificationAuthority)"; PSTR pszAttrCert = "cACertificate"; PSTR pszAttrCrl = "certificateRevocationList"; PSTR pszSearchBaseDN = NULL; PSTR pszDomainName = NULL; LDAPMessage* pSearchResult = NULL; LDAPMessage* pCAResult = NULL; PCHAR attrs[] = { pszAttrCert, pszAttrCrl, NULL}; int nCertCount = 0; int nCrlCount = 0; PVMAFD_CERT_ARRAY pCertArray = NULL; PVMAFD_CRL_FILE_CONTAINER pCrlContainer = NULL; struct berval** ppValues = NULL; if (!ppCertificates || !ppCrls) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMAFD_ERROR(dwError); } dwError = VmAfdGetDefaultDomainName( pLotus, &pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = VmAfdAllocateStringPrintf( &pszSearchBaseDN, "cn=Configuration,%s", pszDomainName); BAIL_ON_VMAFD_ERROR(dwError); dwError = ldap_search_ext_s( pLotus, pszSearchBaseDN, LDAP_SCOPE_SUBTREE, pszFilter, attrs, 0, /* get values and attrs */ NULL, NULL, NULL, 0, &pSearchResult); BAIL_ON_VMAFD_ERROR(dwError); for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult)) { nCertCount += VmAfdCountResultAttribute( pLotus, pCAResult, pszAttrCert); nCrlCount += VmAfdCountResultAttribute( pLotus, pCAResult, pszAttrCrl); } dwError = VmAfdAllocateMemory( sizeof(VMAFD_CERT_ARRAY), (PVOID*)&pCertArray); BAIL_ON_VMAFD_ERROR(dwError); pCertArray->dwCount = nCertCount; dwError = VmAfdAllocateMemory( sizeof(VMAFD_CRL_FILE_CONTAINER), (PVOID*)&pCrlContainer); BAIL_ON_VMAFD_ERROR(dwError); pCrlContainer->dwCount = nCrlCount; if (nCertCount || nCrlCount) { int certIndex = 0; int crlIndex = 0; if (nCertCount) { dwError = VmAfdAllocateMemory( sizeof(VMAFD_CERT_CONTAINER) * nCertCount, (PVOID*)&pCertArray->certificates); BAIL_ON_VMAFD_ERROR(dwError); } if (nCrlCount) { dwError = VmAfdAllocateMemory( sizeof(VMAFD_CRL_DATA) * nCrlCount, (PVOID*)&pCrlContainer->crls); BAIL_ON_VMAFD_ERROR(dwError); } for ( pCAResult = ldap_first_entry(pLotus, pSearchResult); pCAResult != NULL; pCAResult = ldap_next_entry(pLotus, pCAResult)) { // Copy certs ppValues = ldap_get_values_len( pLotus, pCAResult, pszAttrCert); if (ppValues) { int i = 0; while(ppValues[i]) { dwError = VmAfdAllocateMemory( sizeof(CHAR) * ppValues[i]->bv_len + 1, (PVOID)&pCertArray->certificates[certIndex].pCert); BAIL_ON_VMAFD_ERROR(dwError); memcpy( (PVOID) pCertArray->certificates[certIndex].pCert, (PVOID) ppValues[i]->bv_val, (size_t) ppValues[i]->bv_len); i++; certIndex++; } ldap_value_free_len(ppValues); ppValues = NULL; } // Copy CRLs ppValues = ldap_get_values_len( pLotus, pCAResult, pszAttrCrl); if (ppValues) { int i = 0; while(ppValues[i]) { dwError = VmAfdAllocateMemory( sizeof(CHAR) * ppValues[i]->bv_len + 1, (PVOID)&pCrlContainer->crls[crlIndex].buffer); BAIL_ON_VMAFD_ERROR(dwError); memcpy( (PVOID) pCrlContainer->crls[crlIndex].buffer, (PVOID) ppValues[i]->bv_val, (size_t) ppValues[i]->bv_len); i++; crlIndex++; } ldap_value_free_len(ppValues); ppValues = NULL; } } } *ppCertificates = pCertArray; *ppCrls = pCrlContainer; cleanup: VMAFD_SAFE_FREE_MEMORY(pszSearchBaseDN); VMAFD_SAFE_FREE_MEMORY(pszDomainName); if (ppValues != NULL) { ldap_value_free_len(ppValues); ppValues = NULL; } if(pSearchResult != NULL) { ldap_msgfree(pSearchResult); } return dwError; error: *ppCertificates = NULL; VMAFD_SAFE_FREE_MEMORY(pCrlContainer); if (ppCertificates) { *ppCertificates = NULL; } if(ppCrls) { *ppCrls = NULL; } if (pCertArray ) { VecsFreeCertArray(pCertArray); } goto cleanup; }