DWORD VmDirComputeMessageDigest( const EVP_MD* digestMethod, const unsigned char* pData, size_t dataSize, unsigned char** ppMD, size_t* pMDSize ) { DWORD dwError = 0; EVP_MD_CTX mdCtx = {0}; unsigned char md[EVP_MAX_MD_SIZE] = {0}; unsigned int mdSize = 0; unsigned char* pMD = NULL; if (!digestMethod || !pData || !ppMD || !pMDSize) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } EVP_MD_CTX_init(&mdCtx); if (EVP_DigestInit_ex(&mdCtx, digestMethod, NULL) == 0) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: EVP_DigestInit_ex returned 0", __FUNCTION__); BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL); } if (EVP_DigestUpdate(&mdCtx, pData, dataSize) == 0) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: EVP_DigestUpdate returned 0", __FUNCTION__); BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL); } if (EVP_DigestFinal_ex(&mdCtx, md, &mdSize) == 0) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: EVP_DigestFinal_ex returned 0", __FUNCTION__); BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL); } dwError = VmDirAllocateAndCopyMemory(md, mdSize, (PVOID*)&pMD); BAIL_ON_VMDIR_ERROR(dwError); *ppMD = pMD; *pMDSize = mdSize; cleanup: EVP_MD_CTX_cleanup(&mdCtx); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed with error (%d)", __FUNCTION__, dwError); VMDIR_SAFE_FREE_MEMORY(pMD); goto cleanup; }
DWORD VmDirWriteQueuePush( PVDIR_BACKEND_CTX pBECtx, PVMDIR_WRITE_QUEUE pWriteQueue, PVMDIR_WRITE_QUEUE_ELEMENT pWriteQueueEle ) { int dbRetVal = 0; USN localUsn = 0; DWORD dwError = 0; BOOLEAN bInLock = FALSE; if (!pBECtx || !pWriteQueue || !pWriteQueueEle) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } if (pBECtx->wTxnUSN != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: acquiring multiple usn in same operation context, USN: %" PRId64, __FUNCTION__, pBECtx->wTxnUSN); BAIL_WITH_VMDIR_ERROR(dwError, LDAP_OPERATIONS_ERROR); } VMDIR_LOCK_MUTEX(bInLock, gVmDirServerOpsGlobals.pMutex); if ((dbRetVal = pBECtx->pBE->pfnBEGetNextUSN(pBECtx, &localUsn)) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: pfnBEGetNextUSN failed with error code: %d", __FUNCTION__, dbRetVal); BAIL_WITH_VMDIR_ERROR(dwError, LDAP_OPERATIONS_ERROR); } pWriteQueueEle->usn = localUsn; dwError = VmDirLinkedListInsertTail( pWriteQueue->pList, (PVOID) pWriteQueueEle, NULL); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO(LDAP_DEBUG_WRITE_QUEUE, "%s: usn: %"PRId64, __FUNCTION__, localUsn); cleanup: VMDIR_UNLOCK_MUTEX(bInLock, gVmDirServerOpsGlobals.pMutex); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d) localUsn %"PRId64, dwError, localUsn); goto cleanup; }
int VmDirCreateRequestVoteCtrl( PVDIR_REQUEST_VOTE_CONTROL_VALUE pRequestVoteCtrlValue, LDAPControl* pRequestVoteCtrl ) { int retVal = LDAP_SUCCESS; BerElement* pBer = NULL; BerValue candidateIdBV = {0}; BerValue lastLogIndexBV = {0}; if (!pRequestVoteCtrlValue || !pRequestVoteCtrl) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER); } if ((pBer = ber_alloc()) == NULL) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } candidateIdBV.bv_val = pRequestVoteCtrlValue->candidateId; candidateIdBV.bv_len = VmDirStringLenA(pRequestVoteCtrlValue->candidateId); retVal = VmDirAllocateStringPrintf(&lastLogIndexBV.bv_val, "%"PRIu64, pRequestVoteCtrlValue->lastLogIndex); BAIL_ON_VMDIR_ERROR( retVal ); lastLogIndexBV.bv_len = VmDirStringLenA(lastLogIndexBV.bv_val); if ( ber_printf( pBer, "{iOOi}", pRequestVoteCtrlValue->term, &candidateIdBV, &lastLogIndexBV, pRequestVoteCtrlValue->lastLogTerm) == -1) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: ber_printf failed.", __FUNCTION__ ); BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } memset( pRequestVoteCtrl, 0, sizeof( LDAPControl )); pRequestVoteCtrl->ldctl_oid = LDAP_REQUEST_VOTE_CONTROL; pRequestVoteCtrl->ldctl_iscritical = '1'; if (ber_flatten2(pBer, &pRequestVoteCtrl->ldctl_value, 1)) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } cleanup: VMDIR_SAFE_FREE_MEMORY(lastLogIndexBV.bv_val); if (pBer) { ber_free(pBer, 1); } return retVal; error: VmDirFreeCtrlContent(pRequestVoteCtrl); goto cleanup; }
//pszMetadata: <local USN>:<version no>:<originating server ID>:<originating time>:<originating USN> DWORD VmDirMetaDataDeserialize( PCSTR pszMetaData, PVMDIR_ATTRIBUTE_METADATA* ppMetaData ) { DWORD dwError = 0; PCSTR pDelimiter = ":"; PVMDIR_STRING_LIST pStrList = NULL; PVMDIR_ATTRIBUTE_METADATA pMetaData = NULL; if (!pszMetaData || !ppMetaData) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirStringToTokenList(pszMetaData, pDelimiter, &pStrList); BAIL_ON_VMDIR_ERROR(dwError); if (pStrList->dwCount != 5) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_BACKEND_INVALID_METADATA); } dwError = VmDirAllocateMemory(sizeof(VMDIR_ATTRIBUTE_METADATA), (PVOID*) &pMetaData); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringToINT64(pStrList->pStringList[0], NULL, &pMetaData->localUsn); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringToUINT64(pStrList->pStringList[1], NULL, &pMetaData->version); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringA(pStrList->pStringList[2], &pMetaData->pszOrigInvoId); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringA(pStrList->pStringList[3], &pMetaData->pszOrigTime); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringToINT64(pStrList->pStringList[4], NULL, &pMetaData->origUsn); BAIL_ON_VMDIR_ERROR(dwError); *ppMetaData = pMetaData; cleanup: VmDirStringListFree(pStrList); return dwError; error: VmDirFreeMetaData(pMetaData); VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
DWORD VmDirPrepareSwapDBInfo( PCSTR pszHostName, // partner server object cn PVMDIR_SWAP_DB_INFO* ppSwapDBInfo ) { DWORD dwError = 0; PVMDIR_SWAP_DB_INFO pLocalSwapDBInfo = NULL; if (!ppSwapDBInfo) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory(sizeof(VMDIR_SWAP_DB_INFO), (PVOID*)&pLocalSwapDBInfo); BAIL_ON_VMDIR_ERROR(dwError); if (pszHostName) { dwError = VmDirAllocateStringA(pszHostName, &pLocalSwapDBInfo->pszPartnerServerName); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "My partner %s", pLocalSwapDBInfo->pszPartnerServerName); } dwError = VmDirInternalGetDSERootServerCN(&pLocalSwapDBInfo->pszOrgDBServerName); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "DB was from %s", pLocalSwapDBInfo->pszOrgDBServerName); dwError = _VmDirComposeUtdVector(pLocalSwapDBInfo); BAIL_ON_VMDIR_ERROR(dwError); if (!pLocalSwapDBInfo->pszPartnerServerName || // no partner, DR case VmDirStringCompareA( // DB copied from joining partner pLocalSwapDBInfo->pszPartnerServerName, pLocalSwapDBInfo->pszOrgDBServerName, FALSE) == 0) { dwError = VmDirAllocateStringA(pLocalSwapDBInfo->pszOrgDBMaxUSN, &pLocalSwapDBInfo->pszMyHighWaterMark); BAIL_ON_VMDIR_ERROR(dwError); } else { // DB from one node but join to another dwError = _VmDirComposeHighWaterMark(pLocalSwapDBInfo); BAIL_ON_VMDIR_ERROR(dwError); } VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "My High Water Mark %s", pLocalSwapDBInfo->pszMyHighWaterMark); *ppSwapDBInfo = pLocalSwapDBInfo; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, " error (%u)", dwError); VmDirFreeSwapDBInfo(pLocalSwapDBInfo); goto cleanup; }
static PVDIR_PAGED_SEARCH_RECORD VmDirPagedSearchCacheFind( PCSTR pszCookie ) { DWORD dwError = 0; PLW_HASHTABLE_NODE pNode = NULL; PVDIR_PAGED_SEARCH_RECORD pSearchRecord = NULL; BOOLEAN bInLock = FALSE; if (IsNullOrEmptyString(pszCookie)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } VMDIR_LOCK_MUTEX(bInLock, gPagedSearchCache.mutex); dwError = LwRtlHashTableFindKey( gPagedSearchCache.pHashTbl, &pNode, (PVOID)pszCookie); dwError = LwNtStatusToWin32Error(dwError); BAIL_ON_VMDIR_ERROR(dwError); pSearchRecord = LW_STRUCT_FROM_FIELD(pNode, VDIR_PAGED_SEARCH_RECORD, Node); _RefPagedSearchRecord(pSearchRecord); cleanup: VMDIR_UNLOCK_MUTEX(bInLock, gPagedSearchCache.mutex); return pSearchRecord; error: goto cleanup; }
DWORD VmDirInitDCConnThread( PVMDIR_DC_CONNECTION pDCConn ) { DWORD dwError = 0; VMDIR_THREAD threadId = {0}; if (!pDCConn) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirCreateThread( &threadId, FALSE, // no thread join _VmDirDCConnThreadFun, pDCConn); BAIL_ON_VMDIR_ERROR(dwError); cleanup: return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s failed, error %d", __FUNCTION__, dwError); goto cleanup; }
DWORD VmDirMetaDataCopyContent( PVMDIR_ATTRIBUTE_METADATA pSrcMetaData, PVMDIR_ATTRIBUTE_METADATA pDestMetaData ) { DWORD dwError = 0; if (VmDirMetaDataIsEmpty(pSrcMetaData) || !pDestMetaData) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } pDestMetaData->localUsn = pSrcMetaData->localUsn; pDestMetaData->version = pSrcMetaData->version; VMDIR_SAFE_FREE_MEMORY(pDestMetaData->pszOrigInvoId); dwError = VmDirAllocateStringA(pSrcMetaData->pszOrigInvoId, &pDestMetaData->pszOrigInvoId); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_SAFE_FREE_MEMORY(pDestMetaData->pszOrigTime); dwError = VmDirAllocateStringA(pSrcMetaData->pszOrigTime, &pDestMetaData->pszOrigTime); BAIL_ON_VMDIR_ERROR(dwError); pDestMetaData->origUsn = pSrcMetaData->origUsn; cleanup: return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
DWORD VmDirUTDVectorCacheToString( PVMDIR_UTDVECTOR_CACHE pUTDVector, PSTR* ppszUTDVector ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; PSTR pszUTDVector = NULL; if (!pUTDVector || !ppszUTDVector) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } VMDIR_RWLOCK_READLOCK(bInLock, pUTDVector->pUtdVectorLock, 0); dwError = VmDirAllocateStringA(pUTDVector->pszUtdVector, &pszUTDVector); BAIL_ON_VMDIR_ERROR(dwError); *ppszUTDVector = pszUTDVector; cleanup: VMDIR_RWLOCK_UNLOCK(bInLock, pUTDVector->pUtdVectorLock); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
DWORD VmDirSetBaseDN( PVMDIR_TEST_STATE pState ) { PSTR pszBaseDN = NULL; DWORD dwError = 0; PSTR pszDot = NULL; pszDot = strchr(pState->pszDomain, '.'); if (pszDot == NULL) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } *pszDot = '\0'; dwError = VmDirAllocateStringPrintf( &pszBaseDN, "dc=%s,dc=%s", pState->pszDomain, pszDot + 1); *pszDot = '.'; BAIL_ON_VMDIR_ERROR(dwError); pState->pszBaseDN = pszBaseDN; cleanup: return dwError; error: VMDIR_SAFE_FREE_STRINGA(pszBaseDN); goto cleanup; }
DWORD VmDirRESTCacheInit( PVDIR_REST_HEAD_CACHE* ppRestCache ) { DWORD dwError = 0; PVDIR_REST_HEAD_CACHE pRestCache = NULL; if (!ppRestCache) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory( sizeof(VDIR_REST_HEAD_CACHE), (PVOID*)&pRestCache); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateRWLock(&pRestCache->pRWLock); BAIL_ON_VMDIR_ERROR(dwError); *ppRestCache = pRestCache; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); VmDirFreeRESTCache(pRestCache); goto cleanup; }
DWORD VmDirMetaDataSerialize( PVMDIR_ATTRIBUTE_METADATA pMetadata, PSTR pszMetadata ) { DWORD dwError = 0; if (VmDirMetaDataIsEmpty(pMetadata) || !pszMetadata) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirStringPrintFA( pszMetadata, VMDIR_MAX_ATTR_META_DATA_LEN, "%"PRId64":%"PRId64":%s:%s:%"PRId64, pMetadata->localUsn, pMetadata->version, pMetadata->pszOrigInvoId, pMetadata->pszOrigTime, pMetadata->origUsn); BAIL_ON_VMDIR_ERROR(dwError); cleanup: return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
DWORD VmDirWriteQueueElementAllocate( PVMDIR_WRITE_QUEUE_ELEMENT* ppWriteQueueEle ) { DWORD dwError = 0; PVMDIR_WRITE_QUEUE_ELEMENT pWriteQueueEleLocal = NULL; if (!ppWriteQueueEle) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory(sizeof(VMDIR_WRITE_QUEUE_ELEMENT), (PVOID)&pWriteQueueEleLocal); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateCondition(&pWriteQueueEleLocal->pCond); BAIL_ON_VMDIR_ERROR(dwError); *ppWriteQueueEle = pWriteQueueEleLocal; pWriteQueueEleLocal = NULL; cleanup: return dwError; error: VmDirWriteQueueElementFree(pWriteQueueEleLocal); pWriteQueueEleLocal = NULL; VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
DWORD VmDirUTDVectorCacheLookup( PVMDIR_UTDVECTOR_CACHE pUTDVector, PCSTR pszInvocationId, USN* pUsn ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; uintptr_t usn = 0; PVMDIR_UTDVECTOR_CACHE pCache = pUTDVector; if (IsNullOrEmptyString(pszInvocationId) || !pUsn || !pUTDVector) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } VMDIR_RWLOCK_READLOCK(bInLock, pCache->pUtdVectorLock, 0); dwError = LwRtlHashMapFindKey(pCache->pUtdVectorMap, (PVOID*)&usn, pszInvocationId); BAIL_ON_VMDIR_ERROR(dwError); *pUsn = (USN)usn; cleanup: VMDIR_RWLOCK_UNLOCK(bInLock, pCache->pUtdVectorLock); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
/* * API to backup database at the server side */ DWORD VmDirBackupDB( PVMDIR_SERVER_CONTEXT hServer, PCSTR pszBackupPath ) { DWORD dwError = 0; if (!hServer || !hServer->hBinding || IsNullOrEmptyString(pszBackupPath)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = _VmDirBackupDBRInternal(hServer, pszBackupPath); BAIL_ON_VMDIR_ERROR(dwError); cleanup: return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s failed. Error[%d]\n", __FUNCTION__, dwError); goto cleanup; }
static DWORD _VmDirMDBInitializeDBEntry( const char *pszDBPath, PVDIR_MDB_DB *ppDB ) { DWORD dwError = 0; PVDIR_MDB_DB pDB = NULL; if (!pszDBPath || !ppDB) { BAIL_WITH_VMDIR_ERROR(dwError, ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory (sizeof(VDIR_MDB_DB), ((PVOID*)&pDB)); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringA (pszDBPath, &pDB->pszDBPath); BAIL_ON_VMDIR_ERROR(dwError); *ppDB = pDB; cleanup: return dwError; error: if (pDB) { VMDIR_SAFE_FREE_MEMORY(pDB->pszDBPath); VMDIR_SAFE_FREE_MEMORY(pDB); } goto cleanup; }
DWORD VmDirDeleteEntryViaDN( PCSTR pszDN ) { DWORD dwError = 0; VDIR_OPERATION op = {0}; DeleteReq *dr = NULL; if (IsNullOrEmptyString(pszDN)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirInitStackOperation(&op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_DELETE, NULL); BAIL_ON_VMDIR_ERROR(dwError); op.pBEIF = VmDirBackendSelect(NULL); op.reqDn.lberbv_val = (PSTR)pszDN; op.reqDn.lberbv_len = VmDirStringLenA(pszDN); dr = &op.request.deleteReq; dr->dn.lberbv.bv_val = op.reqDn.lberbv.bv_val; dr->dn.lberbv.bv_len = op.reqDn.lberbv.bv_len; dwError = VmDirInternalDeleteEntry(&op); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeOperationContent(&op); return dwError; error: goto cleanup; }
DWORD VmDirQueueInit( PVDIR_QUEUE* ppQueue ) { DWORD dwError = 0; PVDIR_QUEUE pQueue = NULL; if (!ppQueue) { BAIL_WITH_VMDIR_ERROR(dwError, ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory(sizeof(VDIR_QUEUE), (PVOID*)&pQueue); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateMutex(&pQueue->pMutex); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateCondition(&pQueue->pCond); BAIL_ON_VMDIR_ERROR(dwError); *ppQueue = pQueue; cleanup: return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); VmDirQueueFree(pQueue); goto cleanup; }
DWORD VmDirRESTCacheGetBuiltInAdminsGroupSid( PVDIR_REST_HEAD_CACHE pRestCache, PSID* ppBuiltInAdminsGroupSid ) { DWORD dwError = 0; ULONG ulSidLen = 0; BOOLEAN bInLock = FALSE; PSID pSid = NULL; if (!pRestCache || !ppBuiltInAdminsGroupSid) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } VMDIR_RWLOCK_READLOCK(bInLock, gpVdirRestCache->pRWLock, 0); if (!RtlValidSid(pRestCache->pBuiltInAdminsGroupSid)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_NOT_FOUND); } ulSidLen = RtlLengthSid(pRestCache->pBuiltInAdminsGroupSid); dwError = VmDirAllocateMemory(ulSidLen, (PVOID*)&pSid); BAIL_ON_VMDIR_ERROR(dwError); dwError = RtlCopySid(ulSidLen, pSid, pRestCache->pBuiltInAdminsGroupSid); BAIL_ON_VMDIR_ERROR(dwError); *ppBuiltInAdminsGroupSid = pSid; cleanup: VMDIR_RWLOCK_UNLOCK(bInLock, gpVdirRestCache->pRWLock); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); VMDIR_SAFE_FREE_MEMORY(pSid); goto cleanup; }
DWORD VmDirQueueDequeue( BOOL bInLock, PVDIR_QUEUE pQueue, int64_t iTimeoutMs, PVOID* ppElement ) { DWORD dwError = 0; PVDIR_QUEUE_NODE pTemp= NULL; if (!pQueue || !ppElement) { BAIL_WITH_VMDIR_ERROR(dwError, ERROR_INVALID_PARAMETER); } VMDIR_LOCK_MUTEX(bInLock, pQueue->pMutex); if (!pQueue->pHead) { if (iTimeoutMs < 0) // Blocking { while (!pQueue->pHead) { dwError = VmDirConditionWait(pQueue->pCond, pQueue->pMutex); BAIL_ON_VMDIR_ERROR(dwError); } } else if (iTimeoutMs > 0) // Waiting { VmDirConditionTimedWait(pQueue->pCond, pQueue->pMutex, iTimeoutMs); if (!pQueue->pHead) { dwError = VMDIR_ERROR_QUEUE_EMPTY; } } else // Non Blocking { dwError = VMDIR_ERROR_QUEUE_EMPTY; } BAIL_ON_VMDIR_ERROR(dwError); } pQueue->iSize--; pTemp = pQueue->pHead; pQueue->pHead = pQueue->pHead->pNext; *ppElement = pTemp->pElement; VMDIR_SAFE_FREE_MEMORY(pTemp); cleanup: VMDIR_UNLOCK_MUTEX(bInLock, pQueue->pMutex); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); goto cleanup; }
DWORD VmDirPagedSearchCacheRead( PCSTR pszCookie, ENTRYID **ppValidatedEntries, DWORD *pdwEntryCount ) { DWORD dwError = 0; PVDIR_PAGED_SEARCH_RECORD pSearchRecord = NULL; BOOLEAN bInLock = FALSE; PVDIR_PAGED_SEARCH_ENTRY_LIST pEntryList = NULL; pSearchRecord = VmDirPagedSearchCacheFind(pszCookie); if (pSearchRecord == NULL) { // // Barring the client sending us an invalid cookie, failure here // means that the worker thread timed out and freed the cache. // BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_NOT_FOUND); } VMDIR_LOCK_MUTEX(bInLock, pSearchRecord->mutex); dwError = _VmDirPagedSearchCacheWaitAndRead_inlock( pSearchRecord, &pEntryList); BAIL_ON_VMDIR_ERROR(dwError); if (pSearchRecord->bSearchCompleted) { VmDirPagedSearchCacheCullWorkerThread(pSearchRecord); } else { *ppValidatedEntries = pEntryList->pEntryIds; *pdwEntryCount = pEntryList->dwCount; // // We transferred ownership of pEntryList->pEntryIds above but we still // need to delete the rest of the structure. // pEntryList->pEntryIds = NULL; _VmDirPagedSearchEntryListFree(pEntryList); } cleanup: VMDIR_UNLOCK_MUTEX(bInLock, pSearchRecord->mutex); if (pSearchRecord != NULL) { _DerefPagedSearchRecord(pSearchRecord); } return dwError; error: goto cleanup; }
static DWORD _VmGetHighestCommittedUSN( PSTR* ppszHighestCommittedUSN ) { DWORD dwError = 0; USN usn = 0; USN nextUSN = 0; VDIR_ENTRY_ARRAY entryArray = {0}; PSTR pszUSN = NULL; VDIR_BACKEND_CTX beCtx = {0}; beCtx.pBE = VmDirBackendSelect(NULL); assert(beCtx.pBE); dwError = beCtx.pBE->pfnBEGetNextUSN(&beCtx, &nextUSN); BAIL_ON_VMDIR_ERROR(dwError); for (usn=nextUSN; usn > 1LL; usn--) { VMDIR_SAFE_FREE_MEMORY(pszUSN); VmDirFreeEntryArrayContent(&entryArray); dwError = VmDirAllocateStringPrintf(&pszUSN, "%" PRId64, usn); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSimpleEqualFilterInternalSearch( "", LDAP_SCOPE_SUBTREE, ATTR_USN_CHANGED, pszUSN, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if (entryArray.iSize == 1 ) { break; } } if (usn == 0) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_STATE); } *ppszHighestCommittedUSN = pszUSN; pszUSN = NULL; cleanup: VMDIR_SAFE_FREE_MEMORY(pszUSN); VmDirFreeEntryArrayContent(&entryArray); VmDirBackendCtxContentFree(&beCtx); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "error (%u), start USN %" PRId64, dwError, nextUSN); goto cleanup; }
/* add a cert item to json array */ static DWORD _VmDirAddCertItemToJsonArray( PVMDIR_CA_CERT pCert, BOOLEAN bDetail, json_t *pjCertArray ) { DWORD dwError = 0; json_t *pjCert = NULL; pjCert = json_object(); if (!pjCert) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_NO_MEMORY); } dwError = json_object_set_new(pjCert, "cn", json_string(pCert->pCN)); BAIL_ON_VMDIR_ERROR(dwError); dwError = json_object_set_new( pjCert, "subjectdn", json_string(pCert->pSubjectDN)); BAIL_ON_VMDIR_ERROR(dwError); if (bDetail) { dwError = json_object_set_new( pjCert, "cert", json_string(pCert->pCert)); BAIL_ON_VMDIR_ERROR(dwError); /* crl is optional so set to empty string if null */ dwError = json_object_set_new( pjCert, "crl", json_string(pCert->pCrl ? pCert->pCrl : "")); BAIL_ON_VMDIR_ERROR(dwError); } dwError = json_array_append_new(pjCertArray, pjCert); BAIL_ON_VMDIR_ERROR(dwError); cleanup: return dwError; error: if (pjCert) { json_decref(pjCert); } goto cleanup; }
DWORD VmDirRESTCacheGetOIDCSigningCertPEM( PVDIR_REST_HEAD_CACHE pRestCache, PSTR* ppszOIDCSigningCertPEM ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; PSTR pszOIDCSigningCertPEM = NULL; if (!pRestCache || !ppszOIDCSigningCertPEM) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } VMDIR_RWLOCK_READLOCK(bInLock, gpVdirRestCache->pRWLock, 0); if (IsNullOrEmptyString(pRestCache->pszOIDCSigningCertPEM)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_NOT_FOUND); } dwError = VmDirAllocateStringA( pRestCache->pszOIDCSigningCertPEM, &pszOIDCSigningCertPEM); BAIL_ON_VMDIR_ERROR(dwError); *ppszOIDCSigningCertPEM = pszOIDCSigningCertPEM; cleanup: VMDIR_RWLOCK_UNLOCK(bInLock, gpVdirRestCache->pRWLock); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); VMDIR_SAFE_FREE_MEMORY(pszOIDCSigningCertPEM); goto cleanup; }
DWORD VmDirUTDVectorCacheReplace( PVMDIR_UTDVECTOR_CACHE pUTDVector, PCSTR pszNewUTDVector ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; if (!pUTDVector) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } if (IsNullOrEmptyString(pszNewUTDVector)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } VMDIR_RWLOCK_WRITELOCK(bInLock, pUTDVector->pUtdVectorLock, 0); // update hash map first LwRtlHashMapClear(pUTDVector->pUtdVectorMap, VmDirSimpleHashMapPairFreeKeyOnly, NULL); dwError = VmDirStrtoVector(pszNewUTDVector, _VmDirUTDVectorStrToPair, pUTDVector->pUtdVectorMap); BAIL_ON_VMDIR_ERROR(dwError); // update string VMDIR_SAFE_FREE_MEMORY(pUTDVector->pszUtdVector); dwError = VmDirAllocateStringA(pszNewUTDVector, &pUTDVector->pszUtdVector); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VMDIR_RWLOCK_UNLOCK(bInLock, pUTDVector->pUtdVectorLock); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
DWORD VmDirAllocAndSetThrLogCtx( PVMDIR_THREAD_LOG_CONTEXT* ppThrLogCtx ) { DWORD dwError = 0; PVMDIR_THREAD_LOG_CONTEXT pCurrLogCtx = NULL; PVMDIR_THREAD_LOG_CONTEXT pLocalLogCtx = NULL; if (!ppThrLogCtx) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirGetThreadLogContextValue(&pCurrLogCtx); BAIL_ON_VMDIR_ERROR(dwError); if (pCurrLogCtx) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_STATE); } dwError = VmDirAllocateMemory(sizeof(VMDIR_THREAD_LOG_CONTEXT), (PVOID)&pLocalLogCtx); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSetThreadLogContextValue(pLocalLogCtx); BAIL_ON_VMDIR_ERROR(dwError); *ppThrLogCtx = pLocalLogCtx; pLocalLogCtx = NULL; cleanup: return dwError; error: VmDirUnsetAndFreeThrLogCtx(pLocalLogCtx); goto cleanup; }
/* * Waits until there's data from the worker thread to read (or until the * server's shutdown). */ static DWORD _VmDirPagedSearchCacheWaitAndRead_inlock( PVDIR_PAGED_SEARCH_RECORD pSearchRecord, PVDIR_PAGED_SEARCH_ENTRY_LIST *ppEntryList ) { DWORD dwError = 0; PVDIR_PAGED_SEARCH_ENTRY_LIST pEntryList = NULL; while (TRUE) { dwError = dequePopLeft(pSearchRecord->pQueue, (PVOID*)&pEntryList); if (dwError == 0) { break; } else if (pSearchRecord->bProcessingCompleted) { // // Nothing in the queue and processing's complete so we must have // read all the data. // pSearchRecord->bSearchCompleted = TRUE; dwError = 0; break; } else { (VOID)VmDirConditionTimedWait( pSearchRecord->pDataAvailable, pSearchRecord->mutex, VMDIR_PSCACHE_READ_TIMEOUT); } if (VmDirdState() == VMDIRD_STATE_SHUTDOWN) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_UNAVAILABLE); } } *ppEntryList = pEntryList; pSearchRecord->tLastClientRead = time(NULL); cleanup: return dwError; error: goto cleanup; }
static int _VmDirInternalPagedSearch( VDIR_OPERATION * pOperation ) { int retVal = LDAP_SUCCESS; PSTR pszLocalErrMsg = NULL; // should never happen - there are asserts in calling function if (pOperation == NULL) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER); } /* * New page search * TODO: Iterator logic and ranking algorithm will be added in next tasks */ if (pOperation->showPagedResultsCtrl != NULL && IsNullOrEmptyString(pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie)) { retVal = BuildCandidateList(pOperation, pOperation->request.searchReq.filter, 0); BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "BuildCandidateList failed."); if (pOperation->request.searchReq.filter->computeResult == FILTER_RES_TRUE) { retVal = VMDIR_ERROR_UNWILLING_TO_PERFORM; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "Full scan of Entry DB is required. Refine your search."); } } retVal = VmDirProcessPagedSearch(pOperation); BAIL_ON_VMDIR_ERROR(retVal); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return retVal; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error(%d)", __FUNCTION__, retVal); goto cleanup; }
static int _VmDirInternalNormalSearch( VDIR_OPERATION * pOperation ) { int retVal = LDAP_SUCCESS; PSTR pszLocalErrMsg = NULL; ENTRYID eStartingId = 0; // should never happen - there are asserts in calling function if (pOperation == NULL) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER); } retVal = BuildCandidateList(pOperation, pOperation->request.searchReq.filter, eStartingId); BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, pszLocalErrMsg, "BuildCandidateList failed."); if (pOperation->request.searchReq.filter->computeResult == FILTER_RES_TRUE) { retVal = VMDIR_ERROR_UNWILLING_TO_PERFORM; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "Full scan of Entry DB is required. Refine your search."); } retVal = VmDirProcessCandidateList(pOperation); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "VmDirProcessCandidateList failed. (%u)(%s)", retVal, VDIR_SAFE_STRING(pOperation->ldapResult.pszErrMsg)); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return retVal; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error(%d)", __FUNCTION__, retVal); goto cleanup; }
/* * FROM and TO Attributes use same schema context */ DWORD VmDirAttributeDup( PVDIR_ATTRIBUTE pAttr, PVDIR_ATTRIBUTE* ppDupAttr ) { DWORD dwError = 0; DWORD dwCnt = 0; PVDIR_ATTRIBUTE pAttribute = NULL; if (!pAttr || !ppDupAttr) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory(sizeof(VDIR_ATTRIBUTE), (PVOID*)&pAttribute); BAIL_ON_VMDIR_ERROR(dwError); // add one more BerValue as Encode/Decode entry in data store layer needs it. dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (pAttr->numVals + 1), (PVOID*)&pAttribute->vals); BAIL_ON_VMDIR_ERROR(dwError); for (dwCnt = 0 ; dwCnt < pAttr->numVals; dwCnt++) { dwError = VmDirBervalContentDup(&pAttr->vals[dwCnt], &pAttribute->vals[dwCnt]); BAIL_ON_VMDIR_ERROR(dwError); pAttribute->numVals = dwCnt + 1; } // use the same pATDesc and type from pAttr pAttribute->pATDesc = pAttr->pATDesc; dwError = VmDirBervalContentDup(&pAttr->type, &pAttribute->type); BAIL_ON_VMDIR_ERROR(dwError); *ppDupAttr = pAttribute; cleanup: return dwError; error: VmDirFreeAttribute(pAttribute); VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }