Ниже приведён пример программы на языке C, которая использует библиотеку libdomain для выполнения операции поиска LDAP. Программа устанавливает соединение с сервером LDAP и выполняет запрос на поиск для получения записи RootDSE в указанном каталоговом сервере. 

 

Запуск программы: 

$ ./libdomain-qt-sample 

Будет открыто диалоговое окно, где пользователь может указать параметры подключения к серверу LDAP: 

 

Диалог подключения

Основное окно программы: 

 

Основное окно программы

Структура программы

 Программа состоит из следующих модулей: 

   * MainWindow — класс, который инициализирует библиотеку libdomain. Следует обратить внимание, что новый цикл событий не запускается, а используется цикл событий qt. Для этого ничего не нужно делать дополнительно, достаточно проинициализировать библиотеку.

#include <ldap.h>
#include <talloc.h>
 
extern "C"
{
#include <libdomain/common.h>
#include <libdomain/domain.h>
#include <libdomain/domain_p.h>
#include <libdomain/directory.h>
#include <libdomain/entry.h>
#include <libdomain/connection_state_machine.h>
}
 
class CallbackHelper : public QObject
{
    Q_OBJECT
public:
    explicit CallbackHelper(QObject* parent)
        : QObject(parent)
    {}
 
signals:
    void ready();
};
 
CallbackHelper* helper = NULL;
 
void connection_on_update(verto_ctx *ctx, verto_ev *ev)
{
    Q_UNUSED(ctx);
 
    ldap_connection_ctx_t* connection = static_cast<ldap_connection_ctx_t*>(verto_get_private(ev));
 
    if (connection->state_machine->state == LDAP_CONNECTION_STATE_RUN)
    {
        verto_del(ev);
 
        if (helper)
        {
            helper->ready();
        }
    }
}
 
MainWindow::MainWindow(ConnectionSettings *settings, QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    helper = new CallbackHelper(this);
 
    TALLOC_CTX* talloc_ctx = talloc_new(NULL);
 
    const int update_interval = 10;
 
    ld_config_t *config = NULL;
    config = ld_create_config(talloc_ctx, settings->hostname, 0, LDAP_VERSION3, settings->bind_dn,
                              settings->username, settings->password, !settings->useSasl, false, settings->useSasl, false,
                              update_interval, talloc_strdup(talloc_ctx, ""), talloc_strdup(talloc_ctx, ""), talloc_strdup(talloc_ctx, ""));
 
    LDHandle *handle = NULL;
    ld_init(&handle, config);
 
    ld_install_default_handlers(handle);
    ld_install_handler(handle, connection_on_update, update_interval);
 
    ui->setupUi(this);
 
    connect(helper, &CallbackHelper::ready, [&, handle]()
    {
        ui->tableView->setModel(new AttributesModel(handle, this));
    });
}

   * AttributesModel — класс унаследованный от QStandardItemModel. Данный класс осуществляет основную работу. Он отправляет запрос к LDAP серверу, получая от него список атрибутов записи RootDSE. В конструкторе создаётся поисковый запрос для libdomain и запрашивается список атрибутов при помощи функции search_callback. Как только search_callback вызовет сигнал AttributesModelPrivate::ready, начинается заполнение модели данными. Предполагается, что к этому моменту уже есть проинициализированный указатель библиотеки ldhandle и соединение уже установлено.

d->handle = ldhandle;
 
    privateData = d.get();
 
    search(d->handle->connection_ctx,
           "",
           LDAP_SCOPE_BASE,
           NULL,
           const_cast<char**>(LDAP_ATTRS),
           0,
           search_callback);
 
    connect(d.get(), &AttributesModelPrivate::ready, [&]()
    {
        for (size_t i = 0; i < d->attributes.size(); ++i)
        {
            QStandardItem* nameItem = new QStandardItem();
            nameItem->setText(d->attributes[i].name);
 
            QStandardItem* valueItem = new QStandardItem();
            valueItem->setText(d->attributes[i].values.join(";"));
 
            this->appendRow({nameItem, valueItem});
        }
    });

   * ConnectionDialog — содержит диалог настроек подключения. При успешном заполнении он создаёт структуру ConnectionSettings.

   * ConnectionSettings — содержит настройки подключения такие как: сервер, имя пользователя, пароль, bind_dn, использование интерактивного подключения. 

 

Обработка ошибок 

Обработка ошибок подключения осуществляется библиотекой libdomain автоматически при помощи встроенных в неё функций. При желании можно установить свой обработчик при помощи функции ld_install_error_handler(handle, connection_on_error), передав ей callback нужный connection_on_error. 

 

Компиляция 

Ссылка на пример

Для компиляции программы необходимо установить библиотеку libdomain: 

# apt-get install libdomain-devel libconfig-devel cmake rpm-build qt5-base-devel

Далее следует склонировать пример: 

$ git clone https://github.com/libdomain/libdomain-qt-sample

Команда компиляции: 

$ mkdir build && cd build && cmake .. && make -j `nproc`