/* * Numeric ordering attribute has matching rule integerMatch or integerOrderingMatch */ BOOLEAN VmDirSchemaAttrHasIntegerMatchingRule( PVDIR_SCHEMA_CTX pCtx, PCSTR pszName ) { DWORD dwError = 0; BOOLEAN bIsNumericOrdering = FALSE; PVDIR_SCHEMA_AT_DESC pATDesc = NULL; if (pCtx && pszName) { pATDesc = VmDirSchemaAttrNameToDesc(pCtx,pszName); if (!pATDesc) { dwError = ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR(dwError); } if ((pATDesc->pszEqualityMRName && VmDirStringCompareA(pATDesc->pszEqualityMRName, VDIR_MATCHING_RULE_INTEGER_MATCH, FALSE) == 0) || (pATDesc->pszOrderingMRName && VmDirStringCompareA(pATDesc->pszOrderingMRName, VDIR_MATCHING_RULE_INTEGER_ORDERING_MATCH, FALSE) == 0) ) { bIsNumericOrdering = TRUE; } } error: return bIsNumericOrdering; }
DWORD VmDirSchemaCheckSetAttrDesc( PVDIR_SCHEMA_CTX pCtx, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; VDIR_ATTRIBUTE* pAttr = NULL; assert(pCtx && pEntry); for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { if (!pAttr->pATDesc) { if (VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_VMW_ORGANIZATION_GUID, FALSE ) == 0) { continue; // going to delete this attribute any way. } if (VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_VMW_OBJECT_SECURITY_DESCRIPTOR, FALSE ) == 0) { pAttr->pATDesc = VmDirSchemaAttrNameToDesc(pCtx, ATTR_OBJECT_SECURITY_DESCRIPTOR); } else { pAttr->pATDesc = VmDirSchemaAttrNameToDesc(pCtx, pAttr->type.lberbv.bv_val); } if (!pAttr->pATDesc) { pCtx->dwErrorCode = ERROR_INVALID_SCHEMA; VMDIR_SAFE_FREE_MEMORY(pCtx->pszErrorMsg); dwError = VmDirAllocateStringAVsnprintf( &pCtx->pszErrorMsg, "Attribute (%s) is not defined in schema", VDIR_SAFE_STRING(pAttr->type.lberbv.bv_val)); dwError = ERROR_INVALID_SCHEMA; BAIL_ON_VMDIR_ERROR(dwError); } } } error: return dwError; }
/* * Create an Attribute on the heap and establish its pATDesc * two memory allocate * 1. pAttribute * 2. pAttribute->vals (BerValue array is one more then requested) */ DWORD VmDirAttributeAllocate( PCSTR pszName, USHORT usBerSize, PVDIR_SCHEMA_CTX pCtx, PVDIR_ATTRIBUTE* ppOutAttr) { DWORD dwError = 0; PVDIR_ATTRIBUTE pAttr = NULL; if (!ppOutAttr) { return 0; } dwError = VmDirAllocateMemory( sizeof(VDIR_ATTRIBUTE), (PVOID*)&pAttr); BAIL_ON_VMDIR_ERROR(dwError); // add one more BerValue as Encode/Decode entry in data store layer needs it. dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (usBerSize + 1), (PVOID*)&pAttr->vals); BAIL_ON_VMDIR_ERROR(dwError); pAttr->numVals = usBerSize; pAttr->pATDesc = VmDirSchemaAttrNameToDesc( pCtx, pszName); if (!pAttr->pATDesc) { dwError = VMDIR_ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR(dwError); } // pAttr->type.lberbv.bv_val always store in-place pAttr->type.lberbv.bv_val = pAttr->pATDesc->pszName; pAttr->type.lberbv.bv_len = VmDirStringLenA(pAttr->type.lberbv.bv_val); *ppOutAttr = pAttr; cleanup: return dwError; error: if (pAttr) { VmDirFreeAttribute(pAttr); } VmDirLog( LDAP_DEBUG_ANY, "AllocateAttribute failed (%d)(%s)", dwError, VDIR_SAFE_STRING(pszName)); goto cleanup; }
DWORD VmDirAppendAMod( PVDIR_OPERATION pOperation, int modOp, char * attrName, int attrNameLen, char * attrVal, size_t attrValLen ) { DWORD dwError = 0; VDIR_MODIFICATION * mod = NULL; ModifyReq * modReq = &(pOperation->request.modifyReq); VmDirLog( LDAP_DEBUG_TRACE, "appendAMod: Begin, entry DN = %s", modReq->dn.lberbv.bv_val ); dwError = VmDirAllocateMemory( sizeof( VDIR_MODIFICATION ), (PVOID *)&(mod) ); BAIL_ON_VMDIR_ERROR( dwError ); mod->operation = modOp; mod->attr.next = NULL; if ((mod->attr.pATDesc = VmDirSchemaAttrNameToDesc( pOperation->pSchemaCtx, attrName)) == NULL) { VmDirLog( LDAP_DEBUG_ANY, "appendAMod: VmDirSchemaAttrNameToDesc failed."); dwError = -1; /* Any value except 0 should do. */ BAIL_ON_VMDIR_ERROR( dwError ); } mod->attr.type.lberbv.bv_val = mod->attr.pATDesc->pszName; mod->attr.type.lberbv.bv_len = VmDirStringLenA(mod->attr.pATDesc->pszName); dwError = VmDirAllocateMemory( 2 * sizeof( VDIR_BERVALUE ), (PVOID *)&(mod->attr.vals) ); BAIL_ON_VMDIR_ERROR( dwError ); if ( attrVal && attrValLen > 0 ) { dwError = VmDirAllocateMemory( attrValLen + 1, (PVOID *)&(mod->attr.vals[0].lberbv.bv_val) ); BAIL_ON_VMDIR_ERROR( dwError ); dwError = VmDirCopyMemory( mod->attr.vals[0].lberbv.bv_val, attrValLen + 1, attrVal, attrValLen); BAIL_ON_VMDIR_ERROR( dwError ); mod->attr.vals[0].lberbv.bv_len = attrValLen; mod->attr.vals[0].bOwnBvVal = TRUE; mod->attr.numVals = 1; } mod->next = modReq->mods; modReq->mods = mod; modReq->numMods++; cleanup: VmDirLog( LDAP_DEBUG_TRACE, "appendAMod: End." ); return dwError; error: goto cleanup; }
/* * NormalizeMods: * 1. Normalize attribute values present in the modifications list. * 2. Make sure no duplicate value */ int VmDirNormalizeMods( PVDIR_SCHEMA_CTX pSchemaCtx, PVDIR_MODIFICATION pMods, PSTR* ppszErrorMsg ) { int retVal = LDAP_SUCCESS; PVDIR_MODIFICATION pMod = NULL; unsigned int i = 0; PSTR pszDupAttributeName = NULL; PSTR pszLocalErrorMsg = NULL; for (pMod = pMods; pMod != NULL; pMod = pMod->next) { if (pMod->attr.pATDesc == NULL && (pMod->attr.pATDesc = VmDirSchemaAttrNameToDesc(pSchemaCtx, pMod->attr.type.lberbv.bv_val)) == NULL ) { retVal = VMDIR_ERROR_UNDEFINED_TYPE; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "Undefined attribute (%s)", VDIR_SAFE_STRING(pMod->attr.type.lberbv.bv_val)); } for (i=0; i < pMod->attr.numVals; i++) { retVal = VmDirSchemaBervalNormalize(pSchemaCtx, pMod->attr.pATDesc, &pMod->attr.vals[i]); BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "attribute value normalization failed (%s)(%.*s)", VDIR_SAFE_STRING(pMod->attr.pATDesc->pszName), VMDIR_MIN(pMod->attr.vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN), VDIR_SAFE_STRING(pMod->attr.vals[i].lberbv.bv_val)); } // Make sure we have no duplicate value in mod->attr retVal = VmDirAttributeDupValueCheck(&pMod->attr, &pszDupAttributeName); BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "attribute (%s) has duplicate value", VDIR_SAFE_STRING(pszDupAttributeName)); } cleanup: if (ppszErrorMsg) { *ppszErrorMsg = pszLocalErrorMsg; } else { VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); } return retVal; error: goto cleanup; }
/* * Convenient function to add a single attribute to pMod. * * Currently, only handle adding content to EMPTY pMod->attr and use with * pMod->operation = MOD_OP_REPLACE or MOD_OP_ADD or MOD_OP_DELETE * to manipulate ONE attribute value * */ DWORD VmDirModAddSingleValueAttribute( PVDIR_MODIFICATION pMod, PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszAttrName, PCSTR pszAttrValue, size_t iAttrValueLen ) { DWORD dwError = 0; if (!pMod || pMod->attr.pATDesc || pMod->attr.vals || !pSchemaCtx || !pszAttrName || !pszAttrValue || iAttrValueLen < 1) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // add one more BerValue as Encode/Decode entry in data store layer needs it. dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (1 + 1), (PVOID*)&pMod->attr.vals); BAIL_ON_VMDIR_ERROR(dwError); pMod->attr.numVals = 1; pMod->attr.pATDesc = VmDirSchemaAttrNameToDesc(pSchemaCtx, pszAttrName); if (!pMod->attr.pATDesc) { dwError = ERROR_NO_SCHEMA; BAIL_ON_VMDIR_ERROR(dwError); } // pAttr->type.lberbv.bv_val always store in-place pMod->attr.type.lberbv.bv_val = pMod->attr.pATDesc->pszName; pMod->attr.type.lberbv.bv_len = VmDirStringLenA(pMod->attr.type.lberbv.bv_val); dwError = VmDirAllocateMemory( iAttrValueLen + 1, // want string null terminated. (PVOID*)&pMod->attr.vals[0].lberbv.bv_val ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirCopyMemory( pMod->attr.vals[0].lberbv.bv_val, iAttrValueLen + 1, (PCVOID)pszAttrValue, iAttrValueLen ); BAIL_ON_VMDIR_ERROR(dwError); pMod->attr.vals[0].bOwnBvVal = TRUE; pMod->attr.vals[0].lberbv.bv_len = iAttrValueLen; cleanup: return dwError; error: // pMod owns the memory allocated in this function. goto cleanup; }
USHORT VmDirSchemaAttrNameToId( PVDIR_SCHEMA_CTX pCtx, PCSTR pszName ) { PVDIR_SCHEMA_AT_DESC pResult = VmDirSchemaAttrNameToDesc(pCtx,pszName); return pResult ? pResult->usAttrID : NO_ATTR_ID_MAP; }
/* * This is NOT RFC 4514 compliance. * * 1. separate into RDNs * 2. for each RDN, normalize value based on its syntax * (does not handle multi-value RDN case) * remove all leading/trailing spaces * 3. reconstruct DN based on RDNs */ DWORD VmDirNormalizeDN( PVDIR_BERVALUE pBerv, PVDIR_SCHEMA_CTX pSchemaCtx ) { DWORD dwError = 0; PSTR pszTmpDN = NULL; PSTR* ppszRDNs = NULL; PSTR* ppszNormRDNs = NULL; int iNumRDNs = 0; int iCnt = 0; size_t iNormDNSize = 0; PVDIR_SCHEMA_CTX pCtx = pSchemaCtx; if (!pBerv || !pBerv->lberbv.bv_val) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // Already normalized. => Nothing to be done. if ( pBerv->bvnorm_val != NULL ) { dwError = 0; goto cleanup; } // Nothing to be normalized for the ROOT DN if (pBerv->lberbv.bv_len == 0) { pBerv->bvnorm_val = pBerv->lberbv.bv_val; pBerv->bvnorm_len = 0; dwError = 0; goto cleanup; } if (pCtx == NULL) { dwError = VmDirSchemaCtxAcquire(&pCtx); BAIL_ON_VMDIR_ERROR(dwError); } // make a local copy dwError = VmDirAllocateStringA( pBerv->lberbv.bv_val, &pszTmpDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VdirSchemaInPlaceDN2RDNs( pszTmpDN, &ppszRDNs, &iNumRDNs); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateMemory( sizeof(PSTR) * (iNumRDNs + 1), (PVOID)&ppszNormRDNs); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt=0; ppszRDNs[iCnt] && iCnt < iNumRDNs; iCnt++) { size_t iNameLen = 0 ; VDIR_BERVALUE berval = VDIR_BERVALUE_INIT; PVDIR_SCHEMA_AT_DESC pATDesc = NULL; char* pChar = VmDirStringChrA(ppszRDNs[iCnt], '='); if (!pChar) { dwError = ERROR_INVALID_DN; BAIL_ON_VMDIR_ERROR(dwError); } *pChar = '\0'; iNameLen = VmDirStringLenA(ppszRDNs[iCnt]); // attribute name - remove all leading/trailing spaces while (ppszRDNs[iCnt][iNameLen-1] == ' ') { ppszRDNs[iCnt][iNameLen-1] = '\0'; iNameLen--; assert(iNameLen > 0); // MIN 1 char for name } while (ppszRDNs[iCnt][0] == ' ') { ppszRDNs[iCnt]++; } pATDesc = VmDirSchemaAttrNameToDesc(pCtx, ppszRDNs[iCnt]); if (!pATDesc) { dwError = ERROR_INVALID_DN; BAIL_ON_VMDIR_ERROR(dwError); } berval.lberbv.bv_val = pChar+1; berval.lberbv.bv_len = VmDirStringLenA(berval.lberbv.bv_val); dwError = VmDirSchemaBervalNormalize(pCtx, pATDesc, &berval); BAIL_ON_VMDIR_ERROR(dwError); if (berval.bvnorm_len == 0) { dwError = ERROR_INVALID_DN; BAIL_ON_VMDIR_ERROR(dwError); } if (berval.lberbv.bv_val == berval.bvnorm_val) { dwError = VmDirAllocateStringA( berval.lberbv.bv_val, &ppszNormRDNs[iCnt]); BAIL_ON_VMDIR_ERROR(dwError); } else { // ppszNormRDNs takes over bvnorm_val ppszNormRDNs[iCnt] = berval.bvnorm_val; } iNormDNSize = iNormDNSize + berval.bvnorm_len + (pChar - ppszRDNs[iCnt]) + 2; } // Reconstruct normalized DN VMDIR_SAFE_FREE_MEMORY(pBerv->bvnorm_val); pBerv->bvnorm_len = 0; dwError = VmDirAllocateMemory( sizeof(char) * (iNormDNSize+1), (PVOID)&pBerv->bvnorm_val); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt = 0; ppszNormRDNs[iCnt] && iCnt < iNumRDNs; iCnt++) { size_t iValueLen = VmDirStringLenA(ppszNormRDNs[iCnt]); int iValueOffset = 0; // attribute value - remove leading/trailing spaces while (ppszNormRDNs[iCnt][iValueOffset] == ' ') { iValueOffset++; assert(iValueOffset < iValueLen); } while (ppszNormRDNs[iCnt][iValueLen-1] == ' ') { ppszNormRDNs[iCnt][iValueLen-1] = '\0'; iValueLen--; assert(iValueLen > 0); } // attribute name to lower case { char* pToLower = NULL; for (pToLower = ppszRDNs[iCnt]; *pToLower != '\0'; pToLower++) { *pToLower = (char) tolower(*pToLower); } } VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ppszRDNs[iCnt]); VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), "="); VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ppszNormRDNs[iCnt]+iValueOffset); if (iCnt + 1 < iNumRDNs) { VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ","); } } pBerv->bvnorm_len = VmDirStringLenA(pBerv->bvnorm_val); cleanup: if (pCtx && pCtx != pSchemaCtx) { VmDirSchemaCtxRelease(pCtx); } VMDIR_SAFE_FREE_MEMORY(pszTmpDN); VMDIR_SAFE_FREE_MEMORY(ppszRDNs); // ppszRDNs[i] is in place of pszTmpDN VmDirFreeStringArrayA(ppszNormRDNs); VMDIR_SAFE_FREE_MEMORY(ppszNormRDNs); return dwError; error: goto cleanup; }
/* * Add a ModifyRequest to pOperation with- * 1. modOp * 2. create attribute with values from pBerValue * * i.e. this function call is equivalent of a modify section in LDIF file * changetype: modify * add/delete/replace: attributeXYZ <<<<<<<<<<<<<<<< modOp * attributeXYZ: value1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<< pBervalue * attributeXYZ: valueN <<<<<<<<<<<<<<<<<<<<<<<<<<<<< iBerValueSize */ DWORD VmDirOperationAddModReq( PVDIR_OPERATION pOperation, int modOp, char * pszAttrName, PVDIR_BERVALUE pBerValue, size_t iBerValueSize ) { DWORD dwError = 0; PSTR pszLocalErrMsg = NULL; VDIR_MODIFICATION * pMod = NULL; ModifyReq * pModReq = &(pOperation->request.modifyReq); size_t iCnt = 0; if ( !pOperation || !pszAttrName || !pBerValue ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocateMemory( sizeof( *pMod ), (PVOID *)&(pMod) ); BAIL_ON_VMDIR_ERROR( dwError ); pMod->operation = modOp; pMod->attr.next = NULL; pMod->attr.pATDesc = VmDirSchemaAttrNameToDesc( pOperation->pSchemaCtx, pszAttrName); if ( !pMod->attr.pATDesc ) { dwError = ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "attibute (%s) not defined", pszAttrName ); } // attribute.type.lberbv use (schema cache) inplace memory (we don't fee it). pMod->attr.type.lberbv.bv_val = pMod->attr.pATDesc->pszName; pMod->attr.type.lberbv.bv_len = VmDirStringLenA(pMod->attr.pATDesc->pszName); dwError = VmDirAllocateMemory( sizeof( VDIR_BERVALUE ) * (iBerValueSize + 1 ), (PVOID *)&(pMod->attr.vals) ); BAIL_ON_VMDIR_ERROR( dwError ); for (iCnt = 0; iCnt < iBerValueSize; iCnt++) { dwError = VmDirAllocateAndCopyMemory( pBerValue[iCnt].lberbv_val, pBerValue[iCnt].lberbv_len, (PVOID *)&(pMod->attr.vals[iCnt].lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); pMod->attr.vals[iCnt].lberbv.bv_len = pBerValue[iCnt].lberbv_len; pMod->attr.vals[iCnt].bOwnBvVal = TRUE; pMod->attr.numVals++; } pMod->next = pModReq->mods; pModReq->mods = pMod; // pOpeartion->request.modifyRequest takes over pMod pModReq->numMods++; cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return dwError; error: if (pMod) { VmDirModificationFree( pMod ); } VMDIR_SET_LDAP_RESULT_ERROR( &(pOperation->ldapResult), dwError, pszLocalErrMsg ); goto cleanup; }
/* * TODO, to generalize, we should create a strToFilter(pszFilter, &pOutFilter); */ DWORD VmDirSimpleEqualFilterInternalSearch( PCSTR pszBaseDN, int searchScope, PCSTR pszAttrName, PCSTR pszAttrValue, PVDIR_ENTRY_ARRAY pEntryArray ) { DWORD dwError = 0; VDIR_OPERATION searchOP = {0}; VDIR_BERVALUE bervDN = VDIR_BERVALUE_INIT; PVDIR_FILTER pFilter = NULL; if ( !pszBaseDN || !pszAttrName || !pszAttrValue || !pEntryArray ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } 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 = VmDirAllocateMemory( sizeof( VDIR_FILTER ), (PVOID*)&pFilter ); BAIL_ON_VMDIR_ERROR(dwError); pFilter->choice = LDAP_FILTER_EQUALITY; pFilter->filtComp.ava.type.lberbv.bv_val = (PSTR)pszAttrName; pFilter->filtComp.ava.type.lberbv.bv_len = VmDirStringLenA(pszAttrName); pFilter->filtComp.ava.pATDesc = VmDirSchemaAttrNameToDesc( searchOP.pSchemaCtx, pszAttrName); if (pFilter->filtComp.ava.pATDesc == NULL) { dwError = VMDIR_ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR( dwError ); } pFilter->filtComp.ava.value.lberbv.bv_val = (PSTR)pszAttrValue; pFilter->filtComp.ava.value.lberbv.bv_len = VmDirStringLenA(pszAttrValue); dwError = VmDirSchemaBervalNormalize( // TODO, may want to have filter code to do this? searchOP.pSchemaCtx, // so caller does not have to handle this. pFilter->filtComp.ava.pATDesc, &(pFilter->filtComp.ava.value) ); BAIL_ON_VMDIR_ERROR(dwError); pFilter->next = NULL; } //TODO, ideally, we should take pszFilter and dwError = VmDirStrToFilter(pszFilter, &pFilter); searchOP.request.searchReq.filter = pFilter; pFilter = NULL; // search request takes over pFilter 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; cleanup: VmDirFreeOperationContent(&searchOP); if (pFilter) { DeleteFilter(pFilter); } return dwError; error: goto cleanup; }
static int DeleteRefAttributesValue( VDIR_OPERATION * pOperation, VDIR_BERVALUE * dn ) { int retVal = LDAP_SUCCESS; VDIR_FILTER * f = NULL; VDIR_CANDIDATES * cl = NULL; VDIR_ENTRY groupEntry = {0}; VDIR_ENTRY * pGroupEntry = NULL; int i = 0; VDIR_MODIFICATION mod = {0}; ModifyReq mr; VDIR_BERVALUE delVals[2]; PSTR pszLocalErrorMsg = NULL; assert( pOperation != NULL && pOperation->pBEIF != NULL && dn != NULL); retVal = VmDirNormalizeDN( dn, pOperation->pSchemaCtx ); BAIL_ON_VMDIR_ERROR( retVal ); // Set filter retVal = VmDirAllocateMemory( sizeof( VDIR_FILTER ), (PVOID *)&f); BAIL_ON_VMDIR_ERROR( retVal ); f->choice = LDAP_FILTER_EQUALITY; f->filtComp.ava.type.lberbv.bv_val = ATTR_MEMBER; f->filtComp.ava.type.lberbv.bv_len = ATTR_MEMBER_LEN; f->filtComp.ava.value = *dn; if ((f->filtComp.ava.pATDesc = VmDirSchemaAttrNameToDesc( pOperation->pSchemaCtx, ATTR_MEMBER)) == NULL) { retVal = VMDIR_ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "undefined attribute (%s)", VDIR_SAFE_STRING(ATTR_MEMBER)); } // Set ModifyReq structure memset(&mr, 0, sizeof(ModifyReq)); mod.operation = MOD_OP_DELETE; mod.attr.type.lberbv.bv_val = ATTR_MEMBER; mod.attr.type.lberbv.bv_len = ATTR_MEMBER_LEN; mod.attr.pATDesc = f->filtComp.ava.pATDesc; mod.attr.next = NULL; delVals[0] = *dn; memset(&(delVals[1]), 0, sizeof(VDIR_BERVALUE)); mod.attr.vals = delVals; mod.attr.numVals = 1; mod.next = NULL; mr.mods = &mod; mr.numMods = 1; retVal = pOperation->pBEIF->pfnBEGetCandidates( pOperation->pBECtx, f); if ( retVal != 0 ) { if (retVal == VMDIR_ERROR_BACKEND_ENTRY_NOTFOUND) { retVal = LDAP_SUCCESS; // no member refer to this DN. return ok/0 } else { retVal = VMDIR_ERROR_GENERIC; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "DeleteRefAttributesValue: Building group list (BdbGetCandidates()) failed."); } } else { cl = f->candidates; for (i = 0; i < cl->size; i++) { pGroupEntry = &groupEntry; if ((retVal = VmDirModifyEntryCoreLogic( pOperation, &mr, cl->eIds[i], pGroupEntry)) != 0) { switch (retVal) { case VMDIR_ERROR_BACKEND_PARENT_NOTFOUND: case VMDIR_ERROR_BACKEND_ENTRY_NOTFOUND: case VMDIR_ERROR_ENTRY_NOT_FOUND: continue; default: // Including LDAP_LOCK_DEADLOCK, which is handled by the caller BAIL_ON_VMDIR_ERROR( retVal ); } } VmDirFreeBervalContent( &(mr.dn) ); // VmDirModifyEntryCoreLogic fill in DN if not exists VmDirFreeEntryContent( pGroupEntry ); pGroupEntry = NULL; // Reset to NULL so that DeleteEntry is no-op. } } cleanup: memset(&(f->filtComp.ava.value), 0, sizeof(VDIR_BERVALUE)); // Since ava.value is NOT owned by filter. DeleteFilter( f ); VmDirFreeEntryContent( pGroupEntry ); VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return retVal; error: VMDIR_APPEND_ERROR_MSG(pOperation->ldapResult.pszErrMsg, pszLocalErrorMsg); goto cleanup; }
static int LoadReplicationAgreements() { // Load my Replication Agreements VDIR_OPERATION op = {0}; PVDIR_FILTER replAgrFilter = NULL; DWORD dwError = 0; int iCnt = 0; VmDirLog( LDAP_DEBUG_TRACE, "LoadReplicationAgreements: Begin" ); if ( gVmdirServerGlobals.serverObjDN.lberbv.bv_val != NULL ) { dwError = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL ); BAIL_ON_VMDIR_ERROR(dwError); op.pBEIF = VmDirBackendSelect( gVmdirServerGlobals.serverObjDN.lberbv.bv_val ); assert(op.pBEIF); if (VmDirBervalContentDup( &gVmdirServerGlobals.serverObjDN, &op.reqDn ) != 0) { VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: BervalContentDup failed." ); dwError = -1; BAIL_ON_VMDIR_ERROR( dwError ); } op.request.searchReq.scope = LDAP_SCOPE_SUBTREE; if (VmDirAllocateMemory( sizeof( VDIR_FILTER ), (PVOID *)&replAgrFilter ) != 0) { VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: VmDirAllocateMemory failed. " ); dwError = -1; BAIL_ON_VMDIR_ERROR( dwError ); } op.request.searchReq.filter = replAgrFilter; replAgrFilter->choice = LDAP_FILTER_EQUALITY; replAgrFilter->filtComp.ava.type.lberbv.bv_val = ATTR_OBJECT_CLASS; replAgrFilter->filtComp.ava.type.lberbv.bv_len = ATTR_OBJECT_CLASS_LEN; if ((replAgrFilter->filtComp.ava.pATDesc = VmDirSchemaAttrNameToDesc( op.pSchemaCtx, replAgrFilter->filtComp.ava.type.lberbv.bv_val)) == NULL) { dwError = -1; VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: Getting pATDesc for ATTR_OBJECT_CLASS failed " "(hmm... STRANGE). " ); BAIL_ON_VMDIR_ERROR( dwError ); } replAgrFilter->filtComp.ava.value.lberbv.bv_val = OC_REPLICATION_AGREEMENT; replAgrFilter->filtComp.ava.value.lberbv.bv_len = OC_REPLICATION_AGREEMENT_LEN; if (VmDirSchemaBervalNormalize( op.pSchemaCtx, replAgrFilter->filtComp.ava.pATDesc, &(replAgrFilter->filtComp.ava.value) ) != LDAP_SUCCESS) { dwError = -1; VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: Attribute value normalization failed for " "filter type = %s", replAgrFilter->filtComp.ava.type.lberbv.bv_val ); BAIL_ON_VMDIR_ERROR( dwError ); } replAgrFilter->next = NULL; if ((dwError = VmDirInternalSearch( &op )) != 0) { VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: InternalSearch for Replication Agreements failed. " "Error code: %d, Error string: %s", dwError, VDIR_SAFE_STRING(op.ldapResult.pszErrMsg)); dwError = -1; BAIL_ON_VMDIR_ERROR( dwError ); } // load all replication agreements for (iCnt=0; iCnt < op.internalSearchEntryArray.iSize; iCnt++) { dwError = ProcessReplicationAgreementEntry( op.internalSearchEntryArray.pEntry + iCnt ); BAIL_ON_VMDIR_ERROR( dwError ); } VmDirPopulateInvocationIdInReplAgr(); } cleanup: VmDirFreeOperationContent(&op); VmDirLog( LDAP_DEBUG_TRACE, "LoadReplicationAgreements: End" ); return dwError; error: goto cleanup; }
/* * Mod request sanity check * 1. modify attribute is defined * 2. attribute can be modified (we only enforce this for external operation) */ static int _VmDirExternalModsSanityCheck( PVDIR_OPERATION pOp, PVDIR_MODIFICATION pMods ) { int retVal = LDAP_SUCCESS; PSTR pszLocalErrMsg = NULL; PVDIR_MODIFICATION pLocalMod = NULL; for (pLocalMod = pMods; pLocalMod != NULL; pLocalMod = pLocalMod->next) { if (pLocalMod->attr.pATDesc == NULL && (pLocalMod->attr.pATDesc = VmDirSchemaAttrNameToDesc(pOp->pSchemaCtx, pLocalMod->attr.type.lberbv.bv_val)) == NULL ) { retVal = VMDIR_ERROR_UNDEFINED_TYPE; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrMsg), "Undefined attribute (%s)", VDIR_SAFE_STRING(pLocalMod->attr.type.lberbv.bv_val)); } // Make sure attribute can be modified if (pLocalMod->attr.pATDesc->bNoUserModifiable == TRUE && pOp->conn->AccessInfo.bindEID != DEFAULT_ADMINISTRATOR_ENTRY_ID // exempt default administrator ) { retVal = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrMsg), "attribute (%s) can not be modified", VDIR_SAFE_STRING(pLocalMod->attr.pATDesc->pszName)); } if (pLocalMod->operation == MOD_OP_ADD || pLocalMod->operation == MOD_OP_REPLACE) { // ADD or REPLACE principal name, validate its syntax. if (VmDirStringCompareA(pLocalMod->attr.type.lberbv_val, ATTR_KRB_UPN, FALSE) == 0 || VmDirStringCompareA(pLocalMod->attr.type.lberbv_val, ATTR_KRB_SPN, FALSE) == 0) { retVal = VmDirValidatePrincipalName(&(pLocalMod->attr), &pszLocalErrMsg); BAIL_ON_VMDIR_ERROR(retVal); } else if (VmDirStringCompareA(pLocalMod->attr.type.lberbv_val, ATTR_OBJECT_SECURITY_DESCRIPTOR, FALSE) == 0) { BOOLEAN bReturn = FALSE; bReturn = VmDirValidRelativeSecurityDescriptor( (PSECURITY_DESCRIPTOR_RELATIVE)pLocalMod->attr.vals[0].lberbv_val, (ULONG)pLocalMod->attr.vals[0].lberbv_len, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION); if (!bReturn) { retVal = VMDIR_ERROR_BAD_ATTRIBUTE_DATA; BAIL_ON_VMDIR_ERROR(retVal); } } } else if (pLocalMod->operation == MOD_OP_DELETE) { if (VmDirStringCompareA(pLocalMod->attr.type.lberbv_val, ATTR_OBJECT_SECURITY_DESCRIPTOR, FALSE) == 0) { retVal = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION; BAIL_ON_VMDIR_ERROR(retVal); } } } cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return retVal; error: VMDIR_SET_LDAP_RESULT_ERROR(&(pOp->ldapResult), retVal, pszLocalErrMsg); goto cleanup; }