/// <summary> /// Retrieves current state of LDAP database and reflects it to the CMS. /// </summary> public void Synchronize() { try { var request = new SearchRequest(DefaultNamingContext, "(&(|(objectClass=user)(objectClass=group))(usnchanged>="+ (Dispatcher.HighestUsnChanged + 1) +"))", SearchScope.Subtree, null); request.Controls.Add(new ShowDeletedControl()); // Page result var prc = new PageResultRequestControl(5); request.Controls.Add(prc); var soc = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope); request.Controls.Add(soc); while (true) { var searchResponse = (SearchResponse) Connection.SendRequest(request); if (searchResponse != null) { // Find the returned page response control foreach (DirectoryControl control in searchResponse.Controls) { if (control is PageResultResponseControl) { //update the cookie for next set prc.Cookie = ((PageResultResponseControl) control).Cookie; break; } } Dispatcher.AddToQueue(searchResponse.Entries.Cast<SearchResultEntry>().Where(p =>LdapHelper.IsUser(p, PersonObjectCategory) || LdapHelper.IsGroup(p, GroupObjectCategory)).ToList()); if (prc.Cookie.Length == 0) { break; } } else { break; } } } catch (Exception ex) { LogError("Full synchronization failed.", ex); } }
/// <summary> /// Performs LDAP Search and extracts attributes. /// </summary> /// <param name="logger">The logger.</param> /// <param name="CurrentTime">Locked program timestamp value</param> private void ExtractLDAPResults(LogHelper logger, DateTime CurrentTime) { List<string> AttributesToAdd = new List<string>(); foreach (PropertyBase item in this.Properties) AttributesToAdd.Add(item.Mapping); string[] _attrs = AttributesToAdd.ToArray(); String sFilter = SetQueryFilter(this.BatchAction, CurrentTime); SearchRequest searchRequest = new SearchRequest(this.SearchRoot, sFilter, SearchScope.Subtree, _attrs); PageResultRequestControl PageResponse = new PageResultRequestControl(this.PageSize); SearchOptionsControl SearchOptions = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope); searchRequest.Controls.Add(PageResponse); searchRequest.Controls.Add(SearchOptions); logger.LogVerbose(string.Format("Establishing LDAP Connection to: {0}", this.ServerName)); using(LdapConnection connection = CreateLDAPConnection()) { logger.LogVerbose(string.Format("Performing a {0} operation with filter: {1}", this.BatchAction, sFilter)); while (true) { SearchResponse response = null; try { response = connection.SendRequest(searchRequest) as SearchResponse; } catch(Exception ex) { throw new Exception("An error occurred whilst creating the SearchResponse", ex); } int ResponseCount = response.Entries.Count; int CurrentBatchSize; if (ResponseCount != this.PageSize) CurrentBatchSize = ResponseCount; else CurrentBatchSize = this.PageSize; string FilePath = CSVCreateFile(this.CSVDirectoryLocation, _TotalUsers, CurrentBatchSize); foreach (DirectoryControl control in response.Controls) { if (control is PageResultResponseControl) { PageResponse.Cookie = ((PageResultResponseControl)control).Cookie; break; } } // Create CSV file for current batch of users using (CSVWriter BatchFile = new CSVWriter(FilePath)) { // Create column headings for CSV file CSVUserEntry heading = new CSVUserEntry(); // Iterate over attribute headings foreach (PropertyBase item in this.Properties) heading.Add(item.Name); BatchFile.CSVWriteUser(heading, logger); // Create new CSV row for each user foreach (SearchResultEntry sre in response.Entries) { // Placeholder for CSV entry of current user CSVUserEntry user = new CSVUserEntry(); // Exract each user attribute specified in XML file foreach (PropertyBase item in this.Properties) { try { DirectoryAttribute attr = sre.Attributes[item.Mapping]; string value = string.Empty; if (null != attr && attr.Count > 0) value = attr[0].ToString(); if (item.Index == this.UserNameIndex) user.Add(CreateUserAccountName(value, attr)); else user.Add(value); } catch (Exception ex) { if (logger != null) { logger.LogException(string.Empty, ex); _TotalFailures++; } } } // Write current user to CSV file BatchFile.CSVWriteUser(user, logger); // Increment user count value _TotalUsers++; } } logger.LogVerbose(string.Format("Successfully extracted {0} users to {1} - the total user count is: {2}", CurrentBatchSize, FilePath, _TotalUsers)); if (PageResponse.Cookie.Length == 0) break; } } }