DWORD
VmDirDDVectorInit(
    VOID
    )
{
    DWORD   dwError = 0;

    dwError = VmDirAllocateMemory(
            sizeof(VMDIR_REPL_DEADLOCKDETECTION_VECTOR),
            (PVOID*)&gVmdirServerGlobals.pReplDeadlockDetectionVector);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(
            &gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateMutex(
            &gVmdirServerGlobals.pReplDeadlockDetectionVector->pMutex);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #2
0
DWORD
VmDirSchemaAttrIdMapInit(
    PVDIR_SCHEMA_ATTR_ID_MAP*   ppAttrIdMap
    )
{
    DWORD   dwError = 0;
    PVDIR_SCHEMA_ATTR_ID_MAP    pAttrIdMap = NULL;

    if (!ppAttrIdMap)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateMemory(
            sizeof(VDIR_SCHEMA_ATTR_ID_MAP),
            (PVOID*)&pAttrIdMap);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pAttrIdMap->pStoredIds,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pAttrIdMap->pNewIds,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    pAttrIdMap->usNextId = MAX_RESERVED_ATTR_ID_MAP + 1;

    *ppAttrIdMap = pAttrIdMap;

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    VmDirFreeSchemaAttrIdMap(pAttrIdMap);
    goto cleanup;
}
Beispiel #3
0
DWORD
VmDirSuperLogGetTable(
    PVMDIR_SUPERLOG_ENTRY_LDAPOPERATION_ARRAY pEntries,
    PVMDIR_SUPERLOG_TABLE_COLUMN_SET pColumnSet,
    PVMDIR_SUPERLOG_TABLE *ppTable
    )
{
    DWORD                   dwError     = 0;
    PLW_HASHMAP             pHashMap    = NULL;
    PVMDIR_SUPERLOG_TABLE   pTable      = NULL;

    dwError = LwRtlCreateHashMap(
            &pHashMap,
            LwRtlHashDigestPstr,
            LwRtlHashEqualPstr,
            NULL
            );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = _populateHashMapWithSuperlogEntries(
            pHashMap,
            pEntries,
            pColumnSet
            );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = _convertHashMapToSuperlogTable(
            pHashMap,
            pColumnSet,
            &pTable
            );
    BAIL_ON_VMDIR_ERROR(dwError);

    qsort(  pTable->rows,
            pTable->numRows,
            sizeof(VMDIR_SUPERLOG_TABLE_ROW),
            _compareSuperlogTableRows);

    *ppTable = pTable;

cleanup:
    LwRtlHashMapClear(pHashMap, _hashMapPairFree, NULL);
    LwRtlFreeHashMap(&pHashMap);
    return dwError;

error:
    VmDirFreeSuperLogTable(pTable);
    goto cleanup;
}
Beispiel #4
0
DWORD
VmDirUTDVectorCacheInit(
    PVMDIR_UTDVECTOR_CACHE*    ppUTDVector
    )
{
    DWORD                   dwError = 0;
    PVMDIR_UTDVECTOR_CACHE  pCache = NULL;

    if (!ppUTDVector)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    dwError = VmDirAllocateMemory(
            sizeof(VMDIR_UTDVECTOR_CACHE),
            (PVOID*)&pCache);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(
            &pCache->pUtdVectorMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateStringA(
            "", &pCache->pszUtdVector);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateRWLock(
            &pCache->pUtdVectorLock);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppUTDVector = pCache;

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #5
0
DWORD
VmDirLdapSchemaInit(
    PVDIR_LDAP_SCHEMA*  ppSchema
    )
{
    DWORD   dwError = 0;
    PVDIR_LDAP_SCHEMA   pSchema = NULL;

    if (!ppSchema)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateMemory(
            sizeof(VDIR_LDAP_SCHEMA),
            (PVOID*)&pSchema);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->attributeTypes,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->objectClasses,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->contentRules,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->structureRules,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pSchema->nameForms,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppSchema = pSchema;

cleanup:
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    VmDirFreeLdapSchema(pSchema);
    goto cleanup;
}
Beispiel #6
0
DWORD
VmDirEntryIsAttrAllowed(
    PVDIR_ENTRY pEntry,
    PSTR        pszAttrName,
    PBOOLEAN    pbMust,
    PBOOLEAN    pbMay
    )
{
    DWORD   dwError = 0;
    DWORD   i = 0;
    PVDIR_ATTRIBUTE         pAttrOC = NULL;
    PVDIR_SCHEMA_OC_DESC    pOCDesc = NULL;
    PLW_HASHMAP pAllMustAttrMap = NULL;
    PLW_HASHMAP pAllMayAttrMap = NULL;

    if (!pEntry || IsNullOrEmptyString(pszAttrName))
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = LwRtlCreateHashMap(&pAllMustAttrMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(&pAllMayAttrMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    pAttrOC = VmDirFindAttrByName(pEntry, ATTR_OBJECT_CLASS);

    for (i = 0; pAttrOC && i < pAttrOC->numVals; i++)
    {
        dwError = VmDirSchemaOCNameToDescriptor(
                pEntry->pSchemaCtx, pAttrOC->vals[i].lberbv.bv_val, &pOCDesc);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirSchemaClassGetAllMustAttrs(
                pEntry->pSchemaCtx, pOCDesc, pAllMustAttrMap);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirSchemaClassGetAllMayAttrs(
                pEntry->pSchemaCtx, pOCDesc, pAllMayAttrMap);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    if (pbMust)
    {
        *pbMust = FALSE;
        if (LwRtlHashMapFindKey(pAllMustAttrMap, NULL, pszAttrName) == 0)
        {
            *pbMust = TRUE;
        }
    }

    if (pbMay)
    {
        *pbMay = FALSE;
        if (LwRtlHashMapFindKey(pAllMayAttrMap, NULL, pszAttrName) == 0)
        {
            *pbMay = TRUE;
        }
    }

cleanup:
    LwRtlHashMapClear(pAllMustAttrMap, VmDirNoopHashMapPairFree, NULL);
    LwRtlFreeHashMap(&pAllMustAttrMap);
    LwRtlHashMapClear(pAllMayAttrMap, VmDirNoopHashMapPairFree, NULL);
    LwRtlFreeHashMap(&pAllMayAttrMap);
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)", __FUNCTION__, dwError );

    goto cleanup;
}
Beispiel #7
0
//TODO_REMOVE_REPLV2
DWORD
VmDirAttributeMetaDataToHashMap(
    PVDIR_ATTRIBUTE   pAttrAttrMetaData,
    PLW_HASHMAP*      ppMetaDataMap
    )
{
    DWORD            dwError = 0;
    DWORD            dwCnt = 0;
    PLW_HASHMAP      pMetaDataMap = NULL;
    PSTR             pszKey = NULL;
    PVMDIR_ATTRIBUTE_METADATA   pMetaData = NULL;

    if (!pAttrAttrMetaData || !ppMetaDataMap)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    dwError = LwRtlCreateHashMap(
            &pMetaDataMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (dwCnt = 0; pAttrAttrMetaData->vals[dwCnt].lberbv.bv_val != NULL; dwCnt++)
    {
        // Format is: <attr name>:<local USN>:<version no>:<originating server ID>:<originating time>:<originating USN>
        char* pszMetaData = VmDirStringChrA(pAttrAttrMetaData->vals[dwCnt].lberbv.bv_val, ':');
        if (pszMetaData == NULL)
        {
            BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_BACKEND_INVALID_METADATA);
        }

        // pszMetaData now points to <local USN>...
        pszMetaData++;

        //pAttrAttrMetaData->vals[i] has <attr type>\0<pszMetaData>
        *(pszMetaData - 1) = '\0';

        dwError = VmDirAllocateStringA(pAttrAttrMetaData->vals[dwCnt].lberbv.bv_val, &pszKey);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirMetaDataDeserialize(pszMetaData, &pMetaData);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = LwRtlHashMapInsert(pMetaDataMap, pszKey, pMetaData, NULL);
        BAIL_ON_VMDIR_ERROR(dwError);
        pszKey = NULL; pMetaData = NULL;
    }

    *ppMetaDataMap = pMetaDataMap;

cleanup:
    return dwError;

error:
    if (pMetaDataMap)
    {
        LwRtlHashMapClear(
                pMetaDataMap,
                VmDirFreeMetaDataMapPair,
                NULL);
        LwRtlFreeHashMap(&pMetaDataMap);
    }
    VmDirFreeMetaData(pMetaData);
    VMDIR_SAFE_FREE_MEMORY(pszKey);
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #8
0
DWORD
VmDirAttributeMetaDataListConvertToHashMap(
    PVDIR_LINKED_LIST    pMetaDataList,
    PLW_HASHMAP         *ppMetaDataMap
    )
{
    DWORD                            dwError = 0;
    PLW_HASHMAP                      pMetaDataMap = NULL;
    PVDIR_LINKED_LIST_NODE           pCurrNode = NULL;
    PVDIR_LINKED_LIST_NODE           pNextNode = NULL;
    PVMDIR_REPL_ATTRIBUTE_METADATA   pReplMetaData = NULL;

    if (!pMetaDataList || !ppMetaDataMap)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    dwError = LwRtlCreateHashMap(
            &pMetaDataMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirLinkedListGetHead(pMetaDataList, &pCurrNode);
    BAIL_ON_VMDIR_ERROR(dwError);

    while (pCurrNode)
    {
        pReplMetaData = (PVMDIR_REPL_ATTRIBUTE_METADATA) pCurrNode->pElement;

        pNextNode = pCurrNode->pNext;

        dwError = LwRtlHashMapInsert(
                pMetaDataMap, pReplMetaData->pszAttrType, pReplMetaData->pMetaData, NULL);
        BAIL_ON_VMDIR_ERROR(dwError);

        pReplMetaData->pszAttrType = NULL;
        pReplMetaData->pMetaData = NULL;
        VmDirFreeReplMetaData(pReplMetaData);

        dwError = VmDirLinkedListRemove(pMetaDataList, pCurrNode);
        BAIL_ON_VMDIR_ERROR(dwError)

        pCurrNode = pNextNode;
    }

    *ppMetaDataMap = pMetaDataMap;

cleanup:
    return dwError;

error:
    if (pMetaDataMap)
    {
        LwRtlHashMapClear(
                pMetaDataMap,
                VmDirFreeMetaDataMapPair,
                NULL);
        LwRtlFreeHashMap(&pMetaDataMap);
    }
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #9
0
DWORD
VmDirIndexLibInit(
    PVMDIR_MUTEX    pModMutex
    )
{
    static VDIR_DEFAULT_INDEX_CFG defIdx[] = VDIR_INDEX_INITIALIZER;

    DWORD   dwError = 0;
    DWORD   i = 0;
    PSTR    pszLastOffset = NULL;
    ENTRYID maxEId = 0;
    VDIR_BACKEND_CTX    beCtx = {0};
    BOOLEAN             bHasTxn = FALSE;
    PVDIR_INDEX_CFG     pIndexCfg = NULL;
    PVDIR_SCHEMA_CTX    pSchemaCtx = NULL;
    PVDIR_SCHEMA_AT_DESC    pATDesc = NULL;

    if (!pModMutex)
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // pModMutex refers to gVdirSchemaGlobals.cacheModMutex,
    // so do not free it during shutdown
    gVdirIndexGlobals.mutex = pModMutex;

    dwError = VmDirAllocateCondition(&gVdirIndexGlobals.cond);
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = LwRtlCreateHashMap(
            &gVdirIndexGlobals.pIndexCfgMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    beCtx.pBE = VmDirBackendSelect(NULL);

    dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_WRITE);
    BAIL_ON_VMDIR_ERROR(dwError);
    bHasTxn = TRUE;

    // get fields to continue indexing from where it left last time
    dwError = beCtx.pBE->pfnBEUniqKeyGetValue(
            &beCtx, INDEX_LAST_OFFSET_KEY, &pszLastOffset);
    if (dwError)
    {
        dwError = beCtx.pBE->pfnBEMaxEntryId(&maxEId);
        BAIL_ON_VMDIR_ERROR(dwError);

        if (maxEId == ENTRY_ID_SEQ_INITIAL_VALUE)
        {
            gVdirIndexGlobals.bFirstboot = TRUE;
        }
        else
        {
            gVdirIndexGlobals.bLegacyDB = TRUE;
        }

        // set index_last_offset = -1 to indicate indexing has started
        gVdirIndexGlobals.offset = -1;
        dwError = beCtx.pBE->pfnBEUniqKeySetValue(
                &beCtx, INDEX_LAST_OFFSET_KEY, "-1");
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    else
    {
        dwError = VmDirStringToINT64(pszLastOffset, NULL, &gVdirIndexGlobals.offset);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = beCtx.pBE->pfnBETxnCommit(&beCtx);
    BAIL_ON_VMDIR_ERROR(dwError);
    bHasTxn = FALSE;

    dwError = VmDirSchemaCtxAcquire(&pSchemaCtx);
    BAIL_ON_VMDIR_ERROR(dwError);

    // open default indices
    for (i = 0; defIdx[i].pszAttrName; i++)
    {
        dwError = VmDirDefaultIndexCfgInit(&defIdx[i], &pIndexCfg);
        BAIL_ON_VMDIR_ERROR(dwError);

        // update attribute types in schema cache with their index info
        dwError = VmDirSchemaAttrNameToDescriptor(
                pSchemaCtx, pIndexCfg->pszAttrName, &pATDesc);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirIndexCfgGetAllScopesInStrArray(
                pIndexCfg, &pATDesc->ppszUniqueScopes);
        BAIL_ON_VMDIR_ERROR(dwError);

        pATDesc->dwSearchFlags |= 1;

        // for free later
        pATDesc->pLdapAt->ppszUniqueScopes = pATDesc->ppszUniqueScopes;
        pATDesc->pLdapAt->dwSearchFlags = pATDesc->dwSearchFlags;

        dwError = VmDirIndexOpen(pIndexCfg);
        BAIL_ON_VMDIR_ERROR(dwError);
        pIndexCfg = NULL;
    }

    // VMIT support
    dwError = VmDirIndexLibInitVMIT();
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = InitializeIndexingThread();
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    if (bHasTxn)
    {
        beCtx.pBE->pfnBETxnAbort(&beCtx);
    }
    VmDirBackendCtxContentFree(&beCtx);
    VmDirSchemaCtxRelease(pSchemaCtx);
    VMDIR_SAFE_FREE_MEMORY(pszLastOffset);
    return dwError;

error:
    VMDIR_LOG_ERROR(
            VMDIR_LOG_MASK_ALL,
            "%s failed, error (%d)",
            __FUNCTION__,
            dwError);

    VmDirFreeIndexCfg(pIndexCfg);
    goto cleanup;
}
Beispiel #10
0
static
DWORD
_PopulateOperationModAttributes(
        LDAP *pLd,
        LDAPMessage *pEntry,
        PVDIR_OPERATION pLdapOp
        )
{
    DWORD dwError = 0;
    struct berval** ppValues = NULL;
    PLW_HASHMAP pHashMap = NULL;

    PSTR pszBuf = NULL;
    PSTR pszAttrName = NULL;
    PSTR pszAttrMetaData = NULL;
    PSTR pszAttrUsnlessMetaData = NULL;
    PSTR pszAttrNewMetaData = NULL;
    PSTR pszKey = NULL;
    PSTR pszValue = NULL;
    USN localUsn = 0;
    PVDIR_BERVALUE pBerValue = NULL;
    size_t iBerValueSize = 0;
    DWORD i = 0, j = 0;

    dwError = LwRtlCreateHashMap(
            &pHashMap,
            LwRtlHashDigestPstrCaseless,
            LwRtlHashEqualPstrCaseless,
            NULL
            );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = pLdapOp->pBEIF->pfnBEGetNextUSN(pLdapOp->pBECtx, &localUsn);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (!(ppValues = ldap_get_values_len(pLd, pEntry, ATTR_ATTR_META_DATA)))
    {
        dwError = VMDIR_ERROR_SCHEMA_BAD_METADATA;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    for (i = 0; ppValues[i] != NULL; i++)
    {
        dwError = VmDirAllocateStringA(ppValues[i]->bv_val, &pszBuf);
        BAIL_ON_VMDIR_ERROR(dwError);

        pszAttrName = VmDirStringTokA(pszBuf, ":", &pszAttrMetaData);
        VmDirStringTokA(pszAttrMetaData, ":", &pszAttrUsnlessMetaData);

        dwError = VmDirAllocateStringPrintf(
                &pszAttrNewMetaData,
                "%ld:%s",
                localUsn,
                pszAttrUsnlessMetaData);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = VmDirAllocateStringA(pszAttrName, &pszKey);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = LwRtlHashMapInsert(pHashMap, pszKey, pszAttrNewMetaData, NULL);
        BAIL_ON_VMDIR_ERROR(dwError);

        VMDIR_SAFE_FREE_MEMORY(pszBuf);
    }
    ldap_value_free_len(ppValues);
    ppValues = NULL;

    for (i = 0; ppszSchemaEntryAttrs[i] != NULL; i++)
    {
        if (VmDirStringCompareA(ppszSchemaEntryAttrs[i], ATTR_ATTR_META_DATA, FALSE) != 0)
        {
            ppValues = ldap_get_values_len(pLd, pEntry, ppszSchemaEntryAttrs[i]);
            if (ppValues)
            {
                iBerValueSize = ldap_count_values_len(ppValues);
                dwError = VmDirAllocateMemory(
                        sizeof(VDIR_BERVALUE) * iBerValueSize,
                        (PVOID*)&pBerValue);
                BAIL_ON_VMDIR_ERROR(dwError);

                if (VmDirStringCompareA(ppszSchemaEntryAttrs[i], ATTR_USN_CHANGED, FALSE) == 0)
                {
                    assert(iBerValueSize == 1);

                    dwError = VmDirAllocateStringPrintf(&pBerValue[0].lberbv_val, "%ld", localUsn);
                    BAIL_ON_VMDIR_ERROR(dwError);
                    pBerValue[0].lberbv_len = VmDirStringLenA(pBerValue[0].lberbv_val);
                    pBerValue[0].bOwnBvVal = TRUE;
                }
                else
                {
                    for (j = 0; j < iBerValueSize; j++)
                    {
                        dwError = VmDirAllocateStringA(ppValues[j]->bv_val, &pBerValue[j].lberbv_val);
                        BAIL_ON_VMDIR_ERROR(dwError);
                        pBerValue[j].lberbv_len = ppValues[j]->bv_len;
                        pBerValue[j].bOwnBvVal = TRUE;
                    }
                }

                dwError = VmDirOperationAddModReq(
                        pLdapOp,
                        MOD_OP_REPLACE,
                        ppszSchemaEntryAttrs[i],
                        pBerValue,
                        iBerValueSize);
                BAIL_ON_VMDIR_ERROR(dwError);

                dwError = LwRtlHashMapFindKey(
                        pHashMap,
                        (PVOID*)&pszValue,
                        ppszSchemaEntryAttrs[i]);
                BAIL_ON_VMDIR_ERROR(dwError);

                dwError = VmDirStringCpyA(
                        pLdapOp->request.modifyReq.mods->attr.metaData,
                        VMDIR_MAX_ATTR_META_DATA_LEN,
                        pszValue);
                BAIL_ON_VMDIR_ERROR(dwError);

                ldap_value_free_len(ppValues);
                ppValues = NULL;
                for (j = 0; j < iBerValueSize; j++)
                {
                    VmDirFreeBervalContent(&pBerValue[j]);
                }
                VMDIR_SAFE_FREE_MEMORY(pBerValue);
            }
        }
    }

cleanup:
    LwRtlHashMapClear(pHashMap, _FreeStringPair, NULL);
    LwRtlFreeHashMap(&pHashMap);
    return dwError;

error:
    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
            "%s,%d failed, error(%d)", __FUNCTION__, __LINE__, dwError );

    VMDIR_SAFE_FREE_MEMORY(pszBuf);
    VMDIR_SAFE_FREE_MEMORY(pszAttrNewMetaData);
    if (ppValues)
    {
        ldap_value_free_len(ppValues);
    }
    for (j = 0; j < iBerValueSize; j++)
    {
        VmDirFreeBervalContent(&pBerValue[j]);
    }
    VMDIR_SAFE_FREE_MEMORY(pBerValue);
    goto cleanup;
}