Thunderbird. Автоконфигурация для пользователей AD

5 мин на чтение

В один из прекрасных дней передо мной и еще парой человек встала нетривиальная задача переноса почты с одного сервера на другой. Все бы было ничего, если бы в качестве принимающего сервера был Exchange, а почтовые клиенты везде стояли Outlook. В нашем же случае Outlook использовался только на 40-45% ПК, на остальных был настроен и активно использовался Thunderbird.

Число пользователей зашкаливало за 400 человек, а число «бегающих мальчиков» не превышало 5. Но на нашей стороне были умение гуглить, настойчивость и просто желание постичь что-нибудь новое. Первым делом была нагуглена статья по автонастройке Thunderbird на хабре, но код, который в ней предоставлен, из-коробки заработал только после допиливания напильником :)
Самая главная проблема данной статьи заключалась в том, что код, представленный в ней затирал первый ящик, что нам делать было крайне нежелательно, т.к. почту переносить должен был сам пользователь (лимиты ящиков на новом сервере и все такое…). Так же хотелось автоматизировать заполнение логина и подставление почты из AD.

Чтож, перейду ближе к делу: на сервере был развернут Apache и perl. Все делается стандартно. Код скрипта можно наблюдать ниже. Код слегка прокомментирован, так что разобраться будет не так сложно.

#!/usr/bin/perl
use 5.010;
use CGI qw/:standard/;
use warnings;
use autodie;

use Net::LDAP;

# Параметры
$smtp_server = "smtp.server.addr";
$imap_server = "imap.server.addr";
$organization = "ЗАО «Рога и копыта»";

# Прикидываемся жаваскриптом
print header(
-type=>'application/javascript',
-charset=>'utf-8'
);

# Username - из GET переменных
$user = param('user');
unless ($user) { die "We need a user, please!\n" }

# Нам нужен user в lovercase, иначе будут проблемы с большинством IMAP серверов. Поскольку username берётся
# из переменной глупейшей винды, то там может быть любое награмождение заглавных и строчных букв.
$user = lc $user;

#########################################################################
# Создаём конечный конфигурационный файл

#Подключаемся к LDAP и вытягиваем данные пользователя
my $server = "server_ip";
my $ldap = Net::LDAP->new( $server ) or die $@;
$ldap->bind ('user_name@domain.name.loc',
password => 'Password'
);
my $result = $ldap->search(
base => "dc=domain,dc=name,dc=loc",
scope => "subtree",
filter => "(&(objectclass=user)(objectcategory=Person) (sAMAccountName=$user))",
);

die $result->error if $result->code;

foreach my $entry ($result->entries) {
$FIO=$entry->get_value("displayName"),
($umail=$entry->get_value("mail") || '');
}

$ldap->unbind;

print <<HEAD;
//Параметры автонастройки Thunderbird для пользователя $user ($name)
try {
HEAD

# Настройки серверов
# Аккаунт и SMTP сервер добавляется в список уже присутствующих аккаунтов и SMTP серверов соответственно
# с помощью весьма нехитрой конструкции на JavaScript.
# Это нужно для того, чтобы пользователь мог добавлять свои собственные аккаунты вручную в клиент. Если
# заблокировать mail.accountmanager.accounts или mail.smtpservers, то сделать это будет невозможно.
print <<SERVERS;
// Основные параметры настройки серверов

// Добавляем аккаунт в список уже подключённых аккаунтов, если его там ещё нет
var accounts = "account1,account2,account3,account4,account5,account6,account7,account8,account9,account99"
pref("mail.accountmanager.accounts",accounts);

// Настройки IMAP сервера
lockPref("mail.server.server99.type", "imap");
lockPref("mail.server.server99.hostname", "$imap_server"); // Неизвестно, зачем два параметра, но нужны оба,
lockPref("mail.server.server99.realhostname", "$imap_server"); // иначе можно будет менять пользователю
lockPref("mail.server.server99.port", 993); // Порт сервера
lockPref("mail.server.server99.socketType", 3); // Использовать STARTLS
lockPref("mail.server.server99.name", "$umail");
lockPref("mail.server.server99.userName", "$user"); // Логин пользователя,
lockPref("mail.server.server99.realuserName", "$user"); // комментарий аналогично hostname
lockPref("mail.server.server99.login_at_startup", true); // Очень важный параметр! Без него вообще не заработает ничерта;)
lockPref("mail.server.server99.using_subscription", false); //Показ всех папок на сервере

// Привязываем указанный IMAP сервер к аккаунту
lockPref("mail.account.account99.server", "server99");

// Настройки SMTP сервера
lockPref("mail.smtpserver.smtp99.hostname", "$smtp_server");
lockPref("mail.smtpserver.smtp99.port", 587);
lockPref("mail.smtpserver.smtp99.description", "SMTP сервер $organization");
lockPref("mail.smtpserver.smtp99.try_ssl", 2);
lockPref("mail.smtpserver.smtp99.auth_method", 6);
lockPref("mail.smtpserver.smtp99.username", "$user");

// Добавляем SMTP в список
pref("mail.smtpservers", "smtp99,smtp1,smtp2,smtp3,smtp4");

SERVERS

# Различные настройки клиента
print <<MISC;
// Отключаем полосочку "Узнайте о своих правах" при первом запуске
lockPref("mail.rights.version", 1);
// Отключаем автообновление
lockPref("app.update.enabled", false);
lockPref("extensions.update.enabled", false);
// Ставим в качестве сервера локальных папок основной IMAP сервер пользователя,
// тем самым полностью отключая локальные папки в клиенте
lockPref("mail.accountmanager.localfoldersserver", "server99");
// Блокируем корпоративный аккаунт почты в качестве основного аккаунта TB
lockPref("mail.accountmanager.defaultaccount", "account99");
// Ставим в качестве сервера локальных папок основной IMAP сервер пользователя,
// тем самым полностью отключая локальные папки в клиенте
lockPref("mail.accountmanager.localfoldersserver", "server99");

MISC

print <<ID;

pref("mail.identity.id","id99");

// Адрес $mail для пользователя $user ($FIO)
defaultPref("mail.identity.id99.fullName", "$FIO");
lockPref("mail.identity.id99.useremail", "$umail");
lockPref("mail.identity.id99.reply_to", "$umail");
lockPref("mail.identity.id99.valid", true);
lockPref("mail.identity.id99.smtpServer", "smtp99");
lockPref("mail.identity.id99.organization", "$organization");
lockPref("mail.identity.id99.archive_folder", "imap://$user\@$imap_server/Archives");
lockPref("mail.identity.id99.draft_folder", "imap://$user\@$imap_server/Draft");
lockPref("mail.identity.id99.drafts_folder_picker_mode", 0);
lockPref("mail.identity.id99.fcc_folder", "imap://$user\@$imap_server/Sent");
lockPref("mail.identity.id99.fcc_folder_picker_mode", 0);
lockPref("mail.identity.id99.stationery_folder", "imap://$user\@$imap_server/Templates");

ID
print <<IDS;
// Все доступные для этого аккаунта адреса
lockPref("mail.account.account99.identities", "id99");

IDS

# Адресные книги LDAP
print <<BOOKS;
// Адресная книга сотрудников
lockPref("ldap_2.servers.domain.uri", "ldap://ip.server:3268/DC=domain,DC=name,DC=loc??sub?(mail=*)");
lockPref("ldap_2.servers.domain.auth.dn", "$user\@domain.name.loc");
lockPref("ldap_2.servers.domain.auth.saslmech", " ");
lockPref("ldap_2.servers.domain.description", "Domain_address_book");
lockPref("ldap_2.servers.domain.filename", "empl.mab");
lockPref("ldap_2.servers.domain.maxHits", 1000);

// Автодополнение адресов из книги сотрудников
lockPref("ldap_2.autoComplete.directoryServer", "ldap_2.servers.domain");
lockPref("ldap_2.autoComplete.useDirectory", true);

BOOKS

print <<TAIL;
} catch(e) {
displayError("lockedPref", e);
}
TAIL