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; }
int VmDirMLDelete( PVDIR_OPERATION pOperation ) { DWORD dwError = 0; PSTR pszLocalErrMsg = NULL; pOperation->pBECtx->pBE = VmDirBackendSelect(pOperation->reqDn.lberbv.bv_val); assert(pOperation->pBECtx->pBE); // AnonymousBind Or in case of a failed bind, do not grant delete access if (pOperation->conn->bIsAnonymousBind || VmDirIsFailedAccessInfo(&pOperation->conn->AccessInfo)) { dwError = LDAP_INSUFFICIENT_ACCESS; BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "Not bind/authenticate yet" ); } dwError = VmDirInternalDeleteEntry( pOperation ); BAIL_ON_VMDIR_ERROR( dwError ); cleanup: VmDirSendLdapResult( pOperation ); VMDIR_SAFE_FREE_MEMORY( pszLocalErrMsg ); return pOperation->ldapResult.errCode; error: VMDIR_SET_LDAP_RESULT_ERROR( &(pOperation->ldapResult), dwError, pszLocalErrMsg); goto cleanup; }
DWORD VmDirDeleteEntry( PVDIR_ENTRY pEntry ) { DWORD dwError = 0; VDIR_OPERATION op = {0}; DeleteReq *dr = NULL; dwError = VmDirInitStackOperation(&op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_DELETE, NULL); BAIL_ON_VMDIR_ERROR(dwError); op.pBEIF = VmDirBackendSelect(NULL); op.reqDn.lberbv_val = pEntry->dn.lberbv.bv_val; op.reqDn.lberbv_len = pEntry->dn.lberbv.bv_len; 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; }
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 _VmGetHighestCommittedUSN( PSTR* ppszHighestCommittedUSN ) { DWORD dwError = 0; USN usn = 0; USN nextUSN = 0; VDIR_ENTRY_ARRAY entryArray = {0}; PSTR pszUSN = NULL; VDIR_BACKEND_CTX beCtx = {0}; beCtx.pBE = VmDirBackendSelect(NULL); assert(beCtx.pBE); dwError = beCtx.pBE->pfnBEGetNextUSN(&beCtx, &nextUSN); BAIL_ON_VMDIR_ERROR(dwError); for (usn=nextUSN; usn > 1LL; usn--) { VMDIR_SAFE_FREE_MEMORY(pszUSN); VmDirFreeEntryArrayContent(&entryArray); dwError = VmDirAllocateStringPrintf(&pszUSN, "%" PRId64, usn); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSimpleEqualFilterInternalSearch( "", LDAP_SCOPE_SUBTREE, ATTR_USN_CHANGED, pszUSN, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if (entryArray.iSize == 1 ) { break; } } if (usn == 0) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_STATE); } *ppszHighestCommittedUSN = pszUSN; pszUSN = NULL; cleanup: VMDIR_SAFE_FREE_MEMORY(pszUSN); VmDirFreeEntryArrayContent(&entryArray); VmDirBackendCtxContentFree(&beCtx); return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "error (%u), start USN %" PRId64, dwError, nextUSN); goto cleanup; }
static DWORD _VmDirPagedSearchWorkerThread( PVOID pArg ) { PVDIR_PAGED_SEARCH_RECORD pSearchRecord = (PVDIR_PAGED_SEARCH_RECORD)pArg; DWORD dwError = 0; PVDIR_PAGED_SEARCH_ENTRY_LIST pEntryIdList = NULL; VDIR_OPERATION searchOp = {0}; VmDirDropThreadPriority(DEFAULT_THREAD_PRIORITY_DELTA); dwError = VmDirInitStackOperation( &searchOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL); BAIL_ON_VMDIR_ERROR(dwError); searchOp.pBEIF = VmDirBackendSelect(NULL); searchOp.request.searchReq.filter = pSearchRecord->pFilter; while (pSearchRecord->dwCandidatesProcessed < (DWORD)pSearchRecord->pTotalCandidates->size) { dwError = _VmDirPagedSearchEntryListAlloc(pSearchRecord, &pEntryIdList); BAIL_ON_VMDIR_ERROR(dwError); _VmDirPagedSearchProcessEntries(&searchOp, pSearchRecord, pEntryIdList); if (pEntryIdList->dwCount == 0) { _VmDirPagedSearchEntryListFree(pEntryIdList); } else { dwError = VmDirPagedSearchCacheAddData(pSearchRecord, pEntryIdList); BAIL_ON_VMDIR_ERROR(dwError); } } _VmDirPagedSearchCacheWaitForClientCompletion(pSearchRecord); cleanup: // This will be freed when the pSearchRecord is released. searchOp.request.searchReq.filter = NULL; VmDirFreeOperationContent(&searchOp); _DerefPagedSearchRecord(pSearchRecord); return dwError; error: goto cleanup; }
DWORD VmDirSimpleEntryCreateWithGuid( 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 = VmDirBackendSelect(NULL); 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; }
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; }
static BOOLEAN _VmDirIsBenignReplConflict( PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE pAttr ) { int i = 0; CHAR excludeAttrs[] = {ATTR_USN_CHANGED}; DWORD dwError = 0; BOOLEAN bIsBenign = FALSE; VDIR_ENTRY consumerEntry = {0}; if (pEntry->eId) { if (!consumerEntry.dn.lberbv_val) { PVDIR_BACKEND_INTERFACE pBE = NULL; pBE = VmDirBackendSelect(NULL); assert(pBE); dwError = pBE->pfnBESimpleIdToEntry(pEntry->eId, &consumerEntry); BAIL_ON_VMDIR_ERROR(dwError); } for (i=0; i< VMDIR_ARRAY_SIZE(excludeAttrs); i++) { if (VmDirStringCompareA(pAttr->type.lberbv_val, &excludeAttrs[i], FALSE) == 0) { bIsBenign = TRUE; goto cleanup; } } bIsBenign = VmDirIsSameConsumerSupplierEntryAttr(pAttr, pEntry, &consumerEntry); } cleanup: VmDirFreeEntryContent(&consumerEntry); return bIsBenign; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
/* * If you want this update to be a part of bigger transaction, * provide pBECtx. Or leave it NULL otherwise. */ DWORD VmDirIndexUpdateBegin( PVDIR_BACKEND_CTX pBECtx, PVDIR_INDEX_UPD* ppIndexUpd ) { DWORD dwError = 0; PVDIR_INDEX_UPD pIndexUpd = NULL; if (!ppIndexUpd) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirIndexUpdInit(pBECtx, &pIndexUpd); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirIndexUpdCopy(gVdirIndexGlobals.pIndexUpd, pIndexUpd); BAIL_ON_VMDIR_ERROR(dwError); if (pIndexUpd->bOwnBECtx) { PVDIR_BACKEND_INTERFACE pBE = VmDirBackendSelect(NULL); pIndexUpd->pBECtx->pBE = pBE; dwError = pBE->pfnBETxnBegin(pIndexUpd->pBECtx, VDIR_BACKEND_TXN_WRITE); BAIL_ON_VMDIR_ERROR(dwError); pIndexUpd->bHasBETxn = TRUE; } *ppIndexUpd = pIndexUpd; VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "%s succeeded", __FUNCTION__ ); cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError ); VmDirIndexUpdFree(pIndexUpd); goto cleanup; }
/* * should only be used during bootstrap * maybe add state check? */ DWORD VmDirIndexOpen( PVDIR_INDEX_CFG pIndexCfg ) { DWORD dwError = 0; BOOLEAN bInLock = FALSE; PVDIR_BACKEND_INTERFACE pBE = NULL; if (!pIndexCfg) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } VMDIR_LOCK_MUTEX(bInLock, gVdirIndexGlobals.mutex); if (LwRtlHashMapFindKey( gVdirIndexGlobals.pIndexCfgMap, NULL, pIndexCfg->pszAttrName) == 0) { dwError = ERROR_ALREADY_INITIALIZED; BAIL_ON_VMDIR_ERROR(dwError); } dwError = LwRtlHashMapInsert( gVdirIndexGlobals.pIndexCfgMap, pIndexCfg->pszAttrName, pIndexCfg, NULL); BAIL_ON_VMDIR_ERROR(dwError); pBE = VmDirBackendSelect(NULL); dwError = pBE->pfnBEIndexOpen(pIndexCfg); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VMDIR_UNLOCK_MUTEX(bInLock, gVdirIndexGlobals.mutex); return dwError; error: goto cleanup; }
int VmDirMLModify( PVDIR_OPERATION pOperation ) { DWORD dwError = 0; PSTR pszLocalErrMsg = NULL; pOperation->pBECtx->pBE = VmDirBackendSelect(pOperation->request.modifyReq.dn.lberbv.bv_val); assert(pOperation->pBECtx->pBE); // AnonymousBind Or in case of a failed bind, do not grant modify access if (pOperation->conn->bIsAnonymousBind || VmDirIsFailedAccessInfo(&pOperation->conn->AccessInfo)) { dwError = LDAP_INSUFFICIENT_ACCESS; BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "Not bind/authenticate yet"); } if (!VmDirValidTxnState(pOperation->pBECtx, pOperation->reqCode)) { dwError = LDAP_UNWILLING_TO_PERFORM; BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "%s: invaid request for transaction state", __func__); } // Mod request sanity check dwError = _VmDirExternalModsSanityCheck(pOperation, pOperation->request.modifyReq.mods); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirInternalModifyEntry(pOperation); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return pOperation->ldapResult.errCode; error: VMDIR_SET_LDAP_RESULT_ERROR(&(pOperation->ldapResult), dwError, pszLocalErrMsg); goto cleanup; }
DWORD VmDirSimpleEntryCreateWithGuid( PVDIR_SCHEMA_CTX pSchemaCtx, PSTR* ppszEntryInitializer, PSTR pszDN, ENTRYID ulEntryId, PSTR pszGuid /* Optional */ ) { PVDIR_BACKEND_INTERFACE pBE = VmDirBackendSelect(pszDN); assert(pBE); return _VmDirSimpleEntryCreateInBEWithGuid( pBE, pSchemaCtx, ppszEntryInitializer, pszDN, ulEntryId, pszGuid); }
int VmDirMLDelete( PVDIR_OPERATION pOperation ) { DWORD dwError = 0; PSTR pszLocalErrMsg = NULL; pOperation->pBECtx->pBE = VmDirBackendSelect(pOperation->reqDn.lberbv.bv_val); assert(pOperation->pBECtx->pBE); // AnonymousBind Or in case of a failed bind, do not grant delete access if (pOperation->conn->bIsAnonymousBind || VmDirIsFailedAccessInfo(&pOperation->conn->AccessInfo)) { dwError = LDAP_INSUFFICIENT_ACCESS; BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "Not bind/authenticate yet" ); } if (VmDirRaftDisallowUpdates("Delete")) { dwError = VMDIR_ERROR_UNWILLING_TO_PERFORM; BAIL_ON_VMDIR_ERROR( dwError ); } dwError = VmDirInternalDeleteEntry( pOperation ); BAIL_ON_VMDIR_ERROR( dwError ); if (pOperation->opType == VDIR_OPERATION_TYPE_EXTERNAL) { pOperation->pBEIF->pfnBESetMaxOriginatingUSN(pOperation->pBECtx, pOperation->pBECtx->wTxnUSN); } cleanup: VMDIR_SAFE_FREE_MEMORY( pszLocalErrMsg ); return pOperation->ldapResult.errCode; error: VMDIR_SET_LDAP_RESULT_ERROR( &(pOperation->ldapResult), dwError, pszLocalErrMsg); goto cleanup; }
int VmDirMLSearch( PVDIR_OPERATION pOperation ) { int retVal = 0; PSTR pszLocalErrMsg = NULL; pOperation->pBEIF = VmDirBackendSelect(pOperation->reqDn.lberbv.bv_val); assert(pOperation->pBEIF); retVal = VmDirInternalSearch(pOperation); BAIL_ON_VMDIR_ERROR(retVal); cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return pOperation->ldapResult.errCode; error: VMDIR_SET_LDAP_RESULT_ERROR( &(pOperation->ldapResult), retVal, pszLocalErrMsg); goto cleanup; }
int VmDirMLSearch( PVDIR_OPERATION pOperation ) { int retVal = 0; PSTR pszLocalErrMsg = NULL; pOperation->pBEIF = VmDirBackendSelect(pOperation->reqDn.lberbv.bv_val); assert(pOperation->pBEIF); if (pOperation->conn->bIsAnonymousBind && !VmDirIsSearchForDseRootEntry( pOperation )) { retVal = LDAP_INSUFFICIENT_ACCESS; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, pszLocalErrMsg, "Not bind/authenticate yet" ); } // AnonymousBind is handled when retrieving search candidate result // DSE_ROOT_DN and PERSISTED_DSE_ROOT_DN, SCHEMA_NAMING_CONTEXT_DN // SUB_SCHEMA_SUB_ENTRY_DN should allow anonymous bind READ retVal = VmDirInternalSearch( pOperation); BAIL_ON_VMDIR_ERROR(retVal); cleanup: VmDirSendLdapResult( pOperation ); VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return pOperation->ldapResult.errCode; error: VMDIR_SET_LDAP_RESULT_ERROR( &(pOperation->ldapResult), retVal, pszLocalErrMsg); goto cleanup; }
static int ParseSyncRequestControlVal( VDIR_OPERATION * op, BerValue * controlValue, // Input: control value encoded as ber SyncRequestControlValue * syncReqCtrlVal, // Output VDIR_LDAP_RESULT * lr // Output ) { int retVal = LDAP_SUCCESS; ber_tag_t tag = LBER_ERROR; ber_len_t len = 0; UptoDateVectorEntry * utdVectorEntry = NULL; BerElementBuffer berbuf; BerElement * ber = (BerElement *)&berbuf; PSTR pszLocalErrorMsg = NULL; VDIR_BACKEND_CTX backendCtx = {0}; USN maxPartnerVisibleUSN = 0; VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseSyncRequestControlVal: Begin." ); ber_init2( ber, controlValue, LBER_USE_DER ); /* http://www.rfc-editor.org/rfc/rfc4533.txt * * syncCookie ::= OCTET STRING * * syncRequestValue ::= SEQUENCE { * mode ENUMERATED { * -- 0 unused * refreshOnly (1), * -- 2 reserved * refreshAndPersist (3) * }, * cookie syncCookie OPTIONAL, * reloadHint BOOLEAN DEFAULT FALSE * } */ if (ber_scanf( ber, "{i", &(syncReqCtrlVal->mode) ) == LBER_ERROR) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ber_scanf failed while parsing the sync request " "control mode" ); lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Error in reading sync request control mode from PDU."); } syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv.bv_val = ""; syncReqCtrlVal->intLastLocalUsnProcessed = 0; if (VmDirAllocateMemory( sizeof( VDIR_LDAP_CONTROL ), (PVOID *)&op->syncDoneCtrl) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: VmDirAllocateMemory failed " ); lr->errCode = retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseSyncRequestControlVal: VmDirAllocateMemory failed."); } op->syncDoneCtrl->type = LDAP_CONTROL_SYNC_DONE; if (LwRtlCreateHashTable( &op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, UtdVectorEntryGetKey, LwRtlHashDigestPstr, LwRtlHashEqualPstr, NULL, VMDIR_UTD_VECTOR_HASH_TABLE_SIZE ) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "UpdateSyncDoneUtdVectorEntry: LwRtlCreateHashTable failed" ); lr->errCode = retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "UpdateSyncDoneUtdVectorEntry: LwRtlCreateHashTable failed"); } tag = ber_peek_tag( ber, &len ); if (tag == LBER_SEQUENCE) { // syncCookie /* syncCookie ::= SEQUENCE { * reqServerId LDAPString, * lastLocalUsnProcessed INTEGER (0 .. maxInt), * utdVector UptoDateVectorEntryList } * * UptoDateVectorEntryList ::= SEQUENCE OF uptoDateVectorEntry UptoDateVectorEntry * * UptoDateVectorEntry ::= SEQUENCE { * serverId LDAPString, * lastOrigUsnProcessed INTEGER (0 .. maxInt) } */ // {lastLocalUsnProcessed{{<serverid1><lastOrigUsnProcessed1>}{<serverid2><lastOrigUsnProcessed2>}...}} if (ber_scanf( ber, "{mmm}", &syncReqCtrlVal->reqInvocationId.lberbv, &syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv, &syncReqCtrlVal->bvUtdVector.lberbv ) == LBER_ERROR ) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ber_scanf failed while parsing " "lastLocalUsnProcessed in the sync request control value" ); lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Error in reading lastLocalUsnProcessed in the sync request control value"); } VMDIR_LOG_DEBUG( LDAP_DEBUG_REPL, "ParseSyncRequestControlVal: ServerId: %s, lastLocalUsnProcessed: %s, utdVector: %s", syncReqCtrlVal->reqInvocationId.lberbv.bv_val, syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv.bv_val, syncReqCtrlVal->bvUtdVector.lberbv.bv_val ); syncReqCtrlVal->intLastLocalUsnProcessed = op->syncDoneCtrl->value.syncDoneCtrlVal.intLastLocalUsnProcessed = VmDirStringToLA( syncReqCtrlVal->bvLastLocalUsnProcessed.lberbv.bv_val, NULL, 10 ); { char * nextServerIdStr = NULL; char * nextOrigUsnStr = NULL; nextServerIdStr = syncReqCtrlVal->bvUtdVector.lberbv.bv_val; while( nextServerIdStr != NULL && nextServerIdStr[0] != '\0') { PLW_HASHTABLE_NODE pNode = NULL; if (VmDirAllocateMemory( sizeof(UptoDateVectorEntry), (PVOID *)&utdVectorEntry ) != 0) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: VmDirAllocateMemory failed " ); lr->errCode = retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "ParseSyncRequestControlVal: VmDirAllocateMemory failed"); } nextOrigUsnStr = VmDirStringChrA( nextServerIdStr, ':'); *nextOrigUsnStr = '\0'; nextOrigUsnStr++; utdVectorEntry->invocationId.lberbv.bv_val = nextServerIdStr; utdVectorEntry->invocationId.lberbv.bv_len = VmDirStringLenA( nextServerIdStr ); nextServerIdStr = VmDirStringChrA( nextOrigUsnStr, ','); *nextServerIdStr = '\0'; nextServerIdStr++; utdVectorEntry->currMaxOrigUsnProcessed = utdVectorEntry->reqLastOrigUsnProcessed = atol( nextOrigUsnStr ); LwRtlHashTableResizeAndInsert( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &utdVectorEntry->Node, &pNode); assert( pNode == NULL ); // assert the key of added node is unique. } } tag = ber_peek_tag( ber, &len ); } if (tag == LBER_BOOLEAN) { ber_int_t reloadHint; if (ber_scanf( ber, "b", &reloadHint) == LBER_ERROR) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: Error in reading reloadHint from the PDU" ); lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Error in reading reloadHint from the PDU."); } if (reloadHint) { syncReqCtrlVal->reloadHint = TRUE; } } if ( ber_scanf( ber, "}") == LBER_ERROR ) // End of control value { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ber_scanf failed while parsing the end of " "sync request control value." ); lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Decoding error while parsing the end of sync request control value."); } backendCtx.pBE = VmDirBackendSelect(""); maxPartnerVisibleUSN = backendCtx.pBE->pfnBEGetLeastOutstandingUSN( &backendCtx, FALSE ) - 1; if (syncReqCtrlVal->intLastLocalUsnProcessed > maxPartnerVisibleUSN) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ParseSyncRequestControlVal: ServerId %s has processed my USN (%u), my max USN is (%u).", syncReqCtrlVal->reqInvocationId.lberbv.bv_val, syncReqCtrlVal->intLastLocalUsnProcessed, maxPartnerVisibleUSN ); lr->errCode = LDAP_UNWILLING_TO_PERFORM; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Partner is ahead of my changes."); } cleanup: // Even in the error case, syncDoneCtrl should be freed during operation delete. VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "ParseSyncRequestControlVal: End." ); VmDirBackendCtxContentFree( &backendCtx ); VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return retVal; error: VMDIR_APPEND_ERROR_MSG(lr->pszErrMsg, pszLocalErrorMsg); goto cleanup; }
// To get the current max ENTRYID // Entry database is separated from log databases. DWORD VmDirMDBMaxEntryId( PVDIR_BACKEND_INTERFACE pBE, ENTRYID* pEId ) { DWORD dwError = 0; VDIR_DB mdbDBi = 0; PVDIR_DB_DBC pCursor = NULL; MDB_val key = {0}; MDB_val value = {0}; ENTRYID eId = {0}; unsigned char EIDBytes[sizeof(ENTRYID)] = {0}; VDIR_BACKEND_CTX mdbBECtx = {0}; BOOLEAN bHasTxn = FALSE; PVDIR_MDB_DB pDB = VmDirSafeDBFromBE(pBE); assert(pEId && pDB); mdbBECtx.pBE = pBE; dwError = VmDirMDBTxnBegin(&mdbBECtx, VDIR_BACKEND_TXN_READ, &bHasTxn); BAIL_ON_VMDIR_ERROR(dwError); mdbDBi = pDB->mdbEntryDB.pMdbDataFiles[0].mdbDBi; dwError = mdb_cursor_open((PVDIR_DB_TXN)mdbBECtx.pBEPrivate, mdbDBi, &pCursor); BAIL_ON_VMDIR_ERROR(dwError); key.mv_data = &EIDBytes[0]; if (pBE == VmDirBackendSelect(ALIAS_MAIN)) { //Set cursor position equal or above LOG_ENTRY_EID_PREFIX // it would find the first entry id of raft log entry on legacy data // i.e. database creaded before we implemented a split log. eId = LOG_ENTRY_EID_PREFIX; MDBEntryIdToDBT(eId, &key); dwError = mdb_cursor_get(pCursor, &key, &value, MDB_SET_RANGE); if (dwError == MDB_NOTFOUND) { //mainDb was created after we implemented split log (no log entries in mainDb) // - simply find the last id which will be the last entry-id in normal entries. eId = 0; MDBEntryIdToDBT(eId, &key); dwError = mdb_cursor_get(pCursor, &key, &value, MDB_LAST); BAIL_ON_VMDIR_ERROR(dwError); MDBDBTToEntryId(&key, &eId); } else { BAIL_ON_VMDIR_ERROR(dwError); //Found an entry that is LOG_ENTRY_EID_PREFIX or above // - search backward, and the first one is the last normal entry do { dwError = mdb_cursor_get(pCursor, &key, &value, MDB_PREV); BAIL_ON_VMDIR_ERROR(dwError); MDBDBTToEntryId(&key, &eId); } while (eId >= LOG_ENTRY_EID_PREFIX); } } else { //For logDb, the last one is the log entry. eId = 0; MDBEntryIdToDBT(eId, &key); dwError = mdb_cursor_get(pCursor, &key, &value, MDB_LAST); BAIL_ON_VMDIR_ERROR(dwError); MDBDBTToEntryId(&key, &eId); } mdb_cursor_close(pCursor); pCursor = NULL; if (bHasTxn) { dwError = VmDirMDBTxnCommit(&mdbBECtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); } *pEId = eId; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirMDBMaxEntryId: failed with error (%d),(%s)", dwError, mdb_strerror(dwError) ); mdb_cursor_close(pCursor); if (bHasTxn) { VmDirMDBTxnAbort(&mdbBECtx); } VMDIR_SET_BACKEND_ERROR(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; }
/* * Set vmwPasswordNeverExpires (if it doesn't have a value) to TRUE * on the domain administrator's account. */ DWORD VmDirSetAdministratorPasswordNeverExpires( VOID ) { DWORD dwError = 0; PCSTR pszDomainDn = NULL; const CHAR szAdministrator[] = "cn=Administrator,cn=Users"; const CHAR szTrue[] = "TRUE"; PSTR pszAdministratorDn = NULL; VDIR_OPERATION op = {0}; PSTR pszLocalErrMsg = NULL; VDIR_ENTRY_ARRAY entryArray = {0}; PVDIR_ENTRY pEntry = NULL; VDIR_BERVALUE bervBlob = VDIR_BERVALUE_INIT; pszDomainDn = gVmdirServerGlobals.systemDomainDN.lberbv.bv_val; if (pszDomainDn == NULL) { dwError = ERROR_INVALID_STATE; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocateStringPrintf(&pszAdministratorDn, "%s,%s", szAdministrator, pszDomainDn); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSimpleEqualFilterInternalSearch( pszDomainDn, LDAP_SCOPE_SUBTREE, ATTR_DN, pszAdministratorDn, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if (entryArray.iSize != 1) { dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION; BAIL_ON_VMDIR_ERROR(dwError); } pEntry = &(entryArray.pEntry[0]); if (pEntry->allocType == ENTRY_STORAGE_FORMAT_PACK) { dwError = VmDirEntryUnpack( pEntry ); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, NULL); BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "VmDirSetAdministratorPasswordNeverExpire: VmDirInitStackOperation failed: %u", dwError); op.pBEIF = VmDirBackendSelect(NULL); assert(op.pBEIF); op.reqDn.lberbv.bv_val = pEntry->dn.lberbv.bv_val; op.reqDn.lberbv.bv_len = pEntry->dn.lberbv.bv_len; op.request.modifyReq.dn.lberbv = op.reqDn.lberbv; bervBlob.lberbv.bv_val = (PSTR) szTrue; bervBlob.lberbv.bv_len = strlen(szTrue); dwError = VmDirAppendAMod( &op, MOD_OP_REPLACE, ATTR_PASSWORD_NEVER_EXPIRES, ATTR_PASSWORD_NEVER_EXPIRES_LEN, bervBlob.lberbv_val, bervBlob.lberbv_len); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirInternalModifyEntry(&op); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeEntryArrayContent(&entryArray); VmDirFreeOperationContent(&op); VMDIR_SAFE_FREE_STRINGA(pszAdministratorDn); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSetAdministratorPasswordNeverExpires failed, (%u)", dwError); goto cleanup; }
/* * Convenient function to replace ONE single value attribute via InternalModifyEntry * ***************************************************************************** * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * You should NOT call this function while in a backend txn/ctx. * ***************************************************************************** * This may not be easy to determine as we could call this in different places, which * may be nested in external and internal OPERATION. * A better approach is to pass in pOperation and use the same beCtx if exists. * However, this could also cause logic error, e.g. you could lost track if entry/data * has already been changed by beCtx and reread them. * ***************************************************************************** */ DWORD VmDirInternalEntryAttributeReplace( PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszNormDN, PCSTR pszAttrName, PVDIR_BERVALUE pBervAttrValue ) { DWORD dwError = 0; VDIR_OPERATION ldapOp = {0}; PVDIR_MODIFICATION pMod = NULL; if (!pszNormDN || !pszAttrName || !pBervAttrValue) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInitStackOperation( &ldapOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.pBEIF = VmDirBackendSelect(pszNormDN); assert(ldapOp.pBEIF); ldapOp.reqDn.lberbv.bv_val = (PSTR)pszNormDN; ldapOp.reqDn.lberbv.bv_len = VmDirStringLenA(pszNormDN); dwError = VmDirAllocateMemory(sizeof(*pMod)*1, (PVOID)&pMod); BAIL_ON_VMDIR_ERROR(dwError); pMod->next = NULL; pMod->operation = MOD_OP_REPLACE; dwError = VmDirModAddSingleValueAttribute( pMod, ldapOp.pSchemaCtx, pszAttrName, pBervAttrValue->lberbv.bv_val, pBervAttrValue->lberbv.bv_len); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.request.modifyReq.dn.lberbv.bv_val = (PSTR)pszNormDN; ldapOp.request.modifyReq.dn.lberbv.bv_len = VmDirStringLenA(pszNormDN); ldapOp.request.modifyReq.mods = pMod; pMod = NULL; ldapOp.request.modifyReq.numMods = 1; dwError = VmDirInternalModifyEntry(&ldapOp); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeOperationContent(&ldapOp); if (pMod) { VmDirModificationFree(pMod); } return dwError; error: goto cleanup; }
DWORD VmDirSchemaAttrIdMapUpdateDB( PVDIR_SCHEMA_ATTR_ID_MAP pAttrIdMap ) { DWORD dwError = 0; DWORD dwNumNewIds = 0; LW_HASHMAP_ITER iter = LW_HASHMAP_ITER_INIT; LW_HASHMAP_PAIR pair = {NULL, NULL}; PSTR pszMapStr = NULL; PVMDIR_STRING_LIST pMapStrList = NULL; VDIR_BACKEND_CTX beCtx = {0}; BOOLEAN bHasTxn = FALSE; if (!pAttrIdMap) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwNumNewIds = LwRtlHashMapGetCount(pAttrIdMap->pNewIds); if (dwNumNewIds == 0) { // No new Id goto cleanup; } dwError = VmDirStringListInitialize(&pMapStrList, dwNumNewIds); BAIL_ON_VMDIR_ERROR(dwError); while (LwRtlHashMapIterate(pAttrIdMap->pNewIds, &iter, &pair)) { dwError = VmDirAllocateStringPrintf(&pszMapStr, "%d%s%s", (USHORT)(uintptr_t)pair.pValue, SCHEMA_ATTR_ID_MAP_SEP, (PSTR)pair.pKey); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringListAdd(pMapStrList, pszMapStr); BAIL_ON_VMDIR_ERROR(dwError); } beCtx.pBE = VmDirBackendSelect(PERSISTED_DSE_ROOT_DN); dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_WRITE, &bHasTxn); BAIL_ON_VMDIR_ERROR( dwError ); dwError = beCtx.pBE->pfnBEDupKeySetValues(&beCtx, ATTR_ID_MAP_KEY, pMapStrList); BAIL_ON_VMDIR_ERROR(dwError); if (bHasTxn) { dwError = beCtx.pBE->pfnBETxnCommit(&beCtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); } LwRtlHashMapResetIter(&iter); while (LwRtlHashMapIterate(pAttrIdMap->pNewIds, &iter, &pair)) { dwError = LwRtlHashMapInsert(pAttrIdMap->pStoredIds, pair.pKey, pair.pValue, NULL); BAIL_ON_VMDIR_ERROR(dwError); } LwRtlHashMapClear(pAttrIdMap->pNewIds, VmDirNoopHashMapPairFree, NULL); cleanup: VmDirBackendCtxContentFree(&beCtx); VmDirStringListFree(pMapStrList); return dwError; error: if (bHasTxn) { beCtx.pBE->pfnBETxnAbort(&beCtx); } VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError ); goto cleanup; }
/* * Set SRP Identifier's secret on existing entry with Password set */ DWORD VmDirSRPSetIdentityData( PCSTR pszUPN, PCSTR pszClearTextPassword ) { DWORD dwError = 0; VDIR_OPERATION op = {0}; PSTR pszLocalErrMsg = NULL; VDIR_ENTRY_ARRAY entryArray = {0}; PVDIR_ENTRY pEntry = NULL; PVDIR_ATTRIBUTE pAttrSecret = NULL; VDIR_BERVALUE bvUPN = VDIR_BERVALUE_INIT; VDIR_BERVALUE bvClearTextPassword = VDIR_BERVALUE_INIT; VDIR_BERVALUE bervSecretBlob = VDIR_BERVALUE_INIT; if ( IsNullOrEmptyString(pszUPN) || IsNullOrEmptyString(pszClearTextPassword) ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } bvUPN.lberbv_val = (PSTR)pszUPN; bvUPN.lberbv_len = VmDirStringLenA(pszUPN); bvClearTextPassword.lberbv_val = (PSTR)pszClearTextPassword; bvClearTextPassword.lberbv_len = VmDirStringLenA(pszClearTextPassword); dwError = VmDirSimpleEqualFilterInternalSearch( "", LDAP_SCOPE_SUBTREE, ATTR_KRB_UPN, pszUPN, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if (entryArray.iSize == 1) { pAttrSecret = VmDirFindAttrByName(&(entryArray.pEntry[0]), ATTR_SRP_SECRET); if (pAttrSecret) { dwError = VMDIR_ERROR_ENTRY_ALREADY_EXIST; BAIL_ON_VMDIR_ERROR(dwError); } } else { dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION; BAIL_ON_VMDIR_ERROR(dwError); } pEntry = &(entryArray.pEntry[0]); dwError = VdirPasswordCheck(&bvClearTextPassword, pEntry); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSRPCreateSecret(&bvUPN, &bvClearTextPassword, &bervSecretBlob); BAIL_ON_VMDIR_ERROR(dwError); if (pEntry->allocType == ENTRY_STORAGE_FORMAT_PACK) { dwError = VmDirEntryUnpack( pEntry ); BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInitStackOperation( &op, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, NULL); BAIL_ON_VMDIR_ERROR_WITH_MSG(dwError, pszLocalErrMsg, "VmDirSRPSetIdentityData: VmDirInitStackOperation failed: %u", dwError); op.pBEIF = VmDirBackendSelect(NULL); assert(op.pBEIF); op.reqDn.lberbv.bv_val = pEntry->dn.lberbv.bv_val; op.reqDn.lberbv.bv_len = pEntry->dn.lberbv.bv_len; op.request.modifyReq.dn.lberbv = op.reqDn.lberbv; dwError = VmDirAppendAMod( &op, MOD_OP_ADD, ATTR_SRP_SECRET, ATTR_SRP_SECRET_LEN, bervSecretBlob.lberbv_val, bervSecretBlob.lberbv_len); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirInternalModifyEntry(&op); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeBervalContent(&bervSecretBlob); VmDirFreeEntryArrayContent(&entryArray); VmDirFreeOperationContent(&op); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSRPSetIdentityData (%s) failed, (%u)", VDIR_SAFE_STRING(pszUPN), dwError); 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; }
/* * 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; }
DWORD VmDirSchemaAttrIdMapReadDB( PVDIR_SCHEMA_ATTR_ID_MAP pAttrIdMap ) { DWORD dwError = 0; DWORD i = 0; VDIR_BACKEND_CTX beCtx = {0}; BOOLEAN bHasTxn = FALSE; PVMDIR_STRING_LIST pStringList = NULL; PSTR pszBuf = NULL; PSTR pszName = NULL; PSTR pszId = NULL; USHORT usId = 0; if (!pAttrIdMap) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } beCtx.pBE = VmDirBackendSelect(PERSISTED_DSE_ROOT_DN); dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_READ, &bHasTxn); BAIL_ON_VMDIR_ERROR(dwError); dwError = beCtx.pBE->pfnBEDupKeyGetValues( &beCtx, ATTR_ID_MAP_KEY, &pStringList); BAIL_ON_VMDIR_ERROR(dwError); if (bHasTxn) { dwError = beCtx.pBE->pfnBETxnCommit(&beCtx); bHasTxn = FALSE; BAIL_ON_VMDIR_ERROR(dwError); } for (i = 0; i < pStringList->dwCount; i++) { dwError = VmDirAllocateStringA(pStringList->pStringList[i], &pszBuf); BAIL_ON_VMDIR_ERROR(dwError); pszId = VmDirStringTokA(pszBuf, SCHEMA_ATTR_ID_MAP_SEP, &pszName); usId = (USHORT)VmDirStringToIA(pszId); if (VmDirSchemaAttrIdMapGetAttrId(pAttrIdMap, pszName, NULL) != 0) { dwError = VmDirAllocateStringA(pszName, &pszName); BAIL_ON_VMDIR_ERROR(dwError); dwError = LwRtlHashMapInsert(pAttrIdMap->pStoredIds, pszName, (PVOID)(uintptr_t)usId, NULL); BAIL_ON_VMDIR_ERROR(dwError); if (usId >= pAttrIdMap->usNextId) { pAttrIdMap->usNextId = usId + 1; } } VMDIR_SAFE_FREE_MEMORY(pszBuf); } cleanup: VmDirBackendCtxContentFree(&beCtx); VmDirStringListFree(pStringList); return dwError; error: if (bHasTxn) { beCtx.pBE->pfnBETxnAbort(&beCtx); } VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError ); VMDIR_SAFE_FREE_MEMORY(pszBuf); goto cleanup; }
DWORD VmDirGetUPNMemberships( PCSTR pszUpnName, PSTR **pppszMemberships, PDWORD pdwMemberships ) { DWORD dwError = 0; VDIR_ENTRY_ARRAY entryArray = {0}; VDIR_OPERATION searchOp = {0}; BOOLEAN bHasTxn = FALSE; PVDIR_ATTRIBUTE pMemberOf = NULL; PSTR *ppszMemberships = NULL; DWORD dwMemberships = 0; DWORD i = 0; if (IsNullOrEmptyString(pszUpnName) || pppszMemberships == NULL || pdwMemberships == NULL) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirSimpleEqualFilterInternalSearch( "", LDAP_SCOPE_SUBTREE, ATTR_KRB_UPN, pszUpnName, &entryArray); BAIL_ON_VMDIR_ERROR(dwError); if (entryArray.iSize == 0) { dwError = VMDIR_ERROR_ENTRY_NOT_FOUND; BAIL_ON_VMDIR_ERROR(dwError); } else if (entryArray.iSize > 1) { dwError = VMDIR_ERROR_DATA_CONSTRAINT_VIOLATION; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInitStackOperation(&searchOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL); BAIL_ON_VMDIR_ERROR(dwError); searchOp.pBEIF = VmDirBackendSelect(NULL); dwError = searchOp.pBEIF->pfnBETxnBegin(searchOp.pBECtx, VDIR_BACKEND_TXN_READ); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = TRUE; dwError = VmDirBuildMemberOfAttribute(&searchOp, entryArray.pEntry, &pMemberOf); BAIL_ON_VMDIR_ERROR(dwError); if (pMemberOf) { dwMemberships = pMemberOf->numVals; } if (dwMemberships) { dwError = VmDirAllocateMemory(dwMemberships * sizeof(PSTR), (PVOID)&ppszMemberships); BAIL_ON_VMDIR_ERROR(dwError); for (i = 0; i < dwMemberships; i++) { PCSTR pszMemberOf = pMemberOf->vals[i].lberbv.bv_val; dwError = VmDirAllocateStringA(pszMemberOf, &ppszMemberships[i]); BAIL_ON_VMDIR_ERROR(dwError); } } *pppszMemberships = ppszMemberships; *pdwMemberships = dwMemberships; cleanup: if (pMemberOf) { VmDirFreeAttribute(pMemberOf); } if (bHasTxn) { searchOp.pBEIF->pfnBETxnCommit(searchOp.pBECtx); } VmDirFreeOperationContent(&searchOp); VmDirFreeEntryArrayContent(&entryArray); return dwError; error: VmDirFreeMemberships(ppszMemberships, dwMemberships); 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; }
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 VmDirIndexLibInit( PVMDIR_MUTEX pModMutex ) { static VDIR_DEFAULT_INDEX_CFG defIdx[] = VDIR_INDEX_INITIALIZER; DWORD dwError = 0; DWORD i = 0; PSTR pszLastOffset = NULL; ENTRYID maxEId = 0; VDIR_BACKEND_CTX beCtx = {0}; BOOLEAN bHasTxn = FALSE; PVDIR_INDEX_CFG pIndexCfg = NULL; PVDIR_SCHEMA_CTX pSchemaCtx = NULL; PVDIR_SCHEMA_AT_DESC pATDesc = NULL; if (!pModMutex) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // pModMutex refers to gVdirSchemaGlobals.cacheModMutex, // so do not free it during shutdown gVdirIndexGlobals.mutex = pModMutex; dwError = VmDirAllocateCondition(&gVdirIndexGlobals.cond); BAIL_ON_VMDIR_ERROR(dwError); dwError = LwRtlCreateHashMap( &gVdirIndexGlobals.pIndexCfgMap, LwRtlHashDigestPstrCaseless, LwRtlHashEqualPstrCaseless, NULL); BAIL_ON_VMDIR_ERROR(dwError); beCtx.pBE = VmDirBackendSelect(NULL); dwError = beCtx.pBE->pfnBETxnBegin(&beCtx, VDIR_BACKEND_TXN_WRITE); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = TRUE; // get fields to continue indexing from where it left last time dwError = beCtx.pBE->pfnBEUniqKeyGetValue( &beCtx, INDEX_LAST_OFFSET_KEY, &pszLastOffset); if (dwError) { dwError = beCtx.pBE->pfnBEMaxEntryId(&maxEId); BAIL_ON_VMDIR_ERROR(dwError); if (maxEId == ENTRY_ID_SEQ_INITIAL_VALUE) { gVdirIndexGlobals.bFirstboot = TRUE; } else { gVdirIndexGlobals.bLegacyDB = TRUE; } // set index_last_offset = -1 to indicate indexing has started gVdirIndexGlobals.offset = -1; dwError = beCtx.pBE->pfnBEUniqKeySetValue( &beCtx, INDEX_LAST_OFFSET_KEY, "-1"); BAIL_ON_VMDIR_ERROR(dwError); } else { dwError = VmDirStringToINT64(pszLastOffset, NULL, &gVdirIndexGlobals.offset); BAIL_ON_VMDIR_ERROR(dwError); } dwError = beCtx.pBE->pfnBETxnCommit(&beCtx); BAIL_ON_VMDIR_ERROR(dwError); bHasTxn = FALSE; dwError = VmDirSchemaCtxAcquire(&pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); // open default indices for (i = 0; defIdx[i].pszAttrName; i++) { dwError = VmDirDefaultIndexCfgInit(&defIdx[i], &pIndexCfg); BAIL_ON_VMDIR_ERROR(dwError); // update attribute types in schema cache with their index info dwError = VmDirSchemaAttrNameToDescriptor( pSchemaCtx, pIndexCfg->pszAttrName, &pATDesc); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirIndexCfgGetAllScopesInStrArray( pIndexCfg, &pATDesc->ppszUniqueScopes); BAIL_ON_VMDIR_ERROR(dwError); pATDesc->dwSearchFlags |= 1; // for free later pATDesc->pLdapAt->ppszUniqueScopes = pATDesc->ppszUniqueScopes; pATDesc->pLdapAt->dwSearchFlags = pATDesc->dwSearchFlags; dwError = VmDirIndexOpen(pIndexCfg); BAIL_ON_VMDIR_ERROR(dwError); pIndexCfg = NULL; } // VMIT support dwError = VmDirIndexLibInitVMIT(); BAIL_ON_VMDIR_ERROR(dwError); dwError = InitializeIndexingThread(); BAIL_ON_VMDIR_ERROR(dwError); cleanup: if (bHasTxn) { beCtx.pBE->pfnBETxnAbort(&beCtx); } VmDirBackendCtxContentFree(&beCtx); VmDirSchemaCtxRelease(pSchemaCtx); VMDIR_SAFE_FREE_MEMORY(pszLastOffset); return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s failed, error (%d)", __FUNCTION__, dwError); VmDirFreeIndexCfg(pIndexCfg); goto cleanup; }