/* * Bind to partner via "SRP" mechanism. */ DWORD VmDirSafeLDAPBind( LDAP** ppLd, PCSTR pszHost, PCSTR pszUPN, PCSTR pszPassword ) { DWORD dwError = 0; LDAP* pLd = NULL; char ldapURI[VMDIR_MAX_LDAP_URI_LEN + 1] = {0}; if (ppLd == NULL || pszHost == NULL || pszUPN == NULL || pszPassword == NULL) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } if ( VmDirIsIPV6AddrFormat( pszHost ) ) { dwError = VmDirStringPrintFA( ldapURI, sizeof(ldapURI)-1, "%s://[%s]:%d", VMDIR_LDAP_PROTOCOL, pszHost, DEFAULT_LDAP_PORT_NUM); } else { dwError = VmDirStringPrintFA( ldapURI, sizeof(ldapURI)-1, "%s://%s:%d", VMDIR_LDAP_PROTOCOL, pszHost, DEFAULT_LDAP_PORT_NUM); } BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSASLSRPBind( &pLd, &(ldapURI[0]), pszUPN, pszPassword); BAIL_ON_VMDIR_ERROR(dwError); *ppLd = pLd; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSafeLDAPBind to (%s) failed. SRP(%d)", ldapURI, dwError ); if ( pLd ) { ldap_unbind_ext_s( pLd, NULL, NULL); } goto cleanup; }
DWORD VmDirMetaDataSerialize( PVMDIR_ATTRIBUTE_METADATA pMetadata, PSTR pszMetadata ) { DWORD dwError = 0; if (VmDirMetaDataIsEmpty(pMetadata) || !pszMetadata) { BAIL_WITH_VMDIR_ERROR(dwError, VMDIR_ERROR_INVALID_PARAMETER); } dwError = VmDirStringPrintFA( pszMetadata, VMDIR_MAX_ATTR_META_DATA_LEN, "%"PRId64":%"PRId64":%s:%s:%"PRId64, pMetadata->localUsn, pMetadata->version, pMetadata->pszOrigInvoId, pMetadata->pszOrigTime, pMetadata->origUsn); BAIL_ON_VMDIR_ERROR(dwError); cleanup: return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
static DWORD _VmDirSchemaAttrReplaceValue( PVDIR_ATTRIBUTE pAttr, PCSTR pszMatchSubstr, PCSTR pszValue ) { #define MAX_BUF_SIZE_256 256 DWORD dwError = 0; unsigned iCnt = 0; CHAR pszBuf[MAX_BUF_SIZE_256] = {0}; dwError = VmDirStringPrintFA( pszBuf, MAX_BUF_SIZE_256 -1 , "NAME '%s' ", pszMatchSubstr ); BAIL_ON_VMDIR_ERROR(dwError); for (iCnt = 0; iCnt < pAttr->numVals; iCnt++) { if ( VmDirCaselessStrStrA( pAttr->vals[iCnt].lberbv_val, pszBuf ) != NULL ) { if ( VmDirStringCompareA( VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val), pszValue, FALSE ) != 0 ) { VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, replace old - %s", VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val)); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "Merge schema, replace new - %s", pszValue ); } VMDIR_LOG_DEBUG( VMDIR_LOG_MASK_ALL, "Merge schema, replace old - %s", VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val)); VmDirFreeBervalContent( &(pAttr->vals[iCnt]) ); dwError = VmDirAllocateStringA( pszValue, &(pAttr->vals[iCnt].lberbv_val) ); BAIL_ON_VMDIR_ERROR(dwError); pAttr->vals[iCnt].lberbv_len = VmDirStringLenA( pszValue ); pAttr->vals[iCnt].bOwnBvVal = TRUE; VMDIR_LOG_DEBUG( VMDIR_LOG_MASK_ALL, "Merge schema, replace new - %s", VDIR_SAFE_STRING(pAttr->vals[iCnt].lberbv_val)); break; } } cleanup: return dwError; error: goto cleanup; }
/* * Bind to a host with the handle to be used later */ DWORD VmDirConnectLDAPServerWithMachineAccount( PCSTR pszHostName, PCSTR pszDomain, LDAP** ppLd ) { DWORD dwError = 0; PSTR pszDCAccount = NULL; PSTR pszDCAccountPassword = NULL; char bufUPN[VMDIR_MAX_UPN_LEN] = {0}; LDAP* pLd = NULL; dwError = VmDirRegReadDCAccount( &pszDCAccount); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirReadDCAccountPassword( &pszDCAccountPassword); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringPrintFA( bufUPN, sizeof(bufUPN)-1, "%s@%s", pszDCAccount, pszDomain); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSafeLDAPBindExt1( &pLd, pszHostName, bufUPN, pszDCAccountPassword, MAX_LDAP_CONNECT_NETWORK_TIMEOUT); BAIL_ON_VMDIR_ERROR(dwError); *ppLd = pLd; cleanup: VMDIR_SAFE_FREE_STRINGA(pszDCAccount); VMDIR_SECURE_FREE_STRINGA(pszDCAccountPassword); return dwError; error: goto cleanup; }
DWORD VmDirGetVmDirLogPath( PSTR pszPath, PCSTR pszLogFile) { DWORD dwError = 0; #ifndef _WIN32 //BUGBUG, should NOT hard code path dwError = VmDirStringCpyA(pszPath, MAX_PATH, "/var/log/vmware/vmdir/"); BAIL_ON_VMDIR_ERROR(dwError); #else _TCHAR* programDataPath = NULL; if ((dwError = VmDirGetRegKeyValue( VMDIR_CONFIG_SOFTWARE_KEY_PATH, VMDIR_REG_KEY_LOG_PATH, pszPath, MAX_PATH )) != 0) { dwError = VmDirGetProgramDataEnvVar((_TCHAR *)"PROGRAMDATA", &programDataPath); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringPrintFA(pszPath, MAX_PATH, "%s%s", programDataPath, "\\vmware\\cis\\logs\\vmdird\\"); BAIL_ON_VMDIR_ERROR(dwError); } #endif dwError = VmDirStringCatA(pszPath, MAX_PATH, pszLogFile); BAIL_ON_VMDIR_ERROR(dwError); cleanup: #ifdef _WIN32 VMDIR_SAFE_FREE_MEMORY(programDataPath); #endif return dwError; error: VmDirLog(LDAP_DEBUG_ERROR, "VmDirGetVmDirLogPath failed with error (%u)\n", dwError); goto cleanup; }
static DWORD SetPagedSearchCookie( PVDIR_OPERATION pOperation, ENTRYID eId, DWORD dwCandidatesProcessed ) { DWORD dwError = 0; if (gVmdirGlobals.bPagedSearchReadAhead) { dwError = VmDirPagedSearchCacheInsert( pOperation, dwCandidatesProcessed); } if (dwError != 0 || !gVmdirGlobals.bPagedSearchReadAhead) { // // We were unable to cache the information necessary. Fallback to the // old cookie mechanism. // dwError = VmDirStringPrintFA( pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, VMDIR_ARRAY_SIZE(pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie), "%llu", eId); BAIL_ON_VMDIR_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
DWORD VmDirSafeLDAPBindToPort( LDAP** ppLd, PCSTR pszHost, DWORD dwPort, PCSTR pszUPN, PCSTR pszPassword, int iTimeout ) { DWORD dwError = 0; LDAP* pLd = NULL; char ldapURI[VMDIR_MAX_LDAP_URI_LEN + 1] = {0}; DWORD dwLdapPort = DEFAULT_LDAP_PORT_NUM; DWORD dwTmpLdapPort = 0; if (ppLd == NULL || pszHost == NULL || pszUPN == NULL || pszPassword == NULL) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } if (dwPort) { dwLdapPort = dwPort; } else if (VmDirGetRegKeyValueDword( VMDIR_CONFIG_PARAMETER_V1_KEY_PATH, VMDIR_REG_KEY_LDAP_PORT, &dwTmpLdapPort, DEFAULT_LDAP_PORT_NUM) == ERROR_SUCCESS) { dwLdapPort = dwTmpLdapPort; } if ( VmDirIsIPV6AddrFormat( pszHost ) ) { dwError = VmDirStringPrintFA( ldapURI, sizeof(ldapURI)-1, "%s://[%s]:%d", VMDIR_LDAP_PROTOCOL, pszHost, dwLdapPort); } else { dwError = VmDirStringPrintFA( ldapURI, sizeof(ldapURI)-1, "%s://%s:%d", VMDIR_LDAP_PROTOCOL, pszHost, dwLdapPort); } BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSASLSRPBindExt1( &pLd, &(ldapURI[0]), pszUPN, pszPassword, iTimeout); BAIL_ON_VMDIR_ERROR(dwError); *ppLd = pLd; cleanup: return dwError; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s to (%s) failed. SRP(%d)", __FUNCTION__, ldapURI, dwError ); if ( pLd ) { ldap_unbind_ext_s( pLd, NULL, NULL); } goto cleanup; }
static int WriteMetaDataAttribute( VDIR_OPERATION * op, VDIR_ATTRIBUTE * pAttr, int numAttrMetaData, PATTRIBUTE_META_DATA_NODE pAttrMetaData, BerElement * ber, BOOLEAN * nonTrivialAttrsInReplScope, PSTR* ppszErrorMsg ) { int retVal = LDAP_SUCCESS; VDIR_BERVALUE attrMetaData = { {ATTR_ATTR_META_DATA_LEN, ATTR_ATTR_META_DATA}, 0, 0, NULL }; int i = 0; VDIR_BERVALUE berVal = VDIR_BERVALUE_INIT; char attrMetaDataVal[256 + VMDIR_MAX_ATTR_META_DATA_LEN]; PSTR pszLocalErrorMsg = NULL; *nonTrivialAttrsInReplScope = FALSE; if (ber_printf( ber, "{O[", &(attrMetaData) ) == -1 ) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print attribute name ...) failed" ); retVal = LDAP_OTHER; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Encoding attribute type failed."); } for ( ; pAttr != NULL; pAttr = pAttr->next) { // By this time, we have already filtered out attributes that should be send back to replication consumer // in prior WriteAttributes -> IsAttrInReplScope call. They contain proper pAttr->metaData value. if (pAttr->metaData[0] != '\0') { VmDirStringPrintFA( attrMetaDataVal, sizeof(attrMetaDataVal), "%.256s:%s", pAttr->type.lberbv.bv_val, pAttr->metaData); berVal.lberbv.bv_val = attrMetaDataVal; berVal.lberbv.bv_len = VmDirStringLenA( attrMetaDataVal ); if (VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_MODIFYTIMESTAMP, FALSE ) != 0 && VmDirStringCompareA( pAttr->type.lberbv.bv_val, ATTR_USN_CHANGED, FALSE ) != 0) { // To prevent endless replication ping pong, supplier should send result only if there are changes // to attribute other than ATTR_USN_CHANGED and ATTR_MODIFYTIMESTAMP. *nonTrivialAttrsInReplScope = TRUE; } if (ber_printf( ber, "O", &berVal ) == -1 ) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print an attribute value ...) failed." ); retVal = LDAP_OTHER; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Encoding an attribute value failed."); } } } // include attrMetaData for the deleted attributes for (i = 0; i<numAttrMetaData; i++) { if (pAttrMetaData[i].metaData[0] != '\0') { BOOLEAN bSendAttrMetaData = TRUE; PVDIR_SCHEMA_AT_DESC pATDesc = NULL; if (op->syncReqCtrl != NULL) // Replication { retVal = IsAttrInReplScope( op, NULL, pAttrMetaData[i].metaData, &bSendAttrMetaData, &pszLocalErrorMsg ); BAIL_ON_VMDIR_ERROR( retVal ); } else { bSendAttrMetaData = TRUE; } if (bSendAttrMetaData) { if ((pATDesc = VmDirSchemaAttrIdToDesc(op->pSchemaCtx, pAttrMetaData[i].attrID)) == NULL) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: VmDirSchemaAttrIdToDesc failed for attribute id: %d.", pAttrMetaData[i].attrID ); retVal = LDAP_OTHER; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "WriteMetaDataAttribute: VmDirSchemaAttrIdToDesc failed."); } VmDirStringPrintFA( attrMetaDataVal, sizeof(attrMetaDataVal), "%.256s:%s", pATDesc->pszName, pAttrMetaData[i].metaData); berVal.lberbv.bv_val = attrMetaDataVal; berVal.lberbv.bv_len = VmDirStringLenA( attrMetaDataVal ); *nonTrivialAttrsInReplScope = TRUE; if (ber_printf( ber, "O", &berVal ) == -1 ) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to print an attribute value ...) failed." ); retVal = LDAP_OTHER; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Encoding an attribute value failed."); } } } } if ( ber_printf( ber, "]N}" ) == -1 ) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute: ber_printf (to terminate an attribute's values ...) failed" ); retVal = LDAP_OTHER; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Encoding terminating an attribute type failed."); } cleanup: if (ppszErrorMsg) { *ppszErrorMsg = pszLocalErrorMsg; } else { VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); } return( retVal ); error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteMetaDataAttribute failed (%u)(%s)", retVal, VDIR_SAFE_STRING(pszLocalErrorMsg) ); 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; }
static int _VmDirGetRemoteDBUsingRPC( PCSTR pszHostname, PCSTR dbHomeDir, BOOLEAN *pbHasXlog) { DWORD retVal = 0; PSTR pszLocalErrorMsg = NULL; char dbRemoteFilename[VMDIR_MAX_FILE_NAME_LEN] = {0}; char localDir[VMDIR_MAX_FILE_NAME_LEN] = {0}; char localXlogDir[VMDIR_MAX_FILE_NAME_LEN] = {0}; char localFilename[VMDIR_MAX_FILE_NAME_LEN] = {0}; PSTR pszDcAccountPwd = NULL; PVMDIR_SERVER_CONTEXT hServer = NULL; DWORD low_xlognum = 0; DWORD high_xlognum = 0; DWORD xlognum = 0; DWORD remoteDbSizeMb = 0; DWORD remoteDbMapSizeMb = 0; PBYTE pDbPath = NULL; BOOLEAN bMdbWalEnable = FALSE; #ifndef _WIN32 const char fileSeperator = '/'; #else const char fileSeperator = '\\'; #endif retVal = VmDirAllocateMemory(VMDIR_MAX_FILE_NAME_LEN, (PVOID)&pDbPath ); BAIL_ON_VMDIR_ERROR(retVal); retVal = VmDirReadDCAccountPassword(&pszDcAccountPwd); BAIL_ON_VMDIR_ERROR( retVal ); retVal = VmDirOpenServerA(pszHostname, gVmdirServerGlobals.dcAccountUPN.lberbv_val, NULL, pszDcAccountPwd, 0, NULL, &hServer); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirOpenServerA() call failed with error: %d, host name = %s", retVal, pszHostname ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: Connected to the replication partner (%s).", pszHostname ); VmDirGetMdbWalEnable(&bMdbWalEnable); if (bMdbWalEnable) { //Set remote server backend to KEEPXLOGS mode retVal = VmDirSetBackendState (hServer, MDB_STATE_KEEPXLOGS, &low_xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); } else { //Set remote server backend to ReadOnly mode retVal = VmDirSetBackendState (hServer, MDB_STATE_READONLY, &low_xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); } BAIL_ON_VMDIR_ERROR_WITH_MSG(retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirSetBackendState failed, WalEnabled: %d, error: %d", bMdbWalEnable, retVal); retVal = VmDirStringPrintFA( localDir, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", dbHomeDir, fileSeperator, LOCAL_PARTNER_DIR); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = _VmDirMkdir(localDir, 0700); BAIL_ON_VMDIR_ERROR( retVal ); if (low_xlognum > 0) { retVal = VmDirStringPrintFA( localXlogDir, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", localDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = _VmDirMkdir(localXlogDir, 0700); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: _VmDirMkdir() call failed with error: %d %s", retVal ); } retVal = VmDirStringPrintFA( dbRemoteFilename, VMDIR_MAX_FILE_NAME_LEN, "%s/%s", (char *)pDbPath, VMDIR_MDB_DATA_FILE_NAME ); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = VmDirStringPrintFA( localFilename, 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), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: copying remote file %s with data size %ld MB with Map size %ld MB ...", dbRemoteFilename, remoteDbSizeMb, remoteDbMapSizeMb ); retVal = _VmDirGetRemoteDBFileUsingRPC( hServer, dbRemoteFilename, localFilename, remoteDbSizeMb, remoteDbMapSizeMb ); BAIL_ON_VMDIR_ERROR( retVal ); if (low_xlognum == 0) { VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: complete MDB cold copy - WAL not supported by remote"); goto cleanup; } //Query current xlog number retVal = VmDirSetBackendState (hServer, MDB_STATE_GETXLOGNUM, &high_xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirSetBackendState failed to get current xlog: %d", retVal ); VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: start transfering XLOGS from %d to %d", low_xlognum, high_xlognum); for (xlognum = low_xlognum; xlognum <= high_xlognum; xlognum++) { retVal = VmDirStringPrintFA( dbRemoteFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s%c%lu", dbHomeDir, fileSeperator, VMDIR_MDB_XLOGS_DIR_NAME, fileSeperator, xlognum ); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = VmDirStringPrintFA( localFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%lu", localXlogDir, fileSeperator, xlognum); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: VmDirStringPrintFA() call failed with error: %d", retVal ); retVal = _VmDirGetRemoteDBFileUsingRPC( hServer, dbRemoteFilename, localFilename, 0, 0); BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "_VmDirGetRemoteDBUsingRPC: _VmDirGetRemoteDBFileUsingRPC() call failed with error: %d", retVal ); } VMDIR_LOG_INFO( VMDIR_LOG_MASK_ALL, "_VmDirGetRemoteDBUsingRPC: complete transfering XLOGS from %d to %d", low_xlognum, high_xlognum); cleanup: if (hServer) { //clear backend transfering xlog files mode. VmDirSetBackendState (hServer, MDB_STATE_CLEAR, &xlognum, &remoteDbSizeMb, &remoteDbMapSizeMb, pDbPath, VMDIR_MAX_FILE_NAME_LEN); VmDirCloseServer( hServer); } VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); VMDIR_SAFE_FREE_MEMORY(pDbPath); VMDIR_SECURE_FREE_STRINGA(pszDcAccountPwd); *pbHasXlog = (low_xlognum > 0); return retVal; error: retVal = LDAP_OPERATIONS_ERROR; VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "%s", VDIR_SAFE_STRING(pszLocalErrorMsg) ); goto cleanup; }
static DWORD constructDeletedObjDN( VDIR_BERVALUE * dn, const char * objectGuidStr, VDIR_BERVALUE * deletedObjDN ) { DWORD dwError = 0; VDIR_BERVALUE parentDN = VDIR_BERVALUE_INIT; size_t deletedObjDNLen = 0; size_t delObjsConatinerDNLength = gVmdirServerGlobals.delObjsContainerDN.lberbv.bv_len; char * delObjsConatinerDN = gVmdirServerGlobals.delObjsContainerDN.lberbv.bv_val; deletedObjDN->lberbv.bv_val = NULL; deletedObjDN->lberbv.bv_len = 0; if (!delObjsConatinerDN) { dwError = VMDIR_ERROR_ENTRY_NOT_FOUND; BAIL_ON_VMDIR_ERROR( dwError ); } dwError = VmDirGetParentDN( dn, &parentDN ); BAIL_ON_VMDIR_ERROR( dwError ); // Format of the DN of a deleted object is: // <original RDN>#objectGUID:<object GUID string>,<DN of the Deleted objects container> deletedObjDNLen = (parentDN.lberbv.bv_len ? dn->lberbv.bv_len - parentDN.lberbv.bv_len - 1 /* Count out RDN separator */ : dn->lberbv.bv_len) + 1 /* for # */ + ATTR_OBJECT_GUID_LEN + 1 /* for : */ + VmDirStringLenA( objectGuidStr ) + 1 /* for , */ + delObjsConatinerDNLength; dwError = VmDirAllocateMemory( deletedObjDNLen + 1, (PVOID *)&deletedObjDN->lberbv.bv_val ); BAIL_ON_VMDIR_ERROR( dwError ); deletedObjDN->lberbv.bv_len = parentDN.lberbv.bv_len ? dn->lberbv.bv_len - parentDN.lberbv.bv_len - 1 /* Count out RDN separator */ : dn->lberbv.bv_len; // TODO: how do we know the actual buffer size ? dwError = VmDirCopyMemory( deletedObjDN->lberbv.bv_val, deletedObjDN->lberbv.bv_len, dn->lberbv.bv_val, deletedObjDN->lberbv.bv_len ); BAIL_ON_VMDIR_ERROR( dwError ); deletedObjDN->lberbv.bv_val[deletedObjDN->lberbv.bv_len] = '#'; deletedObjDN->lberbv.bv_len++; // TODO: how do we know the actual buffer size ? dwError = VmDirCopyMemory( deletedObjDN->lberbv.bv_val + deletedObjDN->lberbv.bv_len, ATTR_OBJECT_GUID_LEN, ATTR_OBJECT_GUID, ATTR_OBJECT_GUID_LEN ); BAIL_ON_VMDIR_ERROR( dwError ); deletedObjDN->lberbv.bv_len += ATTR_OBJECT_GUID_LEN; deletedObjDN->lberbv.bv_val[deletedObjDN->lberbv.bv_len] = ':'; deletedObjDN->lberbv.bv_len++; // TODO: how do we know the actual buffer size ? dwError = VmDirCopyMemory( deletedObjDN->lberbv.bv_val + deletedObjDN->lberbv.bv_len, VmDirStringLenA( objectGuidStr ), (PVOID)objectGuidStr, VmDirStringLenA( objectGuidStr ) ); BAIL_ON_VMDIR_ERROR( dwError ); deletedObjDN->lberbv.bv_len += VmDirStringLenA( objectGuidStr ); // TODO: how do we know the actual buffer size ? VmDirStringPrintFA( deletedObjDN->lberbv.bv_val + deletedObjDN->lberbv.bv_len, delObjsConatinerDNLength + 2, ",%s", delObjsConatinerDN ); deletedObjDN->lberbv.bv_len += delObjsConatinerDNLength + 1 /* for , */; cleanup: VmDirFreeBervalContent( &parentDN ); return dwError; error: if (deletedObjDN->lberbv.bv_val != NULL) { VmDirFreeMemory( deletedObjDN->lberbv.bv_val ); deletedObjDN->lberbv.bv_val = NULL; } deletedObjDN->lberbv.bv_len = 0; goto cleanup; }
int WriteSyncDoneControl( VDIR_OPERATION * op, BerElement * ber ) { int retVal = LDAP_OPERATIONS_ERROR; PLW_HASHTABLE_NODE pNode = NULL; LW_HASHTABLE_ITER iter = LW_HASHTABLE_ITER_INIT; UptoDateVectorEntry * pUtdVectorEntry = NULL; VDIR_BERVALUE bvCtrlVal = VDIR_BERVALUE_INIT; VDIR_BERVALUE syncDoneCtrlType = { {VmDirStringLenA( LDAP_CONTROL_SYNC_DONE ), LDAP_CONTROL_SYNC_DONE}, 0, 0, NULL }; VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "WriteSyncDoneControl: Begin." ); if ( op->syncDoneCtrl != NULL) { if (ber_printf( ber, "t{{O", LDAP_TAG_CONTROLS, &(syncDoneCtrlType.lberbv) ) == -1 ) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteSyncDoneControl: ber_printf (to print Sync Done Control ...) failed" ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR( retVal ); } { // Construct string format of utdVector int numEntries = LwRtlHashTableGetCount( op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector ); char * writer = NULL; size_t tmpLen = 0; size_t bufferSize = (numEntries + 1 /* for lastLocalUsn */) * (VMDIR_GUID_STR_LEN + 1 + VMDIR_MAX_USN_STR_LEN + 1); // Sync Done control value looks like: <lastLocalUsnChanged>,<serverId1>:<server 1 last originating USN>, // <serverId2>,<server 2 originating USN>,... if (VmDirAllocateMemory( bufferSize, (PVOID *)&bvCtrlVal.lberbv.bv_val) != 0) { retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR( retVal ); } writer = bvCtrlVal.lberbv.bv_val; bvCtrlVal.lberbv.bv_len = 0; VmDirStringPrintFA( writer, bufferSize, "%ld,", op->syncDoneCtrl->value.syncDoneCtrlVal.intLastLocalUsnProcessed ); tmpLen = VmDirStringLenA( writer ); writer += tmpLen; bufferSize -= tmpLen; bvCtrlVal.lberbv.bv_len += tmpLen; while ((pNode = LwRtlHashTableIterate(op->syncDoneCtrl->value.syncDoneCtrlVal.htUtdVector, &iter))) { pUtdVectorEntry = LW_STRUCT_FROM_FIELD(pNode, UptoDateVectorEntry, Node); VmDirStringPrintFA( writer, bufferSize, "%s:%ld,", pUtdVectorEntry->invocationId.lberbv.bv_val, pUtdVectorEntry->currMaxOrigUsnProcessed ); tmpLen = VmDirStringLenA( writer ); writer += tmpLen; bufferSize -= tmpLen; bvCtrlVal.lberbv.bv_len += tmpLen; } } if (ber_printf( ber, "O}}", &bvCtrlVal.lberbv) == -1 ) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "WriteSyncDoneControl: ber_printf (to print Sync Done Control ...) failed" ); retVal = LDAP_OPERATIONS_ERROR; BAIL_ON_VMDIR_ERROR( retVal ); } VMDIR_LOG_DEBUG( LDAP_DEBUG_REPL, "WriteSyncDoneControl: Sync Done Control Value: %s", bvCtrlVal.lberbv.bv_val ); } retVal = LDAP_SUCCESS; cleanup: VMDIR_SAFE_FREE_MEMORY( bvCtrlVal.lberbv.bv_val ); VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "WriteSyncDoneControl: Begin." ); return retVal; error: goto cleanup; }
DWORD BackupDB(PCSTR srcDir, PCSTR tgtDir) { #define VMDIR_MDB_DATA_FILE_NAME "data.mdb" #define VMDIR_LOCK_DATA_FILE_NAME "lock.mdb" DWORD dwError = 0; char dbLocalFilename[VMDIR_MAX_FILE_NAME_LEN] = {0}; PSTR pszLocalErrorMsg = NULL; char cpFileCmdLine[4 /* max of "cp" and "copy" */ + 1 + VMDIR_MAX_FILE_NAME_LEN + 1 + VMDIR_MAX_FILE_NAME_LEN] = {0}; #ifndef _WIN32 const char * cpFileCmd = "cp"; const char fileSeperator = '/'; #else const char * cpFileCmd = "copy"; const char fileSeperator = '\\'; #endif printf( "BackupDB: Setting vmdir state to VMDIRD_READ_ONLY \n" ); dwError = VmDirSetState( NULL, VMDIRD_STATE_READ_ONLY ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg), "BackupDB: VmDirSetState() call failed with error: %d", dwError ); // Backup data.mdb dwError = VmDirStringPrintFA( dbLocalFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", srcDir, fileSeperator, VMDIR_MDB_DATA_FILE_NAME ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg), "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError ); dwError = VmDirStringPrintFA( cpFileCmdLine, sizeof(cpFileCmdLine), "%s %s %s", cpFileCmd, dbLocalFilename, tgtDir ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg), "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError ); printf( "BackupDB: Backing up: %s \n", dbLocalFilename ); dwError = VmDirRun(cpFileCmdLine); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg), "BackupDB: VmDirRun() call failed, cmd: %s", cpFileCmdLine ); // Backup lock.mdb dwError = VmDirStringPrintFA( dbLocalFilename, VMDIR_MAX_FILE_NAME_LEN, "%s%c%s", srcDir, fileSeperator, VMDIR_LOCK_DATA_FILE_NAME ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg), "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError ); dwError = VmDirStringPrintFA( cpFileCmdLine, sizeof(cpFileCmdLine), "%s %s %s", cpFileCmd, dbLocalFilename, tgtDir ); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg), "BackupDB: VmDirStringPrintFA() call failed with error: %d", dwError ); printf( "BackupDB: Backing up: %s \n", dbLocalFilename ); dwError = VmDirRun(cpFileCmdLine); BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, (pszLocalErrorMsg), "BackupDB: VmDirRun() call failed, cmd: %s", cpFileCmdLine ); cleanup: printf( "BackupDB: Setting vmdir state to VMDIRD_NORMAL \n" ); if ((dwError = VmDirSetState( NULL, VMDIRD_STATE_NORMAL )) != 0) { fprintf(stderr, "BackupDB: Setting vmdir state to VMDIRD_NORMAL failed, error (%d) \n", dwError); } VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return dwError; error: fprintf( stderr, "%s\n", pszLocalErrorMsg ? pszLocalErrorMsg : "Hmmm ... no local error message." ); goto cleanup; }
/* * TODO, Should chg db dir to /var/lib/vmware/vmdir/db. * Then we can just swap partner to db directly. */ static DWORD _VmDirSwapDBInternal( PCSTR pszdbHomeDir, // e.g. /var/lib/vmware/vmdir PCSTR pszSwapDir // e.g. /var/lib/vmware/lightwave_tmp ) { DWORD dwError = 0; int errorCode = 0; CHAR cmdBuf[VMDIR_MAX_FILE_NAME_LEN] = {0}; CHAR partnerDBdBuf[VMDIR_MAX_FILE_NAME_LEN] = {0}; CHAR swapDirBuf[VMDIR_MAX_FILE_NAME_LEN] = {0}; // /var/lib/vmware/lightwave_tmp/partner dwError = VmDirStringPrintFA(swapDirBuf, VMDIR_MAX_FILE_NAME_LEN, "%s/%s", pszSwapDir, LOCAL_PARTNER_DIR); BAIL_ON_VMDIR_ERROR(dwError); // /var/lib/vmware/vmdir/partner dwError = VmDirStringPrintFA(partnerDBdBuf, VMDIR_MAX_FILE_NAME_LEN, "%s/%s", pszdbHomeDir, LOCAL_PARTNER_DIR); BAIL_ON_VMDIR_ERROR(dwError); // rm -rf /var/lib/vmware/lightwave_tmp/partner dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN, "rm -rf %s", swapDirBuf); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRun(cmdBuf); BAIL_ON_VMDIR_ERROR(dwError); // mv /var/lib/vmware/vmdir/partner /var/lib/vmware/lightwave_tmp/partner dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN, "mv %s %s", partnerDBdBuf, swapDirBuf); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRun(cmdBuf); BAIL_ON_VMDIR_ERROR(dwError); // rm -rf /var/lib/vmware/vmdir/* dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN, "rm -rf %s/*", pszdbHomeDir); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRun(cmdBuf); BAIL_ON_VMDIR_ERROR(dwError); // mv /var/lib/vmware/lightwave_tmp/partner/* /var/lib/vmware/vmdir/ dwError = VmDirStringPrintFA(cmdBuf, VMDIR_MAX_FILE_NAME_LEN, "mv %s/* %s/", swapDirBuf, pszdbHomeDir); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirRun(cmdBuf); BAIL_ON_VMDIR_ERROR(dwError); VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "%s, DB Swapped", __FUNCTION__); cleanup: return dwError; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "Error %d, errno %d", dwError, errorCode); goto cleanup; }
static int ProcessCandidateList( VDIR_OPERATION * pOperation ) { int retVal = LDAP_SUCCESS; int i = 0; VDIR_CANDIDATES * cl = pOperation->request.searchReq.filter->candidates; VDIR_ENTRY srEntry = {0}; VDIR_ENTRY * pSrEntry = NULL; int numSentEntries = 0; BOOLEAN bInternalSearch = FALSE; BOOLEAN bPageResultsCtrl = FALSE; DWORD dwPageSize = 0; ENTRYID lastEID = 0; /* * If the page size is greater than or equal to the sizeLimit value, * the server should ignore the control as the request can be satisfied in a single page. */ if (pOperation->showPagedResultsCtrl && (pOperation->request.searchReq.sizeLimit == 0 || pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize < (DWORD)pOperation->request.searchReq.sizeLimit)) { VmDirLog( LDAP_DEBUG_TRACE, "showPagedResultsCtrl applies to this query." ); bPageResultsCtrl = TRUE; dwPageSize = pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize; lastEID = atoi(pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie); pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie[0] = '\0'; } if (cl && cl->size > 0) { if (pOperation->opType == VDIR_OPERATION_TYPE_INTERNAL) { //TODO, we should have a hard limit on the cl->size we handle bInternalSearch = TRUE; VmDirFreeEntryArrayContent(&pOperation->internalSearchEntryArray); retVal = VmDirAllocateMemory( sizeof(VDIR_ENTRY) * cl->size, (PVOID*)&pOperation->internalSearchEntryArray.pEntry); BAIL_ON_VMDIR_ERROR(retVal); } for (i = 0, numSentEntries = 0; (i < cl->size) && VmDirdState() != VMDIRD_STATE_SHUTDOWN && (pOperation->request.searchReq.sizeLimit == 0 /* unlimited */ || numSentEntries < pOperation->request.searchReq.sizeLimit); i++) { //skip entries we sent before if (bPageResultsCtrl && lastEID > 0) { if (cl->eIds[i] == lastEID) { lastEID = 0; } continue; } VMDIR_LOG_DEBUG( LDAP_DEBUG_FILTER, "ProcessCandidateList EID(%u)", cl->eIds[i]); pSrEntry = bInternalSearch ? (pOperation->internalSearchEntryArray.pEntry + pOperation->internalSearchEntryArray.iSize) : &srEntry; retVal = pOperation->pBEIF->pfnBEIdToEntry( pOperation->pBECtx, pOperation->pSchemaCtx, cl->eIds[i], pSrEntry, VDIR_BACKEND_ENTRY_LOCK_READ); if (retVal == 0) { if (CheckIfEntryPassesFilter( pOperation, pSrEntry, pOperation->request.searchReq.filter) == FILTER_RES_TRUE) { retVal = VmDirBuildComputedAttribute( pOperation, pSrEntry ); BAIL_ON_VMDIR_ERROR( retVal ); if (bInternalSearch) { pOperation->internalSearchEntryArray.iSize++; pSrEntry = NULL; // EntryArray takes over *pSrEntry content } else { retVal = VmDirSendSearchEntry( pOperation, pSrEntry ); if (retVal == VMDIR_ERROR_INSUFFICIENT_ACCESS) { VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "Access deny on search entry result [%s,%d] (bindedDN-%s) (targetDn-%s)\n", __FILE__, __LINE__, pOperation->conn->AccessInfo.pszBindedDn, pSrEntry->dn.lberbv.bv_val); // make sure search continues retVal = 0; } BAIL_ON_VMDIR_ERROR( retVal ); if (pSrEntry->bSearchEntrySent) { numSentEntries++; } } } //We have sent one page size of entries, so we can break here if (bPageResultsCtrl && numSentEntries == dwPageSize){ retVal = VmDirStringPrintFA( pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, VMDIR_MAX_I64_ASCII_STR_LEN, "%u", pSrEntry->eId); BAIL_ON_VMDIR_ERROR( retVal ); break; } VmDirFreeEntryContent( pSrEntry ); pSrEntry = NULL; // Reset to NULL so that DeleteEntry is no-op. } else { // Ignore BdbEIdToEntry errors. VMDIR_LOG_WARNING( VMDIR_LOG_MASK_ALL, "ProcessCandiateList BEIdToEntry EID(%u), error (%u)", cl->eIds[i], retVal); retVal = 0; } } VMDIR_LOG_VERBOSE( LDAP_DEBUG_FILTER, "(%d) candiates processed and (%d) entries sent", cl->size, numSentEntries); } if ( pOperation->request.searchReq.sizeLimit && numSentEntries < pOperation->request.searchReq.sizeLimit && pOperation->pBECtx->iPartialCandidates) { retVal = LDAP_UNWILLING_TO_PERFORM; VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "ProcessCandiateList may return none or paritial requested entries with sizelimit %d", pOperation->request.searchReq.sizeLimit); } cleanup: pOperation->dwSentEntries = numSentEntries; VmDirFreeEntryContent( pSrEntry ); return retVal; error: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "ProcessCandiateList failed. (%u)", retVal); goto cleanup; }