Make auto-discovery cross-platform (Windows + Linux)
This commit is contained in:
+150
-29
@@ -1,4 +1,6 @@
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Runtime.InteropServices;
|
||||
using ADBulkTool.Models;
|
||||
using DnsClient;
|
||||
|
||||
@@ -16,7 +18,7 @@ public static class DomainDiscovery
|
||||
if (string.IsNullOrWhiteSpace(domain))
|
||||
{
|
||||
return new DiscoveryResult(null, null, null, null, null,
|
||||
"Could not detect a DNS domain from this machine. Check that you are on a domain-joined network and that /etc/resolv.conf has a search or domain entry.");
|
||||
"Could not detect a DNS domain. Ensure the machine is on a domain network with a proper DNS configuration.");
|
||||
}
|
||||
|
||||
steps.Add($"Detected domain: {domain}");
|
||||
@@ -27,8 +29,8 @@ public static class DomainDiscovery
|
||||
var dnsServers = GetDnsServers();
|
||||
var dnsServer = dnsServers.FirstOrDefault();
|
||||
steps.Add(dnsServer is not null
|
||||
? $"DNS server from /etc/resolv.conf: {dnsServer}"
|
||||
: "No DNS server found in /etc/resolv.conf, using system default.");
|
||||
? $"DNS server found: {dnsServer}"
|
||||
: "No DNS server found, using system default resolver.");
|
||||
|
||||
var ldapHost = await FindDomainControllerViaSrvAsync(domain, dnsServer, timeout);
|
||||
|
||||
@@ -62,29 +64,12 @@ public static class DomainDiscovery
|
||||
|
||||
public static List<string> GetDnsServers()
|
||||
{
|
||||
var servers = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
var lines = File.ReadAllLines("/etc/resolv.conf");
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var trimmed = line.Trim();
|
||||
if (trimmed.StartsWith("nameserver ", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var parts = trimmed.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
if (parts.Length >= 2 && IPAddress.TryParse(parts[1], out _))
|
||||
{
|
||||
servers.Add(parts[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return GetDnsServersWindows();
|
||||
}
|
||||
|
||||
return servers;
|
||||
return GetDnsServersLinux();
|
||||
}
|
||||
|
||||
public static string? DomainToSearchBase(string? domain)
|
||||
@@ -109,10 +94,22 @@ public static class DomainDiscovery
|
||||
{
|
||||
using var cts = new CancellationTokenSource(timeout);
|
||||
|
||||
var resolvDomain = await Task.Run(() => GetDomainFromResolvConf(), cts.Token);
|
||||
if (!string.IsNullOrWhiteSpace(resolvDomain))
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return resolvDomain;
|
||||
var resolvDomain = await Task.Run(() => GetDomainFromResolvConf(), cts.Token);
|
||||
if (!string.IsNullOrWhiteSpace(resolvDomain))
|
||||
{
|
||||
return resolvDomain;
|
||||
}
|
||||
}
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var winDomain = await Task.Run(() => GetDomainFromWindows(), cts.Token);
|
||||
if (!string.IsNullOrWhiteSpace(winDomain))
|
||||
{
|
||||
return winDomain;
|
||||
}
|
||||
}
|
||||
|
||||
var hostDomain = await Task.Run(() => GetDomainFromHostname(), cts.Token);
|
||||
@@ -123,8 +120,14 @@ public static class DomainDiscovery
|
||||
|
||||
var ipDomain = await Task.Run(() =>
|
||||
{
|
||||
try { return System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName; }
|
||||
catch { return string.Empty; }
|
||||
try
|
||||
{
|
||||
return IPGlobalProperties.GetIPGlobalProperties().DomainName;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}, cts.Token);
|
||||
if (!string.IsNullOrWhiteSpace(ipDomain) && !string.Equals(ipDomain, "localdomain", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -139,6 +142,68 @@ public static class DomainDiscovery
|
||||
}
|
||||
}
|
||||
|
||||
private static List<string> GetDnsServersWindows()
|
||||
{
|
||||
var servers = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
if (ni.OperationalStatus != OperationalStatus.Up)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var props = ni.GetIPProperties();
|
||||
if (props is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var dns in props.DnsAddresses)
|
||||
{
|
||||
if (dns.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !servers.Contains(dns.ToString()))
|
||||
{
|
||||
servers.Add(dns.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return servers;
|
||||
}
|
||||
|
||||
private static List<string> GetDnsServersLinux()
|
||||
{
|
||||
var servers = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
var lines = File.ReadAllLines("/etc/resolv.conf");
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var trimmed = line.Trim();
|
||||
if (trimmed.StartsWith("nameserver ", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var parts = trimmed.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
if (parts.Length >= 2 && IPAddress.TryParse(parts[1], out _))
|
||||
{
|
||||
servers.Add(parts[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return servers;
|
||||
}
|
||||
|
||||
private static string? GetDomainFromResolvConf()
|
||||
{
|
||||
try
|
||||
@@ -174,6 +239,62 @@ public static class DomainDiscovery
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string? GetDomainFromWindows()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
if (ni.OperationalStatus != OperationalStatus.Up)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var props = ni.GetIPProperties();
|
||||
if (props is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var suffix = props.DnsSuffix;
|
||||
if (!string.IsNullOrWhiteSpace(suffix))
|
||||
{
|
||||
return suffix.TrimEnd('.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416 // Registry access is guarded by platform check
|
||||
try
|
||||
{
|
||||
using var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
|
||||
@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters");
|
||||
if (key is not null)
|
||||
{
|
||||
var domain = key.GetValue("Domain") as string;
|
||||
if (!string.IsNullOrWhiteSpace(domain))
|
||||
{
|
||||
return domain.TrimEnd('.');
|
||||
}
|
||||
|
||||
var dhcpDomain = key.GetValue("DhcpDomain") as string;
|
||||
if (!string.IsNullOrWhiteSpace(dhcpDomain))
|
||||
{
|
||||
return dhcpDomain.TrimEnd('.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
#pragma warning restore CA1416
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string? GetDomainFromHostname()
|
||||
{
|
||||
try
|
||||
@@ -192,7 +313,7 @@ public static class DomainDiscovery
|
||||
|
||||
try
|
||||
{
|
||||
var fullHostname = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().HostName;
|
||||
var fullHostname = IPGlobalProperties.GetIPGlobalProperties().HostName;
|
||||
var dotIndex = fullHostname.IndexOf('.');
|
||||
if (dotIndex > 0 && dotIndex < fullHostname.Length - 1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user