static DWORD VMCABytesToHexString( PUCHAR pData, DWORD length, PSTR *pszHexString ) { DWORD dwError = ERROR_SUCCESS; char* pszOut = NULL; DWORD i = 0; dwError = VMCAAllocateMemory(length * 2 + 1, (PVOID*)&pszOut); BAIL_ON_ERROR(dwError); for (; i < length; ++i) { sprintf(pszOut + i * 2, "%02X", pData[i]); } pszOut[length * 2] = '\0'; *pszHexString = pszOut; error: return dwError; }
DWORD VMCAAllocateStringW( PCWSTR pwszSrc, PWSTR* ppwszDst ) { DWORD dwError = 0; if (!pwszSrc || !ppwszDst) { dwError = ERROR_INVALID_PARAMETER; } else { #ifdef _WIN32 PWSTR pwszNewString = NULL; size_t len = wcslen(pwszSrc); dwError = VMCAAllocateMemory( (DWORD) (len + 1)*sizeof(WCHAR), (PVOID *)&pwszNewString ); BAIL_ON_VMCA_ERROR(dwError); wcscpy_s(pwszNewString, (len + 1), pwszSrc); *ppwszDst = pwszNewString; #else dwError = LwNtStatusToWin32Error( LwRtlWC16StringDuplicate(ppwszDst, pwszSrc)); BAIL_ON_VMCA_ERROR(dwError); #endif } error: return dwError; }
DWORD VMCAAllocateComandLineAFromW(int argc, WCHAR** argv, PSTR** ppUtf8Args) { DWORD dwError = ERROR_SUCCESS; PSTR* pUtf8Args = NULL; dwError = VMCAAllocateMemory( argc * sizeof(PSTR), (PVOID*)&pUtf8Args); BAIL_ON_ERROR(dwError); for(int i = 0; i < argc; ++i) { PSTR utf8Arg = NULL; dwError = VMCAAllocateStringAFromW(argv[i], &utf8Arg); BAIL_ON_ERROR(dwError); pUtf8Args[i] = utf8Arg; } *ppUtf8Args = pUtf8Args; pUtf8Args = NULL; cleanup: return dwError; error: VMCAFreeCommandLineA(argc, pUtf8Args); goto cleanup; }
DWORD VmcaDbCreateContext( PVMCA_DB_CONTEXT* ppDbContext ) { DWORD dwError = 0; PVMCA_DB_CONTEXT pDbContext = NULL; BOOLEAN bInLock = FALSE; VMCA_LOG_(VMCA_LOG_LEVEL_DEBUG,"Creating VMCA database context"); VMCA_LOCK_MUTEX(bInLock, &gVmcaDbGlobals.mutex); if (gVmcaDbGlobals.pDbContextList) { pDbContext = gVmcaDbGlobals.pDbContextList; gVmcaDbGlobals.pDbContextList = gVmcaDbGlobals.pDbContextList->pNext; pDbContext->pNext = NULL; gVmcaDbGlobals.dwNumCachedContexts--; } else { VMCA_LOG_DEBUG("Allocating database context for %s", gVmcaDbGlobals.pszDbPath); dwError = VMCAAllocateMemory(sizeof(*pDbContext), (PVOID*)&pDbContext); BAIL_ON_VMCA_ERROR(dwError); dwError = sqlite3_open( gVmcaDbGlobals.pszDbPath, &pDbContext->pDb); BAIL_ON_VMCA_ERROR(dwError); dwError = sqlite3_busy_timeout( pDbContext->pDb, 5000); BAIL_ON_VMCA_ERROR(dwError); } *ppDbContext = pDbContext; cleanup: VMCA_UNLOCK_MUTEX(bInLock, &gVmcaDbGlobals.mutex); VMCA_LOG_DEBUG("VMCA database context created Error = %d", dwError); return dwError; error: *ppDbContext = NULL; if (pDbContext) { VmcaDbFreeContext(pDbContext); } goto cleanup; }
static DWORD VMCACopyQueryResultAttributeString( PVMCA_LDAP_CONTEXT pContext, LDAPMessage* pSearchResult, PCSTR pszAttribute, BOOL bOptional, PSTR* ppszOut ) { DWORD dwError = 0; struct berval** ppValues = NULL; PSTR pszOut = NULL; ppValues = ldap_get_values_len( pContext->pConnection, pSearchResult, pszAttribute); if (ppValues && ppValues[0]) { dwError = VMCAAllocateMemory( (DWORD)(sizeof(CHAR) * ppValues[0]->bv_len + 1), (PVOID*)&pszOut); BAIL_ON_ERROR(dwError); memcpy( (PVOID) pszOut, (PVOID) ppValues[0]->bv_val, (size_t) ppValues[0]->bv_len); } else if (!bOptional) { dwError = ERROR_INVALID_DATA; BAIL_ON_ERROR(dwError); } *ppszOut = pszOut; cleanup: if (ppValues) { ldap_value_free_len(ppValues); ppValues = NULL; } return dwError; error: if (ppszOut) { *ppszOut = NULL; } VMCA_SAFE_FREE_MEMORY(pszOut); goto cleanup; }
DWORD VMCARESTMakeKrbAccessToken( PVMCA_ACCESS_TOKEN* ppAccessToken ) { DWORD dwError = 0; PVMCA_ACCESS_TOKEN pAccessToken = NULL; if (!ppAccessToken) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateMemory( sizeof(VMCA_ACCESS_TOKEN), (PVOID*)&pAccessToken ); BAIL_ON_VMCA_ERROR(dwError); pAccessToken->tokenType = VMCA_AUTHORIZATION_TOKEN_TYPE_KRB; dwError = VMCAAllocateMemory( sizeof(int), (PVOID*) &pAccessToken->bKrbTicketValid ); BAIL_ON_VMCA_ERROR(dwError); *pAccessToken->bKrbTicketValid = 1; *ppAccessToken = pAccessToken; cleanup: return dwError; error: if (pAccessToken) { VMCA_SAFE_FREE_MEMORY(pAccessToken->bKrbTicketValid); VMCA_SAFE_FREE_MEMORY(pAccessToken); } goto cleanup; }
DWORD VMCARESTParseHttpHeader( PREST_REQUEST pRESTRequest, VMCA_HTTP_REQ_OBJ** ppVMCARequest ) { DWORD dwError = 0; PSTR pszBuff = NULL; VMCA_HTTP_REQ_OBJ* pVMCARequest; HANDLE_NULL_PARAM(ppVMCARequest, dwError); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateMemory( sizeof(VMCA_HTTP_REQ_OBJ), (PVOID*) &pVMCARequest ); BAIL_ON_VMREST_ERROR(dwError); dwError = VmRESTGetHttpMethod(pRESTRequest, &pszBuff); BAIL_ON_VMREST_ERROR(dwError); pVMCARequest->pszMethod = pszBuff; // TRUE - Request c-rest-engine to decode the URI dwError = VmRESTGetHttpURI(pRESTRequest, TRUE, &pszBuff); BAIL_ON_VMREST_ERROR(dwError); pVMCARequest->pszUri = pszBuff; dwError = VmRESTGetHttpVersion(pRESTRequest, &pszBuff); BAIL_ON_VMREST_ERROR(dwError); pVMCARequest->pszVer = pszBuff; dwError = VmRESTGetHttpHeader(pRESTRequest,"Content-Length", &pszBuff); BAIL_ON_VMREST_ERROR(dwError); pVMCARequest->pszContentLength = pszBuff; *ppVMCARequest = pVMCARequest; cleanup: return dwError; error: VMCA_SAFE_FREE_STRINGA(pVMCARequest->pszMethod); VMCA_SAFE_FREE_STRINGA(pVMCARequest->pszUri); VMCA_SAFE_FREE_STRINGA(pVMCARequest->pszVer); VMCA_SAFE_FREE_STRINGA(pszBuff); VMCA_SAFE_FREE_MEMORY(pVMCARequest); goto cleanup; }
static DWORD VMCASrvCreateDirSyncParams( DWORD dwInterval, PVMCA_DIR_SYNC_PARAMS* ppSyncInfo ) { DWORD dwError = 0; PVMCA_DIR_SYNC_PARAMS pSyncInfo = NULL; dwError = VMCAAllocateMemory( sizeof(VMCA_DIR_SYNC_PARAMS), (PVOID*)&pSyncInfo); BAIL_ON_VMCA_ERROR(dwError); pSyncInfo->refCount = 1; dwError = pthread_mutex_init(&pSyncInfo->mutex, NULL); if (dwError) { #ifndef _WIN32 dwError = LwErrnoToWin32Error(dwError); #endif BAIL_ON_VMCA_ERROR(dwError); } pSyncInfo->pMutex = &pSyncInfo->mutex; pSyncInfo->dwSyncIntervalSecs = dwInterval; *ppSyncInfo = pSyncInfo; cleanup: return dwError; error: *ppSyncInfo = NULL; if (pSyncInfo) { VMCASrvReleaseDirSyncParams(pSyncInfo); } goto cleanup; }
DWORD ConvertAnsitoUnicodeString( PCSTR pszSrc, PWSTR* ppwszDst ) { DWORD dwError = 0; #ifdef _WIN32 PSTR pszNewString = NULL; #endif if (!pszSrc || !ppwszDst) { dwError = ERROR_INVALID_PARAMETER; } else { #ifdef _WIN32 // allocate space for new string then pass addr to output // double the original PSTR size for WPSTR ULONG srcLen = (ULONG)strlen(pszSrc)+1; ULONG destLen = (srcLen+1)*2; dwError = VMCAAllocateMemory((DWORD) destLen, (PVOID*)&pszNewString); BAIL_ON_ERROR(dwError); if (0 == MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, (LPWSTR)pszNewString, destLen)) { dwError = GetLastError(); BAIL_ON_ERROR(dwError); } *ppwszDst = (LPWSTR)pszNewString; cleanup: return dwError; error: VMCAFreeMemory(pszNewString); goto cleanup; #else dwError = LwNtStatusToWin32Error( LwRtlWC16StringAllocateFromCString(ppwszDst, pszSrc)); #endif } return dwError; }
DWORD VMCACreateDataDirectory(VOID) { DWORD dwError = 0; PSTR pszDir = NULL; PSTR pszTmpDir = NULL; struct stat buf = {0}; size_t iDirLen = 0; dwError = VMCAGetDataDirectory(&pszDir); BAIL_ON_VMCA_ERROR(dwError); if (stat(pszDir, &buf) != 0) { iDirLen = strlen(pszDir); if (pszDir[iDirLen-1] != VMCA_PATH_SEPARATOR_CHAR) { dwError = VMCAAllocateMemory(iDirLen+2, (PVOID *)&pszTmpDir); BAIL_ON_VMCA_ERROR(dwError); strcpy(pszTmpDir, pszDir); pszTmpDir[iDirLen] = VMCA_PATH_SEPARATOR_CHAR; pszTmpDir[iDirLen+1] = '\0'; VMCA_SAFE_FREE_STRINGA(pszDir); pszDir = pszTmpDir; } dwError = VMCACreateDirectory(pszDir, TRUE); BAIL_ON_VMCA_ERROR(dwError); } #ifdef _WIN32 else { dwError = VMCARestrictDirectoryAccess(pszDir); BAIL_ON_VMCA_ERROR(dwError); } #endif error: VMCA_SAFE_FREE_STRINGA(pszDir); return dwError; }
DWORD ConvertUnicodetoAnsiString( PCWSTR pwszSrc, PSTR* ppszDst ) { DWORD dwError = 0; #ifdef _WIN32 PSTR pszNewString = NULL; #endif if (!pwszSrc || !ppszDst) { dwError = ERROR_INVALID_PARAMETER; } else { #ifdef _WIN32 ULONG srcLen = (ULONG)wcslen(pwszSrc)+1; ULONG destLen = srcLen*2; dwError = VMCAAllocateMemory((DWORD) destLen, (PVOID*)&pszNewString); BAIL_ON_ERROR(dwError); if (0 == WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszNewString, destLen, NULL, NULL )) { dwError = GetLastError(); BAIL_ON_ERROR(dwError); } *ppszDst = pszNewString; cleanup: return dwError; error: VMCAFreeMemory(pszNewString); goto cleanup; #else dwError = LwNtStatusToWin32Error( LwRtlCStringAllocateFromWC16String(ppszDst, pwszSrc)); #endif } return dwError; }
DWORD VMCAReallocateMemory( PVOID pMemory, PVOID* ppNewMemory, DWORD dwSize ) { DWORD dwError = 0; void* pNewMemory = NULL; if (!ppNewMemory) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } if (pMemory) { pNewMemory = realloc(pMemory, dwSize); } else { dwError = VMCAAllocateMemory(dwSize, &pNewMemory); BAIL_ON_VMCA_ERROR(dwError); } if (!pNewMemory) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_VMCA_ERROR(dwError); } *ppNewMemory = pNewMemory; cleanup: return dwError; error: goto cleanup; }
DWORD VMCAAccountDnToUpn( PSTR dn, PSTR *retUpn) { /* * Convert: cn=adam-sles11.ssolabs2.com,ou=Domain Controllers,dc=VSPHERE,dc=LOCAL * to: adam-sles11.ssolabs2.com@VSPHERELOCAL */ DWORD dwError = 0; PSTR ptr = NULL; PSTR end = NULL; PSTR upn = NULL; PSTR fmtupn = NULL; PSTR sep = "."; DWORD len = (DWORD) strlen(dn); dwError = VMCAAllocateMemory( sizeof(CHAR) * (len + 2), (PVOID) &upn); if (dwError) { goto error; } fmtupn = upn; /* * TBD: Note: this code assumes DN is all lower case. * Handle "cn=" portion of UPN */ ptr = strstr(dn, "cn="); if (ptr) { ptr += 3; /* Skip over cn= */ end = strstr(ptr, ",ou="); if (!end) { end = strstr(ptr, ",dc="); } if (end) { fmtupn += snprintf(fmtupn, len, "%.*s@", (int) (end-ptr), ptr); } } ptr = strstr(ptr, "dc="); while (ptr) { ptr += 3; if (*ptr) { end = strstr(ptr, ",dc="); if (!end) { end = ptr + strlen(ptr); sep = ""; } fmtupn += snprintf(fmtupn, len, "%.*s%s", (int) (end-ptr), ptr, sep); } ptr = strstr(ptr, "dc="); } *retUpn = upn; upn = NULL; error: if (dwError) { if (upn) { free(upn); } } return dwError; }
static DWORD VMCAPolicySNValidateOperationParse( json_t *pJsonRule, PDWORD pdwOperationsLen, PVMCA_SNPOLICY_OPERATION **pppOperations ) { DWORD dwError = 0; DWORD dwIdx = 0; PCSTR pcszDataTemp = NULL; PCSTR pcszWithTemp = NULL; size_t szArrayLen = 0; json_t *pJsonTemp = NULL; json_t *pJsonDataTemp = NULL; json_t *pJsonWithTemp = NULL; PVMCA_SNPOLICY_OPERATION *ppOperations = NULL; if (!pJsonRule || !pppOperations) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } if (!json_is_array(pJsonRule)) { VMCA_LOG_ERROR( "[%s,%d] SN policy validate rule in config (%s) must be an array", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } szArrayLen = json_array_size(pJsonRule); if (szArrayLen < 1) { VMCA_LOG_ERROR( "[%s,%d] SN policy rule validate in config (%s) must be an array with at least 1 object", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateMemory( sizeof(PVMCA_SNPOLICY_OPERATION) * (DWORD)szArrayLen, (PVOID *)&ppOperations); BAIL_ON_VMCA_ERROR(dwError); json_array_foreach(pJsonRule, dwIdx, pJsonTemp) { if (!(pJsonDataTemp = json_object_get(pJsonTemp, "data"))) { VMCA_LOG_ERROR( "[%s,%d] SN policy rule validate in config (%s) must have \"data\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_JSON_PARSE_ERROR; BAIL_ON_JSON_PARSE_ERROR(dwError); } if (!(pJsonWithTemp = json_object_get(pJsonTemp, "with"))) { VMCA_LOG_ERROR( "[%s,%d] SN policy validate rule in config (%s) must have \"with\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_JSON_PARSE_ERROR; BAIL_ON_JSON_PARSE_ERROR(dwError); } pcszDataTemp = json_string_value(pJsonDataTemp); if (IsNullOrEmptyString(pcszDataTemp)) { VMCA_LOG_ERROR( "[%s,%d] SN policy validate rule in config (%s) cannot have empty \"data\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } if (VMCAStringCompareA(pcszDataTemp, VMCA_POLICY_REQ_CSR_SUBJ_ORGS, TRUE)) { VMCA_LOG_ERROR( "[%s,%d] Unknown SN policy validate rule \"data\" value. (%s)", __FUNCTION__, __LINE__, pcszDataTemp); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } pcszWithTemp = json_string_value(pJsonWithTemp); if (IsNullOrEmptyString(pcszWithTemp)) { VMCA_LOG_ERROR( "[%s,%d] SN policy validate rule in config (%s) cannot have empty \"with\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } if (VMCAStringCompareA(pcszWithTemp, VMCA_POLICY_REQ_UPN_RDN, TRUE)) { VMCA_LOG_ERROR( "[%s,%d] Unknown SN policy validate rule \"with\" value. (%s)", __FUNCTION__, __LINE__, pcszWithTemp); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateMemory( sizeof(VMCA_SNPOLICY_OPERATION), (PVOID *)&ppOperations[dwIdx]); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringA( pcszWithTemp, &ppOperations[dwIdx]->pszWith); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringA( pcszDataTemp, &ppOperations[dwIdx]->pszData); BAIL_ON_VMCA_ERROR(dwError); } *pdwOperationsLen = (DWORD)szArrayLen; *pppOperations = ppOperations; cleanup: return dwError; error: VMCAPolicySNOperationArrayFree(ppOperations, (DWORD)szArrayLen); if (pppOperations) { *pppOperations = NULL; } goto cleanup; }
static DWORD VMCAPolicySNMatchOperationParse( json_t *pJsonRule, PVMCA_SNPOLICY_OPERATION *ppOperation ) { DWORD dwError = 0; PCSTR pcszDataTemp = NULL; PCSTR pcszConditionTemp = NULL; PCSTR pcszWithTemp = NULL; json_t *pJsonDataTemp = NULL; json_t *pJsonWithTemp = NULL; json_t *pJsonConditionTemp = NULL; PVMCA_SNPOLICY_OPERATION pOperation = NULL; if (!pJsonRule || !ppOperation) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } if (!(pJsonDataTemp = json_object_get(pJsonRule, "data"))) { VMCA_LOG_ERROR( "[%s,%d] SN policy match rule in config (%s) must have \"data\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_JSON_PARSE_ERROR; BAIL_ON_JSON_PARSE_ERROR(dwError); } if (!(pJsonConditionTemp = json_object_get(pJsonRule, "condition"))) { VMCA_LOG_ERROR( "[%s,%d] SN policy match rule in config (%s) must have \"condition\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_JSON_PARSE_ERROR; BAIL_ON_JSON_PARSE_ERROR(dwError); } if (!(pJsonWithTemp = json_object_get(pJsonRule, "with"))) { VMCA_LOG_ERROR( "[%s,%d] SN policy match rule in config (%s) must have \"with\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_JSON_PARSE_ERROR; BAIL_ON_JSON_PARSE_ERROR(dwError); } pcszDataTemp = json_string_value(pJsonDataTemp); if (IsNullOrEmptyString(pcszDataTemp)) { VMCA_LOG_ERROR( "[%s,%d] SN policy match rule in config (%s) cannot have empty \"data\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } if (VMCAStringCompareA(pcszDataTemp, VMCA_POLICY_REQ_UPN_DN, TRUE)) { VMCA_LOG_ERROR( "[%s,%d] Unknown SN policy match rule \"data\" value. (%s)", __FUNCTION__, __LINE__, pcszDataTemp); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } pcszConditionTemp = json_string_value(pJsonConditionTemp); if (IsNullOrEmptyString(pcszConditionTemp)) { VMCA_LOG_ERROR( "[%s,%d] SN policy match rule in config (%s) cannot have empty \"condition\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } if (VMCAStringCompareA(pcszConditionTemp, VMCA_POLICY_COND_BEGINS, TRUE)) { VMCA_LOG_ERROR( "[%s,%d] Unknown SN policy match rule \"condition\" value. (%s)", __FUNCTION__, __LINE__, pcszConditionTemp); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } pcszWithTemp = json_string_value(pJsonWithTemp); if (IsNullOrEmptyString(pcszWithTemp)) { VMCA_LOG_ERROR( "[%s,%d] SN policy match rule in config (%s) cannot have empty \"with\" clause", __FUNCTION__, __LINE__, VMCA_POLICY_FILE_PATH); dwError = VMCA_POLICY_CONFIG_ERROR; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateMemory( sizeof(VMCA_SNPOLICY_OPERATION), (PVOID *)&pOperation); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringA( pcszWithTemp, &pOperation->pszWith); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringA( pcszConditionTemp, &pOperation->pszCondition); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringA( pcszDataTemp, &pOperation->pszData); BAIL_ON_VMCA_ERROR(dwError); *ppOperation = pOperation; cleanup: return dwError; error: VMCAPolicySNOperationFree(pOperation); if (ppOperation) { *ppOperation = NULL; } 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 VMCAAllocateStringPrintfA( RP_PSTR* ppszString, RP_PCSTR pszFormat, ... ) { ULONG ulError = 0; #ifndef _WIN32 if (!ppszString || !pszFormat) { ulError = ERROR_INVALID_PARAMETER; } else { va_list args; va_start(args, pszFormat); ulError = LwNtStatusToWin32Error( LwRtlCStringAllocatePrintfV( ppszString, pszFormat, args)); va_end(args); } return ulError; #else if (!ppszString || !pszFormat) { ulError = ERROR_INVALID_PARAMETER; } else { int len = 0; va_list args; PSTR pTempStr = NULL; va_start(args, pszFormat); len = _vscprintf(pszFormat, args) + 1 ; ulError = VMCAAllocateMemory((DWORD)len, (PVOID*)&pTempStr); BAIL_ON_ERROR(ulError); if (vsprintf( pTempStr, pszFormat, args ) < 0) { ulError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(ulError); } *ppszString = pTempStr; pTempStr = NULL; va_end(args); error : if (pTempStr != NULL) { VMCAFreeStringA(pTempStr); } } #endif return ulError; }
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; }
DWORD VMCAPrintCRLPrivate( PSTR pszFileName, PSTR *ppszCRLString ) { DWORD dwError = 0; X509_CRL *pCrl = NULL; BIO *pBioMem = NULL; BUF_MEM *pBuffMem = NULL; PSTR pszTempCrl = NULL; PSTR pTempCrl = NULL; if(IsNullOrEmptyString(pszFileName)){ dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } pBioMem = BIO_new(BIO_s_mem()); if (pBioMem == NULL) { dwError = VMCA_OUT_MEMORY_ERR; BAIL_ON_ERROR(dwError); } dwError = VMCAReadCRLFromFile(pszFileName, &pCrl); BAIL_ON_ERROR(dwError); dwError = X509_CRL_print(pBioMem, pCrl); BAIL_ON_SSL_ERROR(dwError, VMCA_CRL_DECODE_ERROR); BIO_get_mem_ptr(pBioMem, &pBuffMem); dwError = VMCAAllocateMemory((DWORD)pBuffMem->length, (PVOID*)&pTempCrl); BAIL_ON_ERROR(dwError); memcpy(pTempCrl, pBuffMem->data, pBuffMem->length - 1); dwError = VMCAAllocateStringA(pTempCrl, &pszTempCrl); BAIL_ON_ERROR(dwError); *ppszCRLString = pszTempCrl; pszTempCrl = NULL; cleanup: if (pCrl) { VMCACrlFree(pCrl); } if (pBioMem != NULL) { BIO_free(pBioMem); } VMCA_SAFE_FREE_MEMORY(pTempCrl); return dwError; error : VMCA_SAFE_FREE_STRINGA(pszTempCrl); goto cleanup; }
static DWORD VMCAGenerateCACNForLdap( X509* pCertificate, PSTR* ppszCACN ) { DWORD dwError = ERROR_SUCCESS; int length = 0; unsigned char* pEncodedKey = NULL; unsigned char* pKey = NULL; unsigned char md[SHA_DIGEST_LENGTH]; EVP_PKEY* pPubKey = NULL; PSTR pszCACN = NULL; ASN1_OCTET_STRING* pSid = NULL; if (pCertificate == NULL || ppszCACN == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_ERROR(dwError); } pSid = (ASN1_OCTET_STRING*)X509_get_ext_d2i(pCertificate, NID_subject_key_identifier, NULL, NULL); if (pSid) { dwError = VMCAKeyIdToHexString(pSid, &pszCACN); BAIL_ON_ERROR(dwError); } if (IsNullOrEmptyString(pszCACN)) { pPubKey = X509_get_pubkey(pCertificate); length = i2d_PUBKEY(pPubKey, NULL); dwError = VMCAAllocateMemory(length, (PVOID*)&pEncodedKey); BAIL_ON_ERROR(dwError); pKey = pEncodedKey; length = i2d_PUBKEY(pPubKey, &pKey); SHA1(pEncodedKey, length, md); dwError = VMCABytesToHexString((PUCHAR)md, SHA_DIGEST_LENGTH, &pszCACN, FALSE); BAIL_ON_ERROR(dwError); } *ppszCACN = pszCACN; cleanup: VMCA_SAFE_FREE_MEMORY(pEncodedKey); if (pPubKey) { EVP_PKEY_free(pPubKey); } if (pSid) { ASN1_OCTET_STRING_free(pSid); } return dwError; error: if (*ppszCACN) { *ppszCACN = NULL; } VMCA_SAFE_FREE_MEMORY(pszCACN); goto cleanup; }
DWORD VMCADecodeCert( PSTR pszCertificate, PVMCA_DB_CERTIFICATE_ENTRY* ppEntry ) { DWORD dwError = 0; PVMCA_DB_CERTIFICATE_ENTRY pDBEntry = NULL; PSTR pszCertName = NULL; PSTR pszCertSerial = NULL; PSTR pszNotBefore = NULL; PSTR pszNotAfter = NULL; PSTR pszIssuerName = NULL; X509 *pCert = NULL; if (pszCertificate == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } if (ppEntry == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMCA_ERROR(dwError); } dwError = VMCAAllocateMemory( sizeof(VMCA_DB_CERTIFICATE_ENTRY), (PVOID*) &pDBEntry); BAIL_ON_VMCA_ERROR(dwError); memset(pDBEntry,0, sizeof(VMCA_DB_CERTIFICATE_ENTRY)); VMCAAllocateStringA(pszCertificate, (PSTR*)&pDBEntry->pCertBlob); //pDBEntry->pCertBlob = (PBYTE) pszCertificate; pDBEntry->dwCertSize = (DWORD)strlen(pszCertificate); dwError = VMCAPEMToX509(pszCertificate, &pCert); BAIL_ON_VMCA_ERROR(dwError); if (X509_cmp_current_time(X509_get_notAfter(pCert)) < 0) { pDBEntry->dwRevoked = VMCA_CERTIFICATE_EXPIRED; } dwError = VMCAGetCertificateName(pCert, &pszCertName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszCertName, &pDBEntry->pwszCommonName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCertificateSerial(pCert, &pszCertSerial); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszCertSerial, &pDBEntry->pwszSerial); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetIssuerName(pCert, &pszIssuerName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszIssuerName, &pDBEntry->pwszIssuerName); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAGetCertificateTime(pCert, &pszNotBefore, &pszNotAfter); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszNotBefore, &pDBEntry->pwszTimeValidFrom); BAIL_ON_VMCA_ERROR(dwError); dwError = VMCAAllocateStringWFromA(pszNotBefore, &pDBEntry->pwszTimeValidTo); BAIL_ON_VMCA_ERROR(dwError); *ppEntry = pDBEntry; cleanup: if(pCert) { X509_free(pCert); } VMCA_SAFE_FREE_STRINGA(pszCertName); VMCA_SAFE_FREE_STRINGA(pszCertSerial); VMCA_SAFE_FREE_STRINGA(pszNotBefore); VMCA_SAFE_FREE_STRINGA(pszNotAfter); VMCA_SAFE_FREE_STRINGA(pszIssuerName); return dwError; error : VMCAFreeDBEntryFields(pDBEntry); goto cleanup; }
static DWORD VMCAGetX509Name( X509_NAME* pCertName, DWORD dwFlags, PSTR* ppszSubjectName ) { DWORD dwError = 0; int length = 0; BIO* pBioMem = NULL; PSTR pszSubjectName = NULL; pBioMem = BIO_new(BIO_s_mem()); if (!pBioMem) { dwError = ERROR_OUTOFMEMORY; BAIL_ON_ERROR(dwError); } X509_NAME_print_ex(pBioMem, pCertName, 0, dwFlags); length = BIO_pending(pBioMem); if (length <= 0) { dwError = ERROR_INVALID_DATA; BAIL_ON_ERROR(dwError); } dwError = VMCAAllocateMemory((DWORD)(length + 1), (PVOID*)&pszSubjectName); BAIL_ON_ERROR(dwError); if (BIO_read(pBioMem, pszSubjectName, length) != length) { dwError = ERROR_INVALID_STATE; BAIL_ON_ERROR(dwError); } *ppszSubjectName = pszSubjectName; cleanup: if (pBioMem) { BIO_free(pBioMem); } return dwError; error: if (ppszSubjectName) { *ppszSubjectName = NULL; } VMCA_SAFE_FREE_MEMORY(pszSubjectName); goto cleanup; }