Настройка адресных книг CommuniGate Pro

В этой публикации я покажу, как выполняется настройка адресных книг 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: 6 комментариев

  1. А как сделать, чтобы эти адресные книги отображались в Outlook через mapi-connector?

    1. Добрый день! Насколько я понял из документации – никак 🙁 Адресная книга отображается только в веб клиенте. Мой ответ на абсолютную истину не претендует, но, по крайней мере в быстром доступе в документации я не нашел какого-то решения по отображению адресных книг в Outlook. В ходе локальных экспериментов на стендах тоже не нашел какого-то обходного решения.

  2. Решение по адресной книге (да костыльное но рабочее):
    Для этой задачи есть скрипт, который можно скачать в репозитории: https://www.communigate.ru/main/purchase/scriptrepository.html

    sweepMailboxes.pl – Удаляем почтовые сообщения удовлетворяющие шаблону у всех пользователей. Полезен если много аккаунтов поражено вирусом или если случайно отправили что-то всем пользователям (через all@).

  3. Ошибся кометном выше – по 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’));
    }

    1. Денис, спасибо за комментарий! В целом да – как один из вариантов вполне себе имеет место быть. Единственный нюанс, который я тут вижу – это синхронизация данных. Например, smtp адрес у пользователя в AD может поменяться. Судя по коду, тут предусмотрена какая-то логика обновления, но, честно, я её не тестировал. Или у вас уже по крону запускается этот скрипт и проблем при обновлении вы не испытывали?

Добавить комментарий

Ваш адрес email не будет опубликован.