From d955addc26fb02543b73e7da7ee4f79cec6876ef Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Mon, 2 May 2016 18:54:27 +1000 Subject: [PATCH] AD Performance Improvement When searching very large Active Directories prefix wildcards greatly reduce performance. A configuration switch is implemented when results in only suffix wildcards being used. --- .../Modules/ActiveDirectoryConfiguration.cs | 10 ++++++++++ Disco.Services/Interop/ActiveDirectory/ADGroup.cs | 2 +- .../Interop/ActiveDirectory/ADUserAccount.cs | 2 +- .../Interop/ActiveDirectory/ActiveDirectoryContext.cs | 7 +++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Disco.Data/Configuration/Modules/ActiveDirectoryConfiguration.cs b/Disco.Data/Configuration/Modules/ActiveDirectoryConfiguration.cs index b50caa2f..93f8a13c 100644 --- a/Disco.Data/Configuration/Modules/ActiveDirectoryConfiguration.cs +++ b/Disco.Data/Configuration/Modules/ActiveDirectoryConfiguration.cs @@ -29,5 +29,15 @@ namespace Disco.Data.Configuration.Modules get { return Get(null); } set { Set(value); } } + + /// + /// If true LDAP filters contain wildcards only at the end of the search term. + /// This greatly improves performance in very large AD environments (ie: EDU001/EDU002) + /// + public bool SearchWildcardSuffixOnly + { + get { return Get(false); } + set { Set(value); } + } } } diff --git a/Disco.Services/Interop/ActiveDirectory/ADGroup.cs b/Disco.Services/Interop/ActiveDirectory/ADGroup.cs index fd351026..b2d39d3c 100644 --- a/Disco.Services/Interop/ActiveDirectory/ADGroup.cs +++ b/Disco.Services/Interop/ActiveDirectory/ADGroup.cs @@ -9,7 +9,7 @@ namespace Disco.Services.Interop.ActiveDirectory public class ADGroup : IADObject { internal static readonly string[] LoadProperties = { "name", "distinguishedName", "sAMAccountName", "objectSid", "memberOf" }; - internal const string LdapSearchFilterTemplate = "(&(objectCategory=Group)(|(sAMAccountName=*{0}*)(name=*{0}*)(cn=*{0}*)))"; + internal static string LdapSearchFilterTemplate = "(&(objectCategory=Group)(|(sAMAccountName=*{0}*)(name=*{0}*)(cn=*{0}*)))"; internal const string LdapSamAccountNameFilterTemplate = "(&(objectCategory=Group)(sAMAccountName={0}))"; internal const string LdapSecurityIdentifierFilterTemplate = "(&(objectCategory=Group)(objectSid={0}))"; diff --git a/Disco.Services/Interop/ActiveDirectory/ADUserAccount.cs b/Disco.Services/Interop/ActiveDirectory/ADUserAccount.cs index 8eb389ac..6cfb7bc9 100644 --- a/Disco.Services/Interop/ActiveDirectory/ADUserAccount.cs +++ b/Disco.Services/Interop/ActiveDirectory/ADUserAccount.cs @@ -9,7 +9,7 @@ namespace Disco.Services.Interop.ActiveDirectory public class ADUserAccount : IADObject { internal const string LdapSamAccountNameFilterTemplate = "(&(objectCategory=Person)(sAMAccountName={0}))"; - internal const string LdapSearchFilterTemplate = "(&(objectCategory=Person)(objectClass=user)(|(sAMAccountName=*{0}*)(displayName=*{0}*)))"; + internal static string LdapSearchFilterTemplate = "(&(objectCategory=Person)(objectClass=user)(|(sAMAccountName=*{0}*)(displayName=*{0}*)(sn=*{0}*)(givenName=*{0}*)))"; internal static readonly string[] LoadProperties = { "name", "distinguishedName", "sAMAccountName", "objectSid", "displayName", "sn", "givenName", "memberOf", "primaryGroupID", "mail", "telephoneNumber" }; internal static readonly string[] QuickLoadProperties = { "name", "distinguishedName", "sAMAccountName", "objectSid", "displayName", "sn", "givenName", "mail", "telephoneNumber" }; diff --git a/Disco.Services/Interop/ActiveDirectory/ActiveDirectoryContext.cs b/Disco.Services/Interop/ActiveDirectory/ActiveDirectoryContext.cs index f5de4d7d..c24f9d74 100644 --- a/Disco.Services/Interop/ActiveDirectory/ActiveDirectoryContext.cs +++ b/Disco.Services/Interop/ActiveDirectory/ActiveDirectoryContext.cs @@ -55,6 +55,13 @@ namespace Disco.Services.Interop.ActiveDirectory // Search Entire Forest (default: true) this._SearchAllForestServers = Database.DiscoConfiguration.ActiveDirectory.SearchAllForestServers ?? true; + // Set Search LDAP Filters + if (Database.DiscoConfiguration.ActiveDirectory.SearchWildcardSuffixOnly) + { + ADGroup.LdapSearchFilterTemplate = "(&(objectCategory=Group)(|(sAMAccountName={0}*)(name={0}*)(cn={0}*)))"; + ADUserAccount.LdapSearchFilterTemplate = "(&(objectCategory=Person)(objectClass=user)(|(sAMAccountName={0}*)(displayName={0}*)(sn={0}*)(givenName={0}*)))"; + } + // Determine Site var computerSite = ActiveDirectorySite.GetComputerSite(); this.Site = new ADSite(this, computerSite);