Skip to content

Commit

Permalink
PingCastle 2.8.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
vletoux committed Feb 2, 2020
1 parent 19adb81 commit a49c7f8
Show file tree
Hide file tree
Showing 101 changed files with 9,068 additions and 7,895 deletions.
768 changes: 346 additions & 422 deletions ADWS/ADItem.cs

Large diffs are not rendered by default.

119 changes: 16 additions & 103 deletions ADWS/ADWSConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ private TopologyManagementClient Topology
// in a domain with W2003, ... not every server has ADWS installed
// each binding try to resolve the dns entry which is taking some time ..
// the trick is to test each ip and to assign a working one as the server
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public override void EstablishConnection()
{
if (Uri.CheckHostName(Server) != UriHostNameType.Dns)
Expand All @@ -179,121 +180,33 @@ public override void EstablishConnection()
GetDomainInfo();
return;
}
string initialServer = Server;
Trace.WriteLine("Server is a DNS entry. Checking for connectity on each ip resolved");
IPAddress[] addresses = null;
Domain domain = null;
Trace.WriteLine("Trying to locate the domain");
try
{
addresses = Dns.GetHostEntry(Server).AddressList;
}
catch (Exception ex)
{
Trace.WriteLine("Exception while resolving " + Server);
Trace.WriteLine(ex.Message);
Trace.WriteLine(ex.StackTrace);
throw new EndpointNotFoundException("Unable to resolve the DNS address of " + Server + " (" + ex.Message + ")");
}
if (addresses.Length <= 1)
{
Trace.WriteLine("Only one server found");
GetDomainInfo();
return;
}
foreach (IPAddress ip in addresses)
{
try
{
Server = ip.ToString();
Trace.WriteLine("Trying " + Server);
GetDomainInfo();
Trace.WriteLine("The connection worked");
return;
}
catch (EndpointNotFoundException ex)
if (Credential != null)
{
Trace.WriteLine("The connection didn't worked (EndpointNotFoundException)");
Trace.WriteLine("Exception: " + ex.Message);
CleanConnection<Resource>(_resource);
_resource = null;
domain = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, Server, Credential.UserName, Credential.Password));
}
catch (Exception ex)
else
{
Trace.WriteLine("Exception: " + ex.Message);
Trace.WriteLine("Type: " + ex.GetType().ToString());
Trace.WriteLine("The connection didn't worked");
CleanConnection<Resource>(_resource);
_resource = null;
domain = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, Server));
}
}
Trace.WriteLine("No connection worked");
Trace.WriteLine("Trying ldap to find DC (dns entries are limited by ad site)");
EstablishADWSConnectionUsingDomainConnection(initialServer, addresses);
}

[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
private void EstablishADWSConnectionUsingDomainConnection(string initialServer, IPAddress[] triedIPAddresses)
{
Domain domain = null;
try
{
domain = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, initialServer));
Trace.WriteLine("Domain located");
}
catch (ActiveDirectoryObjectNotFoundException ex)
{
Trace.WriteLine("Unable to get the domain info");
Trace.WriteLine("Unable to get the domain info - trying direct connection");
Trace.WriteLine("Exception: " + ex.Message);
Trace.WriteLine("Type: " + ex.GetType().ToString());
throw;
}
catch (Exception ex)
{
Trace.WriteLine("Unable to get the domain info");
Trace.WriteLine("Exception: " + ex.Message);
Trace.WriteLine("Type: " + ex.GetType().ToString());
}
string message = null;
if (domain == null)
{
Trace.WriteLine("Unable to connect to the domain. Trying manually some ip");
foreach (IPAddress ip in triedIPAddresses)
{
try
{
Trace.WriteLine("Ip tried: " + ip.ToString());
domain = Domain.GetDomain(new DirectoryContext(DirectoryContextType.DirectoryServer, ip.ToString()));
Trace.WriteLine("OK");
break;
}
catch (Exception ex)
{
Trace.WriteLine("Unable to get the domain info");
Trace.WriteLine("Exception: " + ex.Message);
Trace.WriteLine("Type: " + ex.GetType().ToString());
message = ex.Message;
}
}
}
if (domain == null)
{
throw new EndpointNotFoundException("The program was unable to connect to the server/domain " + initialServer + " to find ADWS server. Check that you have access to this domain. Do not forget that you can enter a specific domain controller in replacement of the domain name. (" + message + ")");
GetDomainInfo();
return;
}

foreach (DomainController dc in domain.FindAllDomainControllers())
Trace.WriteLine("Locating a DC");
Server = NativeMethods.GetDC(domain.Name, true, false);
for (int i = 0; i < 2; i++)
{
bool found = false;
for (int i = 0; i < triedIPAddresses.Length; i++)
{
if (triedIPAddresses[i].ToString() == dc.IPAddress)
{
found = true;
break;
}
}
if (found)
continue;
try
{
Server = dc.IPAddress;
Trace.WriteLine("Trying " + Server);
GetDomainInfo();
Trace.WriteLine("The connection worked");
Expand All @@ -313,9 +226,9 @@ private void EstablishADWSConnectionUsingDomainConnection(string initialServer,
CleanConnection<Resource>(_resource);
_resource = null;
}
if (i > 0)
Server = NativeMethods.GetDC(domain.Name, true, true);
}
Trace.WriteLine("No connection worked");
throw new EndpointNotFoundException("The connection to ADWS for " + initialServer + " didn't worked. Check that ADWS is installed in at least one server (by default since Windows 2008 R2, manually since Windows 2003) or that the port 9389 is not firewalled. Do not forget that you can enter a specific domain controller as a replacement for the domain name.");
}

public override void Enumerate(string distinguishedName, string filter, string[] properties, WorkOnReturnedObjectByADWS callback, string scope)
Expand Down
2 changes: 1 addition & 1 deletion ADWS/ADWebService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public enum ADConnectionType
LDAPThenADWS = 3,
}

internal class ADWebService : IDisposable, IADConnection
public class ADWebService : IDisposable, IADConnection
{

public ADWebService(string server, int port, NetworkCredential credential)
Expand Down
16 changes: 7 additions & 9 deletions ADWS/DomainLocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,20 @@ public DomainLocator(string server)

public bool LocateDomainFromNetbios(string netbios, out string domain, out string forest)
{
// DS_IS_FLAT_NAME = 0x00010000,
// DS_RETURN_DNS_NAME = 0x40000000,
// DS_ONLY_LDAP_NEEDED = 0x00008000,
return LocateSomething(netbios, out domain, out forest, 0x40018000);
return LocateSomething(netbios, out domain, out forest, NativeMethods.DSGETDCNAME_FLAGS.DS_IS_FLAT_NAME |
NativeMethods.DSGETDCNAME_FLAGS.DS_RETURN_DNS_NAME |
NativeMethods.DSGETDCNAME_FLAGS.DS_ONLY_LDAP_NEEDED);
}

public bool LocateNetbiosFromFQDN(string fqdn, out string netbios, out string forest)
{
// DS_IS_DNS_NAME = 0x00020000,
// DS_RETURN_FLAT_NAME = 0x80000000
// DS_ONLY_LDAP_NEEDED = 0x00008000,
return LocateSomething(fqdn, out netbios, out forest, 0x80028000);
return LocateSomething(fqdn, out netbios, out forest, NativeMethods.DSGETDCNAME_FLAGS.DS_IS_DNS_NAME |
NativeMethods.DSGETDCNAME_FLAGS.DS_RETURN_FLAT_NAME |
NativeMethods.DSGETDCNAME_FLAGS.DS_ONLY_LDAP_NEEDED);
}

[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
bool LocateSomething(string intput, out string domain, out string forest, uint flag)
bool LocateSomething(string intput, out string domain, out string forest, NativeMethods.DSGETDCNAME_FLAGS flag)
{
IntPtr DomainInfoResolution;
domain = null;
Expand Down
58 changes: 54 additions & 4 deletions ADWS/LDAPConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Permissions;
Expand Down Expand Up @@ -160,13 +162,61 @@ private ADDomainInfo GetLDAPDomainInfo()
}

// connecting using LDAP
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public override void EstablishConnection()
{
GetDomainInfo();
// in case the domain has been set (instead of the FQDN of the DC), set it to the DC for optimization purpose
if (Uri.CheckHostName(Server) == UriHostNameType.Dns)
var serverType= Uri.CheckHostName(Server);
if (serverType != UriHostNameType.Dns)
{
Trace.WriteLine("Server is not DNS - direct connection");
GetDomainInfo();
}
else
{
Server = domainInfo.DnsHostName;
Domain domain = null;
Trace.WriteLine("Trying to locate the domain");
try
{
if (Credential != null)
{
domain = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, Server, Credential.UserName, Credential.Password));
}
else
{
domain = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, Server));
}
Trace.WriteLine("Domain located");
}
catch (ActiveDirectoryObjectNotFoundException)
{
Trace.WriteLine("DcGetDCName was unable to find a DC using the FQDN - using the fqdn as server name");
// server is a FQDN
GetDomainInfo();
return;
}
var dc = domain.FindDomainController();
try
{
Server = dc.Name;
Trace.WriteLine("DsGetDCName returned " + Server);
GetDomainInfo();
}
catch (COMException ex)
{
// server not available - force rediscovery of DC
if ((uint)ex.ErrorCode == 0x8007203a)
{
Trace.WriteLine("Unable to connect - force rediscovery of DC");
dc = domain.FindDomainController(LocatorOptions.ForceRediscovery);
Server = dc.Name;
Trace.WriteLine("DsGetDCName returned " + Server);
GetDomainInfo();
}
else
{
throw;
}
}
}
}
}
Expand Down
Loading

0 comments on commit a49c7f8

Please sign in to comment.