Пример #1
0
/*
 * Free a heap Attribute
 * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as
 * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function;
 * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs'
 */
VOID
VmDirFreeAttribute(
    PVDIR_ATTRIBUTE pAttr
    )
{
    if (!pAttr)
    {
        return;
    }

    // pAttr->type is always store in place and has NO bvnorm_val.  no need to free here.
    if (!dequeIsEmpty(&pAttr->valueMetaDataToAdd))
    {
        VmDirFreeAttrValueMetaDataDequeueContent(&pAttr->valueMetaDataToAdd);
    }
    if (!dequeIsEmpty(&pAttr->valueMetaDataToDelete))
    {
        VmDirFreeAttrValueMetaDataDequeueContent(&pAttr->valueMetaDataToDelete);
    }

    VmDirFreeMetaData(pAttr->pMetaData);

    VmDirFreeBervalContent(&pAttr->type);
    VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals);
    VMDIR_SAFE_FREE_MEMORY(pAttr->vals);
    VMDIR_SAFE_FREE_MEMORY(pAttr);
}
Пример #2
0
DWORD
VmDirEntryAttributeRemoveValue(
    PVDIR_ATTRIBUTE    pAttr,
    PCSTR              pszValue
    )
{
    DWORD             dwError = 0;
    DWORD             dwCnt = 0;
    DWORD             dwBervSize = 0;
    PVDIR_BERVALUE    pNewBerv = NULL;

    if (!pAttr || !pszValue)
    {
        BAIL_WITH_VMDIR_ERROR(dwError, ERROR_INVALID_PARAMETER);
    }

    //Actual size of pAttr->vals size is pAttr->numVals+1
    dwError = VmDirAllocateMemory(sizeof(VDIR_BERVALUE) * (pAttr->numVals), (PVOID*)&pNewBerv);
    BAIL_ON_VMDIR_ERROR(dwError);

    for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++)
    {
        if (VmDirStringCompareA(pszValue, pAttr->vals[dwCnt].lberbv_val, FALSE) != 0)
        {
            pNewBerv[dwBervSize] = pAttr->vals[dwCnt];
            memset(pAttr->vals + dwCnt, 0, sizeof(VDIR_BERVALUE));
            dwBervSize++;
        }
    }

    VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals);
    VMDIR_SAFE_FREE_MEMORY(pAttr->vals);

    pAttr->vals = pNewBerv;
    pAttr->numVals = dwBervSize;
    pNewBerv = NULL;

cleanup:
    return dwError;

error:
    VmDirFreeBervalArrayContent(pNewBerv, dwBervSize);
    VMDIR_SAFE_FREE_MEMORY(pNewBerv);
    VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError);
    goto cleanup;
}
Пример #3
0
void
VmDirModificationFree(
    PVDIR_MODIFICATION pMod
    )
{
    if (pMod != NULL)
    {
        VmDirFreeBervalArrayContent( pMod->attr.vals, pMod->attr.numVals );
        VMDIR_SAFE_FREE_MEMORY( pMod->attr.vals );
        VMDIR_SAFE_FREE_MEMORY( pMod );
    }
}
Пример #4
0
/*
 * Free a heap Attribute
 * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as
 * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function;
 * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs'
 */
VOID
VmDirFreeAttribute(
    PVDIR_ATTRIBUTE pAttr
    )
{
    if (!pAttr)
    {
        return;
    }

    // pAttr->type is always store in place and has NO bvnorm_val.  no need to free here.
    VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals);
    VMDIR_SAFE_FREE_MEMORY(pAttr->vals);
    VMDIR_SAFE_FREE_MEMORY(pAttr);
}
Пример #5
0
/*
 * Free a heap Attribute
 * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as
 * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function;
 * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs'
 */
VOID
VmDirFreeAttribute(
    PVDIR_ATTRIBUTE pAttr
    )
{
    if (!pAttr)
    {
        return;
    }

    VmDirFreeBervalContent(&pAttr->type);
    VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals);
    VMDIR_SAFE_FREE_MEMORY(pAttr->vals);
    VMDIR_SAFE_FREE_MEMORY(pAttr);
}
Пример #6
0
/*
 * reorder value of objectclass in pOCAttr->vals
 * 1. structureOC->parentOC->parentOC->....->TOP(not included)
 *    expand parent objectclass if not supplied.
 * 2. aux OCs
 * We then store its values in this order in backend.
 */
static
DWORD
_VmDirSchemaReorderObjectClassAttr(
    PVDIR_ATTRIBUTE         pOCAttr,
    PVDIR_SCHEMA_OC_DESC    pStructureOCDesc,
    PVDIR_SCHEMA_OC_DESC*   ppAuxOCDesc)
{
    DWORD       dwError = 0;
    int         iCnt = 0;
    int         iAUXCnt = 0;
    int         iTotal = 0;
    PVDIR_BERVALUE          pBerv = NULL;
    PVDIR_SCHEMA_OC_DESC    pLocalDesc = pStructureOCDesc;

    if ( !pOCAttr || !pStructureOCDesc )
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    // number of structure objectclass (except top)
    for (iCnt = 0; pLocalDesc != NULL; pLocalDesc = pLocalDesc->pStructSupOC, iCnt++) {}
    // number of aux objectclass
    for (iAUXCnt = 0; ppAuxOCDesc && ppAuxOCDesc[iAUXCnt] != NULL; iAUXCnt++) {};
    iTotal = iCnt + iAUXCnt;

    dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (iTotal + 1),
                                   (PVOID*)&pBerv);
    BAIL_ON_VMDIR_ERROR(dwError);

    // start with leaf structure objectclass and walk up the tree to top (NOT included)
    for (iCnt = 0, pLocalDesc = pStructureOCDesc;
         pLocalDesc != NULL;
         pLocalDesc = pLocalDesc->pStructSupOC, iCnt++)
    {
        PCSTR pszOrgName = NULL;
        unsigned int   iTmp = 0;

        for (iTmp = 0; iTmp < pOCAttr->numVals; iTmp++)
        {
            if (VmDirStringCompareA( pLocalDesc->pszName,
                                     pOCAttr->vals[iTmp].lberbv_val,
                                     FALSE) == 0)
            {   // keep whatever value provided from clients
                pszOrgName = pOCAttr->vals[iTmp].lberbv_val;
                break;
            }
        }

        dwError = VmDirAllocateStringA( pszOrgName ? pszOrgName : pLocalDesc->pszName,
                                        &(pBerv[iCnt].lberbv_val) );
        BAIL_ON_VMDIR_ERROR(dwError);

        pBerv[iCnt].lberbv_len = VmDirStringLenA(pBerv[iCnt].lberbv_val);
        pBerv[iCnt].bOwnBvVal = TRUE;
        // TODO, Do we need to normalize value here?
    }

    // append aux objectclasses after structure objectclasses
    for (iAUXCnt = 0; ppAuxOCDesc && ppAuxOCDesc[iAUXCnt] != NULL; iAUXCnt++, iCnt++)
    {
        PCSTR pszOrgName = NULL;
        unsigned int   iTmp = 0;

        for (iTmp = 0; iTmp < pOCAttr->numVals; iTmp++)
        {
            if (VmDirStringCompareA( ppAuxOCDesc[iAUXCnt]->pszName,
                                     pOCAttr->vals[iTmp].lberbv_val,
                                     FALSE) == 0)
            {   // keep whatever value provided from clients
                pszOrgName = pOCAttr->vals[iTmp].lberbv_val;
                break;
            }
        }

        dwError = VmDirAllocateStringA( pszOrgName ? pszOrgName : ppAuxOCDesc[iAUXCnt]->pszName,
                                        &(pBerv[iCnt].lberbv_val) );
        BAIL_ON_VMDIR_ERROR(dwError);

        pBerv[iCnt].lberbv_len = VmDirStringLenA(pBerv[iCnt].lberbv_val);
        pBerv[iCnt].bOwnBvVal = TRUE;
        // TODO, Do we need to normalize value here?
    }

    VmDirFreeBervalArrayContent( pOCAttr->vals, pOCAttr->numVals );
    VMDIR_SAFE_FREE_MEMORY( pOCAttr->vals );

    pOCAttr->vals = pBerv;
    pOCAttr->numVals = iTotal;

cleanup:

    return dwError;

error:

    VmDirFreeBervalArrayContent( pBerv, iTotal );
    VMDIR_SAFE_FREE_MEMORY( pBerv );

    goto cleanup;
}
Пример #7
0
void
VmDirFreeEntryContent(
   VDIR_ENTRY * e
   )
{
   VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: Begin" );

   if ( e )
   {
      VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: DN = %s",
              e ? (e->dn.lberbv.bv_val ? e->dn.lberbv.bv_val : "") : "" );

      if (e->pParentEntry)
      {
          VmDirFreeEntryContent(e->pParentEntry);
          VMDIR_SAFE_FREE_MEMORY(e->pParentEntry);
      }

      VmDirFreeLDAPDNContent( &(e->ldapDN) );
      VmDirFreeBervalContent( &(e->dn) );
      VmDirFreeBervalContent( &(e->pdn) );
      VmDirFreeBervalContent( &(e->newpdn) );

      if (e->allocType == ENTRY_STORAGE_FORMAT_PACK)
      {
         PVDIR_ATTRIBUTE    pCurrAttr = NULL;
         PVDIR_ATTRIBUTE    pTempAttr = NULL;

         pCurrAttr = e->attrs;
         while(pCurrAttr != NULL)
         {
             pTempAttr = pCurrAttr->next;
             VmDirFreeMetaData(pCurrAttr->pMetaData);
             pCurrAttr = pTempAttr;
         }
         VMDIR_SAFE_FREE_MEMORY( e->encodedEntry );
         VmDirFreeBervalArrayContent(e->bvs, e->usNumBVs);
         VMDIR_SAFE_FREE_MEMORY( e->bvs );
         VMDIR_SAFE_FREE_MEMORY( e->savedAttrsPtr );
      }
      else if (e->allocType == ENTRY_STORAGE_FORMAT_NORMAL)
      {
         VDIR_ATTRIBUTE * currAttr = NULL;
         VDIR_ATTRIBUTE * tmpAttr = NULL;

         VMDIR_SAFE_FREE_MEMORY( e->encodedEntry );

         for (currAttr = e->attrs; currAttr != NULL; )
         {
            tmpAttr = currAttr->next;
            VmDirFreeAttribute(currAttr);
            currAttr = tmpAttr;
         }
      }

      if (e->pComputedAttrs)
      {
          VDIR_ATTRIBUTE * currAttr = NULL;
          VDIR_ATTRIBUTE * tmpAttr = NULL;

          for (currAttr = e->pComputedAttrs; currAttr != NULL; )
          {
             tmpAttr = currAttr->next;
             VmDirFreeAttribute(currAttr);
             currAttr = tmpAttr;
          }
      }

      VmDirSchemaCtxRelease(e->pSchemaCtx);
      VmDirAclCtxContentFree(e->pAclCtx);
      VMDIR_SAFE_FREE_MEMORY(e->pAclCtx);
      VMDIR_SAFE_FREE_MEMORY(e->pszGuid);

      memset(e, 0, sizeof(*e));
   }

   VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: End" );
}
Пример #8
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;
}
Пример #9
0
void
VmDirSendLdapReferralResult(
   VDIR_OPERATION * op,
   PCSTR pszRefSuffix,
   PBOOLEAN pbRefSent
   )
{
   DWORD dwError = 0;
   BerElementBuffer berbuf;
   BerElement *     ber = (BerElement *) &berbuf;
   ber_int_t        msgId = 0;
   PCSTR            pszSocketInfo = NULL;
   PSTR             pszLeader = NULL;
   PSTR             pszRef = NULL;
   PVDIR_BERVALUE   pBerv = NULL;
   BOOLEAN          bIsLdaps = FALSE;

   *pbRefSent = FALSE;
   (void) memset( (char *)&berbuf, '\0', sizeof( BerElementBuffer ));

   msgId = op->msgId;

   ber_init2( ber, NULL, LBER_USE_DER );

   if (op->conn)
   {
      pszSocketInfo = op->conn->szClientIP;
   }

   dwError = VmDirRaftGetLeader(&pszLeader);
   BAIL_ON_VMDIR_ERROR(dwError);
   
   if (pszLeader == NULL)
   {
       //server self is a raft leader or leader cannot determined (e.g. in voting stage).
       goto done;
   }

   if (op->conn->dwServerPort == VmDirGetLdapsPort())
   {
       bIsLdaps = TRUE;
   }

   dwError = VmDirAllocateStringPrintf(&pszRef, "%s://%s/%s",
               bIsLdaps ? "ldaps":"ldap",
               pszLeader,
               pszRefSuffix );
   BAIL_ON_VMDIR_ERROR(dwError);

   op->ldapResult.errCode = 0;
   if ((op->reqCode == LDAP_REQ_SEARCH && gVmdirGlobals.dwEnableRaftReferral & VMDIR_RAFT_SEARCH_REFERRAL_ERROR_CODE) ||
       ((op->reqCode == LDAP_REQ_ADD || op->reqCode == LDAP_REQ_DELETE ||
         op->reqCode == LDAP_REQ_MODIFY || op->reqCode == LDAP_REQ_MODDN) &&
         gVmdirGlobals.dwEnableRaftReferral & VMDIR_RAFT_ENABLE_UPDATE_ERROR_CODE))
   {
       op->ldapResult.errCode = LDAP_REFERRAL;
   }

   dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * 2, (PVOID*)&pBerv);
   BAIL_ON_VMDIR_ERROR(dwError);

   pBerv[0].lberbv_len = VmDirStringLenA(pszRef);
   pBerv[0].lberbv_val = pszRef;
   pBerv[0].bOwnBvVal = TRUE;
   pBerv[1].lberbv_val = NULL;
   pBerv[1].lberbv_len = 0;

   dwError = ber_printf(ber, "{it{W}N}{it{ess}N}", msgId, LDAP_RES_SEARCH_REFERENCE, pBerv,
                        msgId, GetResultTag(op->reqCode), op->ldapResult.errCode, "", "");
   BAIL_ON_LBER_ERROR(dwError);

   dwError = WriteBerOnSocket( op->conn, ber );
   BAIL_ON_VMDIR_ERROR(dwError);

   *pbRefSent = TRUE;

   VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "VmDirSendLdapReferralResult: sent with referral %s", pszRef);

done:
   ber_free_buf( ber );
   VmDirFreeBervalArrayContent(pBerv, 1);
   VMDIR_SAFE_FREE_MEMORY(pBerv);
   VMDIR_SAFE_FREE_MEMORY(pszLeader);
   return;

error:
   goto done;
}