Beispiel #1
0
        private List <string> ExecuteRuleCollectionSchemaCheck(RuleCollection collection, LdapConnection connection)
        {
            this.OnStatusUpdate?.Invoke(StringLiterals.LdapConnectionEstablishing);
            var schemaDistinguishedName = this.GetSchemaDistinguishedName(connection);

            using (var searcher = collection.CreateSchemaSearcher(schemaDistinguishedName))
            {
                this.OnStatusUpdate?.Invoke(StringLiterals.LdapConnectionEstablished);
                this.OnStatusUpdate?.Invoke(StringLiterals.BeginningQuery);

                if (this.CancellationPending)
                {
                    return(null);
                }

                var replicatedAttributes = new List <string>();
                var results = searcher.FindAll();

                foreach (System.DirectoryServices.SearchResult entry in results)
                {
                    if (entry.Properties.Contains(Constants.IsMemberOfPartialAttributeSetAttribute) &&
                        entry.Properties[Constants.IsMemberOfPartialAttributeSetAttribute].Count > 0 &&
                        (bool)entry.Properties[Constants.IsMemberOfPartialAttributeSetAttribute][0] == true)
                    {
                        replicatedAttributes.Add(entry.Properties[Constants.LdapDisplayNameAttribute][0].ToString());
                    }
                }

                var notReplicatedAttributes = collection.AttributesToQuery.Where(_ => !replicatedAttributes.Contains(_, StringComparer.InvariantCultureIgnoreCase)).ToList();

                return(notReplicatedAttributes);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Executes a rule collection against the supplied connection
        /// </summary>
        /// <param name="collection">The rule collection to execute</param>
        /// <param name="connection">The connection used to retrieve entries for processing</param>
        /// <returns><see cref="RuleCollectionResult"/> or null if canceled</returns>
        private RuleCollectionResult ExecuteRuleCollection(RuleCollection collection, LdapConnection connection)
        {
            // these count all the totals for the connection against which this RuleCollection is being run
            var  stopWatch      = new Stopwatch();
            long skipCount      = 0;
            long entryCount     = 0;
            long duplicateCount = 0;
            long errorCount     = 0;

            this.OnStatusUpdate?.Invoke("Please wait while the LDAP Connection is established.");
            var searchRequest = collection.CreateSearchRequest();

            this.OnStatusUpdate?.Invoke("LDAP Connection established.");

            var errors = new List <ComposedRuleResult>();

            this.OnStatusUpdate?.Invoke("Beginning query");

            while (true)
            {
                var searchResponse = (SearchResponse)connection.SendRequest(searchRequest);

                // verify support for paged results
                if (searchResponse.Controls.Length != 1 || !(searchResponse.Controls[0] is PageResultResponseControl))
                {
                    this.OnStatusUpdate?.Invoke("The server cannot page the result set.");
                    throw new InvalidOperationException("The server cannot page the result set.");
                }

                foreach (SearchResultEntry entry in searchResponse.Entries)
                {
                    if (this.CancellationPending)
                    {
                        return(null);
                    }

                    if (collection.Skip(entry))
                    {
                        skipCount++;
                        continue;
                    }

                    // this tracks the number of entries we have processed and not skipped
                    entryCount++;

                    foreach (var composedRule in collection.Rules)
                    {
                        // run each composed rule which can produce multiple results
                        var results = composedRule.Execute(entry);

                        for (var i = 0; i < results.Length; i++)
                        {
                            if (!results[i].Success)
                            {
                                errorCount++;

                                if (results[i].Results.Any(r => (r.ErrorTypeFlags & ErrorType.Duplicate) != 0))
                                {
                                    duplicateCount++;
                                }

                                errors.Add(results[i]);
                            }
                        }
                    }
                }

                // handle paging
                var cookie = searchResponse.Controls.OfType <PageResultResponseControl>().First().Cookie;

                // if this is true, there are no more pages to request
                if (cookie.Length == 0)
                {
                    break;
                }

                searchRequest.Controls.OfType <PageResultRequestControl>().First().Cookie = cookie;
            }

            // we are all done, stop tracking time
            stopWatch.Stop();

            return(new RuleCollectionResult
            {
                TotalDuplicates = duplicateCount,
                TotalErrors = errorCount,
                TotalFound = skipCount + entryCount,
                TotalSkips = skipCount,
                TotalProcessed = entryCount,
                Elapsed = stopWatch.Elapsed,
                Errors = errors.ToArray()
            });
        }
Beispiel #3
0
        /// <summary>
        /// Executes a rule collection against the supplied connection
        /// </summary>
        /// <param name="collection">The rule collection to execute</param>
        /// <param name="connection">The connection used to retrieve entries for processing</param>
        /// <returns><see cref="RuleCollectionResult"/> or null if canceled</returns>
        private RuleCollectionResult ExecuteRuleCollection(RuleCollection collection, LdapConnection connection)
        {
            // these count all the totals for the connection against which this RuleCollection is being run
            var  stopWatch      = new Stopwatch();
            long skipCount      = 0;
            long entryCount     = 0;
            long duplicateCount = 0;
            long errorCount     = 0;

            this.OnStatusUpdate?.Invoke(StringLiterals.LdapConnectionEstablishing);
            var searchRequest = collection.CreateSearchRequest();

            this.OnStatusUpdate?.Invoke(StringLiterals.LdapConnectionEstablished);

            var errors = new List <ComposedRuleResult>();

            this.OnStatusUpdate?.Invoke(StringLiterals.BeginningQuery);

            while (true)
            {
                var searchResponse = (SearchResponse)connection.SendRequest(searchRequest);

                // verify support for paged results
                if (searchResponse.Controls.Length != 1 || !(searchResponse.Controls[0] is PageResultResponseControl))
                {
                    this.OnStatusUpdate?.Invoke(StringLiterals.CannotPageResultSet);
                    throw new InvalidOperationException(StringLiterals.CannotPageResultSet);
                }

                foreach (SearchResultEntry entry in searchResponse.Entries)
                {
                    if (this.CancellationPending)
                    {
                        return(null);
                    }

                    if (collection.Skip(entry))
                    {
                        skipCount++;
                        continue;
                    }

                    // this tracks the number of entries we have processed and not skipped
                    entryCount++;

                    foreach (var composedRule in collection.Rules)
                    {
                        // run each composed rule which can produce multiple results
                        var results = composedRule.Execute(entry);

                        for (var i = 0; i < results.Length; i++)
                        {
                            var result = results[i];
                            if (!result.Success)
                            {
                                errorCount++;

                                if (result.Results.Any(r => (r.ErrorTypeFlags & ErrorType.Duplicate) != 0))
                                {
                                    duplicateCount++;

                                    if (result.ProposedAction == ActionType.Edit)
                                    {
                                        // Add original LDAP entry with the same value.
                                        var originalEntry    = DuplicateStore.GetOriginalSearchResultEntry(result.AttributeName, result.OriginalValue);
                                        var additionalResult = new ComposedRuleResult
                                        {
                                            AttributeName           = result.AttributeName,
                                            EntityDistinguishedName = originalEntry.DistinguishedName,
                                            EntityCommonName        = originalEntry.Attributes[StringLiterals.Cn][0].ToString(),
                                            ObjectType     = ComposedRule.GetObjectType(entry),
                                            OriginalValue  = result.OriginalValue,
                                            ProposedAction = result.ProposedAction,
                                            ProposedValue  = result.ProposedValue,
                                            Results        = new RuleResult[] {
                                                new RuleResult(false)
                                                {
                                                    ErrorTypeFlags = ErrorType.Duplicate,
                                                    ProposedAction = result.ProposedAction,
                                                    UpdatedValue   = result.OriginalValue
                                                }
                                            },
                                            Success = result.Success
                                        };
                                        errors.Add(additionalResult);
                                    }
                                }

                                errors.Add(result);
                            }
                        }
                    }
                }

                // handle paging
                var cookie = searchResponse.Controls.OfType <PageResultResponseControl>().First().Cookie;

                // if this is true, there are no more pages to request
                if (cookie.Length == 0)
                {
                    break;
                }

                searchRequest.Controls.OfType <PageResultRequestControl>().First().Cookie = cookie;
            }

            // we are all done, stop tracking time
            stopWatch.Stop();

            return(new RuleCollectionResult
            {
                TotalDuplicates = duplicateCount,
                TotalErrors = errorCount,
                TotalFound = skipCount + entryCount,
                TotalSkips = skipCount,
                TotalProcessed = entryCount,
                Elapsed = stopWatch.Elapsed,
                Errors = errors.ToArray()
            });
        }