/* * 1. convert patch file into pNewEntry * 2. merge changes in pNewEntry INTO pEntry * * NOTE, Lotus schema/patch file should NEVER delete schema definitions. */ DWORD VmDirSchemaPatchFileToEntry( PCSTR pszSchemaFilePath, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; PVDIR_ENTRY pNewEntry = NULL; if ( !pszSchemaFilePath || !pEntry ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSchemaInitalizeFileToEntry( pszSchemaFilePath, &pNewEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSchemaPatchMerge( pEntry, pNewEntry ); BAIL_ON_VMDIR_ERROR(dwError); cleanup: if (pNewEntry) { VmDirFreeEntry(pNewEntry); } return dwError; error: goto cleanup; }
/* * This always call in single thread mode during startup or from tools. */ DWORD VmDirSchemaInitializeViaFile( PCSTR pszSchemaFilePath ) { DWORD dwError = 0; PVDIR_ENTRY pEntry = NULL; BOOLEAN bInLock = FALSE; if (IsNullOrEmptyString(pszSchemaFilePath)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSchemaInitalizeFileToEntry( pszSchemaFilePath, &pEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSchemaInitializeViaEntry(pEntry); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); // globals takes over pEntry, use to write to db later gVdirSchemaGlobals.pLoadFromFileEntry = pEntry; VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); cleanup: VMDIR_UNLOCK_MUTEX(bInLock, gVdirSchemaGlobals.mutex); return dwError; error: if (pEntry) { VmDirFreeEntry(pEntry); } goto cleanup; }
DWORD VmDirAttrListToNewEntry( PVDIR_SCHEMA_CTX pSchemaCtx, PSTR pszDN, PSTR* ppszAttrList, PVDIR_ENTRY* ppEntry ) { DWORD dwError = 0; PVDIR_ENTRY pEntry = NULL; assert(pSchemaCtx && pszDN && ppszAttrList && ppEntry); dwError = VmDirAllocateMemory( sizeof(VDIR_ENTRY), (PVOID*)&pEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = AttrListToEntry( pSchemaCtx, pszDN, ppszAttrList, pEntry); BAIL_ON_VMDIR_ERROR(dwError); *ppEntry = pEntry; cleanup: return dwError; error: if (pEntry) { VmDirFreeEntry(pEntry); } goto cleanup; }
DWORD VmDirAttrListToNewEntry( PVDIR_SCHEMA_CTX pSchemaCtx, PSTR pszDN, PSTR* ppszAttrList, BOOLEAN bAllowAnonymousRead, PVDIR_ENTRY* ppEntry ) { DWORD dwError = 0; PVDIR_ENTRY pEntry = NULL; VMDIR_SECURITY_DESCRIPTOR vsd = {0}; assert(pSchemaCtx && pszDN && ppszAttrList && ppEntry); dwError = VmDirAllocateMemory(sizeof(VDIR_ENTRY), (PVOID*)&pEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = AttrListToEntry(pSchemaCtx, pszDN, ppszAttrList, pEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirCreateTransientSecurityDescriptor( bAllowAnonymousRead, &vsd); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirEntryCacheSecurityDescriptor( pEntry, vsd.pSecDesc, vsd.ulSecDesc); BAIL_ON_VMDIR_ERROR(dwError); *ppEntry = pEntry; cleanup: VMDIR_SAFE_FREE_MEMORY(vsd.pSecDesc); return dwError; error: VmDirFreeEntry(pEntry); goto cleanup; }
DWORD VmDirRESTObjectPut( void* pIn, void** ppOut ) { DWORD dwError = 0; PSTR pszTenant = NULL; PVDIR_ENTRY pObj = NULL; PVDIR_REST_OPERATION pRestOp = NULL; PVDIR_OPERATION pAddOp = NULL; if (!pIn) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } pRestOp = (PVDIR_REST_OPERATION)pIn; // put request must have subpath (=objectpath) if (IsNullOrEmptyString(pRestOp->pszSubPath)) { dwError = VMDIR_ERROR_INVALID_REQUEST; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirExternalOperationCreate( NULL, -1, LDAP_REQ_ADD, pRestOp->pConn, &pAddOp); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRESTGetObjectTenantParam(pRestOp, &pszTenant); BAIL_ON_VMDIR_ERROR(dwError) dwError = VmDirRESTDecodeObject( pRestOp->pjInput, pRestOp->pszSubPath, pszTenant, &pObj); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirResetAddRequestEntry(pAddOp, pObj); BAIL_ON_VMDIR_ERROR(dwError); pObj = NULL; dwError = VmDirMLAdd(pAddOp); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VMDIR_SET_REST_RESULT(pRestOp, pAddOp, dwError, NULL); VMDIR_SAFE_FREE_MEMORY(pszTenant); VmDirFreeOperation(pAddOp); VmDirFreeEntry(pObj); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); goto cleanup; }
/* * convert schema file into entry */ DWORD VmDirSchemaInitalizeFileToEntry( PCSTR pszSchemaFilePath, PVDIR_ENTRY* ppEntry ) { DWORD dwError = 0; USHORT dwCnt = 0; PVDIR_ENTRY pEntry = NULL; PSTR pszTag = NULL; PSTR pszTagEnd = NULL; USHORT dwTag = 0; PSTR* ppszDescs = NULL; USHORT dwDescSize = 0; PSTR* ppszSyntaxes = NULL; USHORT dwSyntaxSize = 0; PSTR* ppszMRs = NULL; USHORT dwMRSize = 0; PVDIR_SCHEMA_CTX pCtx = NULL; if ( !pszSchemaFilePath || !ppEntry ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = schemaReadFile( pszSchemaFilePath, &ppszDescs, &dwDescSize); BAIL_ON_VMDIR_ERROR(dwError); // sort ppszDescs by tag order (i.e. ats, ocs, syntax...) qsort(ppszDescs, dwDescSize, sizeof(*ppszDescs), schemaInitPPSTRCmp); dwError = VmDirSchemaCtxAcquire(&pCtx); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateMemory( sizeof(VDIR_ENTRY), (PVOID*)&pEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringA( SUB_SCHEMA_SUB_ENTRY_DN, &pEntry->dn.lberbv.bv_val); BAIL_ON_VMDIR_ERROR(dwError); pEntry->dn.bOwnBvVal = TRUE; pEntry->dn.lberbv.bv_len = VmDirStringLenA(pEntry->dn.lberbv.bv_val); dwError = VmDirNormalizeDN( &(pEntry->dn), pCtx ); BAIL_ON_VMDIR_ERROR(dwError); pEntry->allocType = ENTRY_STORAGE_FORMAT_NORMAL; // load every thing from file except EntryDN, ldapSyntaxes and matchingRules { // By now, we know all PSTR have format - "tag: value" for (dwCnt=0; dwCnt < dwDescSize; dwCnt++) { PSTR pszNewTag = ppszDescs[dwCnt]; PSTR pszNewTagEnd = VmDirStringChrA(ppszDescs[dwCnt], ':'); if (pszTag == NULL) { pszTag = pszNewTag; pszTagEnd = pszNewTagEnd; dwTag = dwCnt; continue; } if (((pszTagEnd - pszTag) == (pszNewTagEnd - pszNewTag)) && VmDirStringNCompareA(pszTag, pszNewTag, pszTagEnd - pszTag, TRUE) == 0) { continue; } else { dwError = schemaInitFillAttrFromFile( pCtx, ppszDescs+dwTag, dwCnt - dwTag, pszTag, pszTagEnd - pszTag, pEntry); BAIL_ON_VMDIR_ERROR(dwError); pszTag = pszNewTag; pszTagEnd = pszNewTagEnd; dwTag = dwCnt; } } dwError = schemaInitFillAttrFromFile( pCtx, ppszDescs+dwTag, dwCnt - dwTag, pszTag, pszTagEnd - pszTag, pEntry); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VdirSyntaxGetDefinition( &ppszSyntaxes, &dwSyntaxSize); BAIL_ON_VMDIR_ERROR(dwError); dwError = schemaInitFillAttrFromCache( pCtx, ppszSyntaxes, dwSyntaxSize, VDIR_ATTRIBUTE_LADPSYNTAXES, pEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = VdirMatchingRuleGetDefinition( &ppszMRs, &dwMRSize); BAIL_ON_VMDIR_ERROR(dwError); dwError = schemaInitFillAttrFromCache( pCtx, ppszMRs, dwMRSize, VDIR_ATTRIBUTE_MATCHINGRULES, pEntry); BAIL_ON_VMDIR_ERROR(dwError); pEntry->eId = SUB_SCEHMA_SUB_ENTRY_ID; // NOTE, entry is only partially constructed to bootstrap schema *ppEntry = pEntry; cleanup: if (pCtx) { VmDirSchemaCtxRelease(pCtx); } if (ppszDescs) { VmDirFreeStringArrayA(ppszDescs); VMDIR_SAFE_FREE_MEMORY(ppszDescs); } if (ppszSyntaxes) { VmDirFreeStringArrayA(ppszSyntaxes); VMDIR_SAFE_FREE_MEMORY(ppszSyntaxes); } if (ppszMRs) { VmDirFreeStringArrayA(ppszMRs); VMDIR_SAFE_FREE_MEMORY(ppszMRs); } return dwError; error: if (pEntry) { VmDirFreeEntry(pEntry); } goto cleanup; }