Beispiel #1
0
DWORD
VmDirSchemaAttrIdMapGetAttrId(
    PVDIR_SCHEMA_ATTR_ID_MAP    pAttrIdMap,
    PSTR                        pszAttrName,
    USHORT*                     pusAttrId
    )
{
    DWORD   dwError = 0;
    uintptr_t   pAttrId = 0;

    if (!pAttrIdMap || IsNullOrEmptyString(pszAttrName))
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = LwRtlHashMapFindKey(pAttrIdMap->pStoredIds,
            (PVOID*)&pAttrId, pszAttrName);
    if (dwError)
    {
        dwError = LwRtlHashMapFindKey(pAttrIdMap->pNewIds,
                    (PVOID*)&pAttrId, pszAttrName);
    }
    BAIL_ON_VMDIR_ERROR(dwError);

    if (pusAttrId)
    {
        *pusAttrId = (USHORT)pAttrId;
    }

error:
    return dwError;
}
Beispiel #2
0
DWORD
VmDirUTDVectorCacheLookup(
    PVMDIR_UTDVECTOR_CACHE  pUTDVector,
    PCSTR                   pszInvocationId,
    USN*                    pUsn
    )
{
    DWORD       dwError = 0;
    BOOLEAN     bInLock = FALSE;
    uintptr_t   usn = 0;
    PVMDIR_UTDVECTOR_CACHE  pCache = pUTDVector;

    if (IsNullOrEmptyString(pszInvocationId) || !pUsn || !pUTDVector)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    VMDIR_RWLOCK_READLOCK(bInLock, pCache->pUtdVectorLock, 0);

    dwError = LwRtlHashMapFindKey(pCache->pUtdVectorMap, (PVOID*)&usn, pszInvocationId);
    BAIL_ON_VMDIR_ERROR(dwError);

    *pUsn = (USN)usn;

cleanup:
    VMDIR_RWLOCK_UNLOCK(bInLock, pCache->pUtdVectorLock);
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #3
0
NTSTATUS
RdrResolveToDomain(
    PCWSTR pwszHostname,
    PWSTR* ppwszDomain
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    BOOLEAN bLocked = FALSE;
    PWSTR pwszDomain = NULL;

    LWIO_LOCK_MUTEX(bLocked, &gRdrRuntime.Lock);

    if (!gRdrRuntime.pDomainHints)
    {
        status = STATUS_NOT_FOUND;
    }
    else
    {
        status = LwRtlHashMapFindKey(
            gRdrRuntime.pDomainHints,
            OUT_PPVOID(&pwszDomain),
            pwszHostname);
    }
    BAIL_ON_NT_STATUS(status);

    status = LwRtlWC16StringDuplicate(ppwszDomain, pwszDomain);
    BAIL_ON_NT_STATUS(status);

error:

    LWIO_UNLOCK_MUTEX(bLocked, &gRdrRuntime.Lock);

    return status;
}
Beispiel #4
0
DWORD
VmDirIndexCfgAcquire(
    PCSTR               pszAttrName,
    VDIR_INDEX_USAGE    usage,
    PVDIR_INDEX_CFG*    ppIndexCfg
    )
{
    DWORD   dwError = 0;
    BOOLEAN bInLock = FALSE;
    PVDIR_INDEX_CFG pIndexCfg = NULL;
    PVMDIR_MUTEX    pMutex = NULL;

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

    *ppIndexCfg = NULL;

    if (LwRtlHashMapFindKey(
            gVdirIndexGlobals.pIndexCfgMap, (PVOID*)&pIndexCfg, pszAttrName))
    {
        goto cleanup;
    }

    pMutex = pIndexCfg->mutex;
    VMDIR_LOCK_MUTEX(bInLock, pMutex);

    if (pIndexCfg->status == VDIR_INDEXING_SCHEDULED)
    {
        goto cleanup;
    }
    else if (pIndexCfg->status == VDIR_INDEXING_IN_PROGRESS &&
            usage == VDIR_INDEX_READ)
    {
        dwError = VMDIR_ERROR_UNWILLING_TO_PERFORM;
    }
    else if (pIndexCfg->status == VDIR_INDEXING_DISABLED ||
            pIndexCfg->status == VDIR_INDEXING_DELETED)
    {
        goto cleanup;
    }
    BAIL_ON_VMDIR_ERROR(dwError);

    pIndexCfg->usRefCnt++;
    *ppIndexCfg = pIndexCfg;

cleanup:
    VMDIR_UNLOCK_MUTEX(bInLock, pMutex);
    return dwError;

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

    goto cleanup;
}
Beispiel #5
0
BOOLEAN
VmDirIndexExist(
    PCSTR   pszAttrName
    )
{
    BOOLEAN bExist = TRUE;
    PLW_HASHMAP pCurMap = NULL;
    PLW_HASHMAP pUpdMap = NULL;
    PVDIR_INDEX_CFG pIndexCfg = NULL;

    pCurMap = gVdirIndexGlobals.pIndexCfgMap;
    pUpdMap = gVdirIndexGlobals.pIndexUpd ?
            gVdirIndexGlobals.pIndexUpd->pUpdIndexCfgMap : NULL;

    if (IsNullOrEmptyString(pszAttrName))
    {
        bExist = FALSE;
    }
    else
    {
        if (pUpdMap)
        {
            LwRtlHashMapFindKey(pUpdMap, (PVOID*)&pIndexCfg, pszAttrName);
        }
        if (!pIndexCfg)
        {
            LwRtlHashMapFindKey(pCurMap, (PVOID*)&pIndexCfg, pszAttrName);
        }
        if (!pIndexCfg ||
            pIndexCfg->status == VDIR_INDEXING_DISABLED ||
            pIndexCfg->status == VDIR_INDEXING_DELETED)
        {
            bExist = FALSE;
        }
    }

    return bExist;
}
Beispiel #6
0
BOOLEAN
VmDirIndexIsDefault(
    PCSTR   pszAttrName
    )
{
    BOOLEAN bIsDefault = FALSE;
    PVDIR_INDEX_CFG pIndexCfg = NULL;

    if (!IsNullOrEmptyString(pszAttrName) &&
            LwRtlHashMapFindKey(
                    gVdirIndexGlobals.pIndexCfgMap,
                    (PVOID*)&pIndexCfg,
                    pszAttrName) == 0)
    {
        bIsDefault = pIndexCfg->bDefaultIndex;
    }

    return bIsDefault;
}
Beispiel #7
0
/*
 * should only be used during bootstrap
 * maybe add state check?
 */
DWORD
VmDirIndexOpen(
    PVDIR_INDEX_CFG pIndexCfg
    )
{
    DWORD   dwError = 0;
    BOOLEAN bInLock = FALSE;
    PVDIR_BACKEND_INTERFACE pBE = NULL;

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

    VMDIR_LOCK_MUTEX(bInLock, gVdirIndexGlobals.mutex);

    if (LwRtlHashMapFindKey(
            gVdirIndexGlobals.pIndexCfgMap, NULL, pIndexCfg->pszAttrName) == 0)
    {
        dwError = ERROR_ALREADY_INITIALIZED;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = LwRtlHashMapInsert(
            gVdirIndexGlobals.pIndexCfgMap,
            pIndexCfg->pszAttrName,
            pIndexCfg,
            NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

    pBE = VmDirBackendSelect(NULL);
    dwError = pBE->pfnBEIndexOpen(pIndexCfg);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    VMDIR_UNLOCK_MUTEX(bInLock, gVdirIndexGlobals.mutex);
    return dwError;

error:
    goto cleanup;
}
Beispiel #8
0
static
DWORD
_populateHashMapWithSuperlogEntries(
        PLW_HASHMAP pHashMap,
        PVMDIR_SUPERLOG_ENTRY_LDAPOPERATION_ARRAY pEntries,
        PVMDIR_SUPERLOG_TABLE_COLUMN_SET pCols
        )
{
    DWORD                       dwError = 0;
    PSTR                        pszKey  = NULL;
    PVMDIR_SUPERLOG_TABLE_ROW   pValue  = NULL;
    unsigned int    i;

    for (i = 0; i < pEntries->dwCount; i++)
    {
        dwError = _generateHashMapKeyString(&pEntries->entries[i], pCols, &pszKey);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = LwRtlHashMapFindKey(pHashMap, (PVOID*)&pValue, pszKey);
        if (dwError == 0)
        {
            pValue->count += 1;
            pValue->totalTime += pEntries->entries[i].iEndTime - pEntries->entries[i].iStartTime;
            VMDIR_SAFE_FREE_MEMORY(pszKey);
        }
        else
        {
            dwError = _allocateSuperlogTableRow(&pEntries->entries[i], pCols, &pValue);
            BAIL_ON_VMDIR_ERROR(dwError);

            dwError = LwRtlHashMapInsert(pHashMap, pszKey, pValue, NULL);
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }

cleanup:
    return dwError;

error:
    goto cleanup;
}
BOOLEAN
VmDirConsumerRoleActive(
    VOID
    )
{
    BOOLEAN   bInLock = FALSE;
    BOOLEAN   bActiveReplCycle = FALSE;

    VMDIR_LOCK_MUTEX(bInLock, gVmdirServerGlobals.pReplDeadlockDetectionVector->pMutex);

    // if consumer role is active, then DD vector will definitely have bvServerObjName key
    if (LwRtlHashMapFindKey(
            gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap,
            NULL,
            gVmdirServerGlobals.bvServerObjName.lberbv_val) == 0)
    {
        bActiveReplCycle = TRUE;
    }

    VMDIR_UNLOCK_MUTEX(bInLock, gVmdirServerGlobals.pReplDeadlockDetectionVector->pMutex);

    return bActiveReplCycle;
}
Beispiel #10
0
DWORD
VmDirIndexDeleteUniquenessScope(
    PVDIR_INDEX_UPD     pIndexUpd,
    PCSTR               pszAttrName,
    PCSTR*              ppszUniqScopes
    )
{
    DWORD   dwError = 0;
    DWORD   i = 0;
    PLW_HASHMAP pCurCfgMap = NULL;
    PLW_HASHMAP pUpdCfgMap = NULL;
    PVDIR_INDEX_CFG pCurCfg = NULL;
    PVDIR_INDEX_CFG pUpdCfg = NULL;
    PVDIR_INDEX_CFG pNewCfg = NULL;

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

    pCurCfgMap = gVdirIndexGlobals.pIndexCfgMap;
    pUpdCfgMap = pIndexUpd->pUpdIndexCfgMap;

    (VOID)LwRtlHashMapFindKey(pCurCfgMap, (PVOID*)&pCurCfg, pszAttrName);
    (VOID)LwRtlHashMapFindKey(pUpdCfgMap, (PVOID*)&pUpdCfg, pszAttrName);

    if (pCurCfg && !pUpdCfg)
    {
        dwError = VmDirIndexCfgCopy(pCurCfg, &pUpdCfg);
        BAIL_ON_VMDIR_ERROR(dwError);
        pNewCfg = pUpdCfg;
    }

    if (!pUpdCfg ||
         pUpdCfg->status == VDIR_INDEXING_DISABLED ||
         pUpdCfg->status == VDIR_INDEXING_DELETED)
    {
        dwError = VMDIR_ERROR_NOT_FOUND;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    if (!pUpdCfg->bScopeEditable ||
         pUpdCfg->status == VDIR_INDEXING_VALIDATING_SCOPES)
    {
        dwError = VMDIR_ERROR_UNWILLING_TO_PERFORM;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    for (i = 0; ppszUniqScopes[i]; i++)
    {
        dwError = VmDirIndexCfgDeleteUniqueScopeMod(pUpdCfg, ppszUniqScopes[i]);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = LwRtlHashMapInsert(pUpdCfgMap, pUpdCfg->pszAttrName, pUpdCfg, NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    return dwError;

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

    VmDirFreeIndexCfg(pNewCfg);
    goto cleanup;
}
Beispiel #11
0
DWORD
VmDirIndexSchedule(
    PVDIR_INDEX_UPD     pIndexUpd,
    PCSTR               pszAttrName,
    PCSTR               pszAttrSyntaxOid
    )
{
    DWORD   dwError = 0;
    PLW_HASHMAP pCurCfgMap = NULL;
    PLW_HASHMAP pUpdCfgMap = NULL;
    PVDIR_INDEX_CFG pCurCfg = NULL;
    PVDIR_INDEX_CFG pUpdCfg = NULL;
    PVDIR_INDEX_CFG pNewCfg = NULL;

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

    pCurCfgMap = gVdirIndexGlobals.pIndexCfgMap;
    pUpdCfgMap = pIndexUpd->pUpdIndexCfgMap;

    (VOID)LwRtlHashMapFindKey(pCurCfgMap, (PVOID*)&pCurCfg, pszAttrName);
    (VOID)LwRtlHashMapFindKey(pUpdCfgMap, (PVOID*)&pUpdCfg, pszAttrName);

    if (pUpdCfg)
    {
        dwError = ERROR_ALREADY_EXISTS;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    if (pCurCfg)
    {
        if (pCurCfg->status == VDIR_INDEXING_DELETED)
        {
            dwError = VmDirIndexCfgCopy(pCurCfg, &pUpdCfg);
            BAIL_ON_VMDIR_ERROR(dwError);
            pNewCfg = pUpdCfg;

            pUpdCfg->status = VDIR_INDEXING_SCHEDULED;
        }
        else if (pCurCfg->status == VDIR_INDEXING_DISABLED)
        {
            dwError = VMDIR_ERROR_BUSY;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
        else
        {
            dwError = ERROR_ALREADY_EXISTS;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }
    else
    {
        dwError = VmDirIndexCfgCreate(pszAttrName, &pUpdCfg);
        BAIL_ON_VMDIR_ERROR(dwError);
        pNewCfg = pUpdCfg;

        pUpdCfg->bIsNumeric = VmDirSchemaSyntaxIsNumeric(pszAttrSyntaxOid);
    }

    dwError = LwRtlHashMapInsert(pUpdCfgMap, pUpdCfg->pszAttrName, pUpdCfg, NULL);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    return dwError;

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

    VmDirFreeIndexCfg(pNewCfg);
    goto cleanup;
}
DWORD
VmDirDDVectorParseString(
    PSTR       pszDeadlockDetectionVectorStr,
    PBOOLEAN   pbCompleteReplCycle
    )
{
    PSTR      pszLocalVectorStr = NULL;
    PDWORD    pdwValue = NULL;
    DWORD     dwError = 0;
    DWORD     dwMinConsecutiveEmptyPage = INT_MAX;
    BOOLEAN   bInLock = FALSE;
    LW_HASHMAP_ITER  iter = LW_HASHMAP_ITER_INIT;
    LW_HASHMAP_PAIR  pair = {NULL, NULL};

    VMDIR_LOCK_MUTEX(bInLock, gVmdirServerGlobals.pReplDeadlockDetectionVector->pMutex);

    if (pszDeadlockDetectionVectorStr && pbCompleteReplCycle)
    {
        dwError = VmDirAllocateStringA(pszDeadlockDetectionVectorStr+VmDirStringLenA("vector:"), &pszLocalVectorStr);
        BAIL_ON_VMDIR_ERROR(dwError);

        // cache the counter value
        if (LwRtlHashMapFindKey(
                    gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap,
                    (PVOID*)&pdwValue,
                    gVmdirServerGlobals.bvServerObjName.lberbv_val) == 0)
        {
            dwMinConsecutiveEmptyPage = *pdwValue;
            dwMinConsecutiveEmptyPage++;
            VMDIR_LOG_INFO(LDAP_DEBUG_REPL, "consecutive empty pages received: %d", dwMinConsecutiveEmptyPage);
        }

        // clear and reconstruct the vector
        LwRtlHashMapClear(
                gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap,
                VmDirSimpleHashMapPairFree,
                NULL);

        dwError = VmDirStrtoVector(
                pszLocalVectorStr,
                _VmDirDeadlockDetectionVectorStrToPair,
                gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap);
        BAIL_ON_VMDIR_ERROR(dwError);

        // update the cached counter value
        dwError = _VmDirDDVectorUpdateDefaultsInLock(dwMinConsecutiveEmptyPage);
        BAIL_ON_VMDIR_ERROR(dwError);

        // check for replication cycle completion
        while (LwRtlHashMapIterate(gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap, &iter, &pair))
        {
            dwMinConsecutiveEmptyPage = VMDIR_MIN(dwMinConsecutiveEmptyPage, *(PDWORD)pair.pValue);
        }

        *pbCompleteReplCycle = (dwMinConsecutiveEmptyPage >= gVmdirGlobals.dwEmptyPageCnt);
        if (*pbCompleteReplCycle)
        {
            VMDIR_LOG_INFO(
                    VMDIR_LOG_MASK_ALL,
                    "%s: Break Empty Pages Received, vec: %s",
                    __FUNCTION__,
                    pszDeadlockDetectionVectorStr);
        }
    }
    else // if vector not present - non empty page - clear the vector contents
    {
        _VmDirDDVectorUpdateInLock(0);
    }

cleanup:
    VMDIR_UNLOCK_MUTEX(bInLock, gVmdirServerGlobals.pReplDeadlockDetectionVector->pMutex);
    VMDIR_SAFE_FREE_MEMORY(pszLocalVectorStr);
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
DWORD
VmDirDDVectorToString(
    PCSTR   pszInvocationId,
    PSTR*   ppszDeadlockDetectionVectorStr
    )
{
    PSTR      pszDeadlockDetectionVectorStr = NULL;
    DWORD     dwError = 0;
    PDWORD    pdwValue = NULL;
    DWORD     dwCacheEmptyPageCnt = 0;
    BOOLEAN   bInLock = FALSE;
    BOOLEAN   bRevertDefaultValue = FALSE;

    if (ppszDeadlockDetectionVectorStr == NULL)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    VMDIR_LOCK_MUTEX(bInLock, gVmdirServerGlobals.pReplDeadlockDetectionVector->pMutex);

    /*
     * Best effort if invocation id is NULL ignore.
     * Ping-pong state is handled by providing supplier's empty page
     * count as 'gVmdirGlobals.dwEmptyPageCnt' so that partner considers only his state
     */
    if (gVmdirServerGlobals.pReplDeadlockDetectionVector->pszInvocationId &&
        pszInvocationId &&
        VmDirStringCompareA(
                pszInvocationId,
                gVmdirServerGlobals.pReplDeadlockDetectionVector->pszInvocationId,
                FALSE) == 0)
    {
        // will reach here only if key is present
        LwRtlHashMapFindKey(
                gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap,
                (PVOID*)&pdwValue,
                gVmdirServerGlobals.bvServerObjName.lberbv_val);

        dwCacheEmptyPageCnt = *pdwValue;

        dwError = _VmDirDDVectorUpdateDefaultsInLock(gVmdirGlobals.dwEmptyPageCnt);
        BAIL_ON_VMDIR_ERROR(dwError);

        bRevertDefaultValue = TRUE;
    }

    dwError = VmDirVectorToStr(
            gVmdirServerGlobals.pReplDeadlockDetectionVector->pEmptyPageSentMap,
            _VmDirDeadlockDetectionVectorPairToStr,
            &pszDeadlockDetectionVectorStr);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppszDeadlockDetectionVectorStr = pszDeadlockDetectionVectorStr;
    pszDeadlockDetectionVectorStr = NULL;

    if (bRevertDefaultValue)
    {
        dwError = _VmDirDDVectorUpdateDefaultsInLock(dwCacheEmptyPageCnt);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

cleanup:
    VMDIR_UNLOCK_MUTEX(bInLock, gVmdirServerGlobals.pReplDeadlockDetectionVector->pMutex);
    return dwError;

error:
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Beispiel #14
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 #15
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;
}