 | Поиск по каталогу
В этом разделе описывается материал по теме 304.1 экзамена на профессионала Linux высокого уровня (LPIC-3) 301. Эта тема обладает весом 2.
Из этого раздела вы узнаете, как:
- Использовать инструменты поиска OpenLDAP на базовом уровне
- Использовать расширенные инструменты поиска OpenLDAP
- Оптимизировать поисковые запросы LDAP
- Использовать фильтры поиска и их синтаксис
Данные дерева каталога полезны только тогда, когда вы можете выполнять поиск нужных вам записей. LDAP содержит ряд мощных инструментов, позволяющих вам извлекать информацию из каталога.
Основы поиска
Для выполнения поиска по дереву каталога вам необходима следующая информация:
- Учетные данные на сервере, содержащем каталог
- Отличительное имя (Distinguished Name, DN) в дереве каталога, на основе которого вы будете выполнять поиск
- Область поиска
- Фильтр поиска
Из
предыдущих руководств этой серии вы уже знаете об учетных данных для сервера. Вы можете выполнять анонимную привязку к каталогу, не используя учетные данные, либо использовать в качестве учетных данных отличительное имя и пароль для определенной записи. Если сервер сможет опознать учетные данные и признает их действительными, он позволит вам выполнять поиск.
Отличительное имя (DN), на основе которого вы выполняете поиск, называется отличительным именем базового объекта (Base DN). Результатом поиска будет являться либо само отличительное имя базового объекта, либо его дочерние элементы. Если DN базового объекта – это ou=people,dc=ertw,dc=com, то результатом поиска может быть cn=Sean Walberg,ou=people,dc=ertw,dc=com, но не cn=Users,ou=Groups,dc=ertw,dc=com, поскольку последний элемент выходит за рамки DN базового объекта, по которому вы выполняете поиск.
Область поиска указывает, по каким элементам отличительного имени базового объекта будет выполняться поиск. Например, вы можете ограничить область поиска из соображений производительности или потому, что нужную вам информацию содержат только определенные дочерние элементы базового объекта. Область поиска по умолчанию, или subordinate (обычно указывается сокращенно как sub), включает в себя имя базового объекта и все его дочерние объекты. Вы можете выполнять поиск только имени базового объекта в области base и всех его дочерних объектов. Вы можете выполнять поиск только имени базового объекта в области base, например, в тех случаях, когда вы хотите проверить существование элемента. Область поиска one указывает, что поиск выполняется только в пределах списка дочерних объектов первого уровня, и исключает из поиска все дочерние объекты последующих уровней, а также сам базовый объект. На рисунке 1 изображено дерево и его элементы, которые будут включены в три различные области поиска.
Рисунок 1. Три различные области поиска
Самым мощным (и сложным) инструментом поиска является фильтр поиска. Учетные данные, отличительное имя базового объекта и область поиска ограничивают набор записей, по которому будет выполняться поиск, а фильтр поиска является запросом, проверяющим каждую запись и возвращающим только те из них, которые удовлетворяют заданным критериям.
Простые фильтры поиска
Фильтры поиска заключаются в круглые скобки, внутри которых содержится одна пара атрибут=значение. Простым фильтром поиска является
(objectClass=inetOrgPerson), выполняющий поиск любых записей класса inetOrgPerson. Сам атрибут не является чувствительным к регистру, а значение может быть чувствительным или нечувствительным к регистру в зависимости от того, как атрибут определен в схеме. Вспомните материал руководства Подготовка к экзамену LPI 301: понятия, архитектура и модель, в котором говорилось о том, что схема определяет атрибуты и их свойства. Одним из свойств атрибута является чувствительность к регистру при сравнении.
Поиск подстроки выполняется с использованием символа звездочки (*). Чтобы найти все записи, начинающиеся с
Sean, выполните поиск подстроки (Sean*). Символ звездочки может располагаться в любом месте строки; например, результатом поиска подстроки (* Walberg) будут являться все записи, оканчивающиеся на Walberg, а результатом поиска S*Wa*berg – все записи, начинающиеся на S, оканчивающиеся на berg и содержащие символы Wa где-либо в середине. Вы можете использовать этот фильтр, например, для поиска имени автора, которое вы не можете назвать точно (Sean или Shawn, Walberg или Wahlberg).
Самая общая форма использования оператора звездочки, атрибут=*, проверяет существование указанного атрибута. Например, чтобы найти все записи, содержащие адреса электронной почты, вы можете использовать фильтр (mail=*).
Операции AND, OR и NOT
Вы можете выполнять логические операции AND ("И") и OR ("ИЛИ") с помощью операторов "&" и "|" соответственно. В строках поиска LDAP операторы помещаются перед условиями, таким образом, вы можете встретить фильтры, подобные следующим.
Листинг 1. Пример фильтров поиска с использованием AND и OR
(|(objectClass=inetOrgPerson)(objectClass=posixAccount))
(&(objectClass=*)(cn=Sean*)(ou=Engineering))
(&(|(objectClass=inetOrgPerson)
(objectClass=posixAccount))(cn=Sean*))
|
Первая строка поиска в листинге 1 выполняет поиск любых записей класса inetOrgPerson или posixAccount. Обратите внимание на то, что каждое условие поиска заключено в круглые скобки, и что оператор OR (|) вместе с этими двумя условиями также заключен в еще одну пару скобок.
Вторая строка поиска похожа на первую, но начинается с оператора AND, а не OR. Здесь должны выполняться три различных условия, которые следуют за символом амперсанда, и каждое из которых заключено в отдельную пару скобок. Первому условию,
objectClass=*, удовлетворяют все записи, класс объекта (objectClass) которых определен (при этом сам класс может быть любым). Поиск записей любого класса часто используется в тех случаях, когда вы хотите выбрать все записи, но при этом должны использовать фильтр поиска. Второму условию удовлетворяют все записи, начинающиеся с Sean.
В третьей строке поиска совместно используются операторы AND и OR. Эта строка ищет любые записи класса inetOrgPerson или posixAccount, обычное имя (CN) которых начинается с Sean.
Для логической операции NOT ("НЕ") используется знак восклицания (!), подобно операциям AND и OR. Логическая операция NOT имеет только один аргумент, поэтому за знаком восклицания может следовать только один набор скобок. В листинге 2 показаны примеры правильного и неправильного использования логической операции NOT.
Листинг 2. Как нужно и как не нужно использовать логическую операцию NOT
(!cn=Sean) # неправильно, ! применяется к условию внутри ()
(!(cn=Sean)) # правильно
(!(cn=Sean)(ou=Engineering)) # неправильно,
операция может быть выполнена только для одного условия
(!((&cn=Sean*)(ou=Engineering))) # правильно, операция NOT выполняется для условия AND
|
В четвертом примере листинга 2 операция NOT применяется к условию AND. Таким образом, это правило возвращает только те записи, которые не удовлетворяют обоим условиям в структуре AND. Будьте аккуратны, когда вы выполняете инверсию для составных условий, поскольку результаты не всегда очевидны. В последнем примере листинга 2 будут возвращены записи с атрибутом ou, равным
Engineering, если их обычное имя не начинается с Sean. Чтобы запись была исключена из результатов поиска, должны выполняться оба условия.
Диапазоны поиска
Часто возникает необходимость выполнить поиск диапазона значений. Для поиска атрибутов в LDAP существуют операторы <= и >=. Обратите внимание на то, что знак равенства (=) входит в состав операторов, поскольку операторов < и > не существует – вы должны также проверять условие равенства.
Не все целочисленные атрибуты можно проверить с помощью операторов диапазонов. Если вы сомневаетесь, проверьте схему, чтобы убедиться в том, что для атрибута реализован тип сортировки через ключевое слово ORDERING. Вспомните материал руководства
Подготовка к экзамену LPI 301: понятия, архитектура и модель, в котором говорилось о том, что атрибут определяется в схеме, и что частью этого определения является способ сортировки атрибута сервером.
Поиск созвучий
Каталог LDAP часто используется для хранения имен, которые могут произноситься одинаково, несмотря на различное написание. Можно, например, спутать имена "Sean", "Shawn" и "Shaun". В LDAP существует оператор "~=", возвращающий результаты, которые произносятся так же, как и строка поиска. Например, (cn~=Shaun) возвращает результаты, обычное имя (CN) которых содержит слово, произносящееся так же, как "Shaun". Так, результатом поиска по подстроке (cn=~Shaun) будет являться элемент cn=Shawn Walberg.В то же время реализация OpenLDAP не совершенна; этот же запрос не возвратит результатов для подстроки с именем "Sean".
Поиск отличительного имени
До сих пор все рассмотренные примеры были нацелены на поиск атрибутов, но не на поиск отличительного имени (DN), которое идентифицирует запись. Хотя крайний левый компонент отличительного имени, относительное отличительное имя (Relative DN, RDN), появляется в качестве атрибута и, следовательно, может быть объектом поиска, фильтры поиска, рассмотренные до сих пор, не выполняют поиск в оставшейся части отличительного имени.
Поиск отличительного имени выполняется при помощи специального фильтра запроса, требующего точного совпадения и имеющего следующий формат: атрибут:dn:=значение, где атрибут – это компонент отличительного имени, которое вы хотите найти, а значение – строка поиска (использование подстановочных символов не разрешено). Например, запрос (ou:dn:=People) возвратит все записи, содержащие подстроку ou=People в отличительном имени, включая сам контейнерный объект.
Изменение правила matchingRule
По умолчанию большинство строк, таких как обычное имя, нечувствительно к регистру. Если вы хотите изменить это правило, вы можете использовать форму, подобную форме поиска отличительного имени. Например, запросу (ou:caseexactmatch:=people) будут соответствовать все организационные подразделения (OU), содержащие строку "people", но не "People". Ниже перечислены некоторые наиболее часто используемые правила сравнения:
-
caseIgnoreMatch выполняет сравнение строк, игнорируя регистр символов. Также игнорируются начальные и завершающие символы пробела.
-
caseExactMatch выполняет сравнение строк с учетом регистра символов, который должен в точности совпадать в исходной и искомой строках.
-
octetStringMatch похож на поиск строки, но знаки пробела не удаляются, то есть выполняется точное побайтовое сравнение.
-
telephoneNumberMatch выполняет поиск телефонного номера, который имеет свой собственный тип данных в LDAP.
Также вы можете изменить правило сравнения для поиска DN, комбинируя поиск DN с поиском на основе правил сравнения. Например, (ou:dn:caseexactmatch:=people) выполняет поиск имени DN, содержащего точную строку "people".
Поиск отличительного имени и поиск на основе правил сравнения также называются расширенным поиском. В обоих случаях необходимо указывать точные значения строк без использования подстановочных символов.
Использование ldapsearch
Утилита командной строки ldapsearch предназначена для поиска по дереву каталога. Она позволяет выполнять привязку к каталогу различными способами, выполнять один или несколько поисков и получать данные в LDIF-формате.
По умолчанию ldapsearch работает следующим образом:
- Пытается выполнить аутентификацию на сервере с использованием SASL (Simple Authentication and Security Layer)
- Подключается к серверу по адресу ldap://localhost:389
- Использует в качестве фильтра поиска конструкцию
(objectClass=*)
- Считывает базу поиска из файла /etc/openldap/ldap.conf
- Выполняет поиск по базе поиска и всем ее дочерним областям
- Возвращает все пользовательские атрибуты, игнорируя рабочие (для внутреннего использования) атрибуты
- Использует для вывода результатов расширенный LDIF-формат (LDAP Data Interchange Format)
- Выводит результаты поиска без сортировки
Аутентификация на сервере
Если вы не используете SASL, вам необходимо выполнить простую аутентификацию, используя параметр -x. Параметр
-x выполняет анонимную привязку, при которой не используется отличительное имя или пароль. При остальных параметрах по умолчанию ldapsearch -x выведет полное дерево каталога, начиная с базы поиска, указанной в файле /etc/openldap/ldap.conf. В листинге 3 показан пример использования простого анонимного поиска.
Листинг 3. Простой анонимный поиск
$ ldapsearch -x
# extended LDIF
#
# LDAPv3
# base <> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# people, ertw.com
dn: ou=people,dc=ertw,dc=com
ou: people
description: All people in organization
objectClass: organizationalUnit
... дальнейшее содержимое не показано ...
|
В листинге показаны заголовок и первая запись, возвращенная в результате выполнения простого анонимного поиска. Первые семь строк формируют заголовок и в соответствии с принятыми в LDIF правилами закомментированы путем добавления в начало строки символа решетки (#). Первые три строки определяют весь последующий текст в качестве данных в расширенном LDIF-формате, возвращенных с использованием LDAP версии 3. Следующая строка показывает, что отличительное имя базового объекта не было указано, и что используется поиск в подразделах дерева (subtree search). Последние две текстовые строки задают фильтр поиска, запрашивающий любые данные, а также указывают на то, что были запрошены все атрибуты.
Если вы хотите выводить результаты, не содержащие комментариев, вы можете использовать параметр -LLL.
После заголовка перечисляются все записи. Каждая запись начинается с заголовка, описывающего ее, а затем идет список всех атрибутов, начиная с DN. Атрибуты не сортируются
Если для подключения вам необходимо указать имя пользователя и пароль, используйте для этого параметры -D и -w соответственно. Например, команда ldapsearch -x D cn=root,dc=ertw,dc=com -w мой_пароль выполнит простую аутентификацию с использованием отличительного имени пароля пользователя root. Если вы хотите, чтобы при вводе пароль не отображался на экране, используйте для этого параметр -W вместо -w пароль.
Вы также можете подключиться к другому серверу, передав унифицированный идентификатор ресурса (Uniform Resource Identifier, URI) удаленного сервера LDAP с помощью параметра -H, например,
ldapsearch -x -H ldap://192.168.1.1/ - чтобы подключиться к LDAP-серверу по адресу 192.168.1.1.
Выполнение запросов
Для выполнения запроса укажите в командной строке фильтр поиска. Вероятнее всего, вам придется заключить фильтр в кавычки, чтобы специальные символы в строке поиска не были восприняты системой как управляющие символы командной оболочки. В листинге 4 приведен пример простого поиска обычного имени.
Листинг 4. Простой поиск из командной строки
$ ldapsearch -LLL -x '(cn=Fred Smith)'
dn: cn=Fred Smith,ou=people,dc=ertw,dc=com
objectClass: inetOrgPerson
sn: Smith
cn: Fred Smith
mail: fred@example.com
|
Поиск в листинге 4 был выполнен с параметром -LLL для пропуска комментариев и параметром -x для использования простой аутентификации. Последний параметр – это строка поиска, которая ищет запись пользователя Fred Smith. Обратите внимание, что запрос заключен в круглые скобки, а также в одиночные кавычки. Эти кавычки необходимы, чтобы скобки не были восприняты системой как обращение к подоболочке, а подстрока "Smith" не была интерпретирована как отдельный аргумент (поскольку строка запроса содержит знак пробела).
В листинге 4 были возвращены все атрибуты записи Fred Smith. Если же вам нужны всего один или два атрибута, то поиск значений всех атрибутов записи будет пустой тратой ресурсов как клиента, так и сервера. Чтобы выполнить поиск только нужных вам атрибутов, добавьте их имена в конец командной строки
ldapsearch. В листинге 5 показано, как будет выглядеть предыдущий запрос в случае, если вы просто хотите узнать адрес электронной почты пользователя Fred Smith.
Листинг 5. Запрос адреса электронной почты пользователя Fred Smith
$ ldapsearch -LLL -x '(cn=Fred Smith)' mail
dn: cn=Fred Smith,ou=people,dc=ertw,dc=com
mail: fred@example.com
|
В листинге 4 в конец командной строки добавлен атрибут mail, в результате чего было найдено отличительное имя и его запрошенные атрибуты.
Чтобы определить базу поиска, ldapsearch ищет в файле /etc/openldap/ldap.conf строку, начинающуюся с BASE, и в случае, если такая строка не обнаружена, использует параметр сервера
defaultsearchbase. База поиска – это точка дерева каталога, с которой начинается поиск. Поиск будет выполняться только в дочерних элементах базы поиска (включая ее саму). Чтобы указать другую базу поиска, используйте параметр -b, например, ldapsearch -x -b ou=groups,dc=ertw,dc=com – для поиска в контейнере groups дерева ertw.com.
Управление выводом результатов
LDAP может хранить двоичные данные, например, изображения. Стандартным способом хранения изображений в дереве каталога является использование атрибута jpegPhoto. Если вы получаете значение атрибута из командной строки, оно возвращается вам в кодировке base64. Для сохранения любых двоичных атрибутов во временном файле используется параметр -t. В листинге 6 показано, как использовать этот параметр.
Листинг 6. Сохранение двоичных атрибутов в файловой системе
$ ldapsearch -LLL -x 'cn=joe*' jpegphoto | head
dn: cn=Joe Blow,ou=people,dc=ertw,dc=com
jpegPhoto:: /9j/4AAQSkZJRgABAQEASABIAAD/
/gAXQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q/9sAQw
... далее следуют еще более 1300 строк ...
$ ldapsearch -LLL -t -x '(cn=joe*)' jpegphoto
dn: cn=Joe Blow,ou=people,dc=ertw,dc=com
jpegPhoto:< file:///tmp/ldapsearch-jpegPhoto-VaIjkE
$ file /tmp/ldapsearch-jpegPhoto-VaIjkE
/tmp/ldapsearch-jpegPhoto-VaIjkE:
JPEG image data, JFIF standard 1.01, comment: \
"Created with The GIMP\377"
|
В листинге 6 показаны два запроса, выполняющих поиск всех людей с именем, начинающимся на "Joe", и возвращающих только атрибут jpegPhoto. В первом запросе параметр -t не используется, поэтому значение атрибута jpegPhoto выводится в консоль в формате base64. При использовании командной строки такой запрос бесполезен, поэтому во втором запросе указан параметр -t. На этот раз значение атрибута jpegPhoto является URI-ссылкой на файл (вы можете изменить директорию с помощью параметра -T). Наконец, полученный файл проверяется, и он действительно является бинарной версией изображения, которое теперь можно просмотреть.
По умолчанию ldapsearch выводит результаты в том порядке, в котором они были получены от сервера. Вы можете выполнить сортировку с помощью параметра
-S, указав имя атрибута, значения которого вы хотите отсортировать. Чтобы выполнить сортировку по нескольким атрибутам, разделяйте их имена запятыми (,).
|  |