Ejemplo n.º 1
0
DWORD
VmDirComputeMessageDigest(
    const EVP_MD*           digestMethod,
    const unsigned char*    pData,
    size_t                  dataSize,
    unsigned char**         ppMD,
    size_t*                 pMDSize
    )
{
    DWORD   dwError = 0;
    EVP_MD_CTX  mdCtx = {0};
    unsigned char   md[EVP_MAX_MD_SIZE] = {0};
    unsigned int    mdSize = 0;
    unsigned char*  pMD = NULL;

    if (!digestMethod || !pData || !ppMD || !pMDSize)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER);
    }

    EVP_MD_CTX_init(&mdCtx);

    if (EVP_DigestInit_ex(&mdCtx, digestMethod, NULL) == 0)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: EVP_DigestInit_ex returned 0", __FUNCTION__);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

    if (EVP_DigestUpdate(&mdCtx, pData, dataSize) == 0)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: EVP_DigestUpdate returned 0", __FUNCTION__);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

    if (EVP_DigestFinal_ex(&mdCtx, md, &mdSize) == 0)
    {
        VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: EVP_DigestFinal_ex returned 0", __FUNCTION__);
        BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_SSL);
    }

    dwError = VmDirAllocateAndCopyMemory(md, mdSize, (PVOID*)&pMD);
    BAIL_ON_VMDIR_ERROR(dwError);

    *ppMD = pMD;
    *pMDSize = mdSize;

cleanup:
    EVP_MD_CTX_cleanup(&mdCtx);
    return dwError;

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

    VMDIR_SAFE_FREE_MEMORY(pMD);
    goto cleanup;
}
Ejemplo n.º 2
0
static
DWORD
_allocateSuperlogTable(
        DWORD tableSize,
        PVMDIR_SUPERLOG_TABLE_COLUMN_SET pCols,
        PVMDIR_SUPERLOG_TABLE *ppTable
        )
{
    DWORD dwError = 0;
    PVMDIR_SUPERLOG_TABLE pTable = NULL;

    dwError = VmDirAllocateMemory(
            sizeof(VMDIR_SUPERLOG_TABLE),
            (PVOID*)&pTable
            );
    BAIL_ON_VMDIR_ERROR(dwError);

    dwError = VmDirAllocateAndCopyMemory(
            pCols,
            sizeof(VMDIR_SUPERLOG_TABLE_COLUMN_SET),
            (PVOID*)&pTable->cols
            );
    BAIL_ON_VMDIR_ERROR(dwError);

    pTable->numRows = tableSize;

    if (tableSize > 0)
    {
        dwError = VmDirAllocateMemory(
                sizeof(VMDIR_SUPERLOG_TABLE_ROW)*tableSize,
                (PVOID*)&pTable->rows
                );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    *ppTable = pTable;

cleanup:
    return dwError;

error:
    if (pTable)
    {
        VMDIR_SAFE_FREE_MEMORY(pTable->rows);
        VMDIR_SAFE_FREE_MEMORY(pTable->cols);
        VMDIR_SAFE_FREE_MEMORY(pTable);
    }
    goto cleanup;
}
Ejemplo n.º 3
0
//Clone a operation struct that share the same
//transaction context with pOp
DWORD
VmDirCloneStackOperation(
    PVDIR_OPERATION         pOp,
    PVDIR_OPERATION         pOutOp,
    VDIR_OPERATION_TYPE     opType,
    ber_tag_t               requestCode,
    PVDIR_SCHEMA_CTX        pSchemaCtx
    )
{
    DWORD               dwError = 0;
    PVDIR_SCHEMA_CTX    pLocalSchemaCtx = NULL;

    BAIL_ON_VMDIR_INVALID_POINTER( pOp, dwError );
    BAIL_ON_VMDIR_INVALID_POINTER( pOutOp, dwError );

    pOutOp->opType  = opType;
    pOutOp->reqCode = requestCode;

    if ( pOutOp->reqCode == LDAP_REQ_ADD )
    {
        dwError = VmDirAllocateMemory( sizeof(*(pOutOp->request.addReq.pEntry)),
                                       (PVOID)&(pOutOp->request.addReq.pEntry) );
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    if ( pSchemaCtx )
    {
        pLocalSchemaCtx = VmDirSchemaCtxClone( pSchemaCtx );
        if ( !pLocalSchemaCtx )
        {
            dwError = ERROR_NO_SCHEMA;
            BAIL_ON_VMDIR_ERROR(dwError);
        }
    }
    else
    {
        dwError = VmDirSchemaCtxAcquire(&pLocalSchemaCtx);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirAllocateAndCopyMemory(pOp->pBECtx, sizeof(*pOutOp->pBECtx ), (PVOID) &(pOutOp->pBECtx));
    BAIL_ON_VMDIR_ERROR(dwError);

    if ( pOutOp->opType == VDIR_OPERATION_TYPE_INTERNAL )
    {   // needs dummy conn->VDIR_ACCESS_INFO for ACL check
        dwError = VmDirAllocateMemory( sizeof( *pOutOp->conn), (PVOID) &(pOutOp->conn) );
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    pOutOp->pSchemaCtx = pLocalSchemaCtx;
    pLocalSchemaCtx = NULL;

cleanup:

   return dwError;

error:

    if ( pLocalSchemaCtx )
    {
        VmDirSchemaCtxRelease( pLocalSchemaCtx );
    }
    VmDirFreeOperationContent(pOutOp);

   goto cleanup;
}
Ejemplo n.º 4
0
/*
 * 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;
}
Ejemplo n.º 5
0
/*
 * Retrieve SRP Identifier's secret and salt
 */
DWORD
VmDirSRPGetIdentityData(
    PCSTR       pszUPN,
    PBYTE*      ppByteSecret,
    DWORD*      pdwSecretLen
    )
{
    DWORD               dwError = 0;
    PVDIR_ATTRIBUTE     pAttrSecret = NULL;
    VDIR_ENTRY_ARRAY    entryArray = {0};
    PBYTE               pLocalSecret = NULL;

    if ( IsNullOrEmptyString(pszUPN)    ||
         ppByteSecret == NULL           ||
         pdwSecretLen == NULL
        )
    {
        dwError = VMDIR_ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = VmDirSimpleEqualFilterInternalSearch(
                    "",
                    LDAP_SCOPE_SUBTREE,
                    ATTR_KRB_UPN,
                    pszUPN,
                    &entryArray);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (entryArray.iSize == 1)
    {
        pAttrSecret = VmDirFindAttrByName(&(entryArray.pEntry[0]), ATTR_SRP_SECRET);
        if (!pAttrSecret)
        {
            dwError = VMDIR_ERROR_NO_SUCH_ATTRIBUTE;
            BAIL_ON_VMDIR_ERROR(dwError);
        }

        dwError = VmDirAllocateAndCopyMemory(   pAttrSecret->vals[0].lberbv_val,
                                                pAttrSecret->vals[0].lberbv_len,
                                                (PVOID*)&pLocalSecret);
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    else if (entryArray.iSize == 0)
    {
        dwError = VMDIR_ERROR_ENTRY_NOT_FOUND;
        BAIL_ON_VMDIR_ERROR(dwError);
    }
    else
    {
        dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    *ppByteSecret = pLocalSecret;
    *pdwSecretLen = (DWORD) (pAttrSecret->vals[0].lberbv_len);

cleanup:

    VmDirFreeEntryArrayContent(&entryArray);

    return dwError;

error:

    VMDIR_SAFE_FREE_MEMORY( pLocalSecret );

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
                     "VmDirSRPGetIdentityData (%s) failed, (%u)", VDIR_SAFE_STRING(pszUPN), dwError);
    goto cleanup;
}
Ejemplo n.º 6
0
DWORD
VmDirUnMarshalContainer(
    DWORD dwBlobSize,
    PBYTE pMarshalledBlob,
    PVMDIR_IPC_DATA_CONTAINER *ppContainer)
{
    DWORD dwError = 0;
    VMDIR_IPC_DATA_CONTAINER *pContainer = NULL;
    PBYTE pCursor = pMarshalledBlob;
    DWORD dwBlobSizeRead = 0;

    if (
        !pMarshalledBlob ||
        !ppContainer
       )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR (dwError);
    }

    if (dwBlobSize < sizeof (UINT32) + sizeof (UINT32))
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR (dwError);
    }

    dwError = VmDirAllocateMemory (
                                    sizeof (VMDIR_IPC_DATA_CONTAINER),
                                    (PVOID *)&pContainer
                                  );
    BAIL_ON_VMDIR_ERROR (dwError);

    dwBlobSizeRead = *((PUINT32)pCursor);
    pCursor += sizeof (UINT32);

    if (dwBlobSizeRead != dwBlobSize)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR (dwError);
    }

    pContainer->dwCount = *((PUINT32)pCursor);
    pCursor += sizeof (UINT32);

    dwError = VmDirAllocateAndCopyMemory(
                             pCursor,
                             pContainer->dwCount,
                             (PVOID*)&pContainer->data);
    BAIL_ON_VMDIR_ERROR (dwError);

    *ppContainer = pContainer;

cleanup:

    return dwError;

error:
    if (ppContainer)
    {
        *ppContainer = NULL;
    }

    goto cleanup;
}
Ejemplo n.º 7
0
/*
 * Continue next SASL negotiation with client.
 */
DWORD
VmDirSASLSessionStep(
    PVDIR_SASL_BIND_INFO    pSaslBindInfo,
    PVDIR_BIND_REQ          pBindReq,
    PVDIR_BERVALUE          pBervSaslReply,
    PVDIR_LDAP_RESULT       pResult
    )
{
    DWORD               dwError = 0;
    PVOID               pOutBlob = NULL;
    unsigned            iRespLen = 0;
    PCSTR               pszRespBlob = NULL;

    dwError = sasl_server_step(     pSaslBindInfo->pSaslCtx,
                                    pBindReq->cred.lberbv.bv_val,
                                    (unsigned) pBindReq->cred.lberbv.bv_len,
                                    &pszRespBlob,
                                    &iRespLen);
    if (dwError == SASL_OK)
    {
        dwError = _VmDirSASLGetCtxProps(pSaslBindInfo);
        BAIL_ON_VMDIR_ERROR(dwError);

        dwError = LDAP_SUCCESS;
        pSaslBindInfo->saslStatus = SASL_STATUS_DONE;
    }
    else if (dwError == SASL_CONTINUE)
    {
        pSaslBindInfo->saslStatus = SASL_STATUS_IN_PROGRESS;

        if (iRespLen > 0)
        {
            dwError = VmDirAllocateAndCopyMemory((PVOID)pszRespBlob, iRespLen, &pOutBlob);
            BAIL_ON_VMDIR_ERROR(dwError);

            pBervSaslReply->lberbv.bv_val = pOutBlob;
            pBervSaslReply->lberbv.bv_len = iRespLen;
            pBervSaslReply->bOwnBvVal = TRUE;
        }
        else
        {
            pBervSaslReply->lberbv.bv_len = 0;
            pBervSaslReply->lberbv.bv_val = "";
            pBervSaslReply->bOwnBvVal = FALSE;
        }

        dwError = LDAP_SUCCESS;
        pResult->errCode = LDAP_SASL_BIND_IN_PROGRESS;
        pResult->replyInfo.type = REP_SASL;
    }
    else
    {
        BAIL_ON_SASL_ERROR(dwError);
    }

cleanup:

    return dwError;

error:

    VMDIR_SAFE_FREE_MEMORY(pOutBlob);

    pBervSaslReply->lberbv.bv_val = NULL;
    pBervSaslReply->lberbv.bv_len = 0;
    pBervSaslReply->bOwnBvVal = FALSE;

    goto cleanup;

sasl_error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL,
                     "SASLSessionStep: sasl error (%d)(%s)",
                     dwError,
                     VDIR_SAFE_STRING(sasl_errdetail(pSaslBindInfo->pSaslCtx)) );

    dwError = _VmDirSASLToLDAPError(dwError);
    if (dwError == LDAP_INVALID_CREDENTIALS )
    {
        _VmDirSASLGetCtxProps(pSaslBindInfo);
        // ignore error
    }

    goto error;
}
Ejemplo n.º 8
0
static
int
_ParseAppendEntriesControlVal(
    VDIR_OPERATION *                        pOp,
    BerValue *                              pControlBer,    // Input: control value encoded as ber
    PVDIR_APPEND_ENTRIES_CONTROL_VALUE      pCtrlVal,       // Output
    VDIR_LDAP_RESULT *                      pLdapResult     // Output
    )
{
    int                 retVal = LDAP_SUCCESS;
    BerElementBuffer    berbuf = {0};
    BerElement *        ber = (BerElement *)&berbuf;
    PSTR                pszLocalErrorMsg = NULL;
    ber_int_t           term = 0;
    BerValue            leader = {0};
    BerValue            preLogIndex= {0};
    ber_int_t           preLogTerm = 0;
    BerValue            leaderCommit = {0};
    BerValue            entries = {0};

    if (!pOp || !pControlBer)
    {
        retVal = LDAP_PROTOCOL_ERROR;
        BAIL_ON_VMDIR_ERROR( retVal );
    }

    if (!pCtrlVal || !pLdapResult)
    {
        retVal = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR( retVal );
    }

    ber_init2( ber, pControlBer, LBER_USE_DER );

    /*
     * The AppendEntriesControl the BER-encoded version of the following SEQUENCE:
     *
     * ControlValue ::= SEQUENCE {
     *        term                    Integer
     *        leader                  OCTET STRING
     *        preLogIndex             OCTET STRING
     *        prevLogTerm             Integer
     *        leaderCommit            OCTET STRING
     *        entries                 OCTET STRING
     *  }
     */

    if (ber_scanf(ber, "{immimm}", &term, &leader, &preLogIndex, &preLogTerm, &leaderCommit, &entries) == LBER_ERROR)
    {
        VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s: ber_scanf failed while parsing filter value", __FUNCTION__);
        pLdapResult->errCode = LDAP_PROTOCOL_ERROR;
        retVal = LDAP_NOTICE_OF_DISCONNECT;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "Error in reading cluster state control filter");
    }

    pCtrlVal->term = term;

    retVal = VmDirAllocateStringA(leader.bv_val, &(pCtrlVal->leader));
    BAIL_ON_VMDIR_ERROR(retVal);

    pCtrlVal->preLogIndex = VmDirStringToLA(preLogIndex.bv_val, NULL, 10);
    BAIL_ON_VMDIR_ERROR(retVal);

    pCtrlVal->preLogTerm = preLogTerm;

    pCtrlVal->leaderCommit = VmDirStringToLA(leaderCommit.bv_val, NULL, 10);
    BAIL_ON_VMDIR_ERROR(retVal);

    retVal = VmDirAllocateAndCopyMemory(entries.bv_val, entries.bv_len, (PVOID*)&(pCtrlVal->entries.lberbv_val));
    BAIL_ON_VMDIR_ERROR(retVal);
    pCtrlVal->entries.lberbv_len = entries.bv_len;

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg);
    return retVal;

error:
    if (pszLocalErrorMsg && pLdapResult->pszErrMsg)
    {
        VMDIR_APPEND_ERROR_MSG(pLdapResult->pszErrMsg, pszLocalErrorMsg);
    }
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s Error: %d", __func__, retVal);
    goto cleanup;
}
Ejemplo n.º 9
0
static
DWORD
_VmKdcGetKrbUPNKey(
    PSTR        pszUpnName,
    PBYTE*      ppKeyBlob,
    DWORD*      pSize
    )
{
    DWORD               dwError = 0;
    PVDIR_ATTRIBUTE     pKrbUPNKey = NULL;
    PBYTE               pRetUPNKey = NULL;
    VDIR_ENTRY_ARRAY    entryArray = {0};

    if (IsNullOrEmptyString(pszUpnName)
        || !ppKeyBlob
        || !pSize
       )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMKDC_ERROR(dwError);
    }

    dwError = VmDirSimpleEqualFilterInternalSearch(
                    "",
                    LDAP_SCOPE_SUBTREE,
                    ATTR_KRB_UPN,
                    pszUpnName,
                    &entryArray);
    BAIL_ON_VMKDC_ERROR(dwError);

    if (entryArray.iSize == 1)
    {
        pKrbUPNKey = VmDirFindAttrByName(&(entryArray.pEntry[0]), ATTR_KRB_PRINCIPAL_KEY);

        if (!pKrbUPNKey)
        {
            dwError = ERROR_NO_PRINC;
            BAIL_ON_VMKDC_ERROR(dwError);
        }

        dwError = VmDirAllocateAndCopyMemory(
                        pKrbUPNKey->vals[0].lberbv.bv_val,
                        pKrbUPNKey->vals[0].lberbv.bv_len,
                        (PVOID*)& pRetUPNKey
                        );
        BAIL_ON_VMKDC_ERROR(dwError);

        *ppKeyBlob = pRetUPNKey;
        *pSize     = (DWORD) pKrbUPNKey->vals[0].lberbv.bv_len;
        pRetUPNKey = NULL;
    }
    else
    {
        dwError = ERROR_NO_PRINC;
        BAIL_ON_VMKDC_ERROR(dwError);
    }

cleanup:

    VmDirFreeEntryArrayContent(&entryArray);

    return dwError;

error:

    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "_VmKdcGetKrbUPNKey: failed (%u)(%s)", dwError, VDIR_SAFE_STRING(pszUpnName));

    VMKDC_SAFE_FREE_MEMORY(pRetUPNKey);

    // keep error code space to KDC specific
    dwError = ERROR_NO_PRINC;

    goto cleanup;

}
Ejemplo n.º 10
0
DWORD
VmDirTestGetAttributeValue(
    LDAP *pLd,
    PCSTR pBase,
    int ldapScope,
    PCSTR pszFilter,
    PCSTR pszAttribute,
    BYTE **ppbAttributeValue,
    PDWORD pdwAttributeLength
    )
{
    DWORD dwError = 0;
    PCSTR ppszAttrs[2] = {0};
    LDAPMessage *pResult = NULL;
    BerValue** ppBerValues = NULL;
    BYTE *pbAttributeValue = NULL;
    DWORD dwAttributeLength = 0;

    ppszAttrs[0] = pszAttribute;
    dwError = ldap_search_ext_s(
                pLd,
                pBase,
                ldapScope,
                pszFilter ? pszFilter : "",
                (PSTR*)ppszAttrs,
                0,
                NULL,
                NULL,
                NULL,
                -1,
                &pResult);
    BAIL_ON_VMDIR_ERROR(dwError);

    if (ldap_count_entries(pLd, pResult) > 0)
    {
        LDAPMessage* pEntry = ldap_first_entry(pLd, pResult);

        for (; pEntry != NULL; pEntry = ldap_next_entry(pLd, pEntry))
        {
            BerValue** ppBerValues = NULL;
            ppBerValues = ldap_get_values_len(pLd, pEntry, pszAttribute);
            if (ppBerValues != NULL && ldap_count_values_len(ppBerValues) > 0)
            {
                dwError = VmDirAllocateAndCopyMemory(
                            ppBerValues[0][0].bv_val,
                            ppBerValues[0][0].bv_len,
                            (PVOID*)&pbAttributeValue);
                BAIL_ON_VMDIR_ERROR(dwError);

                dwAttributeLength = ppBerValues[0][0].bv_len;
                break;
            }
        }
    }

    *ppbAttributeValue = pbAttributeValue;
    *pdwAttributeLength = dwAttributeLength;
    pbAttributeValue = NULL;

cleanup:
    VMDIR_SAFE_FREE_MEMORY(pbAttributeValue);

    if (ppBerValues)
    {
        ldap_value_free_len(ppBerValues);
        ppBerValues = NULL;
    }

    if (pResult)
    {
        ldap_msgfree(pResult);
        pResult = NULL;
    }

    return dwError;

error:
    goto cleanup;
}
Ejemplo n.º 11
0
/*
 * 1) Find the attribute that holds attribute meta data.
 * 2) Attributes for usnCreated/usnChanged are updated with current local USN
 * 3) If we are doing a modify/delete, attribute meta data is checked to see supplier/consumer wins.
 *        - If supplier attribute won, update its meta data with current local USN.
 *        - If consumer wins don't write corresponding attribute.
 *        - Special case: supplier lost for UsnChanged, replace the metaData with consumer's metaData.
 * 4) If no attribute metaData exists, create it.
 */
DWORD
VmDirReplSetAttrNewMetaData(
    PVDIR_OPERATION     pOperation,
    PVDIR_ENTRY         pEntry,
    PLW_HASHMAP*        ppMetaDataMap
    )
{
    DWORD               dwError = LDAP_SUCCESS;
    PVDIR_ATTRIBUTE     pCurrAttr = NULL;
    PVDIR_ATTRIBUTE     pPrevAttr = NULL;
    PVDIR_ATTRIBUTE     pAttrAttrMetaData = NULL;
    PLW_HASHMAP         pMetaDataMap = NULL;

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

    for (pPrevAttr = NULL, pCurrAttr = pEntry->attrs;
         pCurrAttr;
         pPrevAttr = pCurrAttr, pCurrAttr = pCurrAttr->next)
    {
        if (VmDirStringCompareA(pCurrAttr->type.lberbv.bv_val, ATTR_ATTR_META_DATA, FALSE) == 0)
        {
            if (pPrevAttr == NULL)
            {
                pEntry->attrs = pCurrAttr->next;
            }
            else
            {
                pPrevAttr->next = pCurrAttr->next;
            }

            pAttrAttrMetaData = pCurrAttr;

            dwError = VmDirAttributeMetaDataToHashMap(pAttrAttrMetaData, &pMetaDataMap);
            BAIL_ON_VMDIR_ERROR(dwError);

            *ppMetaDataMap = pMetaDataMap;
            continue;
        }

        if (VmDirStringCompareA(pCurrAttr->type.lberbv.bv_val, ATTR_USN_CREATED, FALSE) == 0 ||
            VmDirStringCompareA(pCurrAttr->type.lberbv.bv_val, ATTR_USN_CHANGED, FALSE) == 0)
        {
            char      pszLocalUsn[VMDIR_MAX_USN_STR_LEN] = {'\0'};
            size_t    localUsnStrlen = 0;

            dwError = VmDirStringNPrintFA(
                    pszLocalUsn,
                    sizeof(pszLocalUsn),
                    sizeof(pszLocalUsn) - 1,
                    "%"PRId64,
                    pOperation->pWriteQueueEle->usn);
            BAIL_ON_VMDIR_ERROR(dwError);

            localUsnStrlen = VmDirStringLenA(pszLocalUsn);

            VmDirFreeBervalContent(&pCurrAttr->vals[0]);

            dwError = VmDirAllocateAndCopyMemory(pszLocalUsn, localUsnStrlen, (PVOID*)&pCurrAttr->vals[0].lberbv.bv_val);
            BAIL_ON_VMDIR_ERROR(dwError);

            pCurrAttr->vals[0].lberbv.bv_len = localUsnStrlen;
            pCurrAttr->vals[0].bOwnBvVal = TRUE;
            continue;
        }
    }

    if (pAttrAttrMetaData == NULL)
    {
        VMDIR_LOG_ERROR(
                VMDIR_LOG_MASK_ALL,
                "%s: attrMetaData attribute not present in Entry: %s",
                __FUNCTION__,
                pEntry->dn.lberbv.bv_val);
        BAIL_WITH_VMDIR_ERROR(dwError, LDAP_OPERATIONS_ERROR);
    }

    if (pOperation->reqCode == LDAP_REQ_MODIFY)
    {
        dwError = VmDirReplResolveConflicts(
                pOperation,
                pEntry,
                pMetaDataMap);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    dwError = _VmDirReplPopulateAttrNewMetaData(
            pEntry,
            pOperation->pWriteQueueEle->usn,
            pMetaDataMap);
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:
    VmDirFreeAttribute(pAttrAttrMetaData);
    return dwError;

error:
    goto cleanup;
}