В этой публикации я покажу, как выполняется настройка адресных книг CommuniGate. Как ни странно, но когда я начал разбираться с этим вопросом, то не нашел адекватного руководства. Да, есть раздел в документации, но он довольно поверхностно касается процесса настройки.
Поэтому я решил описать базовый пример настройки адресных книг на основе внешнего LDAP. В моем случае это будет Active Directory.
В комментариях коллеги предложили альтернативный вариант настройки – через синхронизацию директории (или нескольких директорий) в локальную адресную книгу CommuniGate. Если кратко – вы запускаете скрипт convLDAPAddrBook.pl, который есть в библиотеки скриптов. В этом скрипте вы указываете параметры подключения к директории (или директориям) и параметры адресной книги CommuniGate. Есть логика обновления записей. Настроить расписание можно, например, через Cron.
Общий принцип работы адресных книг
Работа адресных книг CommuniGate Pro основана на Справочнике. Для конечных клиентов справочник представляет единую сущность. В действительности же отдельные узлы справочника могут храниться в разных томах. Справочник поддерживает как локальные, так и удаленные тома. Для реализации адресной книги на основе данных из Active Directory нам будет нужен именно удаленный том.
Наглядно связать работу справочника, локальных и удаленных томов можно следующей схемой:

т.е. у CommuniGate есть некоторое локальное представление справочника. В иерархию локального справочника можно добавить любую провизвольную ветвь. Например, company. По факту ветвь company ссылается на удаленный том, который подключен к Active Directory.
Другие примеры приведены в документации к продукту.
Настройка адресных книг CommuniGate
Для примера настроим следующие адресные книги:
- Все пользователи (с электронной почтой).
- Все группы (с электронной почтой).
Для настройки фильтрации нам понадобятся условия для LDAP фильтрации. Ниже приведены условия фильтрации для выборки всех пользователей с электронной почтой:
(&(objectCategory=person)(mail=*)(objectClass=user))
А это условия для выборки всех групп с электронной почтой:
(&(objectCategory=group)(objectClass=group)(mail=*))
Эти условия LDAP фильтрации понадобятся нам чуть ниже.
Настройка необходимых томов
Как выполняется настройка:
1. Подключаемся к веб интерфейсу администрирования CommuniGate.
2. Переходим в следующий раздел – Directory -> Units.
3. Заполняем поле “Unit Name” и “Subtree”. Первое поле просто содержит название тома (без пробелов), а во втором поле содержится важная деталь – путь до тома в иерархии CommuniGate. ВНам понадобится это начение в дальнейшем. Нажимаем кнопку “Create Remote Unit”.

4. Переходим в только что созданный справочник.

5. Заполняет следующие поля:
Параметр | Значение |
LDAP Server Name | Адрес сервера LDAP (контроллер домена в моем случае) для подключения. |
Server Subtree | Иерархия от которой начнется поиск объектов |
Bind DN | Имя пользователя для подключения к серверу LDAP (в формате distinguishedName) |
Bind Password | Пароль пользователя для подключения к серверу LDAP |
Search Filter | Условия выборки объектов. Напомню. Фильтр для выборки всех пользователей с почтой: (&(objectCategory=person)(mail=*)(objectClass=user)) Фильтр для выборки всех групп с почтой: (&(objectCategory=group)(objectClass=group)(mail=*)) |
Protocol Version | Версия протокола для подключения к LDAP |
Пример моих настроек:

6. Сохраняем внесенные изменения.
7. Повторно выполняем шаги для 3-6 только в этот раз используем условия LDAP фильтрации для групп и в качестве Subtree испольузем значение o=allgroups,o=contacts (вы можете использовать любое другое).
8. По итогу у нас должны появиться два новых тома:

Подключение адресных книг в настройках пользователей
После того, как мы настроили тома и условия LDAP фильтрации мы можем выполнить непосредственное подключение адресных книг.
Приступим:
1. Подключаемся к веб интерфейсу администрирования CommuniGate.
2. Переходим в следующий раздел – Users -> Account Defaults -> Preferences.
3. В секции “Contacts” добавим две новые записи адресных книг:

Обратите внимание на значение столбца “Search Base” – это и есть тот Subtree, что мы указывали при создании тома выше.
4. Сохраняем внесенные изменения.
Проверка адресных книг CommuniGate
Теперь давайте посмотрим как адресные книги выглядят глазами пользователей:
1. Запускаем веб клиент Samoware.
2. Перейдем в раздел “Contacts” – “All Groups”.

Здесь должны отобразится все наши почтовые группы (если мы все настроили верно). Обратите внимание, что отображаются как группы рассылки, так и группы безопасности, для которых включена почта.
3. Теперь проверим список пользователей – “Contacts” – “All Users”.

Поскольку я выбрал вообще всех пользователей, то в списке отображаются даже специальные почтовые ящики Exchange.
Настройка адресных книг завершена. По образу и подобию вы можете выполнить настройку адресных книг, которые нужны именно для ваших целей.
Настройка адресных книг CommuniGate Pro: 11 комментариев
А как сделать, чтобы эти адресные книги отображались в Outlook через mapi-connector?
Добрый день! Насколько я понял из документации – никак 🙁 Адресная книга отображается только в веб клиенте. Мой ответ на абсолютную истину не претендует, но, по крайней мере в быстром доступе в документации я не нашел какого-то решения по отображению адресных книг в Outlook. В ходе локальных экспериментов на стендах тоже не нашел какого-то обходного решения.
В версии 6.3.16 и обновленном MAPI коннекторе есть возможность указания поддерева(адресной книги) которую можно создать на удаленном томе, указав LDAP сервер AD.
В более старых версиях такая возможность тоже заявлена https://communigate.ru/CommuniGatePro/russian/Directory.html#RemoteRoot
Добрый день! Спасибо за обратную связь! В ближайшее время постраюсь дополнить статью.
Решение по адресной книге (да костыльное но рабочее):
Для этой задачи есть скрипт, который можно скачать в репозитории: https://www.communigate.ru/main/purchase/scriptrepository.html
sweepMailboxes.pl – Удаляем почтовые сообщения удовлетворяющие шаблону у всех пользователей. Полезен если много аккаунтов поражено вирусом или если случайно отправили что-то всем пользователям (через all@).
Ошибся кометном выше – по mapi:
#!/usr/bin/perl -w
#
# ldapMerge.pl
#
# A script for merging several Directory branches (possible on
# different servers) into one to use as address book.
#
# Please mail your comments to
use Net::LDAP;
use strict;
#
# You should redefine these values
#
my $TargetServerAddress = ‘10.3.8.1’; # You should redefine these values
my $TargetServerLogin = ‘postmaster’;
my $TargetServerPassword = ‘pass’;
my $TargetServerBaseDN = ‘o=common_addressbook’;
my @Sources = (
{ address => ‘10.3.1.216’,
bindDN => ‘postmaster’,
password => ‘admin’,
base => ‘cn=d.dom’
},
{ address => ‘10.3.1.216’,
bindDN => ‘postmaster’,
password => ‘admin’,
base => ‘cn=somedom.ru’
},
);
my @attributesToReturn = qw/
mail
cn
sn
description
telephoneNumber
l st street ou title
postalAddress postalCode
o
givenName
initials
uid
mobile
photo
jpegPhoto
userCertificate
displayName
/;
#
# END of user customiseable parameters
#
#print “Started\n”;
my %cgpData;
my %extData;
my $result;
foreach my $ref (@Sources) {
print “Reading from external LDAP server at $ref->{address} $ref->{base}\n”;
my $eldap = Net::LDAP->new($ref->{address}, port=>389)
|| die “can’t connect to $ref->{address} via LDAP: $@”;
$result=$eldap->bind($ref->{bindDN},password=>$ref->{password} );
$result && $result->code && die “Can’t bind as $ref->bindDN: “.$result->error;
my @args = (
base => $ref->{base},
scope => ‘sub’,
filter => ‘(&(objectClass=inetOrgPerson)(mail=*)(!(|(objectClass=CommuniGateNamedTask)(objectClass=CommuniGateGroup)(objectClass=CommuniGateMailList)(objectClass=CommuniGateForwarder))))’,
attrs => \@attributesToReturn,
);
my $cnt = 0;
my $mesg = $eldap->search( @args );
$mesg->code && print “search failed: “.$mesg->error.”\n”;
foreach my $entry ($mesg->entries) {
$extData{ makeDN($entry) } = $entry;
++$cnt;
}
$eldap->unbind();
print ” $cnt records have been read\n”;
}
my $ldap = Net::LDAP->new($TargetServerAddress, port=>389)
|| die “can’t connect to $TargetServerAddress via LDAP: $@”;
$result=$ldap->bind($TargetServerLogin,password=>$TargetServerPassword );
$result && $result->code && die “Can’t bind as $TargetServerLogin: “.$result->error;
$result = $ldap->add ( $TargetServerBaseDN , attrs => [ ou => “address book”, objectClass => [ “top”,”organizationalUnit” ] ] );
{
print “Reading from CGPro at $TargetServerAddress\n”;
my @args = (
base => $TargetServerBaseDN,
scope => ‘sub’,
filter => ‘(objectClass=*)’,
);
my $cnt = 0;
my $mesg = $ldap->search( @args );
$mesg->code && print “search failed: “.$mesg->error.”\n”;
foreach my $entry ($mesg->entries) {
$cgpData{ $entry->dn() } = $entry;
++$cnt;
}
print ” $cnt records have been read\n”;
}
{
my $cntAdd = 0;
my $cntUpd = 0;
foreach my $cdn (keys %extData) {
my $dn = “uid=$cdn,$TargetServerBaseDN”;
unless(exists $cgpData{$dn}) {
print “adding $dn\n”;
my $CreateArray = [
objectClass => [ “top”, “person”, “organizationalPerson”, “inetOrgPerson” ],
];
foreach my $attr ( $extData{$cdn}->attributes ) {
push(@$CreateArray,$attr,$extData{$cdn}->get_value($attr));
}
$result = $ldap->add ( $dn , attrs => [@$CreateArray] );
if($result->code) {
print “Can’t add $dn: “.$result->error.”\n”;
} else {
++$cntAdd;
}
} else {
my %changes;
foreach my $attr ( $extData{$cdn}->attributes ) {
next if($attr eq ‘uid’);
my $v = $extData{$cdn}->get_value($attr);
my $v2 = $cgpData{$dn}->get_value($attr);
if(!defined($v2) || $v2 ne $v) {
$changes{$attr} = $v;
}
}
if(%changes) {
print “updating $dn\n”;
$result = $ldap->modify ( $dn, replace => { %changes } );
if($result->code) {
print “Can’t update $dn: “.$result->error.”\n”;
} else {
++$cntUpd;
}
}
}
}
print ” $cntAdd records have been added, $cntUpd records have been updated\n”;
}
{
my $cntDel = 0;
foreach my $dn (keys %cgpData) {
$dn=~/uid=(.*),$TargetServerBaseDN/;
my $cdn = $1;
unless(exists $extData{$cdn}) {
print “deleting $dn\n”;
$cgpData{$dn}->delete();
$result = $cgpData{$dn}->update ( $ldap );
if($result->code) {
print “Can’t delete $dn: “.$result->error.”\n”;
} else {
++$cntDel;
}
}
}
print ” $cntDel records have been deleted\n”;
}
$ldap->unbind();
print “Done\n”;
exit(0);
sub makeDN {
my ($entry) = @_;
my $v = ($entry->get_value(‘cn’) ne ‘none’ ? $entry->get_value(‘cn’).’ ‘ : ”);
return $v.join(” “,$entry->get_value(‘mail’));
}
Денис, спасибо за комментарий! В целом да – как один из вариантов вполне себе имеет место быть. Единственный нюанс, который я тут вижу – это синхронизация данных. Например, smtp адрес у пользователя в AD может поменяться. Судя по коду, тут предусмотрена какая-то логика обновления, но, честно, я её не тестировал. Или у вас уже по крону запускается этот скрипт и проблем при обновлении вы не испытывали?
Да скрипт нужно по крону запускать периодически
Всё супер Денис, я настроил первый сервер – мой тестовый DC на MS, второй сервер – он же. а сервер приёмник – мой CommGatePro. Единственно сделал bind под домен админом т.к. тестовый стенд мне было удобно. В результате работы у меня скрипт очистил AD полностью, постирав пользователей, а в адресную книгу CommGatePro – никого не внёс)).
Не увидел в статье решения для кол-ва записей в адресной книге больше 1000. Не все имена отображаются 🙁
Добрый день нашлось ли решения по данной проблеме?