Exemple #1
0
static
int
WriteMetaDataAttribute(
   VDIR_OPERATION *             op,
   VDIR_ATTRIBUTE *             pAttr,
   int                          numAttrMetaData,
   PATTRIBUTE_META_DATA_NODE    pAttrMetaData,
   BerElement *                 ber,
   BOOLEAN *                    nonTrivialAttrsInReplScope,
   PSTR*                        ppszErrorMsg
   )
{
    int             retVal = LDAP_SUCCESS;
    VDIR_BERVALUE   attrMetaData = { {ATTR_ATTR_META_DATA_LEN, ATTR_ATTR_META_DATA}, 0, 0, NULL };
    int             i = 0;
    VDIR_BERVALUE   berVal = VDIR_BERVALUE_INIT;
    char            attrMetaDataVal[256 + VMDIR_MAX_ATTR_META_DATA_LEN];
    PSTR            pszLocalErrorMsg = NULL;

    *nonTrivialAttrsInReplScope = FALSE;

    if (ber_printf( ber, "{O[", &(attrMetaData) ) == -1 )
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print attribute name ...) failed" );
        retVal = LDAP_OTHER;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "Encoding attribute type failed.");
    }

    for ( ; pAttr != NULL; pAttr = pAttr->next)
    {
        // By this time, we have already filtered out attributes that should be send back to replication consumer
        // in prior WriteAttributes -> IsAttrInReplScope call.  They contain proper pAttr->metaData value.
        if (pAttr->metaData[0] != '\0')
        {
            VmDirStringPrintFA( attrMetaDataVal, sizeof(attrMetaDataVal), "%.256s:%s", pAttr->type.lberbv.bv_val, pAttr->metaData);
            berVal.lberbv.bv_val = attrMetaDataVal;
            berVal.lberbv.bv_len = VmDirStringLenA( attrMetaDataVal );
            if (VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_MODIFYTIMESTAMP, FALSE ) != 0 &&
                VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_USN_CHANGED, FALSE ) != 0)
            {
                // To prevent endless replication ping pong, supplier should send result only if there are changes
                // to attribute other than ATTR_USN_CHANGED and ATTR_MODIFYTIMESTAMP.
                *nonTrivialAttrsInReplScope = TRUE;
            }
            if (ber_printf( ber, "O", &berVal ) == -1 )
            {
                VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print an attribute value ...) failed." );
                retVal = LDAP_OTHER;
                BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                "Encoding an attribute value failed.");
            }
        }
    }
    // include attrMetaData for the deleted attributes
    for (i = 0; i<numAttrMetaData; i++)
    {
        if (pAttrMetaData[i].metaData[0] != '\0')
        {
            BOOLEAN                 bSendAttrMetaData = TRUE;
            PVDIR_SCHEMA_AT_DESC    pATDesc = NULL;

            if (op->syncReqCtrl != NULL) // Replication
            {
                retVal = IsAttrInReplScope( op, NULL, pAttrMetaData[i].metaData, &bSendAttrMetaData, &pszLocalErrorMsg );
                BAIL_ON_VMDIR_ERROR( retVal );
            }
            else
            {
                bSendAttrMetaData = TRUE;
            }
            if (bSendAttrMetaData)
            {
                if ((pATDesc = VmDirSchemaAttrIdToDesc(op->pSchemaCtx, pAttrMetaData[i].attrID)) == NULL)
                {
                    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL,
                              "WriteMetaDataAttribute: VmDirSchemaAttrIdToDesc failed for attribute id: %d.",
                              pAttrMetaData[i].attrID  );
                    retVal = LDAP_OTHER;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                    "WriteMetaDataAttribute: VmDirSchemaAttrIdToDesc failed.");
                }
                VmDirStringPrintFA( attrMetaDataVal, sizeof(attrMetaDataVal), "%.256s:%s", pATDesc->pszName, pAttrMetaData[i].metaData);
                berVal.lberbv.bv_val = attrMetaDataVal;
                berVal.lberbv.bv_len = VmDirStringLenA( attrMetaDataVal );
                *nonTrivialAttrsInReplScope = TRUE;
                if (ber_printf( ber, "O", &berVal ) == -1 )
                {
                    VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print an attribute value ...) failed." );
                    retVal = LDAP_OTHER;
                    BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                                    "Encoding an attribute value failed.");
                }
            }
        }
    }

    if ( ber_printf( ber, "]N}" ) == -1 )
    {
        VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to terminate an attribute's values ...) failed" );
        retVal = LDAP_OTHER;
        BAIL_ON_VMDIR_ERROR_WITH_MSG(   retVal, (pszLocalErrorMsg),
                                        "Encoding terminating an attribute type failed.");
    }

cleanup:

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

    return( retVal );

error:

    VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute failed (%u)(%s)",
                     retVal, VDIR_SAFE_STRING(pszLocalErrorMsg) );
    goto cleanup;
}
/* DecodeEntry: Decodes an Entry that was stored using EncodeEntry. Create the Entry structure from entry->encodedEntry
 * string.
 *
 */
DWORD
VmDirDecodeEntry(
   PVDIR_SCHEMA_CTX     pSchemaCtx,
   PVDIR_ENTRY          pEntry
   )
{
    DWORD               dwError = 0;
    int                 len = 0;
    int                 i = 0;
    int                 j = 0;
    int                 nAttrs = 0;
    int                 nVals = 0;
    VDIR_ATTRIBUTE *    pBeginAttr = NULL;
    VDIR_ATTRIBUTE *    pEndAttr = NULL;
    VDIR_ATTRIBUTE *    attr = NULL;
    unsigned char *     strPtr = NULL;
    VDIR_BERVALUE *     bvPtr = NULL;
    BOOLEAN             bKeepAttr = TRUE;

    if (pEntry == NULL || pSchemaCtx == NULL)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    pEntry->pSchemaCtx = VmDirSchemaCtxClone(pSchemaCtx);

    strPtr = pEntry->encodedEntry;
    nAttrs = VmDirDecodeShort(&strPtr);
    nVals = VmDirDecodeShort(&strPtr);

    dwError = VmDirInitializeEntry( pEntry, ENTRY_STORAGE_FORMAT_PACK, nAttrs, nVals);
    BAIL_ON_VMDIR_ERROR( dwError );

    bvPtr = (VDIR_BERVALUE *)pEntry->bvs;

   for (i = 0, attr = pEntry->attrs; i < nAttrs; attr = &(pEntry->attrs[++i]))
   {
       unsigned short usIdMap = VmDirDecodeShort(&strPtr);

       bKeepAttr = TRUE;

       // set pATDesc
       attr->pATDesc = VmDirSchemaAttrIdToDesc(pEntry->pSchemaCtx, usIdMap);
       if (attr->pATDesc == NULL)
       {
           if ( pEntry->eId == SUB_SCEHMA_SUB_ENTRY_ID    &&
                VmDirSchemaCtxIsBootStrap(pSchemaCtx) == TRUE   // bootstrap ctx
              )
           {    // bootstrap schema case, ignore attributes not defined in
                // schema/defines.h VDIR_SCHEMA_BOOTSTRP_ATTR_INITIALIZER table
                // while decoding schema entry during InitializeSchema call.
                bKeepAttr = FALSE;
           }
           else
           {
               dwError = VMDIR_ERROR_INVALID_ATTRIBUTETYPES;
               BAIL_ON_VMDIR_ERROR(dwError);
           }
       }

       if ( bKeepAttr )
       {
           // type.bv_val always uses in-place storage
           attr->type.lberbv.bv_val = attr->pATDesc->pszName;
           attr->type.lberbv.bv_len = VmDirStringLenA(attr->type.lberbv.bv_val);
       }

        // Keep consuming strPtr even if bKeepAttr is FALSE
        // Get number of attribute values
        j = VmDirDecodeShort(&strPtr);
        attr->numVals = j;
        attr->vals = bvPtr;

        // Set vals array
        while (j)
        {
            len = VmDirDecodeShort(&strPtr);
            bvPtr->lberbv.bv_len = len;
            bvPtr->lberbv.bv_val = (char *)strPtr;
            strPtr += len + 1; // Skipping \0
            bvPtr++;
            j--;
        }
        // Set the last BerValue in vals array.
        bvPtr->lberbv.bv_val = NULL;
        bvPtr->lberbv.bv_len = 0;
        bvPtr++;

        if ( bKeepAttr )
        {
            if (VmDirStringCompareA( attr->type.lberbv.bv_val, ATTR_DN, FALSE) == 0)
            {
                pEntry->dn = attr->vals[0];
            }

            if ( pBeginAttr == NULL )
            {
                pBeginAttr = attr;
                pEndAttr   = attr;
            }
            else
            {
                pEndAttr->next = attr;
                pEndAttr = attr;
            }
        }
    }

    if ( pBeginAttr == NULL )
    {
        dwError = VMDIR_ERROR_INVALID_ENTRY;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // reposition pEntry->attrs to the first kept attr
    pEntry->attrs = pBeginAttr;
    pEndAttr->next = NULL;

    dwError = VmDirNormalizeDN( &(pEntry->dn), pSchemaCtx );
    BAIL_ON_VMDIR_ERROR(dwError);

cleanup:

    return dwError;

error:

    VMDIR_LOG_ERROR ( VMDIR_LOG_MASK_ALL, "DecodeEntry failed (%u) DN:(%s)",
                      dwError, pEntry ? VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val) : "unknown" );

    goto cleanup;
}