Среда, 03 февраля 2021 19:00

Расширеный поиск в каталоге LDAP - группы. Работа с LDAP в Qt5. Часть 5.

Россия
Оцените материал
(0 голосов)

Сегодня мы рассмотрим поиск групп в каталоге LDAP, а также пользователей, которые входят в группу.

Мы будем использовать проект из предыдущей статьи.

Добавляем группы

В статье – мы рассмотрели создание виртуальной организации в домене AD с помощью скрипта. Но мы не рассматривали создание групп и добавление в них пользователей. Давайте это исправим.

Нам понадобиться скрипты и тестовые данные, скачать их можно с Github - https://github.com/vasiliyaltunin/ad-company-generator

Чтобы не плодить OU добавим группы сразу в корень

OU=Company,DC=altuninvv,DC=local

В результате PowerShell скрипт у нас примет вид:

Import-Module ActiveDirectory

cls

Write-Host "Importing ou"

$ous = Import-Csv -Encoding UTF8 -Delimiter ';' -Path $PSScriptRoot"\ous.csv"

Write-Host "Creating Company OU"

New-ADOrganizationalUnit –Name Company –Path " DC=altuninvv,DC=local" –Description "Altunin Soft"

Write-Host "Creating Groups"

New-ADGroup -Name gg-ruk -GroupScope Global –Path "OU=Company,DC=altuninvv,DC=local"
New-ADGroup -Name gg-buh -GroupScope Global –Path "OU=Company,DC=altuninvv,DC=local"
New-ADGroup -Name gg-it -GroupScope Global –Path "OU=Company,DC=altuninvv,DC=local"
New-ADGroup -Name gg-otdel1 -GroupScope Global –Path "OU=Company,DC=altuninvv,DC=local"
New-ADGroup -Name gg-otdel2 -GroupScope Global –Path "OU=Company,DC=altuninvv,DC=local"
New-ADGroup -Name gg-otdel3 -GroupScope Global –Path "OU=Company,DC=altuninvv,DC=local"
New-ADGroup -Name gg-otdel4 -GroupScope Global –Path "OU=Company,DC=altuninvv,DC=local"

Write-Host "Creating OUs"

foreach ($ou in $ous) {

New-ADOrganizationalUnit –Name $ou.name `
–Path "OU=Company,DC=altuninvv,DC=local" `
–Description $ou.descr

}

Write-Host "Importing users"

$users = Import-Csv -Encoding UTF8 -Delimiter ';' -Path $PSScriptRoot"\users.csv"

#Write-Host $users

$i=0;
Write-Host "Creating users"

foreach ($user in $users) {

New-ADUser -Name $user.login `
-DisplayName $user.fio `
-GivenName $user.fname `
-Surname $user.lname `
-Initials $user.initials `
-OfficePhone $user.workphone `
-Department $user.department `
-Title $user.jobtitle `
-UserPrincipalName $user.login `
-MobilePhone $user.cellphone `
-SamAccountName $user.samaccname `
-Path $user.ou `
-EmailAddress $user.email `
-StreetAddress $user.addr `
-Office $user.kab `
-Company $user.company `
-Fax $user.fax `
-AccountPassword (ConvertTo-SecureString $user.passwd -AsPlainText -force) -Enabled $true


if (($i -gt -1) -and ($i -lt 4)) {
    $group = 'CN=gg-ruk,OU=Company,DC=altuninvv,DC=local'
    Add-ADGroupMember -Identity $group -Members $user.login
}
if (($i -gt 3) -and ($i -lt 8)) {
    $group = 'CN=gg-buh,OU=Company,DC=altuninvv,DC=local'
    Add-ADGroupMember -Identity $group -Members $user.login
}
if (($i -gt 7) -and ($i -lt 10)) {
    $group = 'CN=gg-it,OU=Company,DC=altuninvv,DC=local'
    Add-ADGroupMember -Identity $group -Members $user.login
}
if (($i -gt 9) -and ($i -lt 32)) {
    $group = 'CN=gg-otdel1,OU=Company,DC=altuninvv,DC=local'
    Add-ADGroupMember -Identity $group -Members $user.login
}
if (($i -gt 31) -and ($i -lt 54)) {
    $group = 'CN=gg-otdel2,OU=Company,DC=altuninvv,DC=local'
    Add-ADGroupMember -Identity $group -Members $user.login
}
if (($i -gt 53) -and ($i -lt 76)) {
    $group = 'CN=gg-otdel3,OU=Company,DC=altuninvv,DC=local'
    Add-ADGroupMember -Identity $group -Members $user.login
}
if ($i -gt 75) {
    $group = 'CN=gg-otdel4,OU=Company,DC=altuninvv,DC=local'
    Add-ADGroupMember -Identity $group -Members $user.login
}

 $i = $i + 1

Set-ADUser -Identity $user.login `
-Add @{otherTelephone=$user.vntel} `
}

Write-Host "Done!"

Удалите OU нашей виртуальной организации Company и запустите скрипт снова.

Будут созданы группы:

2021-01-27_15-17-24.png

А в группы добавлены пользователи

2021-01-27_15-16-32.png

Проверка на наличие ошибок

Давайте добавим локальную функцию для проверки результатов поиска кода на наличие критических ошибок:

void checkForSearchLDAPErrors(QLdap *ldap, int result)
{
    if ( result != LDAP_SUCCESS )
    {
    QString msg = QString("QLdapSearch error: ") + QString(ldap_err2string(result));
    ldap->close();
    qFatal("%s",msg.toLatin1().constData());
    }
    qDebug() << "LDAP Search result = " << ldap_err2string(result);
}

Ищем группу

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

int QLdapSearch::group(QString filter)
{
    this->results->clear();
    QString aFilter = "(&(objectClass=group)" + filter + ")";
    qDebug() << aFilter;
    return this->ldap->search(this->searchDN,
                 aFilter,
                 this->results);
}

Используем созданный метод - в конструктор главной формы добавим: 

    QLdapEntry a;

    QLdapSearch search = QLdapSearch(ldap);

    QLdapEntryList *groupSearchResult = new QLdapEntryList();

    search.setDN("OU=Company,DC=altuninvv,DC=local");
    search.setResult(groupSearchResult);

    result = search.group("");
    checkForSearchLDAPErrors(ldap, result);

    a = groupSearchResult->at(0);
    qDebug() << "\n========\n" << a << "\n=========";

Запустим:

"(&(objectClass=group))"
Search result =  Success
Search results count =  7
LDAP Search result =  Success

========
 QHash(("member", ("CN=LebedevaVA,OU=ruk,OU=Company,DC=altuninvv,DC=local",
"CN=SmirnovAV,OU=ruk,OU=Company,DC=altuninvv,DC=local", 
"CN=KalininaVL,OU=ruk,OU=Company,DC=altuninvv,DC=local",
"CN=PavlovaJAV,OU=ruk,OU=Company,DC=altuninvv,DC=local"))
("sAMAccountType", ("268435456"))("name", ("gg-ruk"))("objectCategory", ("CN=Group,CN=Schema,CN=Configuration,DC=altuninvv,DC=local"))("objectClass", ("top", "group"))("uSNChanged", ("34498"))("objectSid", ("\u0001\u0005"))("objectGUID", ("??\u0010?\u000F\[email protected]?\u0017?4?sT?"))("uSNCreated", ("34419"))("cn", ("gg-ruk"))("groupType", ("-2147483646"))("distinguishedName", ("CN=gg-ruk,OU=Company,DC=altuninvv,DC=local"))("whenChanged", ("20210202085909.0Z"))("dSCorePropagationData", ("20210202085909.0Z", "16010101000000.0Z"))("whenCreated", ("20210202085908.0Z"))("sAMAccountName", ("gg-ruk"))("instanceType", ("4"))) 
=========

Найдено 7 групп, но нам пока достаточно и одной.

Как видите в результате поиска вернулась вся информация о группе, в том числе и о пользователях этой группы.

Давайте напишем для группы класс подобный QLdapUser

Класс для группы

Добавим новый класс QLdapGroup

Заголовок:

#ifndef QLDAPGROUP_H
#define QLDAPGROUP_H

#include <QString>
#include "qldap.h"

class QLdapGroup
{
public:
    QLdapGroup(QLdapEntry *group);
private:
    QLdapEntry *group;
};

#endif // QLDAPGROUP_H

Реализация:

#include "qldapgroup.h"

QLdapGroup::QLdapGroup(QLdapEntry *group)
{
    this->group = group;
}

Список членов группы

Добавим метод

QStringList  QLdapGroup::getMembers() const
{
    return (*this->group)["member"].join(",").split(",");
}

Метод возвращает строки, содержащие DN пользователей, входящих в эту группу.

Добавим в конструктор главной формы код:

    result = search.group("");
    checkForSearchLDAPErrors(ldap, result);

    a = groupSearchResult->at(0);
    QLdapGroup g = QLdapGroup(&a);
    qDebug() << "\n========\n" << g.getMembers() << "\n=========";

Я удаляю код проверки результата поиска, для компактности, но вы обязаны делать проверку результатов поиска!

Запустим:

"(&(objectClass=group))"
Search result =  Success
Search results count =  7
LDAP Search result =  Success

========
 ("CN=LebedevaVA", "OU=ruk", "OU=Company", "DC=altuninvv", "DC=local", 
"CN=SmirnovAV", "OU=ruk", "OU=Company", "DC=altuninvv", "DC=local",
"CN=KalininaVL", "OU=ruk", "OU=Company", "DC=altuninvv", "DC=local", 
"CN=PavlovaJAV", "OU=ruk", "OU=Company", "DC=altuninvv", "DC=local") 
=========

Мы нашли всех пользователей группы.

Поиск группы по имени

Пока что у нас производился поиск вообще всех групп в OU. Давайте найдем одну с именем gg-it:

    result = search.group("(name=gg-it)");
    checkForSearchLDAPErrors(ldap, result);

    a = groupSearchResult->at(0);
    g = QLdapGroup(&a);
    qDebug() << "\n========\n" << g.getMembers() << "\n=========";

Запустим:

"(&(objectClass=group)(name=gg-it))"
Search result =  Success
Search results count =  1
LDAP Search result =  Success

========
 ("CN=LatyshevTS", "OU=it", "OU=Company", "DC=altuninvv", "DC=local",
"CN=ErmakovaKD", "OU=it", "OU=Company", "DC=altuninvv", "DC=local") 
=========

В группе 2 пользователя, как и должно быть.

Полный путь к группе

Так же в группе нас может заинтересовать только её DN, добавим метод для его выгрузки:

QString  QLdapGroup::getDN() const
{
    return (*this->group)["distinguishedName"].join(",");
}

Проверим его:

    result = search.group("(name=gg-it)");
    checkForSearchLDAPErrors(ldap, result);

    a = groupSearchResult->at(0);
    g = QLdapGroup(&a);
    qDebug() << "\n========\n" << g.getDN() << "\n=========";

Запустим:

"(&(objectClass=group)(name=gg-it))"
Search result =  Success
Search results count =  1
LDAP Search result =  Success

========
 "CN=gg-it,OU=Company,DC=altuninvv,DC=local" 
========

Поиск пользователей в группе

Мы смогли получить список пользователей в группе, но как правило, нам интересна подробная информация о пользователях.

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

int QLdapSearch::usersInGroup(QString groupDN)
{
    this->results->clear();
    QString aFilter = "(&(objectCategory=person)(memberOf=" + groupDN + "))";
    qDebug() << aFilter;
    return this->ldap->search(this->searchDN,
                 aFilter,
                 this->results);
}

Добавим код в конструктор главной формы: 

    result = search.group("(name=gg-buh)");
    checkForSearchLDAPErrors(ldap, result);

    a = groupSearchResult->at(0);
    g = QLdapGroup(&a);
    qDebug() << "\n========\n" << g.getDN() << "\n=========";

    QString aDN =  g.getDN();

    result = search.usersInGroup(aDN);
    checkForSearchLDAPErrors(ldap, result);

    for( auto e = groupSearchResult->begin(); e != groupSearchResult->end(); ++e)
    {
        QLdapUser user2 = QLdapUser(&(*e));
        qDebug() << user2["company"];
        qDebug() << user2["displayName"];
    }
    qDebug() << "\n========\n";

Запустим: 

"(&(objectClass=group)(name=gg-buh))"
Search result =  Success
Search results count =  1
LDAP Search result =  Success

========
 "CN=gg-buh,OU=Company,DC=altuninvv,DC=local" 
=========
"(&(objectCategory=person)(memberOf=CN=gg-buh,OU=Company,DC=altuninvv,DC=local))"
Search result =  Success
Search results count =  4
LDAP Search result =  Success
"Altunin Soft"
"Ильинская Ева Матвеевна"
"Altunin Soft"
"Дружинин Павел Демидович"
"Altunin Soft"
"Богданова Малика Олеговна"
"Altunin Soft"
"Румянцева Анна Кирилловна"

Заключение

Сегодня мы рассмотрели поиск по группам в каталоге LDAP.

Был модернизирован скрипт автоматического создания виртуального предприятия в тестовом домене AD. Были добавлены группы, а пользователи в них добавлены.

Был создан класс QLdapGroup

Был реализован поиск группы по её имени.

Мы получили список DN пользователей, состоящих в группе и DN самой группы.

Был создан метод usersInGroup() для поиска пользователей состоящих в группе, по DN этой группы.

В следующей статье мы рассмотрим добавление пользователя в каталог LDAP в Qt5.

исходный код проекта вы можете найти на Github.

Прочитано 283 раз Последнее изменение Среда, 03 февраля 2021 20:51