BOOLEAN VmDirSchemaIsStructureOC( PVDIR_SCHEMA_CTX pCtx, PCSTR pszName ) { DWORD dwError = 0; BOOLEAN bRet = FALSE; PVDIR_SCHEMA_OC_DESC pOCDesc = NULL; if ( !pCtx || !pszName ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSchemaOCNameToDescriptor( pCtx, pszName, &pOCDesc ); BAIL_ON_VMDIR_ERROR(dwError); if ( pOCDesc && pOCDesc->type == VDIR_OC_STRUCTURAL ) { bRet = TRUE; } cleanup: return bRet; error: goto cleanup; }
DWORD VmDirEntryIsAttrAllowed( PVDIR_ENTRY pEntry, PSTR pszAttrName, PBOOLEAN pbMust, PBOOLEAN pbMay ) { DWORD dwError = 0; DWORD i = 0; PVDIR_ATTRIBUTE pAttrOC = NULL; PVDIR_SCHEMA_OC_DESC pOCDesc = NULL; PLW_HASHMAP pAllMustAttrMap = NULL; PLW_HASHMAP pAllMayAttrMap = NULL; if (!pEntry || IsNullOrEmptyString(pszAttrName)) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = LwRtlCreateHashMap(&pAllMustAttrMap, LwRtlHashDigestPstrCaseless, LwRtlHashEqualPstrCaseless, NULL); BAIL_ON_VMDIR_ERROR(dwError); dwError = LwRtlCreateHashMap(&pAllMayAttrMap, LwRtlHashDigestPstrCaseless, LwRtlHashEqualPstrCaseless, NULL); BAIL_ON_VMDIR_ERROR(dwError); pAttrOC = VmDirFindAttrByName(pEntry, ATTR_OBJECT_CLASS); for (i = 0; pAttrOC && i < pAttrOC->numVals; i++) { dwError = VmDirSchemaOCNameToDescriptor( pEntry->pSchemaCtx, pAttrOC->vals[i].lberbv.bv_val, &pOCDesc); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSchemaClassGetAllMustAttrs( pEntry->pSchemaCtx, pOCDesc, pAllMustAttrMap); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSchemaClassGetAllMayAttrs( pEntry->pSchemaCtx, pOCDesc, pAllMayAttrMap); BAIL_ON_VMDIR_ERROR(dwError); } if (pbMust) { *pbMust = FALSE; if (LwRtlHashMapFindKey(pAllMustAttrMap, NULL, pszAttrName) == 0) { *pbMust = TRUE; } } if (pbMay) { *pbMay = FALSE; if (LwRtlHashMapFindKey(pAllMayAttrMap, NULL, pszAttrName) == 0) { *pbMay = TRUE; } } cleanup: LwRtlHashMapClear(pAllMustAttrMap, VmDirNoopHashMapPairFree, NULL); LwRtlFreeHashMap(&pAllMustAttrMap); LwRtlHashMapClear(pAllMayAttrMap, VmDirNoopHashMapPairFree, NULL); LwRtlFreeHashMap(&pAllMayAttrMap); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError ); goto cleanup; }
/* * merge current and patch schema * 1. if new schema defined in patch, copy them over to current schema * 2. if both current and patch schema have schema definition, use value from patch schema * * The output is merged into pCurrentEntry. */ static DWORD VmDirSchemaPatchMerge( PVDIR_ENTRY pCurrentEntry, PVDIR_ENTRY pPatchEntry ) { DWORD dwError = 0; PVDIR_SCHEMA_INSTANCE pPatchSchema = NULL; PVDIR_ATTRIBUTE pAttr = NULL; USHORT usCnt = 0; dwError = _VmDirSchemaEntryToInstance( pPatchEntry, &pPatchSchema); BAIL_ON_VMDIR_ERROR(dwError); pAttr = VmDirEntryFindAttribute( VDIR_ATTRIBUTE_ATTRIBUTE_TYPES, pCurrentEntry ); assert( pAttr ); _VmDirSchemaNormalizeAttrValue( pAttr ); for (usCnt = 0; usCnt < pPatchSchema->ats.usNumATs; usCnt++) { PVDIR_SCHEMA_AT_DESC pATDesc = NULL; dwError = VmDirSchemaAttrNameToDescriptor( pCurrentEntry->pSchemaCtx, pPatchSchema->ats.pATSortName[ usCnt ].pszName, &pATDesc); if ( dwError == ERROR_NO_SUCH_ATTRIBUTE ) { dwError = VmDirEntryAddSingleValueStrAttribute( pCurrentEntry, VDIR_ATTRIBUTE_ATTRIBUTE_TYPES, pPatchSchema->ats.pATSortName[ usCnt ].pszDefinition); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, add - %s", VDIR_SAFE_STRING(pPatchSchema->ats.pATSortName[ usCnt ].pszDefinition)); } else { dwError = _VmDirSchemaAttrReplaceValue( pAttr, pPatchSchema->ats.pATSortName[ usCnt ].pszName, pPatchSchema->ats.pATSortName[ usCnt ].pszDefinition); BAIL_ON_VMDIR_ERROR(dwError); } } pAttr = VmDirEntryFindAttribute( VDIR_ATTRIBUTE_OBJECT_CLASSES, pCurrentEntry ); assert( pAttr ); _VmDirSchemaNormalizeAttrValue( pAttr ); for (usCnt = 0; usCnt < pPatchSchema->ocs.usNumOCs; usCnt++) { PVDIR_SCHEMA_OC_DESC pOCDesc = NULL; dwError = VmDirSchemaOCNameToDescriptor( pCurrentEntry->pSchemaCtx, pPatchSchema->ocs.pOCSortName[ usCnt ].pszName, &pOCDesc); if ( dwError == ERROR_NO_SUCH_OBJECTCLASS ) { dwError = VmDirEntryAddSingleValueStrAttribute( pCurrentEntry, VDIR_ATTRIBUTE_OBJECT_CLASSES, pPatchSchema->ocs.pOCSortName[ usCnt ].pszDefinition); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, add - %s", VDIR_SAFE_STRING(pPatchSchema->ocs.pOCSortName[ usCnt ].pszDefinition)); } else { dwError = _VmDirSchemaAttrReplaceValue( pAttr, pPatchSchema->ocs.pOCSortName[ usCnt ].pszName, pPatchSchema->ocs.pOCSortName[ usCnt ].pszDefinition); BAIL_ON_VMDIR_ERROR(dwError); } } pAttr = VmDirEntryFindAttribute( VDIR_ATTRIBUTE_DIT_CONTENTRULES, pCurrentEntry ); assert ( pAttr ); _VmDirSchemaNormalizeAttrValue( pAttr ); for (usCnt = 0; pAttr && usCnt < pPatchSchema->contentRules.usNumContents; usCnt++) { PVDIR_SCHEMA_CR_DESC pCRDesc = NULL; dwError = VmDirSchemaCRNameToDescriptor( pCurrentEntry->pSchemaCtx, pPatchSchema->contentRules.pContentSortName[ usCnt ].pszName, &pCRDesc); if ( dwError == ERROR_NO_SUCH_DITCONTENTRULES ) { dwError = VmDirEntryAddSingleValueStrAttribute( pCurrentEntry, VDIR_ATTRIBUTE_DIT_CONTENTRULES, pPatchSchema->contentRules.pContentSortName[ usCnt ].pszDefinition); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, add - %s", VDIR_SAFE_STRING(pPatchSchema->contentRules.pContentSortName[ usCnt ].pszDefinition)); } else { dwError = _VmDirSchemaAttrReplaceValue( pAttr, pPatchSchema->contentRules.pContentSortName[ usCnt ].pszName, pPatchSchema->contentRules.pContentSortName[ usCnt ].pszDefinition); BAIL_ON_VMDIR_ERROR(dwError); } } cleanup: if ( pPatchSchema ) { VdirSchemaInstanceFree(pPatchSchema); } return dwError; error: goto cleanup; }