Example #1
0
/*
 * 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;
}
Example #2
0
/*
 * 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;
}
Example #3
0
/*
 * 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;
}
Example #4
0
/*
 * Tweak indices entry to append building flag to newly added values.
 * e.g. user add a new index attribute "myuid eq unique"
 * we want to save it as "myuid eq unique (buildingflag)" instead.
 */
DWORD
VdirIndexingEntryAppendFlag(
    VDIR_MODIFICATION*   pMods,
    PVDIR_ENTRY          pEntry)
{
    DWORD   dwError = 0;
    DWORD   dwCnt = 0;
    PSTR    pszNewStr = NULL;
    PVDIR_ATTRIBUTE  pAttr = NULL;

    assert(pMods && pEntry && pEntry->allocType == ENTRY_STORAGE_FORMAT_NORMAL);


    // unpack entry, so we can manipulate its contents.
    dwError = VmDirEntryUnpack(pEntry);
    BAIL_ON_VMDIR_ERROR(dwError);

    pAttr = VmDirFindAttrByName(pEntry, ATTR_INDEX_DESC);
    if (!pAttr)
    {
        dwError = ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++)
    {
        DWORD iIdx = 0;
        for (iIdx = 0; iIdx < pMods->attr.numVals; iIdx++)
        {
            if (0 == VmDirStringCompareA(pAttr->vals[dwCnt].lberbv.bv_val, pMods->attr.vals[iIdx].lberbv.bv_val, FALSE))
            {
                dwError = VmDirAllocateStringAVsnprintf(
                              &pszNewStr,
                              "%s %s",
                              pAttr->vals[dwCnt].lberbv.bv_val,
                              ATTR_INDEX_BUILDING_FLAG);
                BAIL_ON_VMDIR_ERROR(dwError);

                VmDirFreeBervalArrayContent(&pAttr->vals[dwCnt], 1);

                pAttr->vals[dwCnt].lberbv.bv_val = pszNewStr;
                pszNewStr = NULL;
                pAttr->vals[dwCnt].bOwnBvVal = TRUE;
                pAttr->vals[dwCnt].lberbv.bv_len = VmDirStringLenA(pAttr->vals[dwCnt].lberbv.bv_val);

                dwError = VmDirSchemaBervalNormalize(
                              pEntry->pSchemaCtx,
                              pAttr->pATDesc,
                              &pAttr->vals[dwCnt]);
                BAIL_ON_VMDIR_ERROR(dwError);
            }
        }
    }

cleanup:

    return dwError;

error:

    VMDIR_SAFE_FREE_MEMORY(pszNewStr);

    goto cleanup;
}
Example #5
0
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;
}
Example #6
0
/*
 * DelAttrValsFromEntryStruct: Deletes a complete attribute or specific attribute values from the entry.
 * Assumption: This function assumes/asserts that the modAttr does exist in the entry.
 *
 */
static
int
DelAttrValsFromEntryStruct(
   PVDIR_SCHEMA_CTX  pSchemaCtx,
   VDIR_ENTRY *      e,
   VDIR_ATTRIBUTE *  modAttr,
   PSTR*             ppszErrorMsg
   )
{
    int                 retVal = LDAP_SUCCESS;
    VDIR_ATTRIBUTE *    prevAttr = NULL;
    VDIR_ATTRIBUTE *    currAttr = NULL;
    VDIR_ATTRIBUTE *    eAttr = NULL;
    unsigned int        i = 0;
    unsigned int        j = 0;
    PSTR                pszLocalErrorMsg = NULL;

    assert(e->allocType == ENTRY_STORAGE_FORMAT_NORMAL);

    // Locate which attribute (values) we are trying to delete
    for (currAttr = e->attrs; currAttr != NULL; prevAttr = currAttr, currAttr = currAttr->next)
    {
        if (VmDirStringCompareA(modAttr->type.lberbv.bv_val, currAttr->type.lberbv.bv_val, FALSE) == 0)
        {
            break;
        }
    }

    assert(currAttr != NULL);

    eAttr = currAttr;

    // Normalize eAttr values
    for (i = 0; i < eAttr->numVals; i++)
    {
        retVal = VmDirSchemaBervalNormalize(pSchemaCtx, eAttr->pATDesc, &eAttr->vals[i]);
        BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                            "normalize (%s)(%.*s)",
                            VDIR_SAFE_STRING(eAttr->pATDesc->pszName),
                            VMDIR_MIN(eAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN),
                            VDIR_SAFE_STRING(eAttr->vals[i].lberbv.bv_val));
    }

    if (modAttr->numVals == 1 && eAttr->pATDesc->bSingleValue &&
        (VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_MODIFYTIMESTAMP, FALSE) == 0 ||
         VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_CREATETIMESTAMP, FALSE) == 0 ||
         VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_CREATORS_NAME, FALSE) == 0 ||
         VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_MODIFIERS_NAME, FALSE) == 0))
    {
        /* Force deleting the attribute value whether or not the value matches.
         * A raft follower may alter the timestamps/creator locally, e.g. rollback vmwAttrUniquenessScope,
         * which may fail to remove the value if it doesn't match that value seen  at the raft leader.
         */
        VmDirFreeBervalContent(&modAttr->vals[0]);
        modAttr->numVals = 0;
    }

    // Complete attribute is to be deleted.
    if (modAttr->numVals == 0)
    {
        // Make a copy of BerValues into modAttr so that these values can be used to delete from the index,
        // if it is an indexed attribute.

        VMDIR_SAFE_FREE_MEMORY(modAttr->vals);
        retVal = VmDirAllocateMemory((eAttr->numVals + 1) * sizeof(VDIR_BERVALUE), (PVOID *)&modAttr->vals);
        BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "no memory");

        for (i = 0; i < eAttr->numVals; i++)
        {
            VmDirBervalContentDup(&eAttr->vals[i], &modAttr->vals[i]);
        }
        modAttr->numVals = eAttr->numVals;

        // Adjust the "next" pointer of the attribute before the attribute being deleted. => Altering the attribute
        // chain.
        if (prevAttr == NULL) // if it is the first attribute
        {
            e->attrs = eAttr->next;
        }
        else
        {
            prevAttr->next = eAttr->next;
        }

        VmDirFreeAttribute(eAttr);
    }
    else // Specific attribute values need to be deleted.
    {
        // Check if all attribute values that are being deleted exist in the Attribute
        for (i=0; i < modAttr->numVals; i++)
        {
            // modAttr values are already normalized.
            assert(modAttr->vals[i].bvnorm_val);

            for (j = 0; j < eAttr->numVals; j++)
            {
                // eAttr values are already normalized.
                assert(eAttr->vals[j].bvnorm_val);

                if (modAttr->vals[i].bvnorm_len == eAttr->vals[j].bvnorm_len &&
                    memcmp(modAttr->vals[i].bvnorm_val, eAttr->vals[j].bvnorm_val, modAttr->vals[i].bvnorm_len) == 0)
                {
                    break;
                }
            }
            if (j == eAttr->numVals) // did not find a match
            {
                retVal = VMDIR_ERROR_NO_SUCH_ATTRIBUTE;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                                        "Attribute (%s) value (%.*s) being deleted does not exist.",
                                        VDIR_SAFE_STRING(modAttr->type.lberbv.bv_val),
                                        VMDIR_MIN(modAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN),
                                        VDIR_SAFE_STRING(modAttr->vals[i].lberbv.bv_val));
            }
        }
        // All values are being deleted. => Delete the whole attribute
        if (modAttr->numVals == eAttr->numVals)
        {
            // Adjust the "next" pointer of the attribute before the attribute being deleted. => Altering the attribute
            // chain.
            if (prevAttr == NULL) // if it is the first attribute
            {
                e->attrs = eAttr->next;
            }
            else
            {
                prevAttr->next = eAttr->next;
            }
            VmDirFreeAttribute(eAttr);
        }
        else
        {
            RemoveAttrVals(eAttr, modAttr);
        }
    }

cleanup:

    if (ppszErrorMsg)
    {
        *ppszErrorMsg = pszLocalErrorMsg;
    }
    else
    {
        VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    }

    return retVal;

error:
    goto cleanup;
}
Example #7
0
static
int
CheckIfAnAttrValAlreadyExists(
    PVDIR_SCHEMA_CTX  pSchemaCtx,
    VDIR_ATTRIBUTE *  eAttr,
    VDIR_ATTRIBUTE *  modAttr,
    PSTR*             ppszErrorMsg
    )
{
    int retVal = LDAP_SUCCESS;
    unsigned int i = 0;
    unsigned int j = 0;
    PSTR    pszLocalErrorMsg = NULL;

    for (i=0; i < eAttr->numVals; i++)
    {
        retVal = VmDirSchemaBervalNormalize(pSchemaCtx, modAttr->pATDesc, // Assumption: modAttr type is same as eAttr type
                                              &eAttr->vals[i]) ;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                                "normalize (%s)(%.*s)",
                                VDIR_SAFE_STRING(modAttr->pATDesc->pszName),
                                VMDIR_MIN(eAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN),
                                VDIR_SAFE_STRING(eAttr->vals[i].lberbv.bv_val));

        for (j = 0; j < modAttr->numVals; j++)
        {
            // modAttr values are already normalized.
            assert(modAttr->vals[j].bvnorm_val);

            if (eAttr->vals[i].bvnorm_len == modAttr->vals[j].bvnorm_len &&
                memcmp(eAttr->vals[i].bvnorm_val, modAttr->vals[j].bvnorm_val, modAttr->vals[j].bvnorm_len) == 0)
            {
                break;
            }
        }
        if (j != modAttr->numVals) // found a match in middle
        {
            retVal = VMDIR_ERROR_TYPE_OR_VALUE_EXISTS;
            BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg),
                                    "Attribute (%s) value (%.*s) exists",
                                    VDIR_SAFE_STRING(modAttr->pATDesc->pszName),
                                    VMDIR_MIN(eAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN),
                                    VDIR_SAFE_STRING(eAttr->vals[i].lberbv.bv_val));
        }
    }

cleanup:

    if (ppszErrorMsg)
    {
        *ppszErrorMsg = pszLocalErrorMsg;
    }
    else
    {
        VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    }

    return retVal;

error:
    goto cleanup;
}