//Add one more single value replace mod onto the LdapOp's mods DWORD VmDirAddModSingleAttributeReplace( PVDIR_OPERATION pLdapOp, PCSTR pszNormDN, PCSTR pszAttrName, PVDIR_BERVALUE pBervAttrValue ) { DWORD dwError = 0; PVDIR_MODIFICATION pMod = NULL; if (!pszNormDN || !pszAttrName || !pBervAttrValue) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } pLdapOp->reqDn.lberbv.bv_val = (PSTR)pszNormDN; pLdapOp->reqDn.lberbv.bv_len = VmDirStringLenA(pszNormDN); dwError = VmDirAllocateMemory(sizeof(*pMod)*1, (PVOID)&pMod); BAIL_ON_VMDIR_ERROR(dwError); pMod->operation = MOD_OP_REPLACE; dwError = VmDirModAddSingleValueAttribute( pMod, pLdapOp->pSchemaCtx, pszAttrName, pBervAttrValue->lberbv.bv_val, pBervAttrValue->lberbv.bv_len); BAIL_ON_VMDIR_ERROR(dwError); pLdapOp->request.modifyReq.dn.lberbv.bv_val = (PSTR)pszNormDN; pLdapOp->request.modifyReq.dn.lberbv.bv_len = VmDirStringLenA(pszNormDN); pMod->next = pLdapOp->request.modifyReq.mods; pLdapOp->request.modifyReq.mods = pMod; pLdapOp->request.modifyReq.numMods++; pMod = NULL; cleanup: if (pMod) { VmDirModificationFree(pMod); } return dwError; error: goto cleanup; }
/* * Convenient function to add a single "string" type attribute to pMod. */ DWORD VmDirModAddSingleStrValueAttribute( PVDIR_MODIFICATION pMod, PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszAttrName, PCSTR pszAttrValue ) { DWORD dwError = 0; dwError = VmDirModAddSingleValueAttribute( pMod, pSchemaCtx, pszAttrName, pszAttrValue, pszAttrValue ? VmDirStringLenA(pszAttrValue) : 0); BAIL_ON_VMDIR_ERROR(dwError); error: return dwError; }
/* * Convenient function to replace ONE single value attribute via InternalModifyEntry * ***************************************************************************** * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * You should NOT call this function while in a backend txn/ctx. * ***************************************************************************** * This may not be easy to determine as we could call this in different places, which * may be nested in external and internal OPERATION. * A better approach is to pass in pOperation and use the same beCtx if exists. * However, this could also cause logic error, e.g. you could lost track if entry/data * has already been changed by beCtx and reread them. * ***************************************************************************** */ DWORD VmDirInternalEntryAttributeReplace( PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszNormDN, PCSTR pszAttrName, PVDIR_BERVALUE pBervAttrValue ) { DWORD dwError = 0; VDIR_OPERATION ldapOp = {0}; PVDIR_MODIFICATION pMod = NULL; if (!pszNormDN || !pszAttrName || !pBervAttrValue) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInitStackOperation( &ldapOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.pBEIF = VmDirBackendSelect(pszNormDN); assert(ldapOp.pBEIF); ldapOp.reqDn.lberbv.bv_val = (PSTR)pszNormDN; ldapOp.reqDn.lberbv.bv_len = VmDirStringLenA(pszNormDN); dwError = VmDirAllocateMemory(sizeof(*pMod)*1, (PVOID)&pMod); BAIL_ON_VMDIR_ERROR(dwError); pMod->next = NULL; pMod->operation = MOD_OP_REPLACE; dwError = VmDirModAddSingleValueAttribute( pMod, ldapOp.pSchemaCtx, pszAttrName, pBervAttrValue->lberbv.bv_val, pBervAttrValue->lberbv.bv_len); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.request.modifyReq.dn.lberbv.bv_val = (PSTR)pszNormDN; ldapOp.request.modifyReq.dn.lberbv.bv_len = VmDirStringLenA(pszNormDN); ldapOp.request.modifyReq.mods = pMod; pMod = NULL; ldapOp.request.modifyReq.numMods = 1; dwError = VmDirInternalModifyEntry(&ldapOp); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeOperationContent(&ldapOp); if (pMod) { VmDirModificationFree(pMod); } return dwError; error: goto cleanup; }