/* * 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; if (!pAttr || !ppDupAttr) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } 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; dwError = VmDirBervalContentDup(&pAttr->type, &pAttribute->type); BAIL_ON_VMDIR_ERROR(dwError); *ppDupAttr = pAttribute; cleanup: return dwError; error: VmDirFreeAttribute(pAttribute); VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
static int GenerateNewParent( PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE pDnAttr ) { int retVal = 0; VDIR_BERVALUE NewParent = VDIR_BERVALUE_INIT; if (!pEntry->pdn.bvnorm_val) { VmDirFreeBervalContent(&pEntry->pdn); retVal = VmDirGetParentDN(&pEntry->dn, &pEntry->pdn); BAIL_ON_VMDIR_ERROR(retVal); } retVal = VmDirGetParentDN(&pDnAttr->vals[0], &NewParent); BAIL_ON_VMDIR_ERROR(retVal); if (VmDirStringCompareA(pEntry->pdn.bvnorm_val, NewParent.bvnorm_val, FALSE) != 0) { retVal = VmDirBervalContentDup(&NewParent, &pEntry->newpdn); BAIL_ON_VMDIR_ERROR(retVal); } cleanup: VmDirFreeBervalContent(&NewParent); return retVal; error: 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 AddAttrValsToEntryStruct( VDIR_ENTRY * e, VDIR_ATTRIBUTE * eAttr, // Entry attribute to be updated with new attribute values VDIR_ATTRIBUTE * modAttr, // Modify attribute containing new attribute values PSTR* ppszErrMsg ) { unsigned int i = 0; unsigned int j = 0; DWORD dwError = ERROR_SUCCESS; PSTR pszErrMsg = NULL; assert(e->allocType == ENTRY_STORAGE_FORMAT_NORMAL); if ((size_t)eAttr->numVals + (size_t)modAttr->numVals > UINT16_MAX) { dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION; BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, (pszErrMsg), "Too many %s attribute values, max %u allowed.", VDIR_SAFE_STRING(eAttr->type.lberbv_val), UINT16_MAX); } dwError = VmDirReallocateMemoryWithInit(eAttr->vals, (PVOID*)(&(eAttr->vals)), (eAttr->numVals + modAttr->numVals + 1) * sizeof(VDIR_BERVALUE), (eAttr->numVals + 1) * sizeof(VDIR_BERVALUE)); BAIL_ON_VMDIR_ERROR(dwError); for (i = 0, j = eAttr->numVals; i < modAttr->numVals; i++, j++) { dwError = VmDirBervalContentDup(&modAttr->vals[i], &eAttr->vals[j]); BAIL_ON_VMDIR_ERROR(dwError); } memset(&(eAttr->vals[j]), 0, sizeof(VDIR_BERVALUE)); // set last BerValue.lberbv.bv_val to NULL; eAttr->numVals += modAttr->numVals; cleanup: VMDIR_SAFE_FREE_MEMORY(pszErrMsg); return dwError; error: if (ppszErrMsg) { *ppszErrMsg = pszErrMsg; pszErrMsg = NULL; } goto cleanup; }
/* * Add an array of bervalue attribute values into an entry. */ DWORD VmDirEntryAddBervArrayAttribute( PVDIR_ENTRY pEntry, PCSTR pszAttrName, VDIR_BERVARRAY attrVals, USHORT usNumVals ) { DWORD dwError = 0; PVDIR_ATTRIBUTE pAttr = NULL; USHORT usCnt = 0; if (!pEntry || !pEntry->pSchemaCtx || !pszAttrName || !attrVals) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } if (usNumVals) { dwError = VmDirAttributeAllocate( pszAttrName, usNumVals, pEntry->pSchemaCtx, &pAttr); BAIL_ON_VMDIR_ERROR(dwError); for (usCnt=0; usCnt < usNumVals; usCnt++) { dwError = VmDirBervalContentDup( &attrVals[usCnt], &pAttr->vals[usCnt]); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirEntryAddAttribute(pEntry, pAttr); BAIL_ON_VMDIR_ERROR(dwError); } cleanup: return dwError; error: VmDirFreeAttribute(pAttr); goto cleanup; }
static int IsAttrInReplScope( VDIR_OPERATION * op, char * attrType, char * attrMetaData, BOOLEAN * inScope, PSTR* ppszErrorMsg ) { int retVal = LDAP_SUCCESS; PLW_HASHTABLE_NODE pNode = NULL; char origInvocationId[VMDIR_GUID_STR_LEN]; USN origUsn = VmDirStringToLA( VmDirStringRChrA( attrMetaData, ':' ) + 1, NULL, 10 ); int rc = 0; PSTR pszLocalErrorMsg = NULL; *inScope = FALSE; // attrMetaData format is: <local USN>:<version no>:<originating server ID>:<originating time>:<originating USN> VmDirStringNCpyA( origInvocationId, VMDIR_GUID_STR_LEN, VmDirStringChrA( VmDirStringChrA( attrMetaData, ':' ) + 1, ':') + 1, VMDIR_GUID_STR_LEN - 1); origInvocationId[VMDIR_GUID_STR_LEN - 1] = '\0'; // Skip the attribute: // - if the originating server for the current state is same as the requesting server or if it is one of those // attributes that have "local" scope only. E.g. sending ATTR_LAST_LOCAL_USN_PROCESSED and // ATTR_UP_TO_DATE_VECTOR, causes continuous back-forth replication of Replication Agreements and Server // entries between various servers. assert( op->syncReqCtrl != NULL ); if ((attrType != NULL && (VmDirStringCompareA( attrType, ATTR_LAST_LOCAL_USN_PROCESSED, FALSE) == 0 || VmDirStringCompareA( attrType, ATTR_UP_TO_DATE_VECTOR, FALSE) == 0 || VmDirStringCompareA( attrType, VDIR_ATTRIBUTE_SEQUENCE_RID, FALSE) == 0))) { // Reset metaData value so that we don't send local only attribute back. attrMetaData[0] = '\0'; *inScope = FALSE; goto cleanup; } else if ( attrType != NULL && (VmDirStringCompareA( attrType, ATTR_USN_CHANGED, FALSE) == 0)) { ; // always send uSNChanged. (PR 1573117) } else if (VmDirStringCompareA( origInvocationId, op->syncReqCtrl->value.syncReqCtrlVal.reqInvocationId.lberbv.bv_val,TRUE ) == 0) { // Change is originated from the requesting server. // Reset metaData value so that we don't send metaData as well as this attribute back. attrMetaData[0] = '\0'; *inScope = FALSE; goto cleanup; } else { rc = LwRtlHashTableFindKey( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &pNode, origInvocationId ); rc = LwNtStatusToWin32Error(rc); if (rc != 0 && rc != ERROR_NOT_FOUND) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "IsAttrInReplScope: LwRtlHashTableFindKey failed for origInvocationId: %s", origInvocationId ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "LwRtlHashTableFindKey failed."); } if (pNode == NULL) // Attribute is to be sent in the result entry. { UptoDateVectorEntry * utdVectorEntry = NULL; VDIR_BERVALUE bvServerId = VDIR_BERVALUE_INIT; if (VmDirAllocateMemory( sizeof( UptoDateVectorEntry ), (PVOID *)&utdVectorEntry) != 0) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "IsAttrInReplScope: BervalContentDup failed."); } bvServerId.lberbv.bv_val = origInvocationId; bvServerId.lberbv.bv_len = VmDirStringLenA( origInvocationId ); if (VmDirBervalContentDup( &bvServerId, &utdVectorEntry->invocationId ) != 0) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "IsAttrInReplScope: BervalContentDup failed."); } utdVectorEntry->currMaxOrigUsnProcessed = origUsn; LwRtlHashTableResizeAndInsert( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &utdVectorEntry->Node, &pNode); assert( pNode == NULL ); // assert the key of added node is unique } else { UptoDateVectorEntry * utdVectorEntry = NULL; utdVectorEntry = (UptoDateVectorEntry *)LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node); if (origUsn > utdVectorEntry->reqLastOrigUsnProcessed ) { // Attribute is to be sent in the result entry. // Update if origUsn of this attribute is > the current highest if (origUsn > utdVectorEntry->currMaxOrigUsnProcessed ) { utdVectorEntry->currMaxOrigUsnProcessed = origUsn; } } else { VMDIR_LOG_VERBOSE( LDAP_DEBUG_REPL_ATTR, "IsAttrInReplScope: Attribute: %s, metaData: %s, replication scope = FALSE", attrType, attrMetaData ); // Reset metaData value so that we don't send metaData for this attribute back. attrMetaData[0] = '\0'; *inScope = FALSE; goto cleanup; } } } VMDIR_LOG_INFO( LDAP_DEBUG_REPL_ATTR, "IsAttrInReplScope: Attribute: %s, metaData: %s, replication scope = TRUE", attrType, attrMetaData ); *inScope = TRUE; cleanup: if (ppszErrorMsg) { *ppszErrorMsg = pszLocalErrorMsg; } else { VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); } return( retVal ); error: goto cleanup; }
/* * This generic search with pagination is new and isn't mature. Please be * careful with the * scope, base, and use an indexed filter. * Note that ulPageSize == 0 will ignore paging. */ DWORD VmDirFilterInternalSearch( PCSTR pszBaseDN, int searchScope, PCSTR pszFilter, unsigned long ulPageSize, PSTR *ppszPageCookie, PVDIR_ENTRY_ARRAY pEntryArray ) { DWORD dwError = 0; VDIR_OPERATION searchOP = {0}; VDIR_BERVALUE bervDN = VDIR_BERVALUE_INIT; PVDIR_FILTER pFilter = NULL; PVDIR_LDAP_CONTROL showPagedResultsCtrl = NULL; PSTR pszPageCookie = NULL; if ( !pszBaseDN || !pszFilter || !pEntryArray || (ulPageSize != 0 && ppszPageCookie == NULL)) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } if (ulPageSize != 0) { dwError = VmDirAllocateMemory( sizeof(VDIR_LDAP_CONTROL), (PVOID *)&showPagedResultsCtrl ); BAIL_ON_VMDIR_ERROR(dwError); showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize = ulPageSize; if (ppszPageCookie && *ppszPageCookie) { VmDirStringNCpyA(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, VMDIR_ARRAY_SIZE(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie), *ppszPageCookie, VMDIR_ARRAY_SIZE(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie) - 1); } else { showPagedResultsCtrl->value.pagedResultCtrlVal.cookie[0] = '\0'; } } dwError = VmDirInitStackOperation( &searchOP, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL ); BAIL_ON_VMDIR_ERROR(dwError); bervDN.lberbv.bv_val = (PSTR)pszBaseDN; bervDN.lberbv.bv_len = VmDirStringLenA(pszBaseDN); searchOP.pBEIF = VmDirBackendSelect( pszBaseDN ); assert(searchOP.pBEIF); dwError = VmDirBervalContentDup( &bervDN, &searchOP.reqDn); BAIL_ON_VMDIR_ERROR(dwError); searchOP.request.searchReq.scope = searchScope; dwError = StrFilterToFilter(pszFilter, &pFilter); BAIL_ON_VMDIR_ERROR(dwError); searchOP.request.searchReq.filter = pFilter; pFilter = NULL; // search request takes over pFilter searchOP.showPagedResultsCtrl = showPagedResultsCtrl; dwError = VmDirInternalSearch( &searchOP ); BAIL_ON_VMDIR_ERROR(dwError); // caller takes over searchOP.internalSearchEntryArray contents pEntryArray->iSize = searchOP.internalSearchEntryArray.iSize; pEntryArray->pEntry = searchOP.internalSearchEntryArray.pEntry; searchOP.internalSearchEntryArray.iSize = 0; searchOP.internalSearchEntryArray.pEntry = NULL; if (showPagedResultsCtrl) { dwError = VmDirAllocateStringA(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, &pszPageCookie); BAIL_ON_VMDIR_ERROR(dwError); *ppszPageCookie = pszPageCookie; pszPageCookie = NULL; } cleanup: VMDIR_SAFE_FREE_MEMORY(showPagedResultsCtrl); VmDirFreeOperationContent(&searchOP); if (pFilter) { DeleteFilter(pFilter); } return dwError; error: goto cleanup; }
/* * TODO, to generalize, we should create a strToFilter(pszFilter, &pOutFilter); */ DWORD VmDirSimpleEqualFilterInternalSearch( PCSTR pszBaseDN, int searchScope, PCSTR pszAttrName, PCSTR pszAttrValue, PVDIR_ENTRY_ARRAY pEntryArray ) { DWORD dwError = 0; VDIR_OPERATION searchOP = {0}; VDIR_BERVALUE bervDN = VDIR_BERVALUE_INIT; PVDIR_FILTER pFilter = NULL; if ( !pszBaseDN || !pszAttrName || !pszAttrValue || !pEntryArray ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInitStackOperation( &searchOP, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL ); BAIL_ON_VMDIR_ERROR(dwError); bervDN.lberbv.bv_val = (PSTR)pszBaseDN; bervDN.lberbv.bv_len = VmDirStringLenA(pszBaseDN); searchOP.pBEIF = VmDirBackendSelect( pszBaseDN ); assert(searchOP.pBEIF); dwError = VmDirBervalContentDup( &bervDN, &searchOP.reqDn); BAIL_ON_VMDIR_ERROR(dwError); searchOP.request.searchReq.scope = searchScope; { dwError = VmDirAllocateMemory( sizeof( VDIR_FILTER ), (PVOID*)&pFilter ); BAIL_ON_VMDIR_ERROR(dwError); pFilter->choice = LDAP_FILTER_EQUALITY; pFilter->filtComp.ava.type.lberbv.bv_val = (PSTR)pszAttrName; pFilter->filtComp.ava.type.lberbv.bv_len = VmDirStringLenA(pszAttrName); pFilter->filtComp.ava.pATDesc = VmDirSchemaAttrNameToDesc( searchOP.pSchemaCtx, pszAttrName); if (pFilter->filtComp.ava.pATDesc == NULL) { dwError = VMDIR_ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR( dwError ); } pFilter->filtComp.ava.value.lberbv.bv_val = (PSTR)pszAttrValue; pFilter->filtComp.ava.value.lberbv.bv_len = VmDirStringLenA(pszAttrValue); dwError = VmDirSchemaBervalNormalize( // TODO, may want to have filter code to do this? searchOP.pSchemaCtx, // so caller does not have to handle this. pFilter->filtComp.ava.pATDesc, &(pFilter->filtComp.ava.value) ); BAIL_ON_VMDIR_ERROR(dwError); pFilter->next = NULL; } //TODO, ideally, we should take pszFilter and dwError = VmDirStrToFilter(pszFilter, &pFilter); searchOP.request.searchReq.filter = pFilter; pFilter = NULL; // search request takes over pFilter dwError = VmDirInternalSearch( &searchOP ); BAIL_ON_VMDIR_ERROR(dwError); // caller takes over searchOP.internalSearchEntryArray contents pEntryArray->iSize = searchOP.internalSearchEntryArray.iSize; pEntryArray->pEntry = searchOP.internalSearchEntryArray.pEntry; searchOP.internalSearchEntryArray.iSize = 0; searchOP.internalSearchEntryArray.pEntry = NULL; cleanup: VmDirFreeOperationContent(&searchOP); if (pFilter) { DeleteFilter(pFilter); } return dwError; error: goto cleanup; }
/* * Test whether the origUsn is in scope so that attribute, attr-meta-data or * attr-value-meta-data be sent back to the replicaiton consumer based on whether * the origUsn for that invocationId has been processed already by the consumer * TODO: Needed Refractoring */ DWORD VmDirIsUsnInScope( PVDIR_OPERATION pOperation, PCSTR pAttrName, PCSTR pszOrigInvocationId, USN origUsn, USN localUSN, USN priorSentUSNCreated, PBOOLEAN pbIsUsnInScope ) { DWORD dwError = 0; PLW_HASHTABLE_NODE pNode = NULL; PSTR pszLocalErrorMsg = NULL; UptoDateVectorEntry *pUtdVectorEntry = NULL; UptoDateVectorEntry *pNewUtdVectorEntry = NULL; int retVal = 0; if (!pOperation || !pszOrigInvocationId || !pbIsUsnInScope || !pOperation->syncReqCtrl || !pOperation->syncDoneCtrl) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } *pbIsUsnInScope = FALSE; //Originating server for the current state is same as the requesting server if (VmDirStringCompareA( pszOrigInvocationId, pOperation->syncReqCtrl->value.syncReqCtrlVal.reqInvocationId.lberbv.bv_val, TRUE) == 0) { *pbIsUsnInScope = FALSE; goto cleanup; } retVal = LwRtlHashTableFindKey( pOperation->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &pNode, pszOrigInvocationId); retVal = LwNtStatusToWin32Error(retVal); if (retVal != 0 && retVal != ERROR_NOT_FOUND) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "%s: LwRtlHashTableFindKey failed for origInvocationId: %s", __FUNCTION__, pszOrigInvocationId); dwError = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, (pszLocalErrorMsg), "LwRtlHashTableFindKey failed."); } if (pNode == NULL) { VDIR_BERVALUE bvServerId = VDIR_BERVALUE_INIT; dwError = VmDirAllocateMemory(sizeof(UptoDateVectorEntry), (PVOID *)&pNewUtdVectorEntry); BAIL_ON_VMDIR_ERROR(dwError); bvServerId.lberbv.bv_val = (PSTR)pszOrigInvocationId; bvServerId.lberbv.bv_len = VmDirStringLenA(pszOrigInvocationId); dwError = VmDirBervalContentDup(&bvServerId, &pNewUtdVectorEntry->invocationId); BAIL_ON_VMDIR_ERROR(dwError); pNewUtdVectorEntry->currMaxOrigUsnProcessed = origUsn; LwRtlHashTableResizeAndInsert( pOperation->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &pNewUtdVectorEntry->Node, &pNode); // assert the key of added node is unique assert(pNode == NULL); pNewUtdVectorEntry = NULL; *pbIsUsnInScope = TRUE; goto cleanup; } pUtdVectorEntry = (UptoDateVectorEntry *)LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node); if (origUsn > pUtdVectorEntry->reqLastOrigUsnProcessed ) { // attribute or the valueMetaData item in scope if origUsn valueMetaData is > the current highest if (origUsn > pUtdVectorEntry->currMaxOrigUsnProcessed ) { pUtdVectorEntry->currMaxOrigUsnProcessed = origUsn; } // Note, this handles ADD->MODIFY case but not multiple MODIFYs scenario. // However, it is fine as consumer should be able to handle redundant feed from supplier. // The key point here is to NOT send ATTR_USN_CREATED, so we can derive correct sync_state in WriteSyncStateControl. if (localUSN > priorSentUSNCreated) { *pbIsUsnInScope = TRUE; if (priorSentUSNCreated > 0) { VMDIR_LOG_INFO( LDAP_DEBUG_REPL, "%s new usn %llu after prior usncreated %llu attr %s", __FUNCTION__, origUsn, priorSentUSNCreated, VDIR_SAFE_STRING(pAttrName)); } } else { VMDIR_LOG_INFO( LDAP_DEBUG_REPL, "%s (add->modify) race condition avoided. skip prior usncreated %llu attr %s", __FUNCTION__, priorSentUSNCreated, VDIR_SAFE_STRING(pAttrName)); } goto cleanup; } VMDIR_LOG_INFO( LDAP_DEBUG_REPL, "%s: (not in scope) attr name: %s orig invo: %s utdUsn: %"PRId64" usn: %"PRId64, __FUNCTION__, VDIR_SAFE_STRING(pAttrName), VDIR_SAFE_STRING(pszOrigInvocationId), pUtdVectorEntry->reqLastOrigUsnProcessed, origUsn); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); if (pNewUtdVectorEntry) { VmDirFreeBervalContent(&pNewUtdVectorEntry->invocationId); } VMDIR_SAFE_FREE_MEMORY(pNewUtdVectorEntry); goto cleanup; }
/* * DelAttrValsFromEntryStruct: Deletes a complete attribute or specific attribute values from the entry. * Assumption: This function assumes/asserts that the modAttr does exist in the entry. * */ static int DelAttrValsFromEntryStruct( PVDIR_SCHEMA_CTX pSchemaCtx, VDIR_ENTRY * e, VDIR_ATTRIBUTE * modAttr, PSTR* ppszErrorMsg ) { int retVal = LDAP_SUCCESS; VDIR_ATTRIBUTE * prevAttr = NULL; VDIR_ATTRIBUTE * currAttr = NULL; VDIR_ATTRIBUTE * eAttr = NULL; unsigned int i = 0; unsigned int j = 0; PSTR pszLocalErrorMsg = NULL; assert(e->allocType == ENTRY_STORAGE_FORMAT_NORMAL); // Locate which attribute (values) we are trying to delete for (currAttr = e->attrs; currAttr != NULL; prevAttr = currAttr, currAttr = currAttr->next) { if (VmDirStringCompareA(modAttr->type.lberbv.bv_val, currAttr->type.lberbv.bv_val, FALSE) == 0) { break; } } assert(currAttr != NULL); eAttr = currAttr; // Normalize eAttr values for (i = 0; i < eAttr->numVals; i++) { retVal = VmDirSchemaBervalNormalize(pSchemaCtx, eAttr->pATDesc, &eAttr->vals[i]); BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "normalize (%s)(%.*s)", VDIR_SAFE_STRING(eAttr->pATDesc->pszName), VMDIR_MIN(eAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN), VDIR_SAFE_STRING(eAttr->vals[i].lberbv.bv_val)); } if (modAttr->numVals == 1 && eAttr->pATDesc->bSingleValue && (VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_MODIFYTIMESTAMP, FALSE) == 0 || VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_CREATETIMESTAMP, FALSE) == 0 || VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_CREATORS_NAME, FALSE) == 0 || VmDirStringCompareA(eAttr->pATDesc->pszName, ATTR_MODIFIERS_NAME, FALSE) == 0)) { /* Force deleting the attribute value whether or not the value matches. * A raft follower may alter the timestamps/creator locally, e.g. rollback vmwAttrUniquenessScope, * which may fail to remove the value if it doesn't match that value seen at the raft leader. */ VmDirFreeBervalContent(&modAttr->vals[0]); modAttr->numVals = 0; } // Complete attribute is to be deleted. if (modAttr->numVals == 0) { // Make a copy of BerValues into modAttr so that these values can be used to delete from the index, // if it is an indexed attribute. VMDIR_SAFE_FREE_MEMORY(modAttr->vals); retVal = VmDirAllocateMemory((eAttr->numVals + 1) * sizeof(VDIR_BERVALUE), (PVOID *)&modAttr->vals); BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "no memory"); for (i = 0; i < eAttr->numVals; i++) { VmDirBervalContentDup(&eAttr->vals[i], &modAttr->vals[i]); } modAttr->numVals = eAttr->numVals; // Adjust the "next" pointer of the attribute before the attribute being deleted. => Altering the attribute // chain. if (prevAttr == NULL) // if it is the first attribute { e->attrs = eAttr->next; } else { prevAttr->next = eAttr->next; } VmDirFreeAttribute(eAttr); } else // Specific attribute values need to be deleted. { // Check if all attribute values that are being deleted exist in the Attribute for (i=0; i < modAttr->numVals; i++) { // modAttr values are already normalized. assert(modAttr->vals[i].bvnorm_val); for (j = 0; j < eAttr->numVals; j++) { // eAttr values are already normalized. assert(eAttr->vals[j].bvnorm_val); if (modAttr->vals[i].bvnorm_len == eAttr->vals[j].bvnorm_len && memcmp(modAttr->vals[i].bvnorm_val, eAttr->vals[j].bvnorm_val, modAttr->vals[i].bvnorm_len) == 0) { break; } } if (j == eAttr->numVals) // did not find a match { retVal = VMDIR_ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "Attribute (%s) value (%.*s) being deleted does not exist.", VDIR_SAFE_STRING(modAttr->type.lberbv.bv_val), VMDIR_MIN(modAttr->vals[i].lberbv.bv_len, VMDIR_MAX_LOG_OUTPUT_LEN), VDIR_SAFE_STRING(modAttr->vals[i].lberbv.bv_val)); } } // All values are being deleted. => Delete the whole attribute if (modAttr->numVals == eAttr->numVals) { // Adjust the "next" pointer of the attribute before the attribute being deleted. => Altering the attribute // chain. if (prevAttr == NULL) // if it is the first attribute { e->attrs = eAttr->next; } else { prevAttr->next = eAttr->next; } VmDirFreeAttribute(eAttr); } else { RemoveAttrVals(eAttr, modAttr); } } cleanup: if (ppszErrorMsg) { *ppszErrorMsg = pszLocalErrorMsg; } else { VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); } return retVal; error: goto cleanup; }
static int _VmDirSwapDB( PCSTR dbHomeDir, BOOLEAN bHasXlog) { int retVal = LDAP_SUCCESS; char dbExistingName[VMDIR_MAX_FILE_NAME_LEN] = {0}; char dbNewName[VMDIR_MAX_FILE_NAME_LEN] = {0}; PSTR pszLocalErrorMsg = NULL; int errorCode = 0; BOOLEAN bLegacyDataLoaded = FALSE; PVDIR_BACKEND_INTERFACE pBE = NULL; #ifndef _WIN32 const char fileSeperator = '/'; #else const char fileSeperator = '\\'; #endif // Shutdown backend pBE = VmDirBackendSelect(NULL); assert(pBE); VmDirdStateSet(VMDIRD_STATE_SHUTDOWN); VmDirIndexLibShutdown(); VmDirSchemaLibShutdown(); pBE->pfnBEShutdown(); VmDirBackendContentFree(pBE); // move .mdb files retVal = VmDirStringPrintFA( dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR, fileSeperator, VMDIR_MDB_DATA_FILE_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = VmDirStringPrintFA( dbNewName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator, VMDIR_MDB_DATA_FILE_NAME ); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); #ifdef WIN32 if (MoveFileEx(dbExistingName, dbNewName, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = GetLastError(); #else if (rename(dbExistingName, dbNewName) != 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = errno; #endif BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: rename file from %s to %s failed, errno %d", dbExistingName, dbNewName, errorCode ); } retVal = VmDirStringPrintFA(dbNewName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); if (bHasXlog) { //move xlog directory retVal = VmDirStringPrintFA(dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); #ifdef WIN32 if (MoveFileEx(dbExistingName, dbNewName, MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING) == 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = GetLastError(); #else if (rmdir(dbNewName) != 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = errno; BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirSwapDB cannot remove directory %s, errno %d", dbNewName, errorCode); } if (rename(dbExistingName, dbNewName) != 0) { retVal = LDAP_OPERATIONS_ERROR; errorCode = errno; #endif BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirSwapDB cannot move directory from %s to %s, errno %d", dbNewName, dbExistingName, errorCode); } } retVal = VmDirStringPrintFA(dbExistingName, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirSwapDB: VmDirStringPrintFA() call failed with error: %d", retVal ); #ifdef WIN32 if (RemoveDirectory(dbExistingName)==0) { errorCode = GetLastError(); #else if (rmdir(dbExistingName)) { errorCode = errno; #endif VMDIR_LOG_WARNING(VMDIR_LOG_MASK_ALL, "cannot remove directory %s errno %d", dbExistingName, errorCode); } VmDirdStateSet(VMDIRD_STATE_STARTUP); retVal = VmDirInitBackend(&bLegacyDataLoaded); BAIL_ON_VMDIR_ERROR(retVal); if (bLegacyDataLoaded) { retVal = VmDirPatchLocalSubSchemaSubEntry(); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrorMsg, "_VmDirSwapDB: failed to patch subschema subentry: %d", retVal ); retVal = VmDirWriteSchemaObjects(); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrorMsg, "_VmDirSwapDB: failed to create schema tree: %d", retVal ); } VmDirdStateSet(VMDIRD_STATE_NORMAL); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s", VDIR_SAFE_STRING(pszLocalErrorMsg) ); goto cleanup; } static int _VmDirWrapUpFirstReplicationCycle( PCSTR pszHostname, VMDIR_REPLICATION_AGREEMENT * pReplAgr) { int retVal = LDAP_SUCCESS; PVDIR_ENTRY pPartnerServerEntry = NULL; PVDIR_ATTRIBUTE pAttrUpToDateVector = NULL; PVDIR_ATTRIBUTE pAttrInvocationId = NULL; USN localUsn = 0; USN partnerLocalUsn = 0; char partnerlocalUsnStr[VMDIR_MAX_USN_STR_LEN]; VDIR_BACKEND_CTX beCtx = {0}; struct berval syncDoneCtrlVal = {0}; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; VDIR_OPERATION searchOp = {0}; PVDIR_FILTER pSearchFilter = NULL; PSTR pszSeparator = NULL; retVal = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirInitStackOperation( &searchOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, pSchemaCtx ); BAIL_ON_VMDIR_ERROR(retVal); searchOp.pBEIF = VmDirBackendSelect(NULL); assert(searchOp.pBEIF); searchOp.reqDn.lberbv.bv_val = ""; searchOp.reqDn.lberbv.bv_len = 0; searchOp.request.searchReq.scope = LDAP_SCOPE_SUBTREE; retVal = VmDirConcatTwoFilters(searchOp.pSchemaCtx, ATTR_CN, (PSTR) pszHostname, ATTR_OBJECT_CLASS, OC_DIR_SERVER, &pSearchFilter); BAIL_ON_VMDIR_ERROR(retVal); searchOp.request.searchReq.filter = pSearchFilter; retVal = VmDirInternalSearch(&searchOp); BAIL_ON_VMDIR_ERROR(retVal); if (searchOp.internalSearchEntryArray.iSize != 1) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: Unexpected (not 1) number of partner server entries found (%d)", searchOp.internalSearchEntryArray.iSize ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR(retVal); } pPartnerServerEntry = searchOp.internalSearchEntryArray.pEntry; pAttrUpToDateVector = VmDirEntryFindAttribute( ATTR_UP_TO_DATE_VECTOR, pPartnerServerEntry ); pAttrInvocationId = VmDirEntryFindAttribute( ATTR_INVOCATION_ID, pPartnerServerEntry ); assert( pAttrInvocationId != NULL ); beCtx.pBE = VmDirBackendSelect(NULL); assert(beCtx.pBE); if ((retVal = beCtx.pBE->pfnBEGetNextUSN( &beCtx, &localUsn )) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: pfnBEGetNextUSN failed with error code: %d, " "error message: %s", retVal, VDIR_SAFE_STRING(beCtx.pszBEErrorMsg) ); BAIL_ON_VMDIR_ERROR( retVal ); } retVal = _VmGetHighestCommittedUSN(localUsn, &partnerLocalUsn); BAIL_ON_VMDIR_ERROR( retVal ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: partnerLocalUsn %llu locaUsn %llu", partnerLocalUsn, localUsn); if ((retVal = VmDirStringNPrintFA( partnerlocalUsnStr, sizeof(partnerlocalUsnStr), sizeof(partnerlocalUsnStr) - 1, "%" PRId64, partnerLocalUsn)) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirWrapUpFirstReplicationCycle: VmDirStringNPrintFA failed with error code: %d", retVal ); BAIL_ON_VMDIR_ERROR( retVal ); } if (pAttrUpToDateVector) { if (VmDirStringEndsWith( pAttrUpToDateVector->vals[0].lberbv.bv_val, ",", FALSE)) { pszSeparator = ""; } else { pszSeparator = ","; } // <partnerLocalUSN>,<partner up-to-date vector>,<partner server GUID>:<partnerLocalUSN>, retVal = VmDirAllocateStringPrintf( &(syncDoneCtrlVal.bv_val), "%s,%s%s%s:%s,", partnerlocalUsnStr, pAttrUpToDateVector->vals[0].lberbv.bv_val, pszSeparator, pAttrInvocationId->vals[0].lberbv.bv_val, partnerlocalUsnStr); BAIL_ON_VMDIR_ERROR(retVal); } else { // <partnerLocalUSN>,<partner server GUID>:<partnerLocalUSN>, retVal = VmDirAllocateStringPrintf( &(syncDoneCtrlVal.bv_val), "%s,%s:%s,", partnerlocalUsnStr, pAttrInvocationId->vals[0].lberbv.bv_val, partnerlocalUsnStr); BAIL_ON_VMDIR_ERROR(retVal); } VmDirSetACLMode(); syncDoneCtrlVal.bv_len = VmDirStringLenA(syncDoneCtrlVal.bv_val); if ((retVal = VmDirReplUpdateCookies( pSchemaCtx, &(syncDoneCtrlVal), pReplAgr )) != LDAP_SUCCESS) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "vdirReplicationThrFun: UpdateCookies failed. Error: %d", retVal ); BAIL_ON_VMDIR_ERROR( retVal ); } if ((retVal = _VmDirPatchDSERoot(pSchemaCtx)) != LDAP_SUCCESS) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "vdirReplicationThrFun: _VmDirPatchDSERoot failed. Error: %d", retVal ); BAIL_ON_VMDIR_ERROR( retVal ); } cleanup: VmDirFreeOperationContent(&searchOp); VmDirBackendCtxContentFree(&beCtx); VMDIR_SAFE_FREE_MEMORY(syncDoneCtrlVal.bv_val); VmDirSchemaCtxRelease(pSchemaCtx); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; goto cleanup; } #ifndef VDIR_PSC_VERSION #define VDIR_PSC_VERSION "6.7.0" #endif static int _VmDirPatchDSERoot( PVDIR_SCHEMA_CTX pSchemaCtx) { int retVal = LDAP_SUCCESS; VDIR_OPERATION op = {0}; VDIR_BERVALUE bvDSERootDN = VDIR_BERVALUE_INIT; VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_VmDirPatchDSERoot: Begin" ); bvDSERootDN.lberbv.bv_val = PERSISTED_DSE_ROOT_DN; bvDSERootDN.lberbv.bv_len = VmDirStringLenA( bvDSERootDN.lberbv.bv_val ); retVal = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, pSchemaCtx ); BAIL_ON_VMDIR_ERROR(retVal); retVal = VmDirNormalizeDN( &bvDSERootDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(retVal); retVal = VmDirBervalContentDup( &bvDSERootDN, &op.reqDn ); BAIL_ON_VMDIR_ERROR(retVal); op.pBEIF = VmDirBackendSelect(op.reqDn.lberbv.bv_val); assert(op.pBEIF); if (VmDirBervalContentDup( &op.reqDn, &op.request.modifyReq.dn ) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirPatchDSERoot: BervalContentDup failed." ); BAIL_ON_VMDIR_ERROR( retVal ); } retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_DC_ACCOUNT_UPN, ATTR_DC_ACCOUNT_UPN_LEN, gVmdirServerGlobals.dcAccountUPN.lberbv.bv_val, gVmdirServerGlobals.dcAccountUPN.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_DC_ACCOUNT_DN, ATTR_DC_ACCOUNT_DN_LEN, gVmdirServerGlobals.dcAccountDN.lberbv.bv_val, gVmdirServerGlobals.dcAccountDN.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_SERVER_NAME, ATTR_SERVER_NAME_LEN, gVmdirServerGlobals.serverObjDN.lberbv.bv_val, gVmdirServerGlobals.serverObjDN.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_SITE_NAME, ATTR_SITE_NAME_LEN, gVmdirServerGlobals.pszSiteName, VmDirStringLenA(gVmdirServerGlobals.pszSiteName) ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_PSC_VERSION, ATTR_PSC_VERSION_LEN, VDIR_PSC_VERSION, VmDirStringLenA(VDIR_PSC_VERSION) ); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_MAX_DOMAIN_FUNCTIONAL_LEVEL, ATTR_MAX_DOMAIN_FUNCTIONAL_LEVEL_LEN, VMDIR_MAX_DFL_STRING, VmDirStringLenA(VMDIR_MAX_DFL_STRING) ); BAIL_ON_VMDIR_ERROR( retVal ); if ((retVal = VmDirInternalModifyEntry( &op )) != 0) { // If VmDirInternall call failed, reset retVal to LDAP level error space (for B/C) retVal = op.ldapResult.errCode; VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_VmDirPatchDSERoot: InternalModifyEntry failed. " "Error code: %d, Error string: %s", retVal, VDIR_SAFE_STRING( op.ldapResult.pszErrMsg ) ); BAIL_ON_VMDIR_ERROR( retVal ); } cleanup: VmDirFreeOperationContent(&op); VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_VmDirPatchDSERoot: End" ); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; goto cleanup; }
DWORD VmDirReplAgrEntryToInMemory( PVDIR_ENTRY pEntry, PVMDIR_REPLICATION_AGREEMENT * ppReplAgr ) { DWORD dwError = 0; PVMDIR_REPLICATION_AGREEMENT pReplAgr; PVDIR_ATTRIBUTE pAttr = NULL; VDIR_BERVALUE bv = VDIR_BERVALUE_INIT; if (!ppReplAgr) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory( sizeof(VMDIR_REPLICATION_AGREEMENT), (PVOID*)&pReplAgr); BAIL_ON_VMDIR_ERROR(dwError); for (pAttr = pEntry->attrs; pAttr; pAttr = pAttr->next) { if (VmDirStringCompareA(pAttr->pATDesc->pszName, ATTR_LABELED_URI, FALSE) == 0) { dwError = VmDirStringCpyA( pReplAgr->ldapURI, VMDIR_MAX_LDAP_URI_LEN, pAttr->vals[0].lberbv.bv_val); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirLdapURI2Host( pReplAgr->ldapURI, &pReplAgr->pszHostname); BAIL_ON_VMDIR_ERROR(dwError); } else if (VmDirStringCompareA(pAttr->pATDesc->pszName, ATTR_LAST_LOCAL_USN_PROCESSED, FALSE) == 0) { dwError = VmDirBervalContentDup( &pAttr->vals[0], &pReplAgr->lastLocalUsnProcessed); BAIL_ON_VMDIR_ERROR(dwError); } else if (VmDirStringCompareA(pAttr->pATDesc->pszName, ATTR_DN, FALSE) == 0) { dwError = VmDirBervalContentDup(&pAttr->vals[0], &pReplAgr->dn); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN(&pReplAgr->dn, pEntry->pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); } } if (pReplAgr->lastLocalUsnProcessed.lberbv.bv_val == NULL) // Since ATTR_LAST_LOCAL_USN_PROCESSED is an optional attribute. { bv.lberbv.bv_val = VMDIR_DEFAULT_REPL_LAST_USN_PROCESSED; bv.lberbv.bv_len = VMDIR_DEFAULT_REPL_LAST_USN_PROCESSED_LEN; dwError = VmDirBervalContentDup(&bv, &pReplAgr->lastLocalUsnProcessed); BAIL_ON_VMDIR_ERROR(dwError); } dwError = _VmDirReplDCConnectInit(pReplAgr); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Replication partner: (%s) lastLocalUsnProcessed: (%s)", pReplAgr->ldapURI, pReplAgr->lastLocalUsnProcessed.lberbv_val); *ppReplAgr = pReplAgr; cleanup: return dwError; error: VmDirFreeReplicationAgreement(pReplAgr); goto cleanup; }
static int LoadReplicationAgreements() { // Load my Replication Agreements VDIR_OPERATION op = {0}; PVDIR_FILTER replAgrFilter = NULL; DWORD dwError = 0; int iCnt = 0; VmDirLog( LDAP_DEBUG_TRACE, "LoadReplicationAgreements: Begin" ); if ( gVmdirServerGlobals.serverObjDN.lberbv.bv_val != NULL ) { dwError = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL ); BAIL_ON_VMDIR_ERROR(dwError); op.pBEIF = VmDirBackendSelect( gVmdirServerGlobals.serverObjDN.lberbv.bv_val ); assert(op.pBEIF); if (VmDirBervalContentDup( &gVmdirServerGlobals.serverObjDN, &op.reqDn ) != 0) { VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: BervalContentDup failed." ); dwError = -1; BAIL_ON_VMDIR_ERROR( dwError ); } op.request.searchReq.scope = LDAP_SCOPE_SUBTREE; if (VmDirAllocateMemory( sizeof( VDIR_FILTER ), (PVOID *)&replAgrFilter ) != 0) { VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: VmDirAllocateMemory failed. " ); dwError = -1; BAIL_ON_VMDIR_ERROR( dwError ); } op.request.searchReq.filter = replAgrFilter; replAgrFilter->choice = LDAP_FILTER_EQUALITY; replAgrFilter->filtComp.ava.type.lberbv.bv_val = ATTR_OBJECT_CLASS; replAgrFilter->filtComp.ava.type.lberbv.bv_len = ATTR_OBJECT_CLASS_LEN; if ((replAgrFilter->filtComp.ava.pATDesc = VmDirSchemaAttrNameToDesc( op.pSchemaCtx, replAgrFilter->filtComp.ava.type.lberbv.bv_val)) == NULL) { dwError = -1; VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: Getting pATDesc for ATTR_OBJECT_CLASS failed " "(hmm... STRANGE). " ); BAIL_ON_VMDIR_ERROR( dwError ); } replAgrFilter->filtComp.ava.value.lberbv.bv_val = OC_REPLICATION_AGREEMENT; replAgrFilter->filtComp.ava.value.lberbv.bv_len = OC_REPLICATION_AGREEMENT_LEN; if (VmDirSchemaBervalNormalize( op.pSchemaCtx, replAgrFilter->filtComp.ava.pATDesc, &(replAgrFilter->filtComp.ava.value) ) != LDAP_SUCCESS) { dwError = -1; VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: Attribute value normalization failed for " "filter type = %s", replAgrFilter->filtComp.ava.type.lberbv.bv_val ); BAIL_ON_VMDIR_ERROR( dwError ); } replAgrFilter->next = NULL; if ((dwError = VmDirInternalSearch( &op )) != 0) { VmDirLog( LDAP_DEBUG_ANY, "LoadReplicationAgreements: InternalSearch for Replication Agreements failed. " "Error code: %d, Error string: %s", dwError, VDIR_SAFE_STRING(op.ldapResult.pszErrMsg)); dwError = -1; BAIL_ON_VMDIR_ERROR( dwError ); } // load all replication agreements for (iCnt=0; iCnt < op.internalSearchEntryArray.iSize; iCnt++) { dwError = ProcessReplicationAgreementEntry( op.internalSearchEntryArray.pEntry + iCnt ); BAIL_ON_VMDIR_ERROR( dwError ); } VmDirPopulateInvocationIdInReplAgr(); } cleanup: VmDirFreeOperationContent(&op); VmDirLog( LDAP_DEBUG_TRACE, "LoadReplicationAgreements: End" ); return dwError; error: goto cleanup; }
DWORD VmDirConstructReplAgr( PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszReplURI, PCSTR pszLastLocalUsnProcessed, PCSTR pszReplAgrDN, PVMDIR_REPLICATION_AGREEMENT * ppReplAgr ) { DWORD dwError = 0; VDIR_BERVALUE bv = VDIR_BERVALUE_INIT; PVMDIR_REPLICATION_AGREEMENT pReplAgr = NULL; if (!pSchemaCtx || IsNullOrEmptyString(pszReplURI) || IsNullOrEmptyString(pszLastLocalUsnProcessed) || IsNullOrEmptyString(pszReplAgrDN) || !ppReplAgr) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirAllocateMemory( sizeof(VMDIR_REPLICATION_AGREEMENT), (PVOID*)&pReplAgr); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringCpyA(pReplAgr->ldapURI, VMDIR_MAX_LDAP_URI_LEN, pszReplURI); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirLdapURI2Host(pReplAgr->ldapURI, &pReplAgr->pszHostname); BAIL_ON_VMDIR_ERROR(dwError); bv.lberbv.bv_val = (PSTR)pszLastLocalUsnProcessed; bv.lberbv.bv_len = VmDirStringLenA(bv.lberbv.bv_val); dwError = VmDirBervalContentDup(&bv, &pReplAgr->lastLocalUsnProcessed); BAIL_ON_VMDIR_ERROR(dwError); bv.lberbv.bv_val = (PSTR)pszReplAgrDN; bv.lberbv.bv_len = VmDirStringLenA(bv.lberbv.bv_val); dwError = VmDirBervalContentDup(&bv, &pReplAgr->dn); BAIL_ON_VMDIR_ERROR(dwError); if (pReplAgr->dn.bvnorm_val == NULL) { dwError = VmDirNormalizeDN(&pReplAgr->dn, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); } dwError = _VmDirReplDCConnectInit(pReplAgr); BAIL_ON_VMDIR_ERROR(dwError); *ppReplAgr = pReplAgr; cleanup: return dwError; error: VmDirFreeReplicationAgreement(pReplAgr); goto cleanup; }
int VmDirModifyEntryCoreLogic( VDIR_OPERATION * pOperation, /* IN */ ModifyReq * modReq, /* IN */ ENTRYID entryId, /* IN */ BOOLEAN bNoRaftLog, /* IN */ VDIR_ENTRY * pEntry /* OUT */ ) { int retVal = LDAP_SUCCESS; PSTR pszLocalErrMsg = NULL; BOOLEAN bDnModified = FALSE; BOOLEAN bLeafNode = FALSE; PVDIR_ATTRIBUTE pAttrMemberOf = NULL; extern DWORD VmDirModifyRaftPreCommit(PVDIR_SCHEMA_CTX, ENTRYID, char *, PVDIR_MODIFICATION, PVDIR_OPERATION); retVal = pOperation->pBEIF->pfnBEIdToEntry( pOperation->pBECtx, pOperation->pSchemaCtx, entryId, pEntry, VDIR_BACKEND_ENTRY_LOCK_WRITE); BAIL_ON_VMDIR_ERROR(retVal); if (pOperation->pCondWriteCtrl) { retVal = VmDirMatchEntryWithFilter( pOperation, pEntry, pOperation->pCondWriteCtrl->value.condWriteCtrlVal.pszFilter); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "Conditional Write pre-conditions (%s) failed - (%d)", VDIR_SAFE_STRING(pOperation->pCondWriteCtrl->value.condWriteCtrlVal.pszFilter), retVal); } if (modReq->dn.lberbv.bv_val == NULL) // If not already set by the caller { // e.g. delete membership case via index lookup to get EID. retVal = VmDirBervalContentDup(&pEntry->dn, &modReq->dn); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "VmDirBervalContentDup failed - (%d)", retVal); } retVal = VmDirSrvAccessCheck( pOperation, &pOperation->conn->AccessInfo, pEntry, VMDIR_RIGHT_DS_WRITE_PROP); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "VmDirSrvAccessCheck failed - (%u)", retVal); // Apply modify operations to the current entry (in pack format) retVal = VmDirApplyModsToEntryStruct( pOperation->pSchemaCtx, modReq, pEntry, &bDnModified, &pszLocalErrMsg); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "ApplyModsToEntryStruct failed - (%d)(%s)", retVal, pszLocalErrMsg); if (bDnModified) { retVal = pOperation->pBEIF->pfnBEChkIsLeafEntry( pOperation->pBECtx, entryId, &bLeafNode); BAIL_ON_VMDIR_ERROR(retVal); if (bLeafNode == FALSE) { retVal = LDAP_NOT_ALLOWED_ON_NONLEAF; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "Rename of a non-leaf node is not allowed."); } // Verify not a member of any groups retVal = VmDirFindMemberOfAttribute(pEntry, &pAttrMemberOf); if (pAttrMemberOf && pAttrMemberOf->numVals > 0) { retVal = LDAP_UNWILLING_TO_PERFORM; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "Rename of a node with memberships is not allowed."); } } if (pOperation->opType != VDIR_OPERATION_TYPE_REPL) { // Schema check retVal = VmDirSchemaCheck(pEntry); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "Schema check failed - (%u)(%s)", retVal, VDIR_SAFE_STRING(VmDirSchemaCtxGetErrorMsg(pEntry->pSchemaCtx))); // check and read lock dn referenced entries retVal = pOperation->pBEIF->pfnBEChkDNReference(pOperation->pBECtx, pEntry); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "BECheckDnRef, (%u)(%s)", retVal, VDIR_SAFE_STRING(pOperation->pBECtx->pszBEErrorMsg)); } // Execute plugin logic that require final entry image. (Do this for both normal and repl routes) retVal = VmDirExecutePreModifyPlugins(pOperation, pEntry, retVal); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "PreModifyPlugins failed - (%u)", retVal); // Update DB retVal = pOperation->pBEIF->pfnBEEntryModify(pOperation->pBECtx, modReq->mods, pEntry); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "BEEntryModify, (%u)(%s)", retVal, VDIR_SAFE_STRING(pOperation->pBEErrorMsg)); if (bNoRaftLog == FALSE) { // Generate raft log only on the orignal Add/Modify/Delete, but not on the derived operation. // For instance, a delete may cause a Modify on the referenced entry which shouldn't // initiate a raft log generation. retVal = VmDirModifyRaftPreCommit( pEntry->pSchemaCtx, entryId, modReq->dn.bvnorm_val, modReq->mods, pOperation); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "VmDirModifyRaftPreCommit, (%u)(%s)", retVal, VDIR_SAFE_STRING(pOperation->pBEErrorMsg)); } cleanup: VmDirFreeAttribute(pAttrMemberOf); VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return retVal; error: if (retVal == VMDIR_LDAP_ERROR_PRE_CONDITION) { VMDIR_LOG_VERBOSE( LDAP_DEBUG_ANY, "CoreLogicModifyEntry failed, DN = %s, (%u)(%s)", VDIR_SAFE_STRING(modReq->dn.lberbv.bv_val), retVal, VDIR_SAFE_STRING(pszLocalErrMsg)); } else { VMDIR_LOG_ERROR( LDAP_DEBUG_ANY, "CoreLogicModifyEntry failed, DN = %s, (%u)(%s)", VDIR_SAFE_STRING(modReq->dn.lberbv.bv_val), retVal, VDIR_SAFE_STRING(pszLocalErrMsg)); } if (pOperation->ldapResult.pszErrMsg == NULL) { pOperation->ldapResult.pszErrMsg = pszLocalErrMsg; pszLocalErrMsg = NULL; } goto cleanup; }
DWORD VmDirSrvSetupHostInstance( PCSTR pszFQDomainName, PCSTR pszUsername, PCSTR pszPassword, PCSTR pszSiteName, PCSTR pszReplURI, UINT32 firstReplCycleMode ) { DWORD dwError = 0; PCSTR pszDelObjsContainerName = "Deleted Objects"; PCSTR pszConfigContainerName = VMDIR_CONFIGURATION_CONTAINER_NAME; PCSTR pszCAContainerName = VMDIR_CA_CONTAINER_NAME; PCSTR pszSitesContainerName = VMDIR_SITES_RDN_VAL; PCSTR pszSiteContainerName = "Default-First-Site"; PCSTR pszServersContainerName = VMDIR_SERVERS_CONTAINER_NAME; PCSTR pszReplAgrsContainerName = VMDIR_REPL_AGRS_CONTAINER_NAME; PCSTR pszDCsContainerName = VMDIR_DOMAIN_CONTROLLERS_RDN_VAL; PCSTR pszComputersContainerName = VMDIR_COMPUTERS_RDN_VAL; PCSTR pszMSAsContainerName = VMDIR_MSAS_RDN_VAL; PSTR pszDomainDN = NULL; PSTR pszDelObjsContainerDN = NULL; // CN=Deleted Objects,<domain DN> PSTR pszConfigContainerDN = NULL; // CN=Configuration,<domain DN> PSTR pszCAContainerDN = NULL; // CN=Certificate-Authorities,CN=Configuration,<domain DN> PSTR pszSitesContainerDN = NULL; // CN=Sites,<configuration DN> PSTR pszSiteContainerDN = NULL; // CN=<Site-Name>,<Sites container DN> PSTR pszServersContainerDN = NULL; // CN=Servers,<Site container DN> PSTR pszServerDN = NULL; // CN=<fully qualified host name>,<Servers container DN> PSTR pszReplAgrsContainerDN = NULL; // CN=Replication Agreements,<Server DN> PSTR pszReplAgrDN = NULL; // labeledURI=<ldap://192.165.226.127>,<ReplAgrsContainerDN> PSTR pszDCsContainerDN = NULL; // OU=Domain Controllers,<domain DN> PSTR pszComputersContainerDN = NULL; // OU=Computers,<domain DN> PSTR pszDCAccountDN = NULL; // CN=<fully qualified host name>,OU=Domain Controllers,<domain DN> PSTR pszDCAccountUPN = NULL; // <hostname>@<domain name> PSTR pszComputerAccountDN = NULL; // CN=<fully qualified host name>,OU=Domain Computers,<domain DN> PSTR pszMSAsDN = NULL; // CN=<Managed Service Accounts>,<domain DN> PSTR pszUpperCaseFQDomainName = NULL; PSTR pszLowerCaseHostName = NULL; PSTR pszDefaultAdminDN = NULL; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; char pszHostName[VMDIR_MAX_HOSTNAME_LEN]; VDIR_BERVALUE bv = VDIR_BERVALUE_INIT; BOOLEAN bInLockReplCycle = FALSE; PVMDIR_REPLICATION_AGREEMENT pReplAgr = NULL; BOOLEAN bInLock = FALSE; PSTR pszUserDN = NULL; PCSTR pszUsersContainerName = "Users"; PSTR pszUsersContainerDN = NULL; // CN=Users,<domain DN> VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "Setting up a host instance (%s).", VDIR_SAFE_STRING(pszFQDomainName)); if (pszSiteName) { pszSiteContainerName = pszSiteName; } // If joining another node, copy schema from the partner first. if (!IsNullOrEmptyString(pszReplURI)) { dwError = VmDirCopyPartnerSchema( pszFQDomainName, pszUsername, pszPassword, pszReplURI); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSchemaCtxAcquire( &pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); // Construct important DNs and create the persisted DSE Root entry // Domain DN dwError = VmDirSrvCreateDomainDN( pszFQDomainName, &pszDomainDN ); BAIL_ON_VMDIR_ERROR(dwError); // Deleted objects container DN dwError = VmDirSrvCreateDN( pszDelObjsContainerName, pszDomainDN, &pszDelObjsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Configuration container DN dwError = VmDirSrvCreateDN( pszConfigContainerName, pszDomainDN, &pszConfigContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Domain Controllers container DN dwError = VmDirAllocateStringAVsnprintf(&pszDCsContainerDN, "%s=%s,%s", ATTR_OU, pszDCsContainerName, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); // Domain Computers container DN dwError = VmDirAllocateStringAVsnprintf(&pszComputersContainerDN, "%s=%s,%s", ATTR_OU, pszComputersContainerName, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); // Sites container DN dwError = VmDirSrvCreateDN( pszSitesContainerName, pszConfigContainerDN, &pszSitesContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Certificate-Authorities container DN dwError = VmDirSrvCreateDN( pszCAContainerName, pszConfigContainerDN, &pszCAContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Particular site container DN dwError = VmDirSrvCreateDN( pszSiteContainerName, pszSitesContainerDN, &pszSiteContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Servers within the site container DN dwError = VmDirSrvCreateDN( pszServersContainerName, pszSiteContainerDN, &pszServersContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // This server DN // vdcpromo sets this key. dwError = VmDirGetRegKeyValue( VMDIR_CONFIG_PARAMETER_KEY_PATH, VMDIR_REG_KEY_DC_ACCOUNT, pszHostName, sizeof(pszHostName)-1); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocASCIIUpperToLower( pszHostName, &pszLowerCaseHostName ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszServersContainerDN, &pszServerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Domain controller account DN dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszDCsContainerDN, &pszDCAccountDN ); BAIL_ON_VMDIR_ERROR(dwError); // Domain controller account UPN dwError = VmDirAllocASCIILowerToUpper( pszFQDomainName, &pszUpperCaseFQDomainName ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringAVsnprintf(&pszDCAccountUPN, "%s@%s", pszLowerCaseHostName, pszUpperCaseFQDomainName ); BAIL_ON_VMDIR_ERROR(dwError); // Computer account DN dwError = VmDirSrvCreateDN( pszLowerCaseHostName, pszComputersContainerDN, &pszComputerAccountDN ); BAIL_ON_VMDIR_ERROR(dwError); // Replication agreements container DN dwError = VmDirSrvCreateDN( pszReplAgrsContainerName, pszServerDN, &pszReplAgrsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); // Managed Service Accounts container DN dwError = VmDirSrvCreateDN( pszMSAsContainerName, pszDomainDN, &pszMSAsDN ); BAIL_ON_VMDIR_ERROR(dwError); // Default administrator DN dwError = VmDirAllocateStringAVsnprintf( &pszDefaultAdminDN, "cn=%s,cn=%s,%s", pszUsername, pszUsersContainerName, pszDomainDN ); BAIL_ON_VMDIR_ERROR(dwError); if (firstReplCycleMode != FIRST_REPL_CYCLE_MODE_USE_COPIED_DB) { // Modify persisted DSE Root entry dwError = VmDirSrvModifyPersistedDSERoot( pSchemaCtx, pszDomainDN, pszConfigContainerDN, SCHEMA_NAMING_CONTEXT_DN, SUB_SCHEMA_SUB_ENTRY_DN, pszServerDN, pszDefaultAdminDN, pszDCAccountDN, pszDCAccountUPN, pszDelObjsContainerDN, (PSTR) pszSiteContainerName ); } BAIL_ON_VMDIR_ERROR(dwError); // set gVmdirServerGlobals.bvDefaultAdminDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvDefaultAdminDN, "%s", pszDefaultAdminDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.bvDefaultAdminDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set systemDomainDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.systemDomainDN, "%s", pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.systemDomainDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set serverObjDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.serverObjDN, "%s", pszServerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.serverObjDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set dcAccountDN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.dcAccountDN, "%s", pszDCAccountDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &gVmdirServerGlobals.dcAccountDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set dcAccountUPN dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.dcAccountUPN, "%s", pszDCAccountUPN); BAIL_ON_VMDIR_ERROR(dwError); // Set replInterval and replPageSize gVmdirServerGlobals.replInterval = VmDirStringToIA(VMDIR_DEFAULT_REPL_INTERVAL); gVmdirServerGlobals.replPageSize = VmDirStringToIA(VMDIR_DEFAULT_REPL_PAGE_SIZE); // Set utdVector VmDirFreeBervalContent(&bv); bv.lberbv.bv_val = ""; bv.lberbv.bv_len = 0; dwError = VmDirBervalContentDup( &bv, &gVmdirServerGlobals.utdVector ); BAIL_ON_VMDIR_ERROR(dwError); // Set delObjsContainerDN VmDirFreeBervalContent(&bv); bv.lberbv.bv_val = pszDelObjsContainerDN; bv.lberbv.bv_len = VmDirStringLenA( bv.lberbv.bv_val ); dwError = VmDirBervalContentDup( &bv, &gVmdirServerGlobals.delObjsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN(&gVmdirServerGlobals.delObjsContainerDN, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirAllocateStringA( pszSiteContainerName, &gVmdirServerGlobals.pszSiteName); BAIL_ON_VMDIR_ERROR(dwError); // Create Administrator DN dwError = VmDirSrvCreateDN( pszUsersContainerName, pszDomainDN, &pszUsersContainerDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSrvCreateUserDN( pszUsername, pszUsersContainerDN, &pszUserDN); BAIL_ON_VMDIR_ERROR(dwError); // set DomainControllerGroupDN for first,second+ host setup dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvDCGroupDN, "cn=%s,cn=%s,%s", VMDIR_DC_GROUP_NAME, VMDIR_BUILTIN_CONTAINER_NAME, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvDCGroupDN), pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set DCClientGroupDN for first,second+ host setup dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvDCClientGroupDN, "cn=%s,cn=%s,%s", VMDIR_DCCLIENT_GROUP_NAME, VMDIR_BUILTIN_CONTAINER_NAME, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvDCClientGroupDN), pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // set ServicesRootDN for first,second+ host setup dwError = VmDirAllocateBerValueAVsnprintf( &gVmdirServerGlobals.bvServicesRootDN, "cn=%s,%s", VMDIR_SERVICES_CONTAINER_NAME, pszDomainDN); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirNormalizeDN( &(gVmdirServerGlobals.bvServicesRootDN), pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); if (IsNullOrEmptyString(pszReplURI)) // 1st directory instance is being setup { // Set gVmdirServerGlobals.serverId FIRST, so that correct SID can be generated for the objects added subsequently. gVmdirServerGlobals.serverId = 1; dwError = VmDirSrvSetupDomainInstance( pSchemaCtx, TRUE, TRUE, pszFQDomainName, pszDomainDN, pszUsername, pszPassword ); BAIL_ON_VMDIR_ERROR(dwError); // Create Deleted Objects container dwError = VmDirSrvCreateContainerWithEID( pSchemaCtx, pszDelObjsContainerDN, pszDelObjsContainerName, DEL_ENTRY_CONTAINER_ENTRY_ID ); BAIL_ON_VMDIR_ERROR(dwError); // Create Domain Controllers container dwError = VmDirSrvCreateOUContainer( pSchemaCtx, pszDCsContainerDN, pszDCsContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Computers container dwError = VmDirSrvCreateOUContainer( pSchemaCtx, pszComputersContainerDN, pszComputersContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Managed Service Accounts container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszMSAsDN, pszMSAsContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Configuration container dwError = VmDirSrvCreateConfigContainer( pSchemaCtx, pszConfigContainerDN, pszConfigContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Certificate-Authorities container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszCAContainerDN, pszCAContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Sites container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszSitesContainerDN, pszSitesContainerName ); BAIL_ON_VMDIR_ERROR(dwError); /* // Create Site-Name container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszSiteContainerDN, pszSiteContainerName ); BAIL_ON_VMDIR_ERROR(dwError); // Create Servers container dwError = VmDirSrvCreateContainer( pSchemaCtx, pszServersContainerDN, pszServersContainerName ); BAIL_ON_VMDIR_ERROR(dwError); */ // Create Site-Name container, Servers container, and THE Server object dwError = VmDirSrvCreateServerObj( pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); // Create Replication Agreements container dwError = VmDirSrvCreateReplAgrsContainer( pSchemaCtx ); BAIL_ON_VMDIR_ERROR(dwError); // 1st replica => no replication agreements => 1st replication cycle done VMDIR_LOCK_MUTEX(bInLockReplCycle, gVmdirGlobals.replCycleDoneMutex); VmDirConditionSignal(gVmdirGlobals.replCycleDoneCondition); VMDIR_UNLOCK_MUTEX(bInLockReplCycle, gVmdirGlobals.replCycleDoneMutex); } else { dwError = VmDirAllocateStringAVsnprintf( &pszReplAgrDN, "labeledURI=%s,%s", pszReplURI, pszReplAgrsContainerDN ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirConstructReplAgr( pSchemaCtx, pszReplURI, VMDIR_DEFAULT_REPL_LAST_USN_PROCESSED, pszReplAgrDN, &pReplAgr ); BAIL_ON_VMDIR_ERROR(dwError); gFirstReplCycleMode = firstReplCycleMode; VMDIR_LOCK_MUTEX(bInLock, gVmdirGlobals.replAgrsMutex); pReplAgr->next = gVmdirReplAgrs; gVmdirReplAgrs = pReplAgr; // ownership transfer // wake up replication thread waiting on the existence // of a replication agreement. VmDirConditionSignal(gVmdirGlobals.replAgrsCondition); VMDIR_UNLOCK_MUTEX(bInLock, gVmdirGlobals.replAgrsMutex); } cleanup: if (pSchemaCtx) { VmDirSchemaCtxRelease(pSchemaCtx); } VMDIR_SAFE_FREE_MEMORY(pszDomainDN); VMDIR_SAFE_FREE_MEMORY(pszDelObjsContainerDN); VMDIR_SAFE_FREE_MEMORY(pszConfigContainerDN); VMDIR_SAFE_FREE_MEMORY(pszCAContainerDN); VMDIR_SAFE_FREE_MEMORY(pszSitesContainerDN); VMDIR_SAFE_FREE_MEMORY(pszSiteContainerDN); VMDIR_SAFE_FREE_MEMORY(pszServersContainerDN); VMDIR_SAFE_FREE_MEMORY(pszServerDN); VMDIR_SAFE_FREE_MEMORY(pszReplAgrsContainerDN); VMDIR_SAFE_FREE_MEMORY(pszReplAgrDN); VMDIR_SAFE_FREE_MEMORY(pszDCsContainerDN); VMDIR_SAFE_FREE_MEMORY(pszDCAccountDN); VMDIR_SAFE_FREE_MEMORY(pszDCAccountUPN); VMDIR_SAFE_FREE_MEMORY(pszComputersContainerDN); VMDIR_SAFE_FREE_MEMORY(pszComputerAccountDN); VMDIR_SAFE_FREE_MEMORY(pszMSAsDN); VMDIR_SAFE_FREE_MEMORY(pszUpperCaseFQDomainName); VMDIR_SAFE_FREE_MEMORY(pszUsersContainerDN); VMDIR_SAFE_FREE_MEMORY(pszUserDN); VMDIR_SAFE_FREE_MEMORY(pszDefaultAdminDN); VMDIR_SAFE_FREE_MEMORY(pszLowerCaseHostName); VmDirFreeBervalContent(&bv); return dwError; error: VmDirLog(LDAP_DEBUG_ANY, "VmDirSrvSetupHostInstance failed. Error(%u)", dwError); goto cleanup; }
static DWORD VmDirSrvModifyPersistedDSERoot( PVDIR_SCHEMA_CTX pSchemaCtx, PSTR pszRootNamingContextDN, PSTR pszConfigNamingContextDN, PSTR pszSchemaNamingContextDN, PSTR pszSubSchemaSubEntryDN, PSTR pszServerDN, PSTR pszDefaultAdminDN, PSTR pszDCAccountDN, PSTR pszDCAccountUPN, PSTR pszDelObjsContainerDN, PSTR pszSiteName ) { DWORD dwError = 0; PSTR ppszPersistedDSERootAttrs[] = { ATTR_ROOT_DOMAIN_NAMING_CONTEXT, pszRootNamingContextDN, ATTR_DEFAULT_NAMING_CONTEXT, pszRootNamingContextDN, ATTR_CONFIG_NAMING_CONTEXT, pszConfigNamingContextDN, ATTR_SCHEMA_NAMING_CONTEXT, pszSchemaNamingContextDN, ATTR_SUB_SCHEMA_SUB_ENTRY, pszSubSchemaSubEntryDN, ATTR_NAMING_CONTEXTS, pszRootNamingContextDN, ATTR_NAMING_CONTEXTS, pszConfigNamingContextDN, ATTR_NAMING_CONTEXTS, pszSchemaNamingContextDN, ATTR_SERVER_NAME, pszServerDN, ATTR_DEFAULT_ADMIN_DN, pszDefaultAdminDN, ATTR_DC_ACCOUNT_DN, pszDCAccountDN, ATTR_DC_ACCOUNT_UPN, pszDCAccountUPN, ATTR_DEL_OBJS_CONTAINER, pszDelObjsContainerDN, ATTR_SITE_NAME, pszSiteName, NULL }; VDIR_OPERATION op = {0}; PSTR pszLocalErrMsg = NULL; VDIR_BERVALUE bvDSERootDN = VDIR_BERVALUE_INIT; int i = 0; dwError = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, NULL ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "VmDirSrvModifyPersistedDSERoot: VmDirInitStackOperation failed with error code: %d.", dwError ); // Setup target DN bvDSERootDN.lberbv.bv_val = PERSISTED_DSE_ROOT_DN; bvDSERootDN.lberbv.bv_len = VmDirStringLenA( bvDSERootDN.lberbv.bv_val ); dwError = VmDirNormalizeDN( &bvDSERootDN, op.pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirBervalContentDup( &bvDSERootDN, &op.reqDn ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "VmDirSrvModifyPersistedDSERoot: BervalContentDup failed with error code: %d.", dwError ); op.pBEIF = VmDirBackendSelect(op.reqDn.lberbv.bv_val); assert(op.pBEIF); dwError = VmDirBervalContentDup( &op.reqDn, &op.request.modifyReq.dn ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "VmDirSrvModifyPersistedDSERoot: BervalContentDup failed with error code: %d.", dwError ); // Setup mods for (i = 0; ppszPersistedDSERootAttrs[i] != NULL; i += 2 ) { dwError = VmDirAppendAMod( &op, MOD_OP_REPLACE, ppszPersistedDSERootAttrs[i], (int) VmDirStringLenA(ppszPersistedDSERootAttrs[i]), ppszPersistedDSERootAttrs[i + 1], VmDirStringLenA(ppszPersistedDSERootAttrs[i + 1]) ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "VmDirSrvModifyPersistedDSERoot: VmDirAppendAMod failed with error code: %d.", dwError ); } dwError = VmDirAppendAMod( &op, MOD_OP_DELETE, ATTR_INVOCATION_ID, ATTR_INVOCATION_ID_LEN, gVmdirServerGlobals.invocationId.lberbv.bv_val, gVmdirServerGlobals.invocationId.lberbv.bv_len ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "VmDirSrvModifyPersistedDSERoot: VmDirAppendAMod failed with error code: %d.", dwError ); // Modify dwError = VmDirInternalModifyEntry( &op ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "VmDirSrvModifyPersistedDSERoot: InternalModifyEntry failed. DN: %s, Error code: %d, Error string: %s", op.reqDn.lberbv.bv_val, dwError, VDIR_SAFE_STRING( op.ldapResult.pszErrMsg ) ); cleanup: VmDirFreeBervalContent(&bvDSERootDN); VmDirFreeOperationContent(&op); VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return dwError; error: VmDirLog(LDAP_DEBUG_ANY, VDIR_SAFE_STRING(pszLocalErrMsg) ); goto cleanup; }
/* * Convert entry allocType from FORMAT_PACK to FORMAT_NORMAL */ DWORD VmDirEntryUnpack( PVDIR_ENTRY pEntry ) { DWORD dwError = 0; PVDIR_ATTRIBUTE pAttr = NULL; PVDIR_ATTRIBUTE pDupAttr = NULL; VDIR_ENTRY newEntry = {0}; assert(pEntry); if (pEntry->allocType != ENTRY_STORAGE_FORMAT_PACK) { return 0; } newEntry.allocType = ENTRY_STORAGE_FORMAT_NORMAL; newEntry.eId = pEntry->eId; dwError = VmDirBervalContentDup(&pEntry->dn, &newEntry.dn); BAIL_ON_VMDIR_ERROR(dwError); // pdn.lberbv.bv_val is always in-place of dn.lberbv.bv_val (compatible with DeleteEntry) if (pEntry->pdn.lberbv.bv_val && pEntry->pdn.lberbv.bv_len > 0) { newEntry.pdn.lberbv.bv_val = newEntry.dn.lberbv.bv_val + (pEntry->pdn.lberbv.bv_val - pEntry->dn.lberbv.bv_val); } // pdn.bvnorm_val is ok to heap allocated if (pEntry->pdn.bvnorm_val && pEntry->pdn.bvnorm_len > 0) { dwError = VmDirAllocateStringA( pEntry->pdn.bvnorm_val, &newEntry.pdn.bvnorm_val); BAIL_ON_VMDIR_ERROR(dwError); newEntry.pdn.bvnorm_len = VmDirStringLenA(newEntry.pdn.bvnorm_val); } // copy attribute for (pAttr = pEntry->attrs, pDupAttr = NULL; pAttr; pAttr = pAttr->next) { dwError = VmDirAttributeDup(pAttr, &pDupAttr); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirEntryAddAttribute(&newEntry, pDupAttr); BAIL_ON_VMDIR_ERROR(dwError); pDupAttr = NULL; } ///////////////////////////////////////////////////////////////////// // should never fail from here to the end ///////////////////////////////////////////////////////////////////// // takes over schema ctx (we copy attributes) newEntry.pSchemaCtx = pEntry->pSchemaCtx; assert(newEntry.pSchemaCtx); pEntry->pSchemaCtx = NULL; // TODO, other fields? // takes over pParentEntry newEntry.pParentEntry = pEntry->pParentEntry; pEntry->pParentEntry = NULL; // fee resources VmDirFreeEntryContent(pEntry); // takes over newEntry content VmDirCopyMemory(pEntry, sizeof(VDIR_ENTRY), &newEntry, sizeof(newEntry)); cleanup: return dwError; error: if (pDupAttr) { VmDirFreeAttribute(pDupAttr); } VmDirFreeEntryContent(&newEntry); goto cleanup; }