Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle no ldap data exception #132

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 75 additions & 58 deletions src/CommonLib/LdapConnectionPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,84 +107,101 @@ public void Dispose() {
return CreateNewConnectionForServer(_ldapConfig.Server, globalCatalog);
}

if (CreateLdapConnection(_identifier.ToUpper().Trim(), globalCatalog, out var connectionWrapper)) {
_log.LogDebug("Successfully created ldap connection for domain: {Domain} using strategy 1. SSL: {SSl}", _identifier, connectionWrapper.Connection.SessionOptions.SecureSocketLayer);
return (true, connectionWrapper, "");
}

string tempDomainName;

var dsGetDcNameResult = _nativeMethods.CallDsGetDcName(null, _identifier,
(uint)(NetAPIEnums.DSGETDCNAME_FLAGS.DS_FORCE_REDISCOVERY |
NetAPIEnums.DSGETDCNAME_FLAGS.DS_RETURN_DNS_NAME |
NetAPIEnums.DSGETDCNAME_FLAGS.DS_DIRECTORY_SERVICE_REQUIRED));
if (dsGetDcNameResult.IsSuccess) {
tempDomainName = dsGetDcNameResult.Value.DomainName;
var hasDomainObject = LdapUtils.GetDomain(_identifier, _ldapConfig, out var domainObject);
var primaryDomainController = domainObject?.PdcRoleOwner.Name;
LdapConnectionWrapper connectionWrapper = null;

try {
if (CreateLdapConnection(_identifier.ToUpper().Trim(), globalCatalog, out connectionWrapper)) {
_log.LogDebug("Successfully created ldap connection for domain: {Domain} using strategy 1. SSL: {SSl}", _identifier, connectionWrapper.Connection.SessionOptions.SecureSocketLayer);
return (true, connectionWrapper, "");
}

string tempDomainName;

var dsGetDcNameResult = _nativeMethods.CallDsGetDcName(null, _identifier,
(uint)(NetAPIEnums.DSGETDCNAME_FLAGS.DS_FORCE_REDISCOVERY |
NetAPIEnums.DSGETDCNAME_FLAGS.DS_RETURN_DNS_NAME |
NetAPIEnums.DSGETDCNAME_FLAGS.DS_DIRECTORY_SERVICE_REQUIRED));
if (dsGetDcNameResult.IsSuccess) {
tempDomainName = dsGetDcNameResult.Value.DomainName;

if (!tempDomainName.Equals(_identifier, StringComparison.OrdinalIgnoreCase) &&
CreateLdapConnection(tempDomainName, globalCatalog, out connectionWrapper)) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 2 with name {NewName}",
_identifier, tempDomainName);
return (true, connectionWrapper, "");
}

var server = dsGetDcNameResult.Value.DomainControllerName.TrimStart('\\');

var result =
await CreateLDAPConnectionWithPortCheck(server, globalCatalog);
if (result.success) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 3 to server {Server}",
_identifier, server);
return (true, result.connection, "");
}
}

if (!hasDomainObject || domainObject.Name == null) {
//If we don't get a result here, we effectively have no other ways to resolve this domain, so we'll just have to exit out
_log.LogDebug(
"Could not get domain object from GetDomain, unable to create ldap connection for domain {Domain}",
_identifier);
return (false, null, "Unable to get domain object for further strategies");
}
tempDomainName = domainObject.Name.ToUpper().Trim();

if (!tempDomainName.Equals(_identifier, StringComparison.OrdinalIgnoreCase) &&
CreateLdapConnection(tempDomainName, globalCatalog, out connectionWrapper)) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 2 with name {NewName}",
"Successfully created ldap connection for domain: {Domain} using strategy 4 with name {NewName}",
_identifier, tempDomainName);
return (true, connectionWrapper, "");
}

var server = dsGetDcNameResult.Value.DomainControllerName.TrimStart('\\');

var result =
await CreateLDAPConnectionWithPortCheck(server, globalCatalog);
if (result.success) {
var portConnectionResult =
await CreateLDAPConnectionWithPortCheck(primaryDomainController, globalCatalog);
if (portConnectionResult.success) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 3 to server {Server}",
_identifier, server);
return (true, result.connection, "");
"Successfully created ldap connection for domain: {Domain} using strategy 5 with to pdc {Server}",
_identifier, primaryDomainController);
return (true, portConnectionResult.connection, "");
}
} catch (Exception e) {
_log.LogInformation(e, "Cannot connect to domain controller on {Domain}, trying another if available.", _identifier);
}

if (!LdapUtils.GetDomain(_identifier, _ldapConfig, out var domainObject) || domainObject.Name == null) {
//If we don't get a result here, we effectively have no other ways to resolve this domain, so we'll just have to exit out
_log.LogDebug(
"Could not get domain object from GetDomain, unable to create ldap connection for domain {Domain}",
_identifier);
return (false, null, "Unable to get domain object for further strategies");
}
tempDomainName = domainObject.Name.ToUpper().Trim();

if (!tempDomainName.Equals(_identifier, StringComparison.OrdinalIgnoreCase) &&
CreateLdapConnection(tempDomainName, globalCatalog, out connectionWrapper)) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 4 with name {NewName}",
_identifier, tempDomainName);
return (true, connectionWrapper, "");
}

var primaryDomainController = domainObject.PdcRoleOwner.Name;
var portConnectionResult =
await CreateLDAPConnectionWithPortCheck(primaryDomainController, globalCatalog);
if (portConnectionResult.success) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 5 with to pdc {Server}",
_identifier, primaryDomainController);
return (true, connectionWrapper, "");
}

foreach (DomainController dc in domainObject.DomainControllers) {
portConnectionResult =
foreach (DomainController dc in domainObject?.DomainControllers) {
try {
var portConnectionResult =
await CreateLDAPConnectionWithPortCheck(dc.Name, globalCatalog);
if (portConnectionResult.success) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 6 with to pdc {Server}",
_identifier, primaryDomainController);
return (true, connectionWrapper, "");

if (portConnectionResult.success) {
_log.LogDebug(
"Successfully created ldap connection for domain: {Domain} using strategy 6 with to pdc {Server}",
_identifier, primaryDomainController);
return (true, portConnectionResult.connection, "");
}
} catch (Exception e) {
_log.LogInformation(e, "Cannot connect to domain controller {DC} on {Domain}, trying another if available.", dc.Name, _identifier);
continue;
}
}

return (false, null, "All attempted connections failed");
}

private (bool Success, LdapConnectionWrapper Connection, string Message ) CreateNewConnectionForServer(string identifier, bool globalCatalog = false) {
if (CreateLdapConnection(identifier, globalCatalog, out var serverConnection)) {
return (true, serverConnection, "");
try {
if (CreateLdapConnection(identifier, globalCatalog, out var serverConnection)) {
return (true, serverConnection, "");
}
} catch {
// pass
}

return (false, null, $"Failed to create ldap connection for {identifier}");
Expand Down
Loading