Эффективное использование данных из базы каталога
В составе Windows 2000 имеется утилита, позволяющая импортировать и экспортировать записи Active Directory (AD) для подготовки отчетов и миграции. Эта же программа обеспечивает автоматическое добавление, изменение и удаление объектов AD. Инструмент Lightweight Directory Access Protocol (LDAP) Data Interchange Format (LDIF) Directory Exchange, более известный как Ldifde, позволяет экспортировать данные из AD, объект за объектом (например, пользователь, группа), атрибут за атрибутом (скажем, имя, компания, подразделение) в файл формата LDIF. LDIF — стандартный файловый формат Internet, определенный в документе Request for Comments (RFC) 2849 комитета IETF для импорта и экспорта данных из каталогов LDAP, таких, как AD. После экспорта данных можно использовать LDIF-файл для импорта тех же объектов в другой каталог LDAP. Выходные данные Ldifde можно использовать в качестве «сырых» данных для отчета или как отправную точку для создания LDIF-файла изменений для реимпорта в AD.
На примере нескольких LDIF-файлов можно показать, как наиболее эффективно работать с данными AD с помощью Ldifde и родственной утилиты, Csvde. Csvde — вариант Ldifde, в котором значения разделяются запятыми (формат CSV). Csvde обеспечивает импорт в базы данных, такие, как Microsoft Access, или электронные таблицы, в том числе Microsoft Excel, понимающие файлы в CSV-формате. Утилиты Ldifde и Csvde поставляются вместе с Windows 2000 Server, но их можно скопировать с установочного компакт-диска Windows 2000 Server и запускать на рабочих станциях Windows XP и Windows 2000.
Экспорт из AD
Прежде чем приступить к работе с Ldifde, необходимо разобраться в структуре файла LDIF. На Экране 1 показана организационная единица (OU) с именем Monterey, в состав которой входят четыре пользователя и группа. Для экспорта этой информации из AD необходимо выполнить команду
ldifde -f monterey.ldif -d «ou=Monterey,DC=ad,dc=local»
чтобы создать файл Monterey.ldif. Можно вызвать Ldifde из сценария или запустить исполняемый файл из командной строки. Параметр -f позволяет указать имя LDIF-файла (например, monterey.ldif). С помощью параметра -d можно указать корневое отличительное имя (distinguished name, DN) домена или OU, из которого экспортируются данные (например, Monterey OU домена ad.local), а затем выдать атрибуты всех объектов, начиная с этой точки, в том числе и OU. Факультативные атрибуты, не существующие до тех пор, пока они не будут явно заданы для каждого объекта, могут отсутствовать (например, телефонные номера некоторых пользователей).
Каждая запись в LDIF-файле начинается с DN-строки с обозначением dn:. В LDAP-каталоге DN объекта однозначно определяет объект во всем каталоге. Вторая строка начинается с обозначения changetype:, указывающего тип изменения, которое должно быть выполнено утилитой Ldifde в объекте, идентифицированном именем DN. Changetype всех записей в Monterey.ldif — add. Каждый раз при экспорте записей Ldifde форматирует файл таким образом, чтобы можно было импортировать эти записи в другой каталог LDAP. После того как задан changetype, Ldifde выдает атрибут каждого объекта в следующем формате:
:
Можно определить класс каждого объекта, указав атрибут objectClass. В Monterey.ldif содержится OU, за которой следуют три пользователя, группа и последний пользователь.
Если необходимо экспортировать данные AD (например, список имен пользователей) для подготовки отчета, следует выбрать критерии (например, класс), ограничивающие выходные данные Ldifde, и указать экспортируемые атрибуты объекта: обеих целей можно достичь с помощью параметров -r и -l. Параметр -r назначает поисковый фильтр в синтаксисе LDAP, в котором указываются один или несколько атрибутов и их предпочтительные значения. Например, чтобы экспортировать только записи пользователей, нужно ввести команду:
ldifde -r «(objectClass=User)»
А для экспорта всех пользователей с фамилией Smith следует ввести команду:
ldifde -r «(&(objectClass=user)(sn=Smith))»
С помощью параметра -l, за которым следует разделенный запятыми список атрибутов, можно указать атрибуты, выдаваемые утилитой Ldifde для каждого объекта. Например, команды
ldifde -l «displayName, physicalDeliveryOfficeName»
выводят имя и офис для каждого пользователя (см. Экран 2).
Экран 2. Просмотр имени и офиса пользователей. |
Читателям, незнакомым с запросами LDAP, я рекомендую обратить внимание на врезку «Фильтры LDAP», в которой содержится более подробная информация о структуре запросов. Чтобы уточнить точное имя фильтруемого атрибута или класса, можно воспользоваться оснасткой Active Directory Schema консоли Microsoft Management Console (MMC) или экспортировать OU, содержащую нужный объект, а затем исследовать LDIF-файл. Если в записи объекта искомого атрибута нет, то нужно просто отредактировать объект в AD, установить значение атрибута и вновь экспортировать OU. Например, в процессе редактирования объекта user в оснастке Active Directory Users and Computers консоли MMC на вкладке General появится поле Office (см. Экран 3). Чтобы определить имя атрибута LDAP для этого поля в AD, можно ввести значение для атрибута Office, а затем экспортировать объект с помощью Ldifde. Имя атрибута LDAP появится в LDIF-файле после имени атрибута physicalDeliveryOfficeName.
Экран 3. Свойства пользователя в оснастке Active Directory Users and Computers. |
Хотя файловый формат LDIF не годится для импорта данных AD в базу данных с целью подготовки отчетов и запросов, Microsoft предлагает другую утилиту, Csvde, которая понимает те же параметры, что и Ldifde, но выдает данные в формате CSV. Например, по команде
csvde -f monterey.LDIF -d «ou=Monterey,DC=ad,dc=local» -l «displayName,physicalDeliveryOffice Name» -r «(objectClass=User)»
будут получены те же данные, что и по команде Ldifde, но каждая запись будет состоять из одной строки значений, разделенных запятыми (см. Экран 4). Следует обратить внимание, что в первой строке генерируемых программой Csvde файлов содержатся имена атрибутов, корректно воспринимаемые приложениями Access и Excel как заголовки столбцов.
Экран 4. Результаты работы csvde. |
Работа с текстом и нетекстовыми типами данных
При использовании Ldifde для простого экспорта и импорта файлов между каталогами LDAP никаких проблем не возникает. Но если Ldifde или Csvde используются для экспорта данных в программы построения отчетов либо администратор строит собственные LDIF-файлы для автоматизации внесения изменений в AD, то некоторые атрибуты могут вызвать затруднения. При подготовке отчетов и автоматизации изменений AD, Ldifde и Csvde лучше всего работают с текстовыми атрибутами, а не такими нетекстовыми типами, как даты и двоичные данные. Как ни странно, один атрибут в AD может занимать несколько полей в оснастке Active Directory Users and Computers. Например, один целочисленный атрибут с именем userAccountControl содержит несколько параметров учетной записи (см. Экран 5).
Экран 5. Целочисленный атрибут userAccountControl. |
Импорт изменений в AD
При импорте изменений в AD с помощью Ldifde параметр -i используется для задания режима импорта, а параметр -f — для указания LDIF-файла. Рассмотрим подробнее, как использовать Ldifde для подготовки LDIF-файлов, которые создают, удаляют и изменяют объекты AD.
Создание объектов. Самый простой способ построить LDIF-файл, который создает новый объект, — экспортировать уже существующий объект. Каждый раз, когда Ldifde экспортирует объект, она выдает объект, параметр changetype которого — add. Если затем импортировать файл Ldifde в тот же каталог, то Ldifde попытается создать дубликат только что экспортированного объекта. Поэтому можно экспортировать образцовый объект (например, существующий объект user), а затем отредактировать LDIF-файл так, чтобы создать новый объект. При использовании этого метода необходимо удалить некоторые определения атрибутов из исходного экспортного файла, так как ряд атрибутов может устанавливать только служба каталога. Например, если попытаться установить атрибут whenChanged для объекта user, утилита Ldifde выдаст на экран сообщение Add error on line 1: Constraint Violation. The server side error is «The attribute cannot be modified because it is owned by the system». По умолчанию Ldifde экспортирует все атрибуты, в том числе предназначенные только для чтения, но может и корректно переносить данные из одного каталога в другой. Для этого достаточно указать параметр -k при импорте LDIF-файла, который заставляет утилиту Ldifde игнорировать ошибки типов constraint violations и object already exists. Чтобы повысить скорость импорта больших массивов данных, можно указать параметр -y, в результате чего Ldifde использует укороченные подтверждения транзакций (lazy commit).
Удаление объектов. Создать LDIF-файл, который удаляет один или несколько объектов, сравнительно просто. Достаточно ввести строку DN, а затем указать delete в строке changetype. Например, чтобы удалить учетную запись пользователя Robert Hall из домена acme.com, нужно ввести команду
dn: cn=Robert Hall, ou=Marketing, dc=acme, dc=com changetype: delete
Изменение объектов. Несомненно, самый сложный тип операций импорта, совершаемых LDIF-файлами, — это изменение объектов AD. В начале LDIF-файла следует перечислить DN, затем указать modify в строке changetype. Далее необходимо указать тип операции, выполняемой Ldifde, следом за которой должно быть приведено имя изменяемого атрибута. Например, запись
replace: displayName
указывает утилите, что в следующей строке или строках приведены новое значение или значения для атрибута displayName объекта, идентифицированного с помощью DN. В предыдущем операторе я указал факультативные множественные строки и значения для тех случаев, когда изменяются многозначные атрибуты и нужно указать несколько значений для одного атрибута.
В следующей строке LDIF-файла необходимо указать значение атрибута. Например,
sn: Johnson
указывает фамилию Johnson. Если для этого же атрибута требуется задать дополнительные значения, то следует просто перечислить их в дополнительных строках в том же формате. После того как введена последняя строка со значением для данного атрибута, нужно добавить строку, содержащую только дефис. Например,
dn: CN=Joe Stokes,OU=Monterey, DC=ad,DC=local changetype: modify replace: sn sn: Johnson -
изменяет фамилию Joe на Johnson.
Наряду с операцией replace можно использовать операции add и delete. Операция add применяется, если данный атрибут никогда не назначался для интересующего нас объекта. В случае с многозначными атрибутами при использовании add утилита Ldifde добавляет указанные значения к существующим значениям атрибута. Например, фрагмент
dn: CN=Managers,OU=Monterey, DC=ad,DC=local changetype: modify add: member member: CN=Joe Stokes,OU=Monterey,DC=ad, DC=local member: CN=James White,OU=Monterey,DC=ad, DC=local member: CN=Lamar McCluney,OU=Monterey,DC=ad, DC=local -
добавляет Joe, James и Lamar в группу Managers. Достаточно заменить add: member на replace: member, чтобы перед вводом Joe, James и Lamar утилита Ldifde удалила любых пользователей, ранее входивших в группу Managers. Если операция add применяется к однозначным атрибутам, таким, как sn (surname — фамилия), которым уже присвоено значение, то Ldifde может выдать сообщение Multiple values were specified for an attribute that can have only one value. Операция delete используется для удаления всех значений атрибутов, в результате атрибут исчезает, как будто никогда не назначался для данного объекта. Например,
dn: CN=Joe Stokes,OU=Monterey, DC=ad,DC=local changetype: modify delete: sn -
удаляет текущую фамилию Joe. С помощью операции delete можно удалить и конкретное значение из многозначного атрибута. Например,
dn: CN=Managers,OU=Monterey, DC=ad,DC=local changetype: modify delete: member member: CN=Joe Stokes,OU=Monterey,DC=ad,DC=local -
удаляет Joe из группы Managers, не затрагивая других членов. Это изменение похоже на присвоение полю в строке базы данных Microsoft SQL Server нулевого значения. Для удаления, добавления или замены многозначных атрибутов одного объекта следует разделять строки для каждого атрибута одной чертой. Например,
dn: cn=John Smith, ou=Accounting, dc=acme, dc=com changetype: modify add: postaladdress postaladdress: 100 Main St $ Greenville, CA $ 29605 - replace: telephonenumber telephonenumber: +1 864 555 1212 telephonenumber: +1 864 230 1212 - delete: facsimiletelephonenumber -
добавляет почтовый адрес пользователя John, заменяет его телефонный номер двумя номерами и удаляет номер факса.
Использование Ldifde и Csvde
Теперь, после ознакомления со структурой LDIF-файла, можно применить Ldifde и Csvde на практике. Например, можно составить новый телефонный справочник с указанием имени, номеров рабочего и мобильного телефонов, номера пейджера, названия подразделения и должности каждого сотрудника организации. Чтобы получить файл в CSV-формате, следует выполнить команды
csvde -f users.txt -d «DC=acme,DC=com» -r «(objectClass=user)» -l «name,department,title,telephoneNumber, mobile,pager»
а затем импортировать файл users.txt в базу данных Access и распечатать его как отчет или опубликовать на Web-странице во внутренней сети.
Как получить конкретную информацию о сотрудниках? Многие предприятия проектируют программы для ведения досье сотрудников самостоятельно. Такие программы собирают данные об изменениях учетных записей, паролей и полномочий сотрудников от момента поступления на работу до увольнения. Предположим, нам нужно извлечь все учетные записи пользователей подразделения Research and Development. Для этого достаточно выполнить команды
csvde -f users.LDIF -d «DC=acme,DC=com» -r «(&(objectClass=user) (division=Research and Development))» -l «SAMAccountName,employeeID,telephone Number,department»
чтобы получить регистрационное имя, ID сотрудника, телефон и название отдела для всех сотрудников данного подразделения.
С помощью программы управления досье можно блокировать учетные записи пользователя при увольнении сотрудника в отделе кадров. Для этого приложение должно создать LDIF-файл со следующей структурой:
dn: changetype: modify replace: userAccountControl userAccountControl: 514 -
где — DN сотрудника. Затем приложение должно запустить команду
«ldifde -f -I»
чтоб реимпортировать данные в AD. Если нужно удалить пользователя из группы, следует создать LDIF:
dn: changetype: modify delete: member member: -
где — DN группы, а — DN удаляемого пользователя.
Параметры Ldifde и Csvde
Несколько дополнительных параметров позволяют провести тонкую настройку режима работы Ldifde. По умолчанию Ldifde и Csvde обращаются к AD с использованием учетных данных пользователя. Однако с помощью параметра -b можно указать данные, которые должны использовать Ldifde и Csvde. Чтобы не указывать пароль в командной строке или в сценарии, можно заменить звездочкой (*). В этом случае Ldifde попросит ввести пароль, не показывая на экране вводимые с клавиатуры символы. Если нужно импортировать или экспортировать данные на конкретный сервер, достаточно указать имя сервера с параметром -s. А чтобы получить список DN всех обработанных объектов, следует воспользоваться параметром -v.
Ldifde и Csvde — превосходные инструменты, с помощью которых можно записывать и читать информацию из AD и других каталогов LDAP, не составляя программ на базе служебных интерфейсов Active Directory Service Interfaces (ADSI). С помощью Ldifde можно пересылать объекты из одного каталога в другой и изменять информацию внутри AD, а Csvde позволяет извлекать данные для использования в других приложениях. Более подробная информация о LDIF приведена в документе RFC 2849 по адресу: http://www.faqs.org/rfcs/rfc2849.html. Утилита Ldifde подробно описана в статье Microsoft «Using LDIFDE to Import and Export Directory Objects to Active Directory» (http://support.microsoft.com/?kbid=237677).
Фильтры LDAP
Самый простой фильтр LDAP — (attributeName operator value), например (cn=John Calvin). Наряду с оператором равенства (=) можно использовать операторы «больше или равно» (>=) и «меньше или равно» (<=). Можно применять универсальный символ звездочка (*) для операций сравнения, таких, как (cn=John*) или (cn=*amy*). Например, (telephoneNumber=*) возвращает все объекты с установленным атрибутом telephoneNumber.
Как построить фильтр, анализирующий два или несколько атрибутов (например, чтобы получить все объекты user с фамилией Smith)? Для подготовки такого фильтра необходимо построить два простых фильтра (sn=Smith)(objectClass=user) и заключить их в логический LDAP-оператор and, который представляет собой (&conditionList), где conditionList — два или несколько условий, каждое из которых заключено в скобки. В нашем примере с фамилией следует указать (&(sn=Smith)(objectClass=user)).
Условие ИЛИ задается с помощью логического LDAP-оператора or, который представляет собой (|conditionList). Например, чтобы найти все объекты, в которых displayName начинается с Smi* или John*, нужно указать (|(displayName=Smi*)(displayName=John*)). Для оператора not следует использовать (!condition). LDAP-оператор not — унарный (принимает только один аргумент), но можно указать несколько условий с вложенными скобками. Например, (!(|(displayName=Smi*)(displayName=John*))) возвращает все записи, за исключением тех, в которых фамилия начинается с Smi* или John*.
Рэнди Франклин Смит — редактор Windows & .NET Magazine и президент компании Monterey Technology Group, которая занимается обучением и консалтингом в области защиты Windows NT. Связаться с ним можно по адресу: rsmith@montereytechgroup.com.