static DWORD _VmDirRESTCreateCondWriteCtrl( PVDIR_OPERATION pOp, PCSTR pszTenant, PCSTR pszCondWriteFilter ) { DWORD dwError = 0; VDIR_BERVALUE bvFilter = VDIR_BERVALUE_INIT; PVDIR_FILTER pObjectFilter = NULL; PVDIR_FILTER pDNFilter = NULL; dwError = StrFilterToFilter(pszCondWriteFilter, &pObjectFilter); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRESTFilterObjectToDN( pszTenant, pObjectFilter, &pDNFilter); BAIL_ON_VMDIR_ERROR(dwError); dwError = FilterToStrFilter(pDNFilter, &bvFilter); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAddCondWriteCtrl(pOp, bvFilter.lberbv_val); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeBervalContent(&bvFilter); DeleteFilter(pObjectFilter); DeleteFilter(pDNFilter); return dwError; error: goto cleanup; }
/* * This generic search with pagination is new and isn't mature. Please be * careful with the * scope, base, and use an indexed filter. * Note that ulPageSize == 0 will ignore paging. */ DWORD VmDirFilterInternalSearch( PCSTR pszBaseDN, int searchScope, PCSTR pszFilter, unsigned long ulPageSize, PSTR *ppszPageCookie, PVDIR_ENTRY_ARRAY pEntryArray ) { DWORD dwError = 0; VDIR_OPERATION searchOP = {0}; VDIR_BERVALUE bervDN = VDIR_BERVALUE_INIT; PVDIR_FILTER pFilter = NULL; PVDIR_LDAP_CONTROL showPagedResultsCtrl = NULL; PSTR pszPageCookie = NULL; if ( !pszBaseDN || !pszFilter || !pEntryArray || (ulPageSize != 0 && ppszPageCookie == NULL)) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } if (ulPageSize != 0) { dwError = VmDirAllocateMemory( sizeof(VDIR_LDAP_CONTROL), (PVOID *)&showPagedResultsCtrl ); BAIL_ON_VMDIR_ERROR(dwError); showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize = ulPageSize; if (ppszPageCookie && *ppszPageCookie) { VmDirStringNCpyA(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, VMDIR_ARRAY_SIZE(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie), *ppszPageCookie, VMDIR_ARRAY_SIZE(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie) - 1); } else { showPagedResultsCtrl->value.pagedResultCtrlVal.cookie[0] = '\0'; } } dwError = VmDirInitStackOperation( &searchOP, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL ); BAIL_ON_VMDIR_ERROR(dwError); bervDN.lberbv.bv_val = (PSTR)pszBaseDN; bervDN.lberbv.bv_len = VmDirStringLenA(pszBaseDN); searchOP.pBEIF = VmDirBackendSelect( pszBaseDN ); assert(searchOP.pBEIF); dwError = VmDirBervalContentDup( &bervDN, &searchOP.reqDn); BAIL_ON_VMDIR_ERROR(dwError); searchOP.request.searchReq.scope = searchScope; dwError = StrFilterToFilter(pszFilter, &pFilter); BAIL_ON_VMDIR_ERROR(dwError); searchOP.request.searchReq.filter = pFilter; pFilter = NULL; // search request takes over pFilter searchOP.showPagedResultsCtrl = showPagedResultsCtrl; dwError = VmDirInternalSearch( &searchOP ); BAIL_ON_VMDIR_ERROR(dwError); // caller takes over searchOP.internalSearchEntryArray contents pEntryArray->iSize = searchOP.internalSearchEntryArray.iSize; pEntryArray->pEntry = searchOP.internalSearchEntryArray.pEntry; searchOP.internalSearchEntryArray.iSize = 0; searchOP.internalSearchEntryArray.pEntry = NULL; if (showPagedResultsCtrl) { dwError = VmDirAllocateStringA(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, &pszPageCookie); BAIL_ON_VMDIR_ERROR(dwError); *ppszPageCookie = pszPageCookie; pszPageCookie = NULL; } cleanup: VMDIR_SAFE_FREE_MEMORY(showPagedResultsCtrl); VmDirFreeOperationContent(&searchOP); if (pFilter) { DeleteFilter(pFilter); } return dwError; error: goto cleanup; }
static DWORD VmDirPagedSearchCacheNodeAllocate( PVDIR_PAGED_SEARCH_RECORD *ppSearchRec, PVDIR_OPERATION pOperation, DWORD dwCandidatesProcessed ) { DWORD dwError = 0; PVDIR_PAGED_SEARCH_RECORD pSearchRecord = NULL; char szGuidStr[VMDIR_GUID_STR_LEN] = {0}; uuid_t guid = {0}; VDIR_BERVALUE strFilter = VDIR_BERVALUE_INIT; dwError = VmDirAllocateMemory(sizeof(*pSearchRecord), (PVOID)&pSearchRecord); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirUuidGenerate(&guid); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirUuidToStringLower(&guid, szGuidStr, sizeof(szGuidStr)); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringA(szGuidStr, &pSearchRecord->pszGuid); BAIL_ON_VMDIR_ERROR(dwError); // // Capture the original search filter and mark it as undeletable. Because // the ava strings aren't allocated separately but are part of the request // we have to specifically clone them. // dwError = FilterToStrFilter(pOperation->request.searchReq.filter, &strFilter); BAIL_ON_VMDIR_ERROR(dwError); dwError = StrFilterToFilter(strFilter.lberbv.bv_val, &pSearchRecord->pFilter); BAIL_ON_VMDIR_ERROR(dwError); pSearchRecord->pTotalCandidates = pOperation->request.searchReq.filter->candidates; pOperation->request.searchReq.filter->candidates = NULL; pSearchRecord->dwPageSize = pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize; // // dwCandidatesProcessed is the count of entries of pFilter->candidates // that we went through building up the first page of results. We add // one because we want to start our next search past the point of where // we've already been. // pSearchRecord->dwCandidatesProcessed = dwCandidatesProcessed + 1; dwError = dequeCreate(&pSearchRecord->pQueue); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateMutex(&pSearchRecord->mutex); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateCondition(&pSearchRecord->pDataAvailable); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirPagedSearchCreateThread(pSearchRecord); BAIL_ON_VMDIR_ERROR(dwError); LwRtlHashTableResizeAndInsert( gPagedSearchCache.pHashTbl, &pSearchRecord->Node, NULL); pSearchRecord->dwRefCount = 1; pSearchRecord->tLastClientRead = time(NULL); *ppSearchRec = pSearchRecord; cleanup: VmDirFreeBervalContent(&strFilter); return dwError; error: VmDirPagedSearchCacheRecordFree(pSearchRecord); goto cleanup; }