DWORD VmDirRESTObjectGet( void* pIn, void** ppOut ) { DWORD dwError = 0; PSTR pszTenant = NULL; PSTR pszDN = NULL; size_t skipped = 0; PVDIR_LDAP_CONTROL pPagedResultsCtrl = NULL; json_t* pjResult = NULL; PVDIR_REST_OPERATION pRestOp = NULL; PVDIR_OPERATION pSearchOp = NULL; if (!pIn) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } pRestOp = (PVDIR_REST_OPERATION)pIn; dwError = VmDirExternalOperationCreate( NULL, -1, LDAP_REQ_SEARCH, pRestOp->pConn, &pSearchOp); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRESTGetObjectGetParams( pRestOp, &pszTenant, &pSearchOp->request.searchReq.scope, &pSearchOp->request.searchReq.filter, &pSearchOp->request.searchReq.attrs, &pPagedResultsCtrl); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRESTDecodeObjectPathToDN( pRestOp->pszSubPath, pszTenant, &pszDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringToBervalContent(pszDN, &pSearchOp->reqDn); BAIL_ON_VMDIR_ERROR(dwError); pSearchOp->showPagedResultsCtrl = pPagedResultsCtrl; pSearchOp->request.searchReq.bStoreRsltInMem = TRUE; dwError = VmDirMLSearch(pSearchOp); BAIL_ON_VMDIR_ERROR(dwError); // set operation result dwError = VmDirRESTEncodeObjectArray( &pSearchOp->internalSearchEntryArray, pSearchOp->request.searchReq.attrs, pszTenant, &pjResult, &skipped); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRESTResultSetObjData(pRestOp->pResult, "result", pjResult); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRESTResultSetIntData( pRestOp->pResult, "result_count", pSearchOp->internalSearchEntryArray.iSize - skipped); BAIL_ON_VMDIR_ERROR(dwError); if (pPagedResultsCtrl) { VDIR_PAGED_RESULT_CONTROL_VALUE* pCtrl = &pPagedResultsCtrl->value.pagedResultCtrlVal; if (!IsNullOrEmptyString(pCtrl->cookie)) { dwError = VmDirRESTResultSetStrData( pRestOp->pResult, "paged_results_cookie", pCtrl->cookie); BAIL_ON_VMDIR_ERROR(dwError); } } cleanup: VMDIR_SET_REST_RESULT(pRestOp, pSearchOp, dwError, NULL); VMDIR_SAFE_FREE_MEMORY(pPagedResultsCtrl); VMDIR_SAFE_FREE_MEMORY(pszTenant); VMDIR_SAFE_FREE_MEMORY(pszDN); VmDirFreeOperation(pSearchOp); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); if (pjResult) { json_decref(pjResult); } goto cleanup; }
int VmDirPerformSearch( PVDIR_OPERATION pOperation ) { ber_len_t size = 0; SearchReq * sr = &(pOperation->request.searchReq); int retVal = LDAP_SUCCESS; BerValue* pLberBerv = NULL; PSTR pszLocalErrorMsg = NULL; BOOLEAN bResultAlreadySent = FALSE; PVDIR_LDAP_RESULT pResult = &(pOperation->ldapResult); // Parse base object, scope, deref alias, sizeLimit, timeLimit and typesOnly search parameters. if ( ber_scanf( pOperation->ber, "{miiiib", &(pOperation->reqDn.lberbv), &sr->scope, &sr->derefAlias, &sr->sizeLimit, &sr->timeLimit, &sr->attrsOnly ) == LBER_ERROR ) { VMDIR_LOG_ERROR( LDAP_DEBUG_ARGS, "PerformSearch: Decoding baseDN, ... attrsOnly error." ); pResult->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Decoding error while parsing baseDN, ... attrsOnly."); } VMDIR_LOG_VERBOSE( LDAP_DEBUG_ARGS, "Search Request: base: \"%s\", scope: %d, deref: %d, sizeLimit: %d, timeLimit: %d," "attrsOnly: %d", pOperation->reqDn.lberbv.bv_val, sr->scope, sr->derefAlias, sr->sizeLimit, sr->timeLimit, sr->attrsOnly); if (sr->scope != LDAP_SCOPE_BASE && sr->scope != LDAP_SCOPE_ONELEVEL && sr->scope != LDAP_SCOPE_SUBTREE) { pResult->errCode = retVal = LDAP_PROTOCOL_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Invalid scope" ); } if (sr->sizeLimit < 0 || sr->sizeLimit > LDAP_MAXINT) { pResult->errCode = retVal = LDAP_PROTOCOL_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Invalid size limit: %d", sr->sizeLimit ); } if (sr->timeLimit < 0 || sr->timeLimit > LDAP_MAXINT) { pResult->errCode = retVal = LDAP_PROTOCOL_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Invalid time limit: %d", sr->timeLimit ); } if (sr->derefAlias != LDAP_DEREF_NEVER && sr->derefAlias != LDAP_DEREF_SEARCHING && sr->derefAlias != LDAP_DEREF_FINDING && sr->derefAlias != LDAP_DEREF_ALWAYS) { pResult->errCode = retVal = LDAP_PROTOCOL_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Invalid dereference alias parameter"); } // Parse filter retVal = ParseFilter( pOperation, &sr->filter, pResult ); BAIL_ON_VMDIR_ERROR(retVal); // Log String filter, if desired. if (VmDirLogGetLevel() >= VMDIR_LOG_VERBOSE && VmDirLogGetMask() & LDAP_DEBUG_ARGS) { VDIR_BERVALUE strFilter = VDIR_BERVALUE_INIT; FilterToStrFilter( sr->filter, &strFilter ); VMDIR_LOG_VERBOSE( LDAP_DEBUG_ARGS, " Filter: %s", strFilter.lberbv.bv_val ); VmDirFreeBervalContent(&strFilter); } // Parse attributes. 'M' => attribute names point within (in-place) the ber. size = sizeof( BerValue ); // Size of the structure is passed-in, and number of attributes are returned back in // the same parameter. if ( ber_scanf( pOperation->ber, "{M}}", &pLberBerv, &size, 0 ) == LBER_ERROR ) { pResult->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Decoding error while parsing required attributes."); } // copy pLberBerv content into sr->attrs if (pLberBerv && size > 0) { int iCnt = 0; if (VmDirAllocateMemory(sizeof(VDIR_BERVALUE) * (size+1), (PVOID*)&sr->attrs) != 0) { pResult->errCode = retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "no memory"); } for (iCnt = 0; iCnt < size; iCnt++) { sr->attrs[iCnt].lberbv.bv_val = pLberBerv[iCnt].bv_val; sr->attrs[iCnt].lberbv.bv_len = pLberBerv[iCnt].bv_len; } } // Log list of the required attributes, if desired. if (( VmDirLogGetMask() & LDAP_DEBUG_ARGS) && size > 0) { if (VmDirLogSearchRequest(sr, size) != 0) { pResult->errCode = retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "Error while logging search request"); } } // Parse LDAP controls present (if any) in the request. retVal = ParseRequestControls(pOperation, pResult); // ldapResult.errCode set inside BAIL_ON_VMDIR_ERROR( retVal ); retVal = pResult->errCode = VmDirMLSearch( pOperation ); bResultAlreadySent = TRUE; BAIL_ON_VMDIR_ERROR(retVal); cleanup: VMDIR_SAFE_FREE_MEMORY(pLberBerv); VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return retVal; error: VMDIR_APPEND_ERROR_MSG(pResult->pszErrMsg, pszLocalErrorMsg); if (retVal != LDAP_NOTICE_OF_DISCONNECT && bResultAlreadySent == FALSE) { VmDirSendLdapResult( pOperation ); } goto cleanup; }