Skip to content

Commit

Permalink
Investigating issue #87
Browse files Browse the repository at this point in the history
  • Loading branch information
Yvand committed Jul 18, 2019
1 parent a52aaaf commit 653e1d9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 33 deletions.
28 changes: 10 additions & 18 deletions LDAPCP/LDAPCP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,28 +1006,20 @@ protected virtual void SetLDAPConnection(Uri currentContext, LDAPConnection ldap
ldapConnection.AuthenticationSettings = ldapConnection.Directory.AuthenticationType;
}

// Operations in this block do LDAP queries, so let's monitor their execution time
// This block does LDAP operations
using (new SPMonitoredScope($"[{ProviderInternalName}] Get domain names / root container information about LDAP server \"{ldapConnection.Directory.Path}\"", 2000))
{
// Retrieve FQDN and domain name of current DirectoryEntry
string domainName = String.Empty;
string domainFQDN = String.Empty;
try
{
// Operations below may fail if LDAP server cannot be reached
// Cache those values for the whole lifetime of the process, because getting them triggers LDAP queries in the background
OperationContext.GetDomainInformation(ldapConnection.Directory, out domainName, out domainFQDN);
ldapConnection.DomainName = domainName;
ldapConnection.DomainFQDN = domainFQDN;
if (ldapConnection.Directory.Properties.Contains("distinguishedName"))
{
ldapConnection.RootContainer = ldapConnection.Directory.Properties["distinguishedName"].Value.ToString();
}
}
catch (Exception ex)
{
ClaimsProviderLogging.LogException(ProviderInternalName, $"while getting domain names information for LDAP connection {ldapConnection.Directory.Path}", TraceCategory.Configuration, ex);
}
string domaindistinguishedName = String.Empty;

// If there is no existing LDAPCP configuration, this method will be called each time (LDAPConnection properties will be null)
OperationContext.GetDomainInformation(ldapConnection.Directory, out domaindistinguishedName, out domainName, out domainFQDN);
// Cache those values for the whole lifetime of the process, because getting them requires LDAP operations
ldapConnection.RootContainer = domaindistinguishedName;
ldapConnection.DomainName = domainName;
ldapConnection.DomainFQDN = domainFQDN;
}
}

Expand Down Expand Up @@ -1256,7 +1248,7 @@ protected virtual List<SPClaim> GetGroupsFromActiveDirectory(LDAPConnection ldap
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
UserPrincipal adUser = null;
PrincipalContext principalContext = null;
PrincipalContext principalContext = null;
try
{
using (new SPMonitoredScope($"[{ProviderInternalName}] Get AD Principal of user {currentContext.IncomingEntity.Value} " + directoryDetails, 1000))
Expand Down
60 changes: 45 additions & 15 deletions LDAPCP/LDAPCPConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,9 @@ public void ApplyConfiguration(LDAPCPConfig configToApply)
{
object value = property.GetValue(configToApply);
if (value != null)
{
property.SetValue(this, value);
}
}
}

Expand Down Expand Up @@ -1254,24 +1256,52 @@ public static void GetDomainInformation(string distinguishedName, out string dom
/// <param name="directory">LDAP Server to query</param>
/// <param name="domainName">Domain name</param>
/// <param name="domainFQDN">Fully qualified domain name</param>
public static void GetDomainInformation(DirectoryEntry directory, out string domainName, out string domainFQDN)
public static void GetDomainInformation(DirectoryEntry directory, out string domaindistinguishedName, out string domainName, out string domainFQDN)
{
string distinguishedName = String.Empty;
domainName = domainFQDN = String.Empty;
// Method PropertyCollection.Contains("distinguishedName") does a LDAP bind behind the scene
if (directory.Properties.Contains("distinguishedName"))
{
distinguishedName = directory.Properties["distinguishedName"].Value.ToString();
GetDomainInformation(distinguishedName, out domainName, out domainFQDN);
}
else
bool success = false;
domaindistinguishedName = String.Empty;
domainName = String.Empty;
domainFQDN = String.Empty;
int count = 0;
do
{
// This logic to get the domainName may not work with AD LDS:
// if distinguishedName = "CN=Partition1,DC=MyLDS,DC=local", then both "name" and "cn" = "Partition1", while we expect "MyLDS"
// So now it's only made if the distinguishedName is not available (very unlikely codepath)
if (directory.Properties.Contains("name")) domainName = directory.Properties["name"].Value.ToString();
else if (directory.Properties.Contains("cn")) domainName = directory.Properties["cn"].Value.ToString(); // Tivoli sets domain name in cn property (property name does not exist)
count++;
try
{
#if DEBUG
directory.AuthenticationType = AuthenticationTypes.None;
ClaimsProviderLogging.Log($"directory.AuthenticationType = {directory.AuthenticationType}", TraceSeverity.Unexpected, EventSeverity.Error, TraceCategory.Configuration);
#endif

// Method PropertyCollection.Contains("distinguishedName") does a LDAP bind
// In AD LDS: property "distinguishedName" = "CN=LDSInstance2,DC=ADLDS,DC=local", properties "name" and "cn" = "LDSInstance2"
if (directory.Properties.Contains("distinguishedName"))
{
domaindistinguishedName = directory.Properties["distinguishedName"].Value.ToString();
GetDomainInformation(domaindistinguishedName, out domainName, out domainFQDN);
}
else if (directory.Properties.Contains("name"))
{
domainName = directory.Properties["name"].Value.ToString();
}
else if (directory.Properties.Contains("cn"))
{
// Tivoli stores domain name in property "cn" (properties "distinguishedName" and "name" don't exist)
domainName = directory.Properties["cn"].Value.ToString();
}

success = true;
}
catch (DirectoryServicesCOMException ex)
{
ClaimsProviderLogging.LogException("", $"while getting domain names information for LDAP connection {directory.Path} (DirectoryServicesCOMException) at attempt {count}", TraceCategory.Configuration, ex);
}
catch (Exception ex)
{
ClaimsProviderLogging.LogException("", $"while getting domain names information for LDAP connection {directory.Path} (Exception) at attempt {count}", TraceCategory.Configuration, ex);
}
}
while (success == false && count < 5);
}

/// <summary>
Expand Down

0 comments on commit 653e1d9

Please sign in to comment.