internal static void PopulateGlsProperty(TenantRelocationRequest presentationObject, Task.TaskVerboseLoggingDelegate writeVerbose) { if (ADSessionSettings.IsGlsDisabled) { presentationObject.GLSResolvedForest = GetTenantRelocationRequest.GlsDisabled; return; } Guid externalDirectoryOrganizationId = new Guid(presentationObject.ExternalDirectoryOrganizationId); string text; string glsresolvedForest; string text2; Exception ex; if (GetTenantRelocationRequest.TryGlsLookupByExternalDirectoryOrganizationId(externalDirectoryOrganizationId, out text, out glsresolvedForest, out text2, out ex)) { presentationObject.GLSResolvedForest = glsresolvedForest; } else { presentationObject.GLSResolvedForest = GetTenantRelocationRequest.GlsLookupFailed; } if (ex != null) { presentationObject.GLSResolvedForest = "<" + ex.GetType().Name + ">"; if (writeVerbose != null) { writeVerbose(Strings.ErrorInGlsLookup(ex.ToString())); } } }
protected override void WriteResult(IConfigurable dataObject) { TaskLogger.LogEnter(new object[] { dataObject.Identity }); TenantRelocationRequest tenantRelocationRequest = (TenantRelocationRequest)dataObject; if (!this.SourceStateOnly) { if (tenantRelocationRequest.TargetForest != null) { this.targetForestRIDMaster = ForestTenantRelocationsCache.GetRidMasterName(new PartitionId(tenantRelocationRequest.TargetForest)); } Exception ex; TenantRelocationRequest.PopulatePresentationObject(tenantRelocationRequest, this.targetForestRIDMaster, out ex); if (ex != null) { if (ex is CannotFindTargetTenantException) { base.WriteWarning(ex.Message); } else { base.WriteError(ex, ErrorCategory.InvalidOperation, tenantRelocationRequest.Identity); } } GetTenantRelocationRequest.PopulateGlsProperty(tenantRelocationRequest, new Task.TaskVerboseLoggingDelegate(base.WriteVerbose)); GetTenantRelocationRequest.PopulateRidMasterProperties(tenantRelocationRequest, this.sourceForestRIDMaster, this.targetForestRIDMaster, new Task.TaskVerboseLoggingDelegate(base.WriteVerbose)); if (tenantRelocationRequest.OriginatingServer != this.sourceForestRIDMaster) { this.warning = Strings.WarningShouldReadFromRidMaster(tenantRelocationRequest.OriginatingServer, this.sourceForestRIDMaster); } } base.WriteResult(tenantRelocationRequest); TaskLogger.LogExit(); }
protected override void InternalValidate() { TaskLogger.LogEnter(); base.InternalValidate(); if (string.IsNullOrEmpty(this.DataObject.TargetForest)) { base.WriteError(new InvalidOperationException(Strings.ErrorTenantNotBeingRelocated(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (this.DataObject.RelocationStatus == TenantRelocationStatus.Lockdown) { base.WriteError(new InvalidOperationException(Strings.ErrorTenantInLockdown(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } this.isRelocationComplete = (this.DataObject.RelocationStatusDetailsSource == RelocationStatusDetailsSource.RetiredUpdatedTargetForest); if (this.isRelocationComplete && !this.Complete) { base.WriteError(new InvalidOperationException(Strings.ErrorCompleteFlagRequired(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (!this.isRelocationComplete && this.Complete) { base.WriteError(new InvalidOperationException(Strings.ErrorCompleteFlagNotAllowed(this.Identity.ToString(), this.DataObject.RelocationStatusDetailsSource.ToString(), RelocationStatusDetailsSource.RetiredUpdatedTargetForest.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (this.Complete) { if (!this.DataObject.IsRetiredSourceHoldTimedOut()) { base.WriteError(new InvalidOperationException(Strings.ErrorSourceHoldNotTimedOut(this.Identity.ToString(), TenantRelocationRequest.WaitTimeBeforeRemoveSourceReplicaDays.ToString(), this.DataObject.RetiredStartTime.Value.ToUniversalTime().ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (this.DataObject.RelocationStateRequested != RelocationStateRequested.Cleanup) { base.WriteError(new InvalidOperationException(Strings.ErrorCleanupRequestedAtWrongRequestedState(this.Identity.ToString(), this.DataObject.RelocationStateRequested.ToString(), RelocationStateRequested.Cleanup.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } } if (this.DeprovisionedTarget && !this.Complete) { base.WriteError(new InvalidOperationException(Strings.ErrorDeprovisionedTargetPassedWithoutComplete(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (this.DataObject.RelocationStatusDetailsSource >= RelocationStatusDetailsSource.InitializationFinished) { Exception ex; TenantRelocationRequest.PopulatePresentationObject(this.DataObject, null, out ex); if (ex != null) { if (!(ex is CannotFindTargetTenantException)) { base.WriteError(ex, ErrorCategory.InvalidOperation, this.DataObject.Identity); } else if (!this.DeprovisionedTarget) { base.WriteError(new InvalidOperationException(Strings.ErrorDeprovisionedTargetNotPassed(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } } GetTenantRelocationRequest.PopulateGlsProperty(this.DataObject, new Task.TaskVerboseLoggingDelegate(base.WriteVerbose)); if (!ADSessionSettings.IsGlsDisabled) { if (!string.IsNullOrEmpty(this.DataObject.GLSResolvedForest) && this.DataObject.GLSResolvedForest != GetTenantRelocationRequest.GlsLookupFailed && this.DataObject.GLSResolvedForest != GetTenantRelocationRequest.GlsDisabled && ((this.Complete && !string.IsNullOrEmpty(this.DataObject.TargetForest) && !this.DataObject.TargetForest.Equals(this.DataObject.GLSResolvedForest, StringComparison.OrdinalIgnoreCase)) || (!this.Complete && !string.IsNullOrEmpty(this.DataObject.SourceForest) && !this.DataObject.SourceForest.Equals(this.DataObject.GLSResolvedForest, StringComparison.OrdinalIgnoreCase)))) { base.WriteError(new InvalidOperationException(Strings.ErrorInvalidTenantGlsRecord(this.Identity.ToString(), this.DataObject.GLSResolvedForest, this.DataObject.SourceForest, this.DataObject.TargetForest)), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (this.DataObject.GLSResolvedForest == GetTenantRelocationRequest.GlsLookupFailed && !this.DeprovisionedTarget) { base.WriteError(new InvalidOperationException(Strings.ErrorNoTenantGlsRecord(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } } } if (!TenantRelocationStateCache.IgnoreRelocationTimeConstraints() && this.DataObject.IsRelocationInProgress()) { base.WriteError(new RelocationInProgressException(this.DataObject.OrganizationId.ToString(), this.DataObject.HasPermanentError().ToString(), this.DataObject.Suspended.ToString(), this.DataObject.AutoCompletionEnabled.ToString(), this.DataObject.RelocationStatusDetailsSource.ToString(), this.DataObject.AutoCompletionEnabled ? RelocationStatusDetailsSource.RetiredUpdatedTargetForest.ToString() : this.DataObject.RelocationStateRequested.ToString()), ErrorCategory.InvalidOperation, this.DataObject.Identity); } TaskLogger.LogExit(); }
protected override void InternalProcessRecord() { TaskLogger.LogEnter(); this.DataObject.AutoCompletionEnabled = this.AutoCompletionEnabled; this.DataObject.LargeTenantModeEnabled = this.LargeTenantModeEnabled; this.DataObject.SafeLockdownSchedule = (this.SafeLockdownSchedule ?? Schedule.Always); if (base.Fields.IsModified(TenantRelocationRequestSchema.RelocationStateRequested)) { this.DataObject.RelocationStateRequested = (RelocationStateRequested)this.RelocationStateRequested; } this.DataObject.TargetForest = this.targetAccountPartitionFqdn; this.sourceForestRIDMaster = ForestTenantRelocationsCache.GetRidMasterName(this.sourceAccountPartitionId); DirectorySessionFactory @default = DirectorySessionFactory.Default; Fqdn domainController = base.DomainController; ITenantConfigurationSession tenantConfigurationSession = @default.CreateTenantConfigurationSession((domainController != null) ? domainController : this.sourceForestRIDMaster, false, ConsistencyMode.PartiallyConsistent, null, ADSessionSettings.FromAllTenantsPartitionId(this.sourceAccountPartitionId), 334, "InternalProcessRecord", "f:\\15.00.1497\\sources\\dev\\Management\\src\\Management\\Relocation\\NewTenantRelocationRequest.cs"); PartitionId partitionId = new PartitionId(this.targetAccountPartitionFqdn); this.targetForestRIDMaster = ForestTenantRelocationsCache.GetRidMasterName(partitionId); ITenantConfigurationSession tenantConfigurationSession2 = DirectorySessionFactory.Default.CreateTenantConfigurationSession(this.targetForestRIDMaster, false, ConsistencyMode.PartiallyConsistent, null, ADSessionSettings.FromAllTenantsPartitionId(partitionId), 343, "InternalProcessRecord", "f:\\15.00.1497\\sources\\dev\\Management\\src\\Management\\Relocation\\NewTenantRelocationRequest.cs"); tenantConfigurationSession2.SessionSettings.TenantConsistencyMode = TenantConsistencyMode.IncludeRetiredTenants; MsoTenantCookieContainer msoTenantCookieContainer = tenantConfigurationSession2.GetMsoTenantCookieContainer(this.externalDirectoryOrganizationId); if (msoTenantCookieContainer != null && !NewTenantRelocationRequest.IntraForestRelocationEnabled()) { InvalidOperationException exception = new InvalidOperationException(Strings.ErrorTargetPartitionHasTenantWithSameId(this.DataObject.DistinguishedName, this.targetAccountPartitionFqdn, msoTenantCookieContainer.DistinguishedName, this.DataObject.ExternalDirectoryOrganizationId)); base.WriteError(exception, ErrorCategory.InvalidOperation, this.DataObject.Identity); } string text = this.GetInitialDomainName(tenantConfigurationSession, this.DataObject.OrganizationId); ExchangeConfigurationUnit exchangeConfigurationUnitByName = tenantConfigurationSession2.GetExchangeConfigurationUnitByName(text); if (exchangeConfigurationUnitByName != null) { if (text.Length > 50) { text = text.Substring(0, 50); } text = string.Format("{0}-RELO-{1}", text, Guid.NewGuid().ToString()); if (text.Length > 64) { text = text.Substring(0, 64); } } Exception ex; OrganizationId targetSharedOrgId = SharedConfiguration.FindMostRecentSharedConfigurationInPartition(this.DataObject.OrganizationId, partitionId, out ex); if (ex != null) { base.WriteError(ex, ErrorCategory.InvalidOperation, this.DataObject.Identity); } ADOrganizationalUnit adorganizationalUnit = null; bool useConfigNC = tenantConfigurationSession.UseConfigNC; try { tenantConfigurationSession.UseConfigNC = false; adorganizationalUnit = tenantConfigurationSession.Read <ADOrganizationalUnit>(this.DataObject.OrganizationId.OrganizationalUnit); } finally { tenantConfigurationSession.UseConfigNC = useConfigNC; } this.DataObject.RelocationStatusDetailsRaw = RelocationStatusDetails.InitializationStarted; base.InternalProcessRecord(); ADObjectId enclosureContainerId = this.CreateEnclosureConfigContainer(text, tenantConfigurationSession2); ExchangeConfigurationUnit exchangeConfigurationUnit = this.CreateOrgConfigurationContainer(enclosureContainerId, targetSharedOrgId, this.DataObject.ExternalDirectoryOrganizationId, this.DataObject.ProgramId, this.DataObject.OfferId, this.DataObject.IsDehydrated, this.DataObject.IsStaticConfigurationShared, this.sourceForestFqdn, this.DataObject.Guid, this.DataObject.ExchangeObjectId, tenantConfigurationSession2); ADObjectId organizationalUnitLink = this.CreateOrganizationUnitContainer(text, adorganizationalUnit.Guid, adorganizationalUnit.ExchangeObjectId, tenantConfigurationSession2); exchangeConfigurationUnit.OrganizationalUnitLink = organizationalUnitLink; exchangeConfigurationUnit.RelocationStatusDetailsRaw = RelocationStatusDetails.InitializationFinished; tenantConfigurationSession2.Save(exchangeConfigurationUnit); this.DataObject.RelocationStatusDetailsRaw = RelocationStatusDetails.InitializationFinished; base.DataSession.Save(this.DataObject); TenantRelocationRequest tenantRelocationRequest = (TenantRelocationRequest)base.DataSession.Read <TenantRelocationRequest>(this.DataObject.Identity); TenantRelocationRequest targetForestObject = tenantConfigurationSession2.Read <TenantRelocationRequest>(exchangeConfigurationUnit.Id); TenantRelocationRequest.PopulatePresentationObject(tenantRelocationRequest, targetForestObject); GetTenantRelocationRequest.PopulateGlsProperty(tenantRelocationRequest, new Task.TaskVerboseLoggingDelegate(base.WriteVerbose)); GetTenantRelocationRequest.PopulateRidMasterProperties(tenantRelocationRequest, this.sourceForestRIDMaster, this.targetForestRIDMaster, new Task.TaskVerboseLoggingDelegate(base.WriteVerbose)); if (tenantRelocationRequest.OriginatingServer != this.sourceForestRIDMaster) { this.WriteWarning(Strings.WarningShouldWriteToRidMaster(tenantRelocationRequest.OriginatingServer, this.sourceForestRIDMaster)); } base.WriteObject(tenantRelocationRequest); TaskLogger.LogExit(); }
protected override void InternalValidate() { TaskLogger.LogEnter(); base.InternalValidate(); if (!string.IsNullOrEmpty(this.DataObject.TargetForest) || !string.IsNullOrEmpty(this.DataObject.RelocationSourceForestRaw)) { base.WriteError(new InvalidOperationException(Strings.ErrorTenantAlreadyBeingRelocated(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if ((this.DataObject.OrganizationStatus != OrganizationStatus.Active && this.DataObject.OrganizationStatus != OrganizationStatus.Suspended && this.DataObject.OrganizationStatus != OrganizationStatus.LockedOut) || this.DataObject.IsUpdatingServicePlan) { base.WriteError(new InvalidOperationException(Strings.ErrorTenantNotInActiveOrgState(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (this.DataObject.EnableAsSharedConfiguration || this.DataObject.ImmutableConfiguration) { base.WriteError(new InvalidOperationException(Strings.ErrorSCTsCannotBeMigrated(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (this.DataObject.AdminDisplayVersion.ExchangeBuild < ExchangeObjectVersion.Exchange2012.ExchangeBuild) { base.WriteError(new InvalidOperationException(Strings.ErrorOldTenantsCannotBeMigrated(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } this.sourceAccountPartitionId = this.DataObject.OrganizationId.PartitionId; this.sourceForestFqdn = this.sourceAccountPartitionId.ForestFQDN; Organization rootOrgContainer = ADSystemConfigurationSession.GetRootOrgContainer(this.sourceForestFqdn, null, null); if (!rootOrgContainer.TenantRelocationsAllowed) { base.WriteError(new InvalidOperationException(Strings.ErrorTenantRelocationNotAllowed(this.Identity.ToString(), this.sourceForestFqdn)), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (TopologyProvider.LocalForestFqdn.Equals(this.TargetAccountPartition.RawIdentity, StringComparison.OrdinalIgnoreCase)) { this.targetAccountPartitionFqdn = PartitionId.LocalForest.ForestFQDN; } else { AccountPartition accountPartition = (AccountPartition)base.GetDataObject <AccountPartition>(this.TargetAccountPartition, DirectorySessionFactory.Default.CreateTopologyConfigurationSession(ConsistencyMode.PartiallyConsistent, ADSessionSettings.SessionSettingsFactory.Default.FromRootOrgScopeSet(), 207, "InternalValidate", "f:\\15.00.1497\\sources\\dev\\Management\\src\\Management\\Relocation\\NewTenantRelocationRequest.cs"), null, null, null); this.targetAccountPartitionFqdn = accountPartition.PartitionId.ForestFQDN; } if (this.targetAccountPartitionFqdn.IndexOf(PartitionId.LocalForest.ForestFQDN, StringComparison.InvariantCultureIgnoreCase) > 0) { this.targetAccountPartitionFqdn = PartitionId.LocalForest.ForestFQDN; } rootOrgContainer = ADSystemConfigurationSession.GetRootOrgContainer(this.targetAccountPartitionFqdn, null, null); if (!rootOrgContainer.TenantRelocationsAllowed) { base.WriteError(new InvalidOperationException(Strings.ErrorTenantRelocationNotAllowed(this.Identity.ToString(), this.targetAccountPartitionFqdn)), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (!base.Fields.IsModified(TenantRelocationRequestSchema.AutoCompletionEnabled)) { this.AutoCompletionEnabled = false; } if (this.AutoCompletionEnabled && base.Fields.IsModified(TenantRelocationRequestSchema.RelocationStateRequested)) { base.WriteError(new InvalidOperationException(Strings.ErrorRelocationStateRequestedIsNotAllowed(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (!this.AutoCompletionEnabled && !base.Fields.IsModified(TenantRelocationRequestSchema.RelocationStateRequested)) { base.WriteError(new InvalidOperationException(Strings.ErrorRelocationStateRequestedIsMandatory(this.Identity.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } ADUser[] array = OrganizationMailbox.FindByOrganizationId(this.DataObject.OrganizationId, OrganizationCapability.Management); if (array.Length != 1) { base.WriteError(new InvalidOperationException(Strings.ErrorOneManagementOrgMailboxIsRequired(this.Identity.ToString(), array.Length.ToString())), ErrorCategory.InvalidOperation, this.DataObject.Identity); } TenantOrganizationPresentationObject tenantOrganizationPresentationObject = new TenantOrganizationPresentationObject(this.DataObject); DateTime utcNow = DateTime.UtcNow; bool config = TenantRelocationConfigImpl.GetConfig <bool>("IgnoreRelocationConstraintExpiration"); foreach (RelocationConstraint relocationConstraint in tenantOrganizationPresentationObject.RelocationConstraints) { if (config || relocationConstraint.ExpirationDate > utcNow) { base.WriteError(new InvalidOperationException(Strings.ErrorRelocationConstraintsPresent(this.Identity.ToString(), relocationConstraint.Name)), ErrorCategory.InvalidOperation, this.DataObject.Identity); } } this.externalDirectoryOrganizationId = Guid.Parse(this.DataObject.ExternalDirectoryOrganizationId); if (!NewTenantRelocationRequest.GLSRecordCheckDisabled() && GlsMServDirectorySession.GlsLookupMode != GlsLookupMode.MServOnly) { string text; string text2; string text3; Exception ex; bool flag = GetTenantRelocationRequest.TryGlsLookupByExternalDirectoryOrganizationId(this.externalDirectoryOrganizationId, out text, out text2, out text3, out ex); if (ex != null) { base.WriteError(ex, ErrorCategory.InvalidOperation, this.DataObject.Identity); } if (!flag || string.IsNullOrEmpty(text2) || !text2.Equals(this.sourceForestFqdn, StringComparison.InvariantCultureIgnoreCase)) { base.WriteError(new InvalidOperationException(Strings.ErrorUnexpectedAccountForestValueInGls(this.Identity.ToString(), text2, this.sourceForestFqdn)), ErrorCategory.InvalidOperation, this.DataObject.Identity); } } TaskLogger.LogExit(); }