Я использую C# 3.0 и пространство имен System.DirectoryServices
(а не новое пространство имен System.DirectoryServices.AccountManagement
.NET 3.5). Как я могу найти все SMTP-серверы в локальном домене? Возможно ли это? Есть ли другой способ сделать это?C# 3.0: Найти SMTP-серверы в домене
ответ
Я не думаю, что вы можете сделать это с помощью DirectoryServices.
Один из вариантов - попытаться подключиться к каждому серверу в домене SMTP-порта (25) и посмотреть, отвечают ли они на стандартные команды SMTP. Это можно легко сделать с помощью класса TcpClient, если у вас есть список компьютеров в домене.
Конечно, что бы не найти серверы, не используя стандартный порт (но если сервер не использует стандартный порт, он не может быть заинтересован в том, нашли в первую очередь :-)
Сомневаюсь что серверы домена явно публиковать факт, что они SMTP-серверы (возможно, я ошибаюсь), хотя решение должно быть довольно простым.
- Найти каждый сервер в активном домене.
- Попытка подключения к серверу на порту 25 (SMTP).
- Ждите ответа
220
, что указывает на то, что сервер готов. (См. Протокол RFC document.) Если вы получили эту команду в течение определенного времени после подключения (скажем, 3 секунды), вы можете сделать вывод, что текущий компьютер является SMTP-сервером.
Надеюсь, что это поможет.
Другой подход должен был бы сделать DNS MX (Mail обмена запись) запросов, чтобы найти SMTP-серверы для данного домена:
На основании предложения нолдорин, вот некоторые код, примечание Я просто подключаюсь к 25, я не жду 220 от сервера. Это работало в нашем домене. Это жестокое регулярное выражение, чтобы получить имя сервера на основе пути LDAP.
static void Main()
{
DirectorySearcher ds = new DirectorySearcher("");
ds.Filter = "objectCategory=computer";
SearchResultCollection results = ds.FindAll();
foreach (SearchResult result in results)
{
string pattern = @"(?<=LDAP://CN=)(?<serverName>\w*)(?=,*)";
Match m = Regex.Match(result.Path, pattern);
string serverName = m.Groups["serverName"].Value;
System.Net.Sockets.TcpClient tcp = new System.Net.Sockets.TcpClient();
try
{
tcp.Connect(serverName, 25);
if (tcp.Connected)
{
Console.WriteLine(String.Format("Connected to {0} on Port 25", serverName));
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
finally
{
tcp.Close();
}
}
Console.WriteLine("Done.");
Console.ReadLine();
}
Кроме того, я думаю, что FindAll страдает от обычного AD ограничение, которое в 1000 результатов, поэтому если у вас есть более чем 1000 серверов в домене, возможно, придется переделывать
Если вы хотите найти почтовый сервер домена для отправки почты в этот домен, а затем использовать DNS MX - это путь, как уже предполагал mjmarh. Если вы хотите идентифицировать все произвольные службы SMTP в своем домене с помощью AD, вы можете использовать тот факт, что большинство SMTP-серверов регистрируются в AD, например Exchange, и вы можете опросить службы AD, чтобы узнать их местоположение. Например, в этом техническом документе объясняется, как клиенты Outlook обнаруживают свой сервер почтовых ящиков с помощью активных каталогов: http://technet.microsoft.com/en-us/library/bb332063.aspx В определенном домене, выполняющем сканирование портов на всех компьютерах, будет освещен любой механизм обнаружения вторжений, который у них есть как Рождественская елка, и вы можете оказаться в своем приложении сетевой адрес отключен.
Следует отметить, что такое сетевое сканирование, как правило, неодобрительно относится к моим ИТ-специалистам и может приземлить вас в горячей воде, если они обнаружат это. – cyberconte
@cyberconte: Это может быть единственный способ, однако. Пока вы кешируете результаты, это не должно быть большой проблемой. – Noldorin