/* a fixed time string comparision function */ BOOLEAN VmDirIsValidSecret( PCSTR pszTheirs, PCSTR pszOurs ) { ULONG ret = 0; int len = 0; int i = 0; PCSTR p = NULL; if (pszOurs == NULL) { return FALSE; } len = VmDirStringLenA(pszOurs); if (pszTheirs == NULL || VmDirStringLenA(pszTheirs) != len) { ret = 1; p = pszOurs; } else { p = pszTheirs; } for (i = len - 1; i >= 0; i--) ret |= p[i] ^ pszOurs[i]; return ret == 0; }
int VmDirCreateRequestVoteCtrl( PVDIR_REQUEST_VOTE_CONTROL_VALUE pRequestVoteCtrlValue, LDAPControl* pRequestVoteCtrl ) { int retVal = LDAP_SUCCESS; BerElement* pBer = NULL; BerValue candidateIdBV = {0}; BerValue lastLogIndexBV = {0}; if (!pRequestVoteCtrlValue || !pRequestVoteCtrl) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_INVALID_PARAMETER); } if ((pBer = ber_alloc()) == NULL) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } candidateIdBV.bv_val = pRequestVoteCtrlValue->candidateId; candidateIdBV.bv_len = VmDirStringLenA(pRequestVoteCtrlValue->candidateId); retVal = VmDirAllocateStringPrintf(&lastLogIndexBV.bv_val, "%"PRIu64, pRequestVoteCtrlValue->lastLogIndex); BAIL_ON_VMDIR_ERROR( retVal ); lastLogIndexBV.bv_len = VmDirStringLenA(lastLogIndexBV.bv_val); if ( ber_printf( pBer, "{iOOi}", pRequestVoteCtrlValue->term, &candidateIdBV, &lastLogIndexBV, pRequestVoteCtrlValue->lastLogTerm) == -1) { VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "%s: ber_printf failed.", __FUNCTION__ ); BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } memset( pRequestVoteCtrl, 0, sizeof( LDAPControl )); pRequestVoteCtrl->ldctl_oid = LDAP_REQUEST_VOTE_CONTROL; pRequestVoteCtrl->ldctl_iscritical = '1'; if (ber_flatten2(pBer, &pRequestVoteCtrl->ldctl_value, 1)) { BAIL_WITH_VMDIR_ERROR(retVal, VMDIR_ERROR_NO_MEMORY); } cleanup: VMDIR_SAFE_FREE_MEMORY(lastLogIndexBV.bv_val); if (pBer) { ber_free(pBer, 1); } return retVal; error: VmDirFreeCtrlContent(pRequestVoteCtrl); goto cleanup; }
//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; }
static DWORD VmDirRegConfigMultiStringToDwords( PCSTR pszValues, PDWORD* ppdwValues, DWORD* pdwValuesLen ) { DWORD dwError = 0; PDWORD pdwValues = NULL; DWORD dwValuesLen = 0; DWORD dwCount = 0; PCSTR pszIter = NULL; if (pszValues) { pszIter = pszValues; while (pszIter != NULL && *pszIter != '\0') { dwValuesLen++; pszIter += VmDirStringLenA(pszIter) + 1; } /* Allocate space for one even if no space is really needed, * that way we have a valid pointer. */ dwError = VmDirAllocateMemory(sizeof(DWORD) * (dwValuesLen == 0 ? 1 : dwValuesLen), (PVOID)&pdwValues); BAIL_ON_VMDIR_ERROR(dwError); pszIter = pszValues; while (pszIter != NULL && *pszIter != '\0') { DWORD dwVal = atoi(pszIter); pdwValues[dwCount++] = dwVal; pszIter += VmDirStringLenA(pszIter) + 1; } } *ppdwValues = pdwValues; *pdwValuesLen = dwValuesLen; cleanup: return dwError; error: VMDIR_SAFE_FREE_MEMORY(pdwValues); goto cleanup; }
DWORD VmDirDeleteEntryViaDN( PCSTR pszDN ) { DWORD dwError = 0; VDIR_OPERATION op = {0}; DeleteReq *dr = NULL; if (IsNullOrEmptyString(pszDN)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirInitStackOperation(&op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_DELETE, NULL); BAIL_ON_VMDIR_ERROR(dwError); op.pBEIF = VmDirBackendSelect(NULL); op.reqDn.lberbv_val = (PSTR)pszDN; op.reqDn.lberbv_len = VmDirStringLenA(pszDN); dr = &op.request.deleteReq; dr->dn.lberbv.bv_val = op.reqDn.lberbv.bv_val; dr->dn.lberbv.bv_len = op.reqDn.lberbv.bv_len; dwError = VmDirInternalDeleteEntry(&op); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeOperationContent(&op); return dwError; error: goto cleanup; }
static DWORD _CreateCopyOperation( LDAPMessage *pEntry, PVDIR_OPERATION pLdapOp ) { DWORD dwError = 0; dwError = VmDirInitStackOperation( pLdapOp, VDIR_OPERATION_TYPE_REPL, LDAP_REQ_MODIFY, NULL); BAIL_ON_VMDIR_ERROR(dwError); pLdapOp->pBEIF = VmDirBackendSelect(NULL); assert(pLdapOp->pBEIF); pLdapOp->reqDn.lberbv.bv_val = SUB_SCHEMA_SUB_ENTRY_DN; pLdapOp->reqDn.lberbv.bv_len = VmDirStringLenA(SUB_SCHEMA_SUB_ENTRY_DN); pLdapOp->request.modifyReq.dn.lberbv.bv_val = pLdapOp->reqDn.lberbv.bv_val; pLdapOp->request.modifyReq.dn.lberbv.bv_len = pLdapOp->reqDn.lberbv.bv_len; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s,%d failed, error(%d)", __FUNCTION__, __LINE__, dwError ); goto cleanup; }
/* * Allocate string into pDupBerval */ DWORD VmDirStringToBervalContent( PCSTR pszBerval, PVDIR_BERVALUE pDupBerval ) { DWORD dwError = 0; VmDirFreeBervalContent(pDupBerval); dwError = VmDirAllocateStringA(pszBerval, &pDupBerval->lberbv.bv_val); BAIL_ON_VMDIR_ERROR(dwError); pDupBerval->bOwnBvVal = TRUE; pDupBerval->lberbv.bv_len = VmDirStringLenA(pDupBerval->lberbv.bv_val); cleanup: return dwError; error: VmDirFreeBervalContent(pDupBerval); goto cleanup; }
/* * Convenient function to add a single "string" type attribute to pEntry. */ DWORD VmDirEntryAddSingleValueStrAttribute( PVDIR_ENTRY pEntry, PCSTR pszAttrName, PCSTR pszAttrValue) { DWORD dwError = 0; if (!pEntry || !pEntry->pSchemaCtx || !pszAttrName || !pszAttrValue) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirEntryAddSingleValueAttribute( pEntry, pszAttrName, pszAttrValue, VmDirStringLenA(pszAttrValue)); BAIL_ON_VMDIR_ERROR(dwError); error: return dwError; }
static DWORD VmDirRegConfigMultiStringToStrList( PCSTR pszValues, PVMDIR_STRING_LIST* ppStrList ) { DWORD dwError = 0; DWORD dwValuesLen = 0; PCSTR pszIter = NULL; PVMDIR_STRING_LIST pStrList = NULL; if (pszValues) { pszIter = pszValues; while (pszIter != NULL && *pszIter != '\0') { dwValuesLen++; pszIter += VmDirStringLenA(pszIter) + 1; } dwError = VmDirStringListInitialize(&pStrList, dwValuesLen); BAIL_ON_VMDIR_ERROR(dwError); pszIter = pszValues; while (pszIter != NULL && *pszIter != '\0') { dwError = VmDirStringListAddStrClone(pszIter, pStrList); BAIL_ON_VMDIR_ERROR(dwError); pszIter += VmDirStringLenA(pszIter) + 1; } *ppStrList = pStrList; pStrList = NULL; } cleanup: if (pStrList) { VmDirStringListFree(pStrList); } return dwError; error: goto cleanup; }
DWORD VmDirSimpleEntryDeleteAttribute( PCSTR pszDN, PCSTR pszAttr ) { DWORD dwError = 0; size_t dnlen = 0; size_t attrlen = 0; VDIR_OPERATION ldapOp = {0}; if (IsNullOrEmptyString(pszDN) || IsNullOrEmptyString(pszAttr)) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirInitStackOperation( &ldapOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, NULL); BAIL_ON_VMDIR_ERROR(dwError); dnlen = VmDirStringLenA(pszDN); attrlen = VmDirStringLenA(pszAttr); ldapOp.pBEIF = VmDirBackendSelect(NULL); ldapOp.reqDn.lberbv_val = (PSTR)pszDN; ldapOp.reqDn.lberbv_len = dnlen; ldapOp.request.modifyReq.dn.lberbv_val = ldapOp.reqDn.lberbv_val; ldapOp.request.modifyReq.dn.lberbv_len = ldapOp.reqDn.lberbv_len; dwError = VmDirAppendAMod( &ldapOp, MOD_OP_DELETE, pszAttr, attrlen, NULL, 0); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirInternalModifyEntry(&ldapOp); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeOperationContent(&ldapOp); return dwError; error: goto cleanup; }
/* * Create an Attribute on the heap and establish its pATDesc * two memory allocate * 1. pAttribute * 2. pAttribute->vals (BerValue array is one more then requested) */ DWORD VmDirAttributeAllocate( PCSTR pszName, USHORT usBerSize, PVDIR_SCHEMA_CTX pCtx, PVDIR_ATTRIBUTE* ppOutAttr) { DWORD dwError = 0; PVDIR_ATTRIBUTE pAttr = NULL; if (!ppOutAttr) { return 0; } dwError = VmDirAllocateMemory( sizeof(VDIR_ATTRIBUTE), (PVOID*)&pAttr); BAIL_ON_VMDIR_ERROR(dwError); // add one more BerValue as Encode/Decode entry in data store layer needs it. dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (usBerSize + 1), (PVOID*)&pAttr->vals); BAIL_ON_VMDIR_ERROR(dwError); pAttr->numVals = usBerSize; pAttr->pATDesc = VmDirSchemaAttrNameToDesc( pCtx, pszName); if (!pAttr->pATDesc) { dwError = VMDIR_ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR(dwError); } // pAttr->type.lberbv.bv_val always store in-place pAttr->type.lberbv.bv_val = pAttr->pATDesc->pszName; pAttr->type.lberbv.bv_len = VmDirStringLenA(pAttr->type.lberbv.bv_val); *ppOutAttr = pAttr; cleanup: return dwError; error: if (pAttr) { VmDirFreeAttribute(pAttr); } VmDirLog( LDAP_DEBUG_ANY, "AllocateAttribute failed (%d)(%s)", dwError, VDIR_SAFE_STRING(pszName)); goto cleanup; }
DWORD VmDirAppendAMod( PVDIR_OPERATION pOperation, int modOp, char * attrName, int attrNameLen, char * attrVal, size_t attrValLen ) { DWORD dwError = 0; VDIR_MODIFICATION * mod = NULL; ModifyReq * modReq = &(pOperation->request.modifyReq); VmDirLog( LDAP_DEBUG_TRACE, "appendAMod: Begin, entry DN = %s", modReq->dn.lberbv.bv_val ); dwError = VmDirAllocateMemory( sizeof( VDIR_MODIFICATION ), (PVOID *)&(mod) ); BAIL_ON_VMDIR_ERROR( dwError ); mod->operation = modOp; mod->attr.next = NULL; if ((mod->attr.pATDesc = VmDirSchemaAttrNameToDesc( pOperation->pSchemaCtx, attrName)) == NULL) { VmDirLog( LDAP_DEBUG_ANY, "appendAMod: VmDirSchemaAttrNameToDesc failed."); dwError = -1; /* Any value except 0 should do. */ BAIL_ON_VMDIR_ERROR( dwError ); } mod->attr.type.lberbv.bv_val = mod->attr.pATDesc->pszName; mod->attr.type.lberbv.bv_len = VmDirStringLenA(mod->attr.pATDesc->pszName); dwError = VmDirAllocateMemory( 2 * sizeof( VDIR_BERVALUE ), (PVOID *)&(mod->attr.vals) ); BAIL_ON_VMDIR_ERROR( dwError ); if ( attrVal && attrValLen > 0 ) { dwError = VmDirAllocateMemory( attrValLen + 1, (PVOID *)&(mod->attr.vals[0].lberbv.bv_val) ); BAIL_ON_VMDIR_ERROR( dwError ); dwError = VmDirCopyMemory( mod->attr.vals[0].lberbv.bv_val, attrValLen + 1, attrVal, attrValLen); BAIL_ON_VMDIR_ERROR( dwError ); mod->attr.vals[0].lberbv.bv_len = attrValLen; mod->attr.vals[0].bOwnBvVal = TRUE; mod->attr.numVals = 1; } mod->next = modReq->mods; modReq->mods = mod; modReq->numMods++; cleanup: VmDirLog( LDAP_DEBUG_TRACE, "appendAMod: End." ); return dwError; error: goto cleanup; }
static DWORD _VmDirSchemaCheckNameform( PVDIR_SCHEMA_CTX pCtx, PVDIR_ENTRY pEntry, PVDIR_SCHEMA_OC_DESC pStructOCDesc ) { DWORD dwError = 0; PSTR pszLocalErrorMsg = NULL; if ( !pCtx || !pStructOCDesc || !pEntry || !pEntry->dn.bvnorm_val ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } #if 0 // should NOT enable this until we have all namform and structure rule defined if ( pStructOCDesc->usNumMustRDNs > 0 ) { // not yet support multi RDNs case. only check the first MUST RDN for now. size_t iLen = VmDirStringLenA(pStructOCDesc->ppszMustRDNs[0]); if ( VmDirStringNCompareA( pEntry->dn.bvnorm_val, pStructOCDesc->ppszMustRDNs[0], iLen, FALSE ) != 0 || pEntry->dn.bvnorm_val[iLen] != '=' ) { dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrorMsg, "_VmDirSchemaCheckNameform: rdn must be (%s). (%d)", VDIR_SAFE_STRING( pStructOCDesc->ppszMustRDNs[0] ), dwError ); } } #endif cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return dwError; error: if ( !pCtx->pszErrorMsg ) { pCtx->pszErrorMsg = pszLocalErrorMsg; pszLocalErrorMsg = NULL; pCtx->dwErrorCode = dwError; } goto cleanup; }
DWORD VmDirMDBSimpleDnToEntry( PSTR pszEntryDN, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; VDIR_BERVALUE entryDn = VDIR_BERVALUE_INIT; VDIR_BACKEND_CTX mdbBECtx = {0}; BOOLEAN bHasTxn = FALSE; assert(pEntry); dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); entryDn.lberbv.bv_val = pszEntryDN; entryDn.lberbv.bv_len = VmDirStringLenA(entryDn.lberbv.bv_val); dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = TRUE; dwError = VmDirMDBDNToEntry( &mdbBECtx, pSchemaCtx, &entryDn, pEntry, VDIR_BACKEND_ENTRY_LOCK_READ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirMDBTxnCommit(&mdbBECtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } mdbBECtx.pBEPrivate = NULL; VmDirBackendCtxContentFree(&mdbBECtx); VmDirFreeBervalContent(&entryDn); return dwError; error: if (bHasTxn) { VmDirMDBTxnAbort(&mdbBECtx); } goto cleanup; }
/* * Convenient function to add a single attribute to pMod. * * Currently, only handle adding content to EMPTY pMod->attr and use with * pMod->operation = MOD_OP_REPLACE or MOD_OP_ADD or MOD_OP_DELETE * to manipulate ONE attribute value * */ DWORD VmDirModAddSingleValueAttribute( PVDIR_MODIFICATION pMod, PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszAttrName, PCSTR pszAttrValue, size_t iAttrValueLen ) { DWORD dwError = 0; if (!pMod || pMod->attr.pATDesc || pMod->attr.vals || !pSchemaCtx || !pszAttrName || !pszAttrValue || iAttrValueLen < 1) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // add one more BerValue as Encode/Decode entry in data store layer needs it. dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (1 + 1), (PVOID*)&pMod->attr.vals); BAIL_ON_VMDIR_ERROR(dwError); pMod->attr.numVals = 1; pMod->attr.pATDesc = VmDirSchemaAttrNameToDesc(pSchemaCtx, pszAttrName); if (!pMod->attr.pATDesc) { dwError = ERROR_NO_SCHEMA; BAIL_ON_VMDIR_ERROR(dwError); } // pAttr->type.lberbv.bv_val always store in-place pMod->attr.type.lberbv.bv_val = pMod->attr.pATDesc->pszName; pMod->attr.type.lberbv.bv_len = VmDirStringLenA(pMod->attr.type.lberbv.bv_val); dwError = VmDirAllocateMemory( iAttrValueLen + 1, // want string null terminated. (PVOID*)&pMod->attr.vals[0].lberbv.bv_val ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirCopyMemory( pMod->attr.vals[0].lberbv.bv_val, iAttrValueLen + 1, (PCVOID)pszAttrValue, iAttrValueLen ); BAIL_ON_VMDIR_ERROR(dwError); pMod->attr.vals[0].bOwnBvVal = TRUE; pMod->attr.vals[0].lberbv.bv_len = iAttrValueLen; cleanup: return dwError; error: // pMod owns the memory allocated in this function. goto cleanup; }
static DWORD schemaInitFillAttrFromCache( PVDIR_SCHEMA_CTX pCtx, PSTR* ppszValues, USHORT dwValueSize, PSTR pszAttrName, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; DWORD dwCnt = 0; VDIR_ATTRIBUTE* pAttr = NULL; dwError = VmDirAttributeAllocate( pszAttrName, dwValueSize, pCtx, &pAttr); BAIL_ON_VMDIR_ERROR(dwError); for (dwCnt = 0; dwCnt < dwValueSize; dwCnt++) { char* pszStr = &ppszValues[dwCnt][0]; //ignore leading spaces while (*pszStr == ' ') pszStr++; dwError = VmDirAllocateStringA( ppszValues[dwCnt], &pAttr->vals[dwCnt].lberbv.bv_val); BAIL_ON_VMDIR_ERROR(dwError); pAttr->vals[dwCnt].bOwnBvVal = TRUE; pAttr->vals[dwCnt].lberbv.bv_len = VmDirStringLenA(pAttr->vals[dwCnt].lberbv.bv_val); } dwError = VmDirEntryAddAttribute( pEntry, pAttr); BAIL_ON_VMDIR_ERROR(dwError); pAttr = NULL; cleanup: return dwError; error: if (pAttr) { VmDirFreeAttribute(pAttr); } goto cleanup; }
DWORD VmDirConfigSetDefaultSiteandLduGuid( PCSTR pszDefaultSiteGuid, PCSTR pszDefaultLduGuid ) #ifndef _WIN32 { DWORD dwError = 0; if (IsNullOrEmptyString(pszDefaultSiteGuid) || IsNullOrEmptyString(pszDefaultLduGuid)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = RegUtilSetValue( NULL, HKEY_THIS_MACHINE, VMDIR_CONFIG_PARAMETER_KEY_PATH, NULL, VMDIR_REG_KEY_SITE_GUID, REG_SZ, (PVOID)pszDefaultSiteGuid, VmDirStringLenA(pszDefaultSiteGuid)+1); BAIL_ON_VMDIR_ERROR(dwError); dwError = RegUtilSetValue( NULL, HKEY_THIS_MACHINE, VMDIR_CONFIG_PARAMETER_KEY_PATH, NULL, VMDIR_REG_KEY_LDU_GUID, REG_SZ, (PVOID)pszDefaultLduGuid, VmDirStringLenA(pszDefaultLduGuid)+1); BAIL_ON_VMDIR_ERROR(dwError); cleanup: return dwError; error: VmDirLog(LDAP_DEBUG_ANY, "VmDirConfigSetDefaultSiteandLduGuid failed with error (%u)", dwError); goto cleanup; }
static DWORD _VmDirSchemaAttrReplaceValue( PVDIR_ATTRIBUTE pAttr, PCSTR pszMatchSubstr, PCSTR pszValue ) { #define MAX_BUF_SIZE_256 256 DWORD dwError = 0; unsigned iCnt = 0; CHAR pszBuf[MAX_BUF_SIZE_256] = {0}; dwError = VmDirStringPrintFA( pszBuf, MAX_BUF_SIZE_256 -1 , "NAME '%s' ", pszMatchSubstr ); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt = 0; iCnt < pAttr->numVals; iCnt++) { if ( VmDirCaselessStrStrA( pAttr->vals[iCnt].lberbv_val, pszBuf ) != NULL ) { if ( VmDirStringCompareA( VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val), pszValue, FALSE ) != 0 ) { VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, replace old - %s", VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val)); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, replace new - %s", pszValue ); } VMDIR_LOG_DEBUG( VMDIR_LOG_MASK_ALL, "Merge schema, replace old - %s", VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val)); VmDirFreeBervalContent( &(pAttr->vals[iCnt]) ); dwError = VmDirAllocateStringA( pszValue, &(pAttr->vals[iCnt].lberbv_val) ); BAIL_ON_VMDIR_ERROR(dwError); pAttr->vals[iCnt].lberbv_len = VmDirStringLenA( pszValue ); pAttr->vals[iCnt].bOwnBvVal = TRUE; VMDIR_LOG_DEBUG( VMDIR_LOG_MASK_ALL, "Merge schema, replace new - %s", VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val)); break; } } cleanup: return dwError; error: goto cleanup; }
/* * pEntry is created from a difference instance of schema. * Path it to use new instance it now associates with. * 1. inpalce menory of pAttr->type * 2. pEntry->pSchemaCtx */ static DWORD _VmDirSchemaInitFixBootstrapEntry( PVDIR_SCHEMA_INSTANCE pSchema, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; VDIR_ATTRIBUTE* pAttr = NULL; PVDIR_SCHEMA_CTX pNewCtx = NULL; dwError = VmDirAllocateMemory( sizeof(*pNewCtx), (PVOID)&pNewCtx ); BAIL_ON_VMDIR_ERROR(dwError); // create the very first ctx for pSchema pNewCtx->pSchema = pSchema; pNewCtx->pSchema->usRefCount++; // switch pEntry to use the new schema instance it creates. VmDirSchemaCtxRelease(pEntry->pSchemaCtx); pEntry->pSchemaCtx = pNewCtx; pNewCtx = NULL; for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { USHORT usId = pAttr->pATDesc->usAttrID; PVDIR_SCHEMA_AT_DESC pResult = pSchema->ats.ppATSortIdMap[usId - 1]; if (!pResult) { // this should never happen as attribute ID never change once it is assigned. dwError = ERROR_INVALID_SCHEMA; BAIL_ON_VMDIR_ERROR(dwError); } // patch Attribute.pATDesc pAttr->pATDesc = pResult; // patch Attribute.type in-place storage as well pAttr->type.lberbv.bv_val = pResult->pszName; pAttr->type.lberbv.bv_len = VmDirStringLenA(pAttr->type.lberbv.bv_val); } cleanup: return dwError; error: if ( pNewCtx ) { VmDirSchemaCtxRelease( pNewCtx ); } goto cleanup; }
static DWORD _VmDirSchemaComputeAllowedChildClassesEffective( PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE* ppOutAttr ) { DWORD dwError = 0; PVDIR_SCHEMA_OC_DESC pStructureOCDesc = NULL; PVDIR_ATTRIBUTE pLocalAttr = NULL; int iCnt = 0; dwError = VmDirSchemaGetEntryStructureOCDesc( pEntry, &pStructureOCDesc ); BAIL_ON_VMDIR_ERROR(dwError); if ( !pStructureOCDesc ) { dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } for (iCnt = 0; pStructureOCDesc->ppszAllowedChildOCs && pStructureOCDesc->ppszAllowedChildOCs[iCnt]; iCnt++) {} if (iCnt > 0) { dwError = VmDirAttributeAllocate( ATTR_ALLOWD_CHILD_CLASSES_EFFECTIVE, iCnt, pEntry->pSchemaCtx, &pLocalAttr); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt = 0; pStructureOCDesc->ppszAllowedChildOCs[iCnt]; iCnt++) { dwError = VmDirAllocateStringA( pStructureOCDesc->ppszAllowedChildOCs[iCnt], &(pLocalAttr->vals[iCnt].lberbv_val)); BAIL_ON_VMDIR_ERROR(dwError); pLocalAttr->vals[iCnt].lberbv_len = VmDirStringLenA(pLocalAttr->vals[iCnt].lberbv_val); pLocalAttr->vals[iCnt].bOwnBvVal = TRUE; } } *ppOutAttr = pLocalAttr; cleanup: return dwError; error: VmDirFreeAttribute( pLocalAttr ); goto cleanup; }
/* * FROM and TO Attributes use same schema context */ DWORD VmDirAttributeDup( PVDIR_ATTRIBUTE pAttr, PVDIR_ATTRIBUTE* ppDupAttr ) { DWORD dwError = 0; DWORD dwCnt = 0; PVDIR_ATTRIBUTE pAttribute = NULL; assert(pAttr && ppDupAttr); dwError = VmDirAllocateMemory( sizeof(VDIR_ATTRIBUTE), (PVOID*)&pAttribute); BAIL_ON_VMDIR_ERROR(dwError); // add one more BerValue as Encode/Decode entry in data store layer needs it. dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (pAttr->numVals + 1), (PVOID*)&pAttribute->vals); BAIL_ON_VMDIR_ERROR(dwError); for (dwCnt = 0 ; dwCnt < pAttr->numVals; dwCnt++) { dwError = VmDirBervalContentDup( &pAttr->vals[dwCnt], &pAttribute->vals[dwCnt]); BAIL_ON_VMDIR_ERROR(dwError); pAttribute->numVals = dwCnt + 1; } // use the same pATDesc and type from pAttr pAttribute->pATDesc = pAttr->pATDesc; // type.lberbv.bv_val always store in-place pAttribute->type.lberbv.bv_val = pAttr->pATDesc->pszName; pAttribute->type.lberbv.bv_len = VmDirStringLenA(pAttr->type.lberbv.bv_val); *ppDupAttr = pAttribute; cleanup: return dwError; error: if (pAttribute) { VmDirFreeAttribute(pAttribute); } goto cleanup; }
static DWORD _VmDirSimpleEntryCreateInBEWithGuid( PVDIR_BACKEND_INTERFACE pBE, PVDIR_SCHEMA_CTX pSchemaCtx, PSTR* ppszEntryInitializer, PSTR pszDN, ENTRYID ulEntryId, PSTR pszGuid /* Optional */ ) { DWORD dwError = 0; VDIR_OPERATION ldapOp = {0}; dwError = VmDirInitStackOperation( &ldapOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_ADD, pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.pBEIF = pBE; assert(ldapOp.pBEIF); ldapOp.reqDn.lberbv.bv_val = pszDN; ldapOp.reqDn.lberbv.bv_len = VmDirStringLenA(pszDN); dwError = AttrListToEntry( pSchemaCtx, pszDN, ppszEntryInitializer, ldapOp.request.addReq.pEntry); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.request.addReq.pEntry->eId = ulEntryId; if (!IsNullOrEmptyString(pszGuid)) { dwError = VmDirAllocateStringA(pszGuid, &ldapOp.request.addReq.pEntry->pszGuid); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInternalAddEntry(&ldapOp); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeOperationContent(&ldapOp); return dwError; error: goto cleanup; }
/* * pszString is expected to be a multistring. * A multistring consists of a list of zero or more non-empty nul-terminated * strings in which the list is terminated with nul. * * Examples: * A list with one string ("abc"): abc\0\0 * A list with two strings ("abc", "d"): abc\0d\0\0 * An empty list: \0 * An INVALID multistring (No string may be empty): abc\0\0\dce\0\0 * * Note that some believe all multistrings are 'double terminated'; the * empty list is not. * */ DWORD VmDirAllocateMultiStringA( PCSTR pszString, PSTR* ppszString ) { DWORD dwError = 0; PCSTR pszIter = NULL; PSTR pszNewString = NULL; size_t dwLen = 0; if (!pszString || !ppszString) { if (ppszString) { *ppszString = NULL; } return VMDIR_ERROR_INVALID_PARAMETER; } pszIter = pszString; while (*pszIter != '\0') { pszIter += VmDirStringLenA(pszIter) + 1; } dwLen = (pszIter - pszString) + 1; dwError = VmDirAllocateMemory(dwLen, (PVOID*)&pszNewString); BAIL_ON_VMDIR_ERROR(dwError); #ifndef _WIN32 memcpy(pszNewString, pszString, dwLen); #else memcpy_s(pszNewString, dwLen, pszString, dwLen); #endif *ppszString = pszNewString; cleanup: return dwError; error: VMDIR_SAFE_FREE_MEMORY(pszNewString); goto cleanup; }
static int _VmDirSASLSRPInteraction( LDAP * pLd, unsigned flags, void * pDefaults, void * pIn ) { sasl_interact_t* pInteract = pIn; PVMDIR_SASL_INTERACTIVE_DEFAULT pDef = pDefaults; while( (pDef != NULL) && (pInteract->id != SASL_CB_LIST_END) ) { switch( pInteract->id ) { case SASL_CB_GETREALM: pInteract->defresult = pDef->pszRealm; break; case SASL_CB_AUTHNAME: pInteract->defresult = pDef->pszAuthName; break; case SASL_CB_PASS: pInteract->defresult = pDef->pszPass; break; case SASL_CB_USER: pInteract->defresult = pDef->pszUser; break; default: break; } pInteract->result = (pInteract->defresult) ? pInteract->defresult : ""; pInteract->len = (unsigned int) VmDirStringLenA( pInteract->result ); pInteract++; } return LDAP_SUCCESS; }
DWORD VmDirKrbRealmNameNormalize( PCSTR pszName, PSTR* ppszNormalizeName ) { DWORD dwError = 0; PSTR pszRealmName = NULL; if ( !pszName || !ppszNormalizeName) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocateStringA(pszName, &pszRealmName); BAIL_ON_VMDIR_ERROR(dwError); { size_t iCnt=0; size_t iLen = VmDirStringLenA(pszRealmName); for (iCnt = 0; iCnt < iLen; iCnt++) { VMDIR_ASCII_LOWER_TO_UPPER(pszRealmName[iCnt]); } } *ppszNormalizeName = pszRealmName; cleanup: return dwError; error: VmDirFreeMemory(pszRealmName); goto cleanup; }
DWORD VmDirResetPassword( PCSTR pszUPN, PCSTR pszNewPassword ) { DWORD dwError = 0; VDIR_BERVALUE bvPassword = VDIR_BERVALUE_INIT; PSTR pszDN = NULL; if ( IsNullOrEmptyString(pszUPN) || IsNullOrEmptyString(pszNewPassword) ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirUPNToDN( pszUPN, &pszDN ); BAIL_ON_VMDIR_ERROR(dwError); bvPassword.lberbv_val = (PSTR)pszNewPassword; bvPassword.lberbv_len = VmDirStringLenA(pszNewPassword); dwError = VmDirInternalEntryAttributeReplace( NULL, pszDN, ATTR_USER_PASSWORD, &bvPassword); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeBervalContent(&bvPassword); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirResetPassword (%s) failed, (%u)", VDIR_SAFE_STRING(pszUPN), dwError); 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; }
DWORD VmDirAllocateStringA( PCSTR pszString, PSTR* ppszString ) { DWORD dwError = 0; PSTR pszNewString = NULL; size_t dwLen = 0; if (!pszString || !ppszString) { if (ppszString) { *ppszString = NULL; } return 0; } dwLen = VmDirStringLenA(pszString); // + 1 for \'0' dwError = VmDirAllocateMemory(dwLen + 1, (PVOID*)&pszNewString); BAIL_ON_VMDIR_ERROR(dwError); #ifndef _WIN32 memcpy(pszNewString, pszString, dwLen); #else memcpy_s(pszNewString, (dwLen + 1), pszString, dwLen); #endif *ppszString = pszNewString; cleanup: return dwError; error: VMDIR_SAFE_FREE_MEMORY(pszNewString); goto cleanup; }
/* * read one schema element definition from file and normalize its definition. */ static DWORD _VmDirReadOneDefFromFile( FILE* fp, PVMDIR_STRING_LIST pStrList ) { DWORD dwError = 0; size_t iSize = VMDIR_SIZE_9216, iLen = 0; CHAR pDescBuf[VMDIR_SIZE_9216+1] = {0}; CHAR pbuf[VMDIR_SIZE_4096] = {0}; PCSTR pPrefix = "( "; size_t iPrefixLen = VmDirStringLenA(pPrefix); PSTR pOut = NULL; dwError = VmDirStringNCatA( pDescBuf+iLen, iSize-iLen, pPrefix, iPrefixLen); BAIL_ON_VMDIR_ERROR(dwError); iLen += iPrefixLen; while (fgets(pbuf, sizeof(pbuf), fp) != NULL) { size_t len = VmDirStringLenA(pbuf) - 1; if (pbuf[len] == '\n') { pbuf[len] = '\0'; } if ( pbuf[0] == '#') { continue; } if ( pbuf[0] == ' ') { dwError = VmDirStringNCatA( pDescBuf+iLen, iSize-iLen, pbuf, VmDirStringLenA(pbuf)); BAIL_ON_VMDIR_ERROR(dwError); iLen += VmDirStringLenA(pbuf); } else { break; } } if (pDescBuf[0] != '\0') { VmdDirNormalizeString(pDescBuf); dwError = VmDirAllocateStringA(pDescBuf, &pOut); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringListAdd(pStrList, pOut); BAIL_ON_VMDIR_ERROR(dwError); pOut = NULL; } cleanup: return dwError; error: VMDIR_SAFE_FREE_MEMORY(pOut); goto cleanup; }
/* * This is NOT RFC 4514 compliance. * * 1. separate into RDNs * 2. for each RDN, normalize value based on its syntax * (does not handle multi-value RDN case) * remove all leading/trailing spaces * 3. reconstruct DN based on RDNs */ DWORD VmDirNormalizeDN( PVDIR_BERVALUE pBerv, PVDIR_SCHEMA_CTX pSchemaCtx ) { DWORD dwError = 0; PSTR pszTmpDN = NULL; PSTR* ppszRDNs = NULL; PSTR* ppszNormRDNs = NULL; int iNumRDNs = 0; int iCnt = 0; size_t iNormDNSize = 0; PVDIR_SCHEMA_CTX pCtx = pSchemaCtx; if (!pBerv || !pBerv->lberbv.bv_val) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // Already normalized. => Nothing to be done. if ( pBerv->bvnorm_val != NULL ) { dwError = 0; goto cleanup; } // Nothing to be normalized for the ROOT DN if (pBerv->lberbv.bv_len == 0) { pBerv->bvnorm_val = pBerv->lberbv.bv_val; pBerv->bvnorm_len = 0; dwError = 0; goto cleanup; } if (pCtx == NULL) { dwError = VmDirSchemaCtxAcquire(&pCtx); BAIL_ON_VMDIR_ERROR(dwError); } // make a local copy dwError = VmDirAllocateStringA( pBerv->lberbv.bv_val, &pszTmpDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VdirSchemaInPlaceDN2RDNs( pszTmpDN, &ppszRDNs, &iNumRDNs); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateMemory( sizeof(PSTR) * (iNumRDNs + 1), (PVOID)&ppszNormRDNs); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt=0; ppszRDNs[iCnt] && iCnt < iNumRDNs; iCnt++) { size_t iNameLen = 0 ; VDIR_BERVALUE berval = VDIR_BERVALUE_INIT; PVDIR_SCHEMA_AT_DESC pATDesc = NULL; char* pChar = VmDirStringChrA(ppszRDNs[iCnt], '='); if (!pChar) { dwError = ERROR_INVALID_DN; BAIL_ON_VMDIR_ERROR(dwError); } *pChar = '\0'; iNameLen = VmDirStringLenA(ppszRDNs[iCnt]); // attribute name - remove all leading/trailing spaces while (ppszRDNs[iCnt][iNameLen-1] == ' ') { ppszRDNs[iCnt][iNameLen-1] = '\0'; iNameLen--; assert(iNameLen > 0); // MIN 1 char for name } while (ppszRDNs[iCnt][0] == ' ') { ppszRDNs[iCnt]++; } pATDesc = VmDirSchemaAttrNameToDesc(pCtx, ppszRDNs[iCnt]); if (!pATDesc) { dwError = ERROR_INVALID_DN; BAIL_ON_VMDIR_ERROR(dwError); } berval.lberbv.bv_val = pChar+1; berval.lberbv.bv_len = VmDirStringLenA(berval.lberbv.bv_val); dwError = VmDirSchemaBervalNormalize(pCtx, pATDesc, &berval); BAIL_ON_VMDIR_ERROR(dwError); if (berval.bvnorm_len == 0) { dwError = ERROR_INVALID_DN; BAIL_ON_VMDIR_ERROR(dwError); } if (berval.lberbv.bv_val == berval.bvnorm_val) { dwError = VmDirAllocateStringA( berval.lberbv.bv_val, &ppszNormRDNs[iCnt]); BAIL_ON_VMDIR_ERROR(dwError); } else { // ppszNormRDNs takes over bvnorm_val ppszNormRDNs[iCnt] = berval.bvnorm_val; } iNormDNSize = iNormDNSize + berval.bvnorm_len + (pChar - ppszRDNs[iCnt]) + 2; } // Reconstruct normalized DN VMDIR_SAFE_FREE_MEMORY(pBerv->bvnorm_val); pBerv->bvnorm_len = 0; dwError = VmDirAllocateMemory( sizeof(char) * (iNormDNSize+1), (PVOID)&pBerv->bvnorm_val); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt = 0; ppszNormRDNs[iCnt] && iCnt < iNumRDNs; iCnt++) { size_t iValueLen = VmDirStringLenA(ppszNormRDNs[iCnt]); int iValueOffset = 0; // attribute value - remove leading/trailing spaces while (ppszNormRDNs[iCnt][iValueOffset] == ' ') { iValueOffset++; assert(iValueOffset < iValueLen); } while (ppszNormRDNs[iCnt][iValueLen-1] == ' ') { ppszNormRDNs[iCnt][iValueLen-1] = '\0'; iValueLen--; assert(iValueLen > 0); } // attribute name to lower case { char* pToLower = NULL; for (pToLower = ppszRDNs[iCnt]; *pToLower != '\0'; pToLower++) { *pToLower = (char) tolower(*pToLower); } } VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ppszRDNs[iCnt]); VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), "="); VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ppszNormRDNs[iCnt]+iValueOffset); if (iCnt + 1 < iNumRDNs) { VmDirStringCatA(pBerv->bvnorm_val, (iNormDNSize+1), ","); } } pBerv->bvnorm_len = VmDirStringLenA(pBerv->bvnorm_val); cleanup: if (pCtx && pCtx != pSchemaCtx) { VmDirSchemaCtxRelease(pCtx); } VMDIR_SAFE_FREE_MEMORY(pszTmpDN); VMDIR_SAFE_FREE_MEMORY(ppszRDNs); // ppszRDNs[i] is in place of pszTmpDN VmDirFreeStringArrayA(ppszNormRDNs); VMDIR_SAFE_FREE_MEMORY(ppszNormRDNs); return dwError; error: goto cleanup; }