/// <summary> /// Asynchronous callback that processes changes from Active Directory. /// </summary> /// <param name="asyncResult">Result of permanens search</param> private void RunAsyncSearch(IAsyncResult asyncResult) { var results = new List <SearchResultEntry>(); // Get changes if (!asyncResult.IsCompleted) { PartialResultsCollection partialResults = null; try { partialResults = Connection.GetPartialResults(asyncResult); } catch (Exception e) { LogError("Retrieving partial results from Active Directory asynchronous search failed.", e); } if (partialResults != null) { // Add only users and groups results.AddRange(partialResults.OfType <SearchResultEntry>().Where(p => LdapHelper.IsUser(p, PersonObjectCategory) || LdapHelper.IsGroup(p, GroupObjectCategory))); } } else { LogMessage("The change notification control unexpectedly ended the search."); mSearches.Remove(asyncResult); StartIncrementalSynchronization(); } // Send changes to CMS Dispatcher.AddToQueue(results); }
private void Notify(IAsyncResult result) { lock (this.lockObject) { try { if (this.stopped) { this.connection?.EndSendRequest(result); return; } PartialResultsCollection resultsCollection = this.connection?.GetPartialResults(result); if (resultsCollection == null) { this.Trace("Results collection was empty"); return; } if (DateTime.Now < this.nextTriggerAfter) { //this.Trace("Discarding change because next trigger time has not been reached"); return; } DateTime lastLogonOldestDate = DateTime.UtcNow.Subtract(this.LastLogonTimestampOffset); foreach (SearchResultEntry r in resultsCollection.OfType <SearchResultEntry>()) { if (r.Attributes == null || !r.Attributes.Contains(ActiveDirectoryChangeTrigger.ObjectClassAttribute)) { this.Trace($"Skipping entry {r.DistinguishedName} because the object class list was empty"); continue; } IList <string> objectClasses = r.Attributes[ActiveDirectoryChangeTrigger.ObjectClassAttribute].GetValues(typeof(string)).OfType <string>().ToList(); if (!this.ObjectClasses.Intersect(objectClasses, StringComparer.OrdinalIgnoreCase).Any()) { continue; } if (objectClasses.Contains("computer", StringComparer.OrdinalIgnoreCase) && !this.ObjectClasses.Contains("computer", StringComparer.OrdinalIgnoreCase)) { continue; } bool dateTooSoon = false; foreach (string timestampAttribute in ActiveDirectoryChangeTrigger.TimeStampAttributesToIgnore) { if (r.Attributes.Contains(timestampAttribute)) { string ts = r.Attributes[timestampAttribute][0] as string; DateTime date1 = DateTime.FromFileTimeUtc(Convert.ToInt64(ts)); if (date1 > lastLogonOldestDate) { dateTooSoon = true; break; } } } if (dateTooSoon) { continue; } this.Log($"Change detected on {r.DistinguishedName}"); this.Fire(); } } catch (LdapException ex) { if (ex.ErrorCode == 85) { this.SetupListener(); } else { this.LogError("The AD change listener encountered an unexpected error", ex); if (MessageSender.CanSendMail()) { string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, false, ex); MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent); Thread.Sleep(1000); } } } catch (Exception ex) { this.LogError("The AD change listener encountered an unexpected error", ex); if (MessageSender.CanSendMail()) { string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, false, ex); MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent); Thread.Sleep(1000); } } } }