DWORD VMCAUpdateCRL( PSTR pszCertificate, UINT32 uReason ) { DWORD dwError = 0; PSTR pszCRLFile = NULL; time_t tmLastUpdate = 0; time_t tmNextUpdate = 0; X509_CRL *pCrl = NULL; X509 *pCert = NULL; DWORD dwCrlNum = 0; PVMCA_X509_CA pCA = NULL; dwError = VMCASrvGetCA(&pCA); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCRLNamePath(&pszCRLFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAOpenCRLPrivate(pCA, pszCRLFile, &pCrl); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAPEMToX509(pszCertificate, &pCert); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAddCertToCRL(pCrl, pCert, 1); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASortCRL(pCrl); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetNextCrlNumber(pCrl, &dwCrlNum); BAIL_ON_VMCA_ERROR(dwError); tmLastUpdate = time(NULL); dwError = VMCAGetNextUpdateTime(pCrl, &tmNextUpdate); if (dwError == VMCA_CRL_NULL_TIME ) { tmNextUpdate = tmLastUpdate + ( VMCAGetDefaultValidityPeriod() * 24 * 60 * 60); dwError = 0; } BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAUpdateTimeStamps (pCrl, tmLastUpdate, tmNextUpdate, dwCrlNum); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCACrlSign(pCrl, pCA); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCACRLToFile(pCrl, pszCRLFile); BAIL_ON_VMCA_ERROR(dwError); error: if (pCert != NULL) { X509_free(pCert); } VMCA_SAFE_FREE_STRINGA(pszCRLFile); if(pCrl != NULL) { VMCACrlFree(pCrl); } if (pCA) { VMCAReleaseCA(pCA); } return dwError; }
unsigned int VMCAGetCRL( unsigned char *pszClientCachedCRLID, unsigned int dwFileOffset, unsigned int dwSize, VMCA_FILE_BUFFER **ppCRLData ) { DWORD dwError = 0; PVMCA_FILE_BUFFER pCRLData = NULL; DWORD dwCount = 0; PSTR pszCRLFile = NULL; unsigned char buff[FILE_CHUNK] = { 0 }; BOOLEAN bLocked = FALSE; VMCA_LOCK_MUTEX_SHARED(&gVMCAServerGlobals.svcMutex, bLocked); dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCRLNamePath(&pszCRLFile); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCARpcAllocateMemory( sizeof(VMCA_FILE_BUFFER), (PVOID*)&pCRLData); BAIL_ON_VMCA_ERROR(dwError); memset(pCRLData, 0, sizeof(VMCA_FILE_BUFFER)); dwError = VMCAReadDataFromFile( pszCRLFile, dwFileOffset, dwSize, (char*)&buff, &dwCount); BAIL_ON_VMCA_ERROR(dwError); if (dwCount > 0) { dwError = VMCARpcAllocateMemory(dwCount * sizeof(unsigned char), (PVOID*) &pCRLData->buffer); BAIL_ON_VMCA_ERROR(dwError); memcpy((PVOID) pCRLData->buffer, buff,(size_t) dwCount); } pCRLData->dwCount = dwCount; *ppCRLData = pCRLData; cleanup : VMCA_LOCK_MUTEX_UNLOCK(&gVMCAServerGlobals.svcMutex, bLocked); VMCA_SAFE_FREE_STRINGA(pszCRLFile); return dwError; error: if(pCRLData != NULL) { if(pCRLData->buffer != NULL) { VMCARpcFreeMemory((PVOID) pCRLData->buffer); } VMCARpcFreeMemory((PVOID)pCRLData); } if(ppCRLData) { *ppCRLData = NULL; } goto cleanup; }
DWORD VMCAUpdateCrlCAAttribute( PVMCA_LDAP_CONTEXT pContext, PSTR pszConfigurationDN, PSTR pszCrl ) { DWORD dwError = 0; PSTR pszCADN = NULL; PSTR pszCrlAuthorityKeyId = NULL; PSTR pszCAContainerDN = NULL; X509_CRL* pCrl = NULL; ATTR_SEARCH_RESULT attrSearchResult = ATTR_NOT_FOUND; X509_NAME* pIssuer = NULL; PSTR pszCAIssuerDN = NULL; PSTR pszFoundCADN = NULL; dwError = VMCAPEMToX509Crl(pszCrl, &pCrl); BAIL_ON_ERROR(dwError); dwError = VMCAAllocateStringPrintfA( &pszCAContainerDN, "CN=%s,%s", CA_CONTAINER_NAME, pszConfigurationDN); BAIL_ON_ERROR(dwError); dwError = VMCAGetCrlAuthKeyIdHexString(pCrl, &pszCrlAuthorityKeyId); if (dwError == ERROR_SUCCESS) { if (!IsNullOrEmptyString(pszCrlAuthorityKeyId)) { dwError = VMCAAllocateStringPrintfA( &pszCADN, "CN=%s,%s", pszCrlAuthorityKeyId, pszCAContainerDN); BAIL_ON_ERROR(dwError); } } if (!pszCADN) { pIssuer = X509_CRL_get_issuer(pCrl); // Don't free dwError = VMCAGetX509Name(pIssuer, XN_FLAG_COMPAT, &pszCAIssuerDN); BAIL_ON_ERROR(dwError); if (pszCAIssuerDN == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } } dwError = VMCACheckCAObject( pContext, pszCAContainerDN, pszCADN, pszCAIssuerDN, &pszFoundCADN ); if (dwError == ERROR_INVALID_STATE && pszCAIssuerDN) { VMCA_LOG_ERROR("More than one CA found with given issuer DN: %s", pszCAIssuerDN); } BAIL_ON_ERROR(dwError); if (!pszFoundCADN) { dwError = ERROR_NOT_FOUND; BAIL_ON_ERROR(dwError); } dwError = VMCACheckAttribute( pContext, pszFoundCADN, ATTR_CRL, pszCrl, &attrSearchResult ); BAIL_ON_ERROR(dwError); if (attrSearchResult != ATTR_MATCH) { dwError = VMCAUpdateAttribute(pContext, pszFoundCADN, ATTR_CRL, pszCrl, (attrSearchResult == ATTR_NOT_FOUND)); BAIL_ON_ERROR(dwError); } cleanup: VMCA_SAFE_FREE_MEMORY(pszFoundCADN); VMCA_SAFE_FREE_MEMORY(pszCAIssuerDN); VMCA_SAFE_FREE_STRINGA(pszCADN); VMCA_SAFE_FREE_STRINGA(pszCrlAuthorityKeyId); VMCA_SAFE_FREE_STRINGA(pszCAContainerDN); if (pCrl) { X509_CRL_free(pCrl); } return dwError; error: goto cleanup; }
DWORD VMCAUpdatePkiCAAttribute( PVMCA_LDAP_CONTEXT pContext, PSTR pszConfigurationDN, X509* pCertificate ) { DWORD dwError = 0; PSTR pszCertificate = NULL; PSTR pszCAContainerDN = NULL; PSTR pszCADN = NULL; PSTR pszCACN = NULL; PSTR pszCAIssuerDN = NULL; PSTR pszFoundCADN = NULL; X509_NAME *pCertName = NULL; ATTR_SEARCH_RESULT attrSearchResult = ATTR_NOT_FOUND; if (!pCertificate || !pContext || IsNullOrEmptyString(pszConfigurationDN) ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR (dwError); } dwError = VMCACertToPEM( pCertificate, &pszCertificate ); BAIL_ON_ERROR (dwError); pCertName = X509_get_subject_name(pCertificate); if ( pCertName == NULL) // Don't free { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } dwError = VMCAGetX509Name(pCertName, XN_FLAG_COMPAT, &pszCAIssuerDN); BAIL_ON_ERROR(dwError); dwError = VMCAGenerateCACNForLdap(pCertificate, &pszCACN); BAIL_ON_ERROR(dwError); dwError = VMCAAllocateStringPrintfA( &pszCAContainerDN, "CN=%s,%s", CA_CONTAINER_NAME, pszConfigurationDN); BAIL_ON_ERROR(dwError); dwError = VMCAAllocateStringPrintfA( &pszCADN, "CN=%s,%s", pszCACN, pszCAContainerDN); BAIL_ON_ERROR(dwError); dwError = VMCACheckCAObject( pContext, NULL, pszCADN, NULL, &pszFoundCADN ); BAIL_ON_ERROR(dwError); if (IsNullOrEmptyString(pszFoundCADN)) { dwError = VMCACreateCAObject( pContext, pszCACN, pszCADN ); BAIL_ON_ERROR(dwError); } dwError = VMCACheckAttribute( pContext, pszCADN, ATTR_CA_CERTIFICATE, pszCertificate, &attrSearchResult); BAIL_ON_ERROR(dwError); if (attrSearchResult != ATTR_MATCH) { dwError = VMCAUpdateAttribute(pContext, pszCADN, ATTR_CA_CERTIFICATE, pszCertificate, (attrSearchResult == ATTR_NOT_FOUND)); BAIL_ON_ERROR(dwError); } dwError = VMCACheckAttribute( pContext, pszCADN, ATTR_CA_CERTIFICATE_DN, pszCAIssuerDN, &attrSearchResult); BAIL_ON_ERROR(dwError); if (attrSearchResult != ATTR_MATCH) { dwError = VMCAUpdateAttribute(pContext, pszCADN, ATTR_CA_CERTIFICATE_DN, pszCAIssuerDN, (attrSearchResult == ATTR_NOT_FOUND)); BAIL_ON_ERROR(dwError); } cleanup: VMCA_SAFE_FREE_STRINGA(pszCertificate); VMCA_SAFE_FREE_STRINGA(pszFoundCADN); VMCA_SAFE_FREE_STRINGA(pszCAContainerDN); VMCA_SAFE_FREE_STRINGA(pszCACN); VMCA_SAFE_FREE_STRINGA(pszCADN); VMCA_SAFE_FREE_STRINGA(pszCAIssuerDN); return dwError; error: goto cleanup; }
DWORD VMCALdapGetMemberships( PVMCA_LDAP_CONTEXT pConnection, PCSTR pszUPNName, PSTR **pppszMemberships, PDWORD pdwMemberships ) { DWORD dwError = 0; PSTR pszFilter = NULL; PSTR pszAttrMemberOf = ATTR_MEMBEROF; // memberOf PSTR ppszAttrs[] = { pszAttrMemberOf, NULL}; DWORD dwCount = 0; LDAPMessage *pResult = NULL; LDAPMessage *pEntry = NULL; struct berval** ppValues = NULL; PSTR *ppszMemberships = NULL; DWORD dwMemberships = 0; DWORD i = 0; LDAP *pLd = NULL; if (pConnection == NULL || pConnection->pConnection == NULL || IsNullOrEmptyString(pszUPNName) || pppszMemberships == NULL || pdwMemberships == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } pLd = pConnection->pConnection; dwError = VMCAAllocateStringPrintfA(&pszFilter, "(%s=%s)", ATTR_KRB_UPN, pszUPNName); // userPrincipalName BAIL_ON_VMCA_ERROR(dwError); dwError = ldap_search_ext_s( pLd, "", LDAP_SCOPE_SUBTREE, pszFilter, (PSTR*)ppszAttrs, 0, NULL, NULL, NULL, -1, &pResult); BAIL_ON_VMCA_ERROR(dwError); dwCount = ldap_count_entries(pLd, pResult); if (dwCount == 0) { dwError = LDAP_NO_SUCH_OBJECT; BAIL_ON_VMCA_ERROR(dwError); } else if (dwCount > 1) { dwError = LDAP_OPERATIONS_ERROR; BAIL_ON_VMCA_ERROR(dwError); } pEntry = ldap_first_entry(pLd, pResult); if (!pEntry) { dwError = LDAP_NO_SUCH_OBJECT; BAIL_ON_VMCA_ERROR(dwError); } ppValues = ldap_get_values_len(pLd, pEntry, pszAttrMemberOf); if (!ppValues) { dwMemberships = 0; } else { dwMemberships = ldap_count_values_len(ppValues); } if (dwMemberships) { dwError = VMCAAllocateMemory(dwMemberships * sizeof(PSTR), (PVOID*)&ppszMemberships); BAIL_ON_VMCA_ERROR(dwError); for (i = 0; ppValues[i] != NULL; i++) { PCSTR pszMemberOf = ppValues[i]->bv_val; dwError = VMCAAllocateStringA(pszMemberOf, &ppszMemberships[i]); BAIL_ON_VMCA_ERROR(dwError); } } *pppszMemberships = ppszMemberships; *pdwMemberships = dwMemberships; cleanup: if(ppValues) { ldap_value_free_len(ppValues); } if (pResult) { ldap_msgfree(pResult); } VMCA_SAFE_FREE_MEMORY(pszFilter); return dwError; error: if (ppszMemberships != NULL && dwMemberships > 0) { for (i = 0; i < dwMemberships; i++) { VMCA_SAFE_FREE_STRINGA(ppszMemberships[i]); } VMCA_SAFE_FREE_MEMORY(ppszMemberships); } goto cleanup; }
DWORD VMCALdapConnect( PSTR pszHostName, DWORD dwPort, PSTR pszUsername, PSTR pszPassword, PVMCA_LDAP_CONTEXT* ppLotus ) { DWORD dwError = 0; PVMCA_LDAP_CONTEXT pContext = NULL; PSTR pszUrl = NULL; BerValue ldapBindPwd = {0}; //LDAP_SUCCESS is defined as Zero in the Standard // Which plays well with our BAIL_ON_ERROR macro DWORD dwVersion = LDAP_VERSION3; DWORD dwReturns = 20; if(dwPort == 0) { // Let us use the default LDAP_PORT, 389 dwPort = LDAP_PORT; } dwError = VMCAAllocateMemory(sizeof(*pContext), (PVOID*)&pContext); BAIL_ON_ERROR(dwError); if (VMCAIsIPV6AddrFormat(pszHostName)) { dwError = VMCAAllocateStringPrintfA( &pszUrl, "ldap://[%s]:%d", pszHostName, dwPort); } else { dwError = VMCAAllocateStringPrintfA( &pszUrl, "ldap://%s:%d", pszHostName, dwPort); } BAIL_ON_ERROR(dwError); if(IsNullOrEmptyString(pszPassword)) { // no credentials, do anonymous bind. dwError = ldap_initialize(&pContext->pConnection, pszUrl); BAIL_ON_ERROR(dwError); if (pContext->pConnection == NULL) { ldap_get_option(pContext->pConnection, LDAP_OPT_ERROR_NUMBER, &dwError); //dwError = ld_errno; //LdapGetLastError(); BAIL_ON_ERROR(dwError); } dwError = ldap_set_option(pContext->pConnection, LDAP_OPT_PROTOCOL_VERSION, (void*)&dwVersion); BAIL_ON_ERROR(dwError); dwError = ldap_set_option(pContext->pConnection, LDAP_OPT_SIZELIMIT, (void*)& dwReturns); BAIL_ON_ERROR(dwError); dwError = ldap_sasl_bind_s( pContext->pConnection, pszUsername, LDAP_SASL_SIMPLE, &ldapBindPwd, // no credentials NULL, NULL, NULL); } else { dwError = VmCASASLSRPBind( &pContext->pConnection, pszUrl, pszUsername, pszPassword); } #ifdef LDAP_ERROR_MESSAGE if(dwError != 0) { printf("Error :%s\n",ldap_err2string(dwError)); } #endif BAIL_ON_ERROR(dwError); *ppLotus = pContext; cleanup: VMCA_SAFE_FREE_STRINGA(pszUrl); return dwError; error: if ((dwError != 0) && pContext) { VMCALdapClose(pContext); } goto cleanup; }
static DWORD VMCALdapFindObject( PVMCA_LDAP_CONTEXT pContext, PCSTR pszBaseDN, ber_int_t scope, PCSTR pszAttribute, PCSTR pszValue, PSTR *ppszObjectDN ) { DWORD dwError = 0; DWORD dwNumEntries = 0; LDAPMessage* pResult = NULL; LDAPMessage* pEntry = NULL; PSTR pszFilter = NULL; PSTR pszObjectDN = NULL; if (pszAttribute && pszValue) { VMCAAllocateStringPrintfA(&pszFilter, "(%s=%s)", pszAttribute, pszValue); } dwError = ldap_search_ext_s( pContext->pConnection, (PSTR)pszBaseDN, scope, pszFilter, NULL, /* attributes */ TRUE, NULL, /* server controls */ NULL, /* client controls */ NULL, /* timeout */ 0, &pResult); BAIL_ON_ERROR(dwError); dwNumEntries = ldap_count_entries(pContext->pConnection, pResult); if (dwNumEntries > 1) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } else if (dwNumEntries == 0) { dwError = ERROR_NOT_FOUND; BAIL_ON_ERROR(dwError); } else { pEntry = ldap_first_entry(pContext->pConnection, pResult); if (!pEntry) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } pszObjectDN = ldap_get_dn(pContext->pConnection, pEntry); if (IsNullOrEmptyString(pszObjectDN)) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } *ppszObjectDN = pszObjectDN; } cleanup: if (pResult) { ldap_msgfree(pResult); } VMCA_SAFE_FREE_STRINGA(pszFilter); return dwError; error : VMCA_SAFE_FREE_STRINGA(pszObjectDN); if (dwError == LDAP_NO_SUCH_OBJECT) { dwError = 0; } goto cleanup; }
static DWORD VMCACheckAttribute( PVMCA_LDAP_CONTEXT pContext, PCSTR pszObjectDN, PCSTR pszAttribute, PCSTR pszValue, ATTR_SEARCH_RESULT* pAttrStatus ) { DWORD dwError = 0; PCHAR pszFilter = "(objectClass=*)"; PSTR pszRetrievedValue = NULL; DWORD dwNumEntries = 0; LDAPMessage* pSearchResult = NULL; PCHAR ppszAttr[] = { (PSTR)pszAttribute, NULL }; dwError = ldap_search_ext_s( pContext->pConnection, (PSTR)pszObjectDN, LDAP_SCOPE_BASE, pszFilter, ppszAttr, /* attributes */ FALSE, NULL, /* server controls */ NULL, /* client controls */ NULL, /* timeout */ 0, &pSearchResult); BAIL_ON_ERROR(dwError); dwNumEntries = ldap_count_entries(pContext->pConnection, pSearchResult); if (dwNumEntries == 0) { // Caller should make sure that the ObjectDN passed in does exist // by calling DirCliLdapCheckCAObject first. dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } else if (dwNumEntries != 1) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } dwError = VMCACopyQueryResultAttributeString(pContext, pSearchResult, pszAttribute, TRUE, &pszRetrievedValue); BAIL_ON_ERROR(dwError); if (!pszRetrievedValue) { *pAttrStatus = ATTR_NOT_FOUND; } else if (VMCAStringCompareA(pszValue, pszRetrievedValue, FALSE)) { *pAttrStatus = ATTR_DIFFER; } else { *pAttrStatus = ATTR_MATCH; } cleanup: if (pSearchResult) { ldap_msgfree(pSearchResult); } VMCA_SAFE_FREE_STRINGA(pszRetrievedValue); return dwError; error : *pAttrStatus = ATTR_NOT_FOUND; if (dwError == LDAP_NO_SUCH_OBJECT) { dwError = 0; } goto cleanup; }
void VMCALog( VMCA_LOG_LEVEL level, const char* fmt, ...) { #define LEVEL_LEN 13 char logMessage[VMCA_MAX_MSG_SIZE]; char extraLogMessage[VMCA_MAX_MSG_SIZE] = {0}; int msgsize; DWORD dwError = 0; BOOLEAN bLocked = FALSE; PSTR szTimeString = NULL; va_list va; // Record time as soon as possible if ( (int)currentLevel < (int)level) { //Nothing to do goto cleanup ; } // Look like syslogd time stamp va_start( va, fmt ); msgsize = vsnprintf(logMessage, VMCA_MAX_MSG_SIZE, fmt, va ); if ((msgsize > 0) && (msgsize < VMCA_MAX_MSG_SIZE-2)) { logMessage[msgsize++] = '\n'; logMessage[msgsize] = '\0'; } else { logMessage[VMCA_MAX_MSG_SIZE-1] = '\0'; } va_end( va ); #ifndef WIN32 if (gVMCALogType == VMCA_LOG_TYPE_SYSLOG) { int sysLogLevel = VMCALevelToSysLogLevel(level); snprintf( extraLogMessage, sizeof(extraLogMessage) - 1, "t@%lu: ", (unsigned long) pthread_self()); syslog(sysLogLevel, "%s%s", extraLogMessage, logMessage); } #endif if (gVMCALogType == VMCA_LOG_TYPE_FILE && fpCurrentLog) { dwError = VMCAGetUTCTimeString(&szTimeString); BAIL_ON_VMCA_ERROR_NO_LOG(dwError); pthread_rwlock_wrlock(&rwloglock); bLocked = TRUE; fwrite((PVOID)szTimeString, strlen(szTimeString), 1, fpCurrentLog); fwrite((PVOID)VMCALevelToText(level), VMCALevelToLen(level) - 1 , 1, fpCurrentLog); fwrite((PVOID)logMessage, msgsize, 1, fpCurrentLog); fflush(fpCurrentLog); gVMCACurrentLogSizeBytes += strlen(szTimeString) + VMCALevelToLen(level) - 1 + msgsize; if (gVMCACurrentLogSizeBytes >= gVMCAMaxLogSizeBytes) { dwError = VMCARotateLogs(); BAIL_ON_VMCA_ERROR(dwError); } } if (gVMCALogType == VMCA_LOG_TYPE_CONSOLE) { unsigned long ulThreadId = -1; #ifdef _WIN32 ulThreadId = (unsigned long) pthread_self().p; #else ulThreadId = (unsigned long) pthread_self(); #endif fprintf(stderr, "VMCA:t@%lu:%-3.7s: %s\n", ulThreadId, VMCALevelToText(level), logMessage); fflush( stderr ); } cleanup: if (bLocked) { pthread_rwlock_unlock(&rwloglock); } VMCA_SAFE_FREE_STRINGA(szTimeString); return ; error : goto cleanup; }
// This function renames logs to rotate. // for example if max old log is 5, then // vmca.log.4 -> vmca.log.5 // vmca.log.3 -> vmca.log.4 // vmca.log.2 -> vmca.log.3 // vmca.log.1 -> vmca.log.2 // vmca.log.0 -> vmca.log.1 // where vmca.log.1 is the most current log. DWORD VMCARenameLogs() { int nCounter = 0; PSTR pszSourceFile = NULL; PSTR pszDestFile = NULL; PSTR pszLogDir = NULL; struct STAT st = { 0 }; DWORD dwError = 0; dwError = VMCAGetLogFileDirectory(&pszLogDir); BAIL_ON_VMCA_ERROR(dwError); if (fpCurrentLog) { fclose(fpCurrentLog); fpCurrentLog = NULL; } for ( nCounter = (int)gVMCAMaxOldLogs; nCounter > 0 ; nCounter --) { dwError = VMCAAllocateStringPrintfA( &pszDestFile, FORMATSTR, pszLogDir, VMCA_LOG_STRING, nCounter); BAIL_ON_VMCA_ERROR(dwError); if(STAT(pszDestFile, &st) == VMCA_OK ) { UNLINK(pszDestFile); } dwError = VMCAAllocateStringPrintfA( &pszSourceFile, FORMATSTR, pszLogDir, VMCA_LOG_STRING, nCounter - 1); BAIL_ON_VMCA_ERROR(dwError); if (RENAME(pszSourceFile, pszDestFile) != VMCA_OK ) { // Emit an Error Event once we have support for that } VMCA_SAFE_FREE_STRINGA(pszDestFile); pszDestFile = NULL; VMCA_SAFE_FREE_STRINGA(pszSourceFile); pszSourceFile = NULL; } cleanup : VMCA_SAFE_FREE_STRINGA(pszLogDir); return dwError; error : VMCA_SAFE_FREE_STRINGA(pszDestFile); VMCA_SAFE_FREE_STRINGA(pszSourceFile); goto cleanup; }
DWORD VMCASrvGetMachineAccountInfoA( PSTR* ppszAccount, PSTR* ppszDomainName, PSTR* ppszPassword ) { DWORD dwError = 0; PVMW_CFG_CONNECTION pConnection = NULL; PVMW_CFG_KEY pRootKey = NULL; CHAR szParamsKeyPath[] = VMDIR_CONFIG_PARAMETER_KEY_PATH; CHAR szRegValName_Acct[] = VMDIR_REG_KEY_DC_ACCOUNT; CHAR szRegValName_Pwd[] = VMDIR_REG_KEY_DC_PASSWORD; CHAR szAfdParamsKeyPath[] = VMAFD_CONFIG_PARAMETER_KEY_PATH; CHAR szRegValDomain_Name[] = VMAFD_REG_KEY_DOMAIN_NAME; PVMW_CFG_KEY pParamsKey = NULL; PVMW_CFG_KEY pAfdParamsKey = NULL; PSTR pszAccount = NULL; PSTR pszPassword = NULL; PSTR pszDomainName = NULL; dwError = VmwConfigOpenConnection(&pConnection); BAIL_ON_VMCA_ERROR(dwError); dwError = VmwConfigOpenRootKey( pConnection, "HKEY_LOCAL_MACHINE", 0, KEY_READ, &pRootKey); BAIL_ON_VMCA_ERROR(dwError); dwError = VmwConfigOpenKey( pConnection, pRootKey, &szParamsKeyPath[0], 0, KEY_READ, &pParamsKey); BAIL_ON_VMCA_ERROR(dwError); dwError = VmwConfigReadStringValue( pParamsKey, NULL, &szRegValName_Acct[0], &pszAccount); BAIL_ON_VMCA_ERROR(dwError); dwError = VmwConfigReadStringValue( pParamsKey, NULL, &szRegValName_Pwd[0], &pszPassword); BAIL_ON_VMCA_ERROR(dwError); dwError = VmwConfigOpenKey( pConnection, pRootKey, &szAfdParamsKeyPath[0], 0, KEY_READ, &pAfdParamsKey); BAIL_ON_VMCA_ERROR(dwError); dwError = VmwConfigReadStringValue( pAfdParamsKey, NULL, &szRegValDomain_Name[0], &pszDomainName); BAIL_ON_VMCA_ERROR(dwError); *ppszAccount = pszAccount; *ppszDomainName = pszDomainName; *ppszPassword = pszPassword; cleanup: if (pParamsKey) { VmwConfigCloseKey(pParamsKey); } if (pAfdParamsKey) { VmwConfigCloseKey(pAfdParamsKey); } if (pRootKey) { VmwConfigCloseKey(pRootKey); } if (pConnection) { VmwConfigCloseConnection(pConnection); } return dwError; error: VMCA_SAFE_FREE_STRINGA(pszAccount); VMCA_SAFE_FREE_STRINGA(pszDomainName); VMCA_SAFE_FREE_STRINGA(pszPassword); goto cleanup; }
static DWORD VMCASrvUpdateRootCerts( PVMCA_DIR_SYNC_PARAMS pDirSyncParams, PBOOLEAN pbSynced ) { DWORD dwError = 0; PVMCA_X509_CA pCA = NULL; PSTR pszAccount = NULL; PSTR pszPassword = NULL; PSTR pszDomainName = NULL; PSTR pszCAContainerDN = NULL; PSTR pszCertificate = NULL; PSTR pszCRL = NULL; X509_CRL* pCrl = NULL; DWORD dwCount = 0; DWORD dwIndex = 0; PVMCA_LDAP_CONTEXT pContext = NULL; PSTR pszUPN = NULL; dwError = VMCASrvValidateCA(); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvGetCA(&pCA); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCASrvGetMachineAccountInfoA( &pszAccount, &pszDomainName, &pszPassword); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringPrintfA( &pszUPN, "%s@%s", pszAccount, pszDomainName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCALdapConnect( "localhost", 0, /* use default port */ pszUPN, pszPassword, &pContext); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetDSERootAttribute( pContext, "configurationNamingContext", &pszCAContainerDN); BAIL_ON_VMCA_ERROR(dwError); dwError = VmcaSrvReGenCRL( &pCrl ); BAIL_ON_VMCA_ERROR (dwError); dwError = VMCACRLToPEM( pCrl, &pszCRL ); BAIL_ON_VMCA_ERROR (dwError); dwCount = sk_X509_num(pCA->skCAChain); for (; dwIndex <dwCount; dwIndex++) { X509 *pCert = sk_X509_value( pCA->skCAChain, dwIndex ); dwError = VMCAUpdatePkiCAAttribute( pContext, pszCAContainerDN, pCert ); BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAUpdateCrlCAAttribute( pContext, pszCAContainerDN, pszCRL ); BAIL_ON_VMCA_ERROR (dwError); *pbSynced = TRUE; cleanup: VMCA_SAFE_FREE_STRINGA(pszUPN); VMCA_SAFE_FREE_STRINGA(pszDomainName); VMCA_SAFE_FREE_STRINGA(pszCertificate); VMCA_SAFE_FREE_STRINGA(pszAccount); VMCA_SAFE_FREE_STRINGA(pszPassword); if (pContext) { VMCALdapClose(pContext); } if (pCA) { VMCAReleaseCA(pCA); } return dwError; error: *pbSynced = FALSE; VMCA_LOG_ERROR("Failed to update root certs due to error [%u]", dwError); // TODO : Check specific errors dwError = 0; goto cleanup; }
unsigned int RpcVMCAGetRootCACertificate( handle_t IDL_handle, unsigned int *pdwCertLength, VMCA_CERTIFICATE_CONTAINER **ppCertContainer) { DWORD dwError = 0; DWORD dwCertLength = 0; VMCA_CERTIFICATE_CONTAINER* pTempCertContainer = NULL; PVMCA_CERTIFICATE pTempCertificate = NULL; VMCA_LOG_DEBUG("Entering %s", __FUNCTION__); /* * TBD: This cannot be protected now; certool --WaitVMCA uses this * interface to determine vmcad is up and responding. */ /* Restrict access to this RPC. Should use VECS APIs */ dwError = VMCACheckAccess(IDL_handle, FALSE); BAIL_ON_VMCA_ERROR(dwError); if (ppCertContainer == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAGetRootCACertificate( &dwCertLength, &pTempCertificate); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCARpcAllocateCertificateContainer(pTempCertificate, &pTempCertContainer); BAIL_ON_VMCA_ERROR(dwError); strcpy((char*) (pTempCertContainer)->pCert, pTempCertificate); *ppCertContainer = pTempCertContainer; *pdwCertLength = dwCertLength; pTempCertContainer = NULL; cleanup: VMCA_SAFE_FREE_STRINGA(pTempCertificate); VMCA_LOG_DEBUG("Exiting %s, Status = %d", __FUNCTION__, dwError); return dwError; error: if (pdwCertLength) { *pdwCertLength = 0; } if (ppCertContainer) { *ppCertContainer = NULL; } if (pTempCertContainer) { VMCARpcFreeCertificateContainer(pTempCertContainer); } goto cleanup; }