public void ItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, CoreFolder folder, bool onBeforeNotification, OperationResult result, CallbackContext callbackContext) { Util.ThrowOnNullArgument(session, "session"); Util.ThrowOnNullArgument(item, "item"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); EnumValidator.ThrowIfInvalid <OperationResult>(result, "result"); COWContactLinking.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWContactLinking.ItemOperation: processing contact linking for item {0}.", itemId); MailboxSession mailboxSession = (MailboxSession)session; MailboxInfoForLinking mailboxInfo = MailboxInfoForLinking.CreateFromMailboxSession(mailboxSession); ContactLinkingPerformanceTracker performanceTracker = new ContactLinkingPerformanceTracker(mailboxSession); DirectoryPersonSearcher directoryPersonSearcher = new DirectoryPersonSearcher(mailboxSession.MailboxOwner); ContactStoreForContactLinking contactStoreForContactLinking = new ContactStoreForCowContactLinking(mailboxSession, performanceTracker); ContactLinkingLogger logger = new ContactLinkingLogger("COWContactLinking", mailboxInfo); AutomaticLink automaticLink = new AutomaticLink(mailboxInfo, logger, performanceTracker, directoryPersonSearcher, contactStoreForContactLinking); automaticLink.LinkNewOrUpdatedContactBeforeSave(item, new Func <ContactInfoForLinking, IContactStoreForContactLinking, IEnumerable <ContactInfoForLinking> >(this.GetOtherContactsEnumeratorForCOW)); if (!onBeforeNotification) { item.SaveFlags |= PropertyBagSaveFlags.ForceNotificationPublish; try { item.Save(SaveMode.NoConflictResolution); } finally { item.SaveFlags &= ~PropertyBagSaveFlags.ForceNotificationPublish; } } callbackContext.ContactLinkingProcessingState = ContactLinkingProcessingState.Processed; }
public bool SkipItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, bool onBeforeNotification, bool onDumpster, bool success, CallbackContext callbackContext) { Util.ThrowOnNullArgument(session, "session"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); Util.ThrowOnNullArgument(callbackContext, "callbackContext"); if (!WorkingSetPublisher.IsGroupWSPublishingEnabled()) { COWGroupMessageWSPublishing.Tracer.Information((long)this.GetHashCode(), "COWGroupMessageWSPublishing.SkipItemOperation: skipping group message working set publishing as the feature is disabled."); return(true); } switch (callbackContext.COWGroupMessageWSPublishingState) { case COWProcessorState.Unknown: callbackContext.COWGroupMessageWSPublishingState = this.InspectNotification(operation, session, item, onBeforeNotification, onDumpster); COWGroupMessageWSPublishing.Tracer.TraceDebug <StoreObjectId, COWProcessorState>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.SkipItemOperation: inspected item {0} and result is {1}.", itemId, callbackContext.COWGroupMessageWSPublishingState); return(true); case COWProcessorState.DoNotProcess: COWGroupMessageWSPublishing.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.SkipItemOperation: skipping notification for item {0} because it should not be processed.", itemId); return(true); case COWProcessorState.ProcessAfterSave: return(onBeforeNotification); case COWProcessorState.Processed: COWGroupMessageWSPublishing.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.SkipItemOperation: skipping notification for item {0} because it has already been processed.", itemId); return(true); default: return(true); } }
public bool SkipItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, bool onBeforeNotification, bool onDumpster, bool success, CallbackContext callbackContext) { Util.ThrowOnNullArgument(session, "session"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); switch (callbackContext.ContactLinkingProcessingState) { case ContactLinkingProcessingState.DoNotProcess: COWContactLinking.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWContactLinking.SkipItemOperation: skipping notification for item {0} because it should not be processed.", itemId); return(true); case ContactLinkingProcessingState.ProcessBeforeSave: return(!onBeforeNotification || state != COWTriggerActionState.Flush); case ContactLinkingProcessingState.ProcessAfterSave: return(onBeforeNotification); case ContactLinkingProcessingState.Processed: COWContactLinking.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWContactLinking.SkipItemOperation: skipping notification for item {0} because it has already been processed.", itemId); return(true); } callbackContext.ContactLinkingProcessingState = this.InspectNotification(operation, session, item, onBeforeNotification, onDumpster); COWContactLinking.Tracer.TraceDebug <StoreObjectId, ContactLinkingProcessingState>((long)this.GetHashCode(), "COWContactLinking.SkipItemOperation: inspected item {0} and result is {1}.", itemId, callbackContext.ContactLinkingProcessingState); return(callbackContext.ContactLinkingProcessingState != ContactLinkingProcessingState.ProcessBeforeSave || !onBeforeNotification || state != COWTriggerActionState.Flush); }
public bool SkipItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, bool onBeforeNotification, bool onDumpster, bool success, CallbackContext callbackContext) { Util.ThrowOnNullArgument(settings, "settings"); Util.ThrowOnNullArgument(session, "session"); Util.ThrowOnNullArgument(dumpster, "dumpster"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); if (onDumpster) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)session.GetHashCode(), "Skipping calendar COW item operation for user {0}, since the operation is on dumpster", session.UserLegacyDN); return(true); } if (!CalendarLoggingHelper.ShouldLog(operation)) { ExTraceGlobals.CalendarLoggingTracer.Information <string, COWTriggerAction>((long)session.GetHashCode(), "Skipping calendar COW item operation for user {0}, since the trigger action {1} is not interesting", session.UserLegacyDN, operation); return(true); } if (!onBeforeNotification && operation != COWTriggerAction.Update) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)session.GetHashCode(), "Skipping calendar COW item operation for user {0}, since we are only interested in on-before notifications and update trigger actions", session.UserLegacyDN); return(true); } if (COWSettings.IsImapPoisonMessage(onBeforeNotification, operation, session, item)) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)session.GetHashCode(), "Skipping calendar COW item operation for user {0}, since the items is marked as IMAP poison message", session.UserLegacyDN); return(true); } if (!settings.IsCalendarLoggingEnabled()) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)session.GetHashCode(), "Skipping calendar COW item operation for user {0}, since calendar logging is disabled for this user", session.UserLegacyDN); return(true); } return(false); }
public bool SkipItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, bool onBeforeNotification, bool onDumpster, bool success, CallbackContext callbackContext) { Util.ThrowOnNullArgument(settings, "settings"); Util.ThrowOnNullArgument(session, "session"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); if (onDumpster) { return(true); } if (COWSettings.IsImapPoisonMessage(onBeforeNotification, operation, session, item)) { return(true); } switch (operation) { case COWTriggerAction.Create: case COWTriggerAction.ItemBind: case COWTriggerAction.Submit: break; case COWTriggerAction.Update: return(!settings.LegalHoldEnabled()); default: if (operation != COWTriggerAction.FolderBind) { return(true); } break; } return(true); }
internal static bool LegalHoldEnabled(MailboxSession mailboxSession) { if (mailboxSession.COWSettings != null) { return(mailboxSession.COWSettings.HoldEnabled()); } return(COWSettings.HoldEnabled(mailboxSession)); }
public CowClientOperationSensitivity SkipGroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId sourceFolderId, StoreObjectId destinationFolderId, ICollection <StoreObjectId> itemIds, bool onBeforeNotification, bool onDumpster, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); MailboxSession mailboxSession = sourceSession as MailboxSession; if (mailboxSession == null) { return(CowClientOperationSensitivity.Skip); } if (onBeforeNotification && (COWTriggerAction.Copy == operation || COWTriggerAction.HardDelete == operation || COWTriggerAction.Move == operation || COWTriggerAction.MoveToDeletedItems == operation || COWTriggerAction.SoftDelete == operation)) { StoreObjectId auditsFolderId = dumpster.AuditsFolderId; StoreObjectId adminAuditLogsFolderId = dumpster.AdminAuditLogsFolderId; if (settings.CurrentFolderId != null && (COWTriggerAction.HardDelete != operation || LogonType.SystemService != sourceSession.LogonType || !settings.IsMrmAction())) { this.CheckAccessOnAuditFolders(mailboxSession, settings.CurrentFolderId, dumpster, false); } if (itemIds != null) { foreach (StoreObjectId storeObjectId in itemIds) { if (storeObjectId != null) { if (storeObjectId.IsMessageId) { if (settings.CurrentFolderId == null && (COWTriggerAction.HardDelete != operation || LogonType.SystemService != sourceSession.LogonType || !settings.IsMrmAction())) { StoreObjectId parentIdFromMessageId = IdConverter.GetParentIdFromMessageId(storeObjectId); if (parentIdFromMessageId.Equals(auditsFolderId)) { throw new AccessDeniedException(ServerStrings.ExAuditsUpdateDenied); } if (parentIdFromMessageId.Equals(adminAuditLogsFolderId)) { throw new AccessDeniedException(ServerStrings.ExAdminAuditLogsUpdateDenied); } if (dumpster.IsAuditFolder(parentIdFromMessageId)) { throw new AccessDeniedException((auditsFolderId != null) ? ServerStrings.ExAuditsUpdateDenied : ServerStrings.ExAdminAuditLogsUpdateDenied); } } } else if (storeObjectId.IsFolderId) { this.CheckAccessOnAuditFolders(mailboxSession, storeObjectId, dumpster, true); } } } } } return(CowClientOperationSensitivity.Skip); }
public void ItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, CoreFolder folder, bool onBeforeNotification, OperationResult result, CallbackContext callbackContext) { Util.ThrowOnNullArgument(dumpster, "dumpster"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <OperationResult>(result, "result"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); MailboxSession sessionWithBestAccess = callbackContext.SessionWithBestAccess; if (onBeforeNotification) { if (CalendarLoggingHelper.ShouldLog(item, operation)) { StoreObjectId storeObjectId = ((ICoreObject)item).StoreObjectId; CalendarLoggingHelper.AddMetadata(item, operation, null); if (operation == COWTriggerAction.Update && state == COWTriggerActionState.Save && CalendarLoggingHelper.ShouldBeCopiedOnWrite(storeObjectId)) { if (settings.HoldEnabled() && item.IsLegallyDirty) { return; } if (!settings.IsCurrentFolderItemEnabled(sessionWithBestAccess, item) && !COWCalendarLogging.IsParkedMessagesFolder(settings, sessionWithBestAccess)) { return; } if (dumpster.IsDumpsterOverCalendarLoggingQuota(sessionWithBestAccess, settings)) { ExTraceGlobals.CalendarLoggingTracer.Information <string, string>((long)session.GetHashCode(), "User {0} has exceeded the calendar logging quota of {1}", session.UserLegacyDN, settings.CalendarLoggingQuota.Value.ToString("A")); StorageGlobals.EventLogger.LogEvent(StorageEventLogConstants.Tuple_COWCalendarLoggingStopped, session.UserLegacyDN, new object[] { session.UserLegacyDN }); } else if (dumpster.IsDumpsterOverWarningQuota(settings)) { ExTraceGlobals.CalendarLoggingTracer.Information <string, string>((long)session.GetHashCode(), "Disabling calendar logging for user {0}, since it has exceeded the dumpster warning quota of {1}", session.UserLegacyDN, settings.DumpsterWarningQuota.Value.ToString("A")); dumpster.DisableCalendarLogging(); } else { StoreObjectId calendarLogGeneratedId = this.PerformCopyOnWrite(sessionWithBestAccess, dumpster, storeObjectId); dumpster.Results.CalendarLogGeneratedId = calendarLogGeneratedId; } } COWSettings.AddMetadata(settings, item, operation); return; } } else if (operation == COWTriggerAction.Update && state == COWTriggerActionState.Save && result == OperationResult.Failed) { dumpster.RollbackItemVersion(sessionWithBestAccess, item, dumpster.Results.CalendarLogGeneratedId); dumpster.Results.CalendarLogGeneratedId = null; } }
public void ItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, CoreFolder folder, bool onBeforeNotification, OperationResult result, CallbackContext callbackContext) { Util.ThrowOnNullArgument(session, "session"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); EnumValidator.ThrowIfInvalid <OperationResult>(result, "result"); Util.ThrowOnNullArgument(item, "item"); Util.ThrowOnNullArgument(callbackContext, "callbackContext"); if (callbackContext.COWGroupMessageWSPublishingState != COWProcessorState.ProcessAfterSave) { COWGroupMessageWSPublishing.Tracer.TraceError <COWProcessorState>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.ItemOperation: Skipping working set publishing because the state doesn't indicate processing is needed: {0}", callbackContext.COWGroupMessageWSPublishingState); return; } if (onBeforeNotification) { COWGroupMessageWSPublishing.Tracer.TraceError((long)this.GetHashCode(), "COWGroupMessageWSPublishing.ItemOperation: Skipping working set publishing because we should only publish after saving"); return; } if (result != OperationResult.Succeeded) { COWGroupMessageWSPublishing.Tracer.TraceDebug <OperationResult>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.ItemOperation: Skipping working set publishing of message because the operation wasn't successful: {0}", result); return; } MailboxSession mailboxSession = session as MailboxSession; if (mailboxSession == null) { COWGroupMessageWSPublishing.Tracer.TraceError <OperationResult>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.ItemOperation: Skipping working set publishing the session is not a mailbox session", result); return; } if (mailboxSession.MailboxOwner == null || mailboxSession.MailboxOwner.MailboxInfo == null) { COWGroupMessageWSPublishing.Tracer.TraceError <OperationResult>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.ItemOperation: Skipping working set publishing, the session does not contain the mailbox info", result); return; } string displayName = mailboxSession.DisplayName; string groupId = mailboxSession.MailboxOwner.MailboxInfo.PrimarySmtpAddress.ToString(); Exception ex = this.groupWSPublisher.PublishGroupPost(item, displayName, groupId); if (ex == null) { COWGroupMessageWSPublishing.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.ItemOperation: working set publishing of message {0} from group mailbox successful", itemId); } else { COWGroupMessageWSPublishing.Tracer.TraceDebug <StoreObjectId, string>((long)this.GetHashCode(), "COWGroupMessageWSPublishing.ItemOperation: working set publishing of message {0} from group mailbox failed. Error: {1}", itemId, ex.ToString()); } callbackContext.COWGroupMessageWSPublishingState = COWProcessorState.Processed; }
private static string GetCurrentFolderPathName(MailboxSession session, COWSettings settings) { string text = null; Folder currentFolder = settings.GetCurrentFolder(session); if (currentFolder != null) { text = (currentFolder.TryGetProperty(FolderSchema.FolderPathName) as string); if (text != null) { text = text.Replace(COWSettings.StoreIdSeparator, '\\'); } } return(text); }
public void GroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId destinationFolderId, StoreObjectId[] itemIds, GroupOperationResult result, bool onBeforeNotification, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); if (settings.CurrentFolderId.Equals(dumpster.RecoverableItemsPurgesFolderId)) { ExTraceGlobals.SessionTracer.TraceDebug((long)dumpster.StoreSession.GetHashCode(), "Attempt to hard delete items in the dumpster purges folder"); throw new RecoverableItemsAccessDeniedException("Purges"); } if (settings.CurrentFolderId.Equals(dumpster.RecoverableItemsDiscoveryHoldsFolderId)) { ExTraceGlobals.SessionTracer.TraceDebug((long)dumpster.StoreSession.GetHashCode(), "Attempt to hard delete items in the dumpster discoveryholds folder"); throw new RecoverableItemsAccessDeniedException("DiscoveryHolds"); } if (COWTriggerAction.HardDelete == operation) { try { StoreObjectId storeObjectId; if (settings.IsOnlyInPlaceHoldEnabled()) { settings.Session.CowSession.CheckAndCreateDiscoveryHoldsFolder(callbackContext.SessionWithBestAccess); storeObjectId = dumpster.RecoverableItemsDiscoveryHoldsFolderId; } else { storeObjectId = dumpster.RecoverableItemsPurgesFolderId; } if (!settings.CurrentFolderId.Equals(storeObjectId)) { dumpster.MoveItemsToDumpster(callbackContext.SessionWithBestAccess, storeObjectId, itemIds); } return; } catch (DumpsterOperationException) { if (dumpster.Results.AnyPartialResultFailure()) { throw; } List <GroupOperationResult> partialResults = dumpster.Results.GetPartialResults(); ExTraceGlobals.SessionTracer.TraceWarning <GroupOperationResult>((long)dumpster.StoreSession.GetHashCode(), "DumpsterOperationException during HardDelete and Partial success: leave the current results {0}", partialResults[partialResults.Count - 1]); return; } } dumpster.CopyItemsToDumpster(callbackContext.SessionWithBestAccess, dumpster.RecoverableItemsPurgesFolderId, itemIds, COWTriggerAction.DoneWithMessageDelete == operation); }
protected override void InternalDispose(bool disposing) { if (disposing) { if (this.SubmitEffectiveMailboxSession != null) { this.SubmitEffectiveMailboxSession.Dispose(); this.SubmitEffectiveMailboxSession = null; } if (this.sessionWithBestAccess != null) { COWSettings.ReturnAdminMailboxSession(this.sessionWithBestAccess); this.sessionWithBestAccess = null; COWSession.PerfCounters.DumpsterDelegateSessionsActive.Decrement(); } } base.InternalDispose(disposing); }
public CowClientOperationSensitivity SkipGroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId sourceFolderId, StoreObjectId destinationFolderId, ICollection <StoreObjectId> itemIds, bool onBeforeNotification, bool onDumpster, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); Util.ThrowOnNullArgument(settings, "settings"); Util.ThrowOnNullArgument(sourceSession, "sourceSession"); Util.ThrowOnNullArgument(dumpster, "dumpster"); if (onDumpster) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)sourceSession.GetHashCode(), "Skipping calendar COW group operation for user {0}, since the operation is on dumpster", sourceSession.UserLegacyDN); return(CowClientOperationSensitivity.Skip); } if (!onBeforeNotification) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)sourceSession.GetHashCode(), "Skipping calendar COW group operation for user {0}, since we are only interested in on-before notifications", sourceSession.UserLegacyDN); return(CowClientOperationSensitivity.Skip); } if (!CalendarLoggingHelper.ShouldLog(operation)) { ExTraceGlobals.CalendarLoggingTracer.Information <string, COWTriggerAction>((long)sourceSession.GetHashCode(), "Skipping calendar COW group operation for user {0}, since the trigger action {1} is not interesting", sourceSession.UserLegacyDN, operation); return(CowClientOperationSensitivity.Skip); } if (DumpsterFolderHelper.IsAuditFolder(callbackContext.SessionWithBestAccess, sourceFolderId)) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)sourceSession.GetHashCode(), "Skipping calendar COW group operation for user {0}, since the operation is on audit folder", sourceSession.UserLegacyDN); return(CowClientOperationSensitivity.Skip); } if (!settings.IsCalendarLoggingEnabled()) { ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)sourceSession.GetHashCode(), "Skipping calendar COW group operation for user {0}, since calendar logging is disabled for this user", sourceSession.UserLegacyDN); return(CowClientOperationSensitivity.Skip); } if (!DumpsterFolderHelper.IsDumpsterFolder(callbackContext.SessionWithBestAccess, sourceFolderId)) { return(CowClientOperationSensitivity.Capture); } if (operation == COWTriggerAction.HardDelete && !sourceFolderId.Equals(dumpster.CalendarLoggingFolderId)) { return(CowClientOperationSensitivity.Capture); } ExTraceGlobals.CalendarLoggingTracer.Information <string>((long)sourceSession.GetHashCode(), "Skipping calendar COW group operation for user {0}, since we are not interested in hard deletes in calendar logging folder", sourceSession.UserLegacyDN); return(CowClientOperationSensitivity.Skip); }
internal override void Recover(DefaultFolder defaultFolder, Exception e, ref DefaultFolderData defaultFolderData) { if (e is DefaultFolderPropertyValidationException && defaultFolderData.FolderId != null) { using (Folder folder = Folder.Bind(defaultFolder.Session, defaultFolderData.FolderId)) { defaultFolder.SetProperties(folder); } return; } COWSettings cowsettings = new COWSettings(defaultFolder.Session); if (cowsettings.HoldEnabled()) { CorruptDataRecoveryStrategy.Throw.Recover(defaultFolder, e, ref defaultFolderData); return; } CorruptDataRecoveryStrategy.Recreate.Recover(defaultFolder, e, ref defaultFolderData); }
public AuditEvent(MailboxSession session, MailboxAuditOperations operation, COWSettings settings, OperationResult result, LogonType logonType, bool externalAccess) { EnumValidator.ThrowIfInvalid <MailboxAuditOperations>(operation); EnumValidator.ThrowIfInvalid <OperationResult>(result, "result"); EnumValidator.ThrowIfInvalid <LogonType>(logonType, "logonType"); Util.ThrowOnNullArgument(session, "session"); Util.ThrowOnNullArgument(settings, "settings"); this.MailboxSession = session; this.AuditOperation = operation; this.COWSettings = settings; this.OperationSucceeded = result; this.LogonType = logonType; this.ExternalAccess = externalAccess; this.CreationTime = DateTime.UtcNow; this.RecordId = CombGuidGenerator.NewGuid(this.CreationTime); this.OrganizationId = (string.IsNullOrEmpty(session.OrganizationId.ToString()) ? "First Org" : session.OrganizationId.ToString()); this.MailboxGuid = session.MailboxGuid; this.OperationName = operation.ToString(); this.LogonTypeName = logonType.ToString(); }
private bool PerformFolderCopyOnWrite(COWSettings settings, IDumpsterItemOperations dumpster, ICoreItem item, MailboxSession sessionWithBestAccess, COWTriggerAction operation, FolderChangeOperationFlags folderChangeOperationFlags, bool copyAfterSave) { bool result = false; if (settings.IsCurrentFolderEnabled(sessionWithBestAccess) || COWCalendarLogging.IsParkedMessagesFolder(settings, sessionWithBestAccess)) { StoreObjectId storeObjectId = item.StoreObjectId; this.PerformCopyOnWrite(sessionWithBestAccess, dumpster, storeObjectId); item.OpenAsReadWrite(); CalendarLoggingHelper.AddMetadata(item, operation, new FolderChangeOperationFlags?(folderChangeOperationFlags)); COWSettings.AddMetadata(settings, item, operation); this.SaveItem(item, sessionWithBestAccess, operation); if (copyAfterSave) { this.PerformCopyOnWrite(sessionWithBestAccess, dumpster, storeObjectId); } result = true; } return(result); }
public void ItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, CoreFolder folder, bool onBeforeNotification, OperationResult result, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <OperationResult>(result, "result"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); StoreObjectId storeObjectId = ((ICoreObject)item).StoreObjectId; if (storeObjectId is OccurrenceStoreObjectId) { return; } if (onBeforeNotification) { List <string> legallyDirtyProperties = item.GetLegallyDirtyProperties(); if (legallyDirtyProperties != null && legallyDirtyProperties.Count > 0) { COWSettings.AddMetadata(settings, item, operation); if (state == COWTriggerActionState.Save) { StoreObjectId destinationFolderId; if (settings.IsOnlyInPlaceHoldEnabled()) { settings.Session.CowSession.CheckAndCreateDiscoveryHoldsFolder(callbackContext.SessionWithBestAccess); destinationFolderId = dumpster.RecoverableItemsDiscoveryHoldsFolderId; } else { destinationFolderId = dumpster.RecoverableItemsVersionsFolderId; } StoreObjectId copyOnWriteGeneratedId = dumpster.CopyItemToDumpster(callbackContext.SessionWithBestAccess, destinationFolderId, item); dumpster.Results.CopyOnWriteGeneratedId = copyOnWriteGeneratedId; return; } } } else if (operation == COWTriggerAction.Update && state == COWTriggerActionState.Save && result == OperationResult.Failed) { dumpster.RollbackItemVersion(callbackContext.SessionWithBestAccess, item, dumpster.Results.CopyOnWriteGeneratedId); dumpster.Results.CopyOnWriteGeneratedId = null; } }
public bool SkipItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, bool onBeforeNotification, bool onDumpster, bool success, CallbackContext callbackContext) { if (!COWContactLogging.COWContactLoggingConfiguration.Instance.IsLoggingEnabled()) { return(true); } Util.ThrowOnNullArgument(session, "session"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); if (item == null) { COWContactLogging.Tracer.TraceDebug((long)this.GetHashCode(), "COWContactLogging.SkipItemOperation: Item is null"); return(true); } if (!onBeforeNotification) { COWContactLogging.Tracer.TraceDebug((long)this.GetHashCode(), "COWContactLogging.SkipItemOperation: Not onBeforeNotification"); return(true); } string valueOrDefault = item.PropertyBag.GetValueOrDefault <string>(StoreObjectSchema.ItemClass, string.Empty); COWContactLogging.Tracer.TraceDebug <string>((long)this.GetHashCode(), "COWContactLogging.SkipItemOperation: ItemClass: {0}", valueOrDefault); if (ObjectClass.IsPlace(valueOrDefault)) { return(true); } if (!ObjectClass.IsContact(valueOrDefault) && !ObjectClass.IsDistributionList(valueOrDefault) && !ObjectClass.IsContactsFolder(valueOrDefault)) { return(true); } foreach (IContactChangeTracker contactChangeTracker in COWContactLogging.ChangeTrackers) { if (contactChangeTracker.ShouldLoadPropertiesForFurtherCheck(operation, valueOrDefault, itemId, item)) { COWContactLogging.Tracer.TraceDebug((long)this.GetHashCode(), "COWContactLogging.SkipItemOperation: A tracker interested."); return(false); } } return(true); }
public void ItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, CoreFolder folder, bool onBeforeNotification, OperationResult result, CallbackContext callbackContext) { Util.ThrowOnNullArgument(session, "session"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); EnumValidator.ThrowIfInvalid <OperationResult>(result, "result"); Util.ThrowOnNullArgument(item, "item"); MailboxSession mailboxSession = session as MailboxSession; ExDateTime now = ExDateTime.Now; try { item.PropertyBag.Load(COWSiteMailboxMessageDedup.PropsForMessageRemoval); if (item.Id != null && item.Id.ObjectId != null) { StoreObjectId storeObjectId = item.PropertyBag.TryGetProperty(StoreObjectSchema.ParentItemId) as StoreObjectId; if (storeObjectId != null) { using (CoreFolder coreFolder = CoreFolder.Bind(session, storeObjectId)) { DeleteItemFlags deleteItemFlags = DeleteItemFlags.HardDelete | DeleteItemFlags.SuppressReadReceipt; coreFolder.DeleteItems(deleteItemFlags, new StoreObjectId[] { item.Id.ObjectId }); } COWSiteMailboxMessageDedup.Tracer.TraceDebug <StoreObjectId, string, double>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.ItemOperation: deleting message {0} from site mailbox {1} used {2} milliseconds", itemId, mailboxSession.DisplayName, (ExDateTime.Now - now).TotalMilliseconds); } } } catch (StoragePermanentException arg) { COWSiteMailboxMessageDedup.Tracer.TraceError <StoragePermanentException>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.ItemOperation: got store permanent exception: {0}", arg); } catch (StorageTransientException arg2) { COWSiteMailboxMessageDedup.Tracer.TraceError <StorageTransientException>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.ItemOperation: got store transient exception: {0}", arg2); } callbackContext.SiteMailboxMessageDedupState = COWProcessorState.Processed; }
public bool SkipItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, bool onBeforeNotification, bool onDumpster, bool success, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); if (onBeforeNotification && COWTriggerAction.Update == operation) { if (settings.CurrentFolderId != null) { if (settings.CurrentFolderId.Equals(dumpster.AuditsFolderId)) { throw new AccessDeniedException(ServerStrings.ExAuditsUpdateDenied); } if (settings.CurrentFolderId.Equals(dumpster.AdminAuditLogsFolderId)) { throw new AccessDeniedException(ServerStrings.ExAdminAuditLogsUpdateDenied); } if (dumpster.IsAuditFolder(settings.CurrentFolderId)) { throw new AccessDeniedException((dumpster.AuditsFolderId != null) ? ServerStrings.ExAuditsUpdateDenied : ServerStrings.ExAdminAuditLogsUpdateDenied); } } else if (itemId != null) { StoreObjectId parentIdFromMessageId = IdConverter.GetParentIdFromMessageId(itemId); if (parentIdFromMessageId.Equals(dumpster.AuditsFolderId)) { throw new AccessDeniedException(ServerStrings.ExAuditsUpdateDenied); } if (parentIdFromMessageId.Equals(dumpster.AdminAuditLogsFolderId)) { throw new AccessDeniedException(ServerStrings.ExAdminAuditLogsUpdateDenied); } if (dumpster.IsAuditFolder(settings.CurrentFolderId)) { throw new AccessDeniedException((dumpster.AuditsFolderId != null) ? ServerStrings.ExAuditsUpdateDenied : ServerStrings.ExAdminAuditLogsUpdateDenied); } } } return(true); }
public void GroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId destinationFolderId, StoreObjectId[] itemIds, GroupOperationResult result, bool onBeforeNotification, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); int num = 0; if (itemIds != null) { foreach (StoreObjectId storeObjectId in itemIds) { if (!(storeObjectId is OccurrenceStoreObjectId)) { num++; } } } if (itemIds == null || num == itemIds.Length) { dumpster.MoveItemsToDumpster(callbackContext.SessionWithBestAccess, dumpster.RecoverableItemsDeletionsFolderId, itemIds); return; } if (num > 0) { StoreObjectId[] array = new StoreObjectId[num]; num = 0; foreach (StoreObjectId storeObjectId2 in itemIds) { if (!(storeObjectId2 is OccurrenceStoreObjectId)) { array[num] = storeObjectId2; num++; } } dumpster.MoveItemsToDumpster(callbackContext.SessionWithBestAccess, dumpster.RecoverableItemsDeletionsFolderId, array); } }
public CowClientOperationSensitivity SkipGroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId sourceFolderId, StoreObjectId destinationFolderId, ICollection <StoreObjectId> itemIds, bool onBeforeNotification, bool onDumpster, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); Util.ThrowOnNullArgument(settings, "settings"); Util.ThrowOnNullArgument(sourceSession, "sourceSession"); if (onDumpster) { return(CowClientOperationSensitivity.Skip); } if (!onBeforeNotification) { return(CowClientOperationSensitivity.Skip); } if (operation != COWTriggerAction.SoftDelete) { return(CowClientOperationSensitivity.Skip); } if (COWSession.IsDelegateSession(sourceSession)) { return(CowClientOperationSensitivity.Capture); } return(CowClientOperationSensitivity.CaptureAndPerformOperation); }
public CowClientOperationSensitivity SkipGroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId sourceFolderId, StoreObjectId destinationFolderId, ICollection <StoreObjectId> itemIds, bool onBeforeNotification, bool onDumpster, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); Util.ThrowOnNullArgument(settings, "settings"); Util.ThrowOnNullArgument(sourceSession, "sourceSession"); if (onDumpster) { return(CowClientOperationSensitivity.Skip); } if (!onBeforeNotification) { return(CowClientOperationSensitivity.Skip); } bool flag; if (!settings.HoldEnabled()) { flag = true; } else { switch (operation) { case COWTriggerAction.Move: case COWTriggerAction.MoveToDeletedItems: { Util.ThrowOnNullArgument(sourceSession, "sourceSession"); if (destinationSession == null) { flag = true; ExTraceGlobals.SessionTracer.TraceDebug((long)dumpster.StoreSession.GetHashCode(), "Destination session is null, meaning item moving to same mailbox, so don't keep a copy."); goto IL_187; } Guid mailboxGuid = destinationSession.MailboxGuid; Guid mailboxGuid2 = sourceSession.MailboxGuid; if (destinationSession.MailboxGuid == sourceSession.MailboxGuid) { flag = true; ExTraceGlobals.SessionTracer.TraceDebug((long)dumpster.StoreSession.GetHashCode(), "Mailbox guids are the same, meaning item moving to same mailbox, so don't keep a copy."); goto IL_187; } if (destinationSession is MailboxSession && sourceSession is MailboxSession && string.Compare(((MailboxSession)sourceSession).MailboxOwner.LegacyDn, ((MailboxSession)destinationSession).MailboxOwner.LegacyDn, StringComparison.OrdinalIgnoreCase) == 0) { flag = true; ExTraceGlobals.SessionTracer.TraceDebug((long)dumpster.StoreSession.GetHashCode(), "MailboxOwner.LegacyDistinguishedName is the same, meaning same person owns both mailboxes (eg primary and archive), so don't keep a copy."); goto IL_187; } flag = false; ExTraceGlobals.SessionTracer.TraceDebug((long)dumpster.StoreSession.GetHashCode(), "Item moving to a different mailbox owned by someone else. Keep a copy."); goto IL_187; } case COWTriggerAction.HardDelete: flag = (settings.IsMrmAction() && DumpsterFolderHelper.IsDumpsterFolder(callbackContext.SessionWithBestAccess, sourceFolderId)); goto IL_187; case COWTriggerAction.DoneWithMessageDelete: flag = false; goto IL_187; } flag = true; } IL_187: if (flag) { return(CowClientOperationSensitivity.Skip); } if (COWSession.IsDelegateSession(sourceSession)) { return(CowClientOperationSensitivity.Capture); } return(CowClientOperationSensitivity.CaptureAndPerformOperation); }
public void GroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId destinationFolderId, StoreObjectId[] itemIds, GroupOperationResult result, bool onBeforeNotification, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); }
public CowClientOperationSensitivity SkipGroupOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, FolderChangeOperationFlags flags, StoreSession sourceSession, StoreSession destinationSession, StoreObjectId sourceFolderId, StoreObjectId destinationFolderId, ICollection <StoreObjectId> itemIds, bool onBeforeNotification, bool onDumpster, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <FolderChangeOperationFlags>(flags, "flags"); return(CowClientOperationSensitivity.Skip); }
public void ItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, CoreFolder folder, bool onBeforeNotification, OperationResult result, CallbackContext callbackContext) { EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <OperationResult>(result, "result"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); }
public virtual bool IsDumpsterOverWarningQuota(COWSettings settings) { throw new NotImplementedException(); }
public bool SkipItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, bool onBeforeNotification, bool onDumpster, bool success, CallbackContext callbackContext) { Util.ThrowOnNullArgument(session, "session"); EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation"); EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state"); MailboxSession mailboxSession = session as MailboxSession; if (mailboxSession == null || !Utils.IsTeamMailbox(session) || !ClientInfo.MOMT.IsMatch(session.ClientInfoString)) { return(true); } if (callbackContext.SiteMailboxMessageDedupState == COWProcessorState.DoNotProcess) { COWSiteMailboxMessageDedup.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.SkipItemOperation: skipping notification for item {0} because it should not be processed.", itemId); return(true); } if (callbackContext.SiteMailboxMessageDedupState == COWProcessorState.Processed) { COWSiteMailboxMessageDedup.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.SkipItemOperation: skipping notification for item {0} because it was already processed.", itemId); return(true); } if (callbackContext.SiteMailboxMessageDedupState == COWProcessorState.ProcessAfterSave) { return(onBeforeNotification); } if (onDumpster || item == null || operation != COWTriggerAction.Create) { callbackContext.SiteMailboxMessageDedupState = COWProcessorState.DoNotProcess; return(true); } if (!settings.IsSiteMailboxMessageDedupEnabled()) { callbackContext.SiteMailboxMessageDedupState = COWProcessorState.DoNotProcess; COWSiteMailboxMessageDedup.Tracer.Information <string>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.SkipItemOperation: skipping message dedup for site mailbox {0} because the feature is disabled for the mailbox.", mailboxSession.DisplayName); return(true); } ExDateTime now = ExDateTime.Now; bool flag = false; try { flag = this.IsDuplicateMessageBySiteMailboxDrop(mailboxSession, item); } catch (StoragePermanentException arg) { COWSiteMailboxMessageDedup.Tracer.TraceError <StoragePermanentException>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.SkipItemOperation: got store permanent exception: {0}", arg); } catch (StorageTransientException arg2) { COWSiteMailboxMessageDedup.Tracer.TraceError <StorageTransientException>((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.SkipItemOperation: got store transient exception: {0}", arg2); } if (flag) { callbackContext.SiteMailboxMessageDedupState = COWProcessorState.ProcessAfterSave; } else { callbackContext.SiteMailboxMessageDedupState = COWProcessorState.DoNotProcess; } COWSiteMailboxMessageDedup.Tracer.TraceDebug((long)this.GetHashCode(), "COWSiteMailboxMessageDedup.SkipItemOperation: inspecting message {0} dragged & dropped to site mailbox {1} costed {2} milliseconds, and the result is {3}.", new object[] { itemId, mailboxSession.DisplayName, (ExDateTime.Now - now).TotalMilliseconds, callbackContext.SiteMailboxMessageDedupState }); return(true); }
public ItemOperationAuditEvent(MailboxSession session, MailboxAuditOperations operation, COWSettings settings, OperationResult result, LogonType logonType, bool externalAccess, StoreObjectId itemId, CoreItem item, ItemAuditInfo itemAuditInfo) : base(session, operation, settings, result, logonType, externalAccess) { if (MailboxAuditOperations.FolderBind != operation && MailboxAuditOperations.SendAs != operation && MailboxAuditOperations.SendOnBehalf != operation && MailboxAuditOperations.Create != operation) { Util.ThrowOnNullArgument(itemId, "itemId"); } this.itemId = itemId; this.item = item; this.itemAuditInfo = itemAuditInfo; }
public virtual bool IsDumpsterOverCalendarLoggingQuota(MailboxSession sessionWithBestAccess, COWSettings settings) { throw new NotImplementedException(); }