Сравнение данных LDAP между контроллерами домена
Для проверки согласованности данных службы каталогов между контроллерами домена «Эллес» и Windows Server путем сравнения LDAP-представления объектов и атрибутов в выбранных разделах каталога может использоваться подкоманда samba-tool ldapcmp.
Механизм сравнения LDAP-данных между контроллерами домена
Подкоманда ldapcmp предназначена для сравнения содержимого БД LDAP на двух одновременно работающих серверах. Она выполняет прямое сравнение данных на уровне объектов и атрибутов и используется как диагностический инструмент для выявления расхождений между контроллерами домена, которые логически должны содержать эквивалентное состояние каталога. Сравнение возможно как между контроллерами одного домена, так и между контроллерами, принадлежащими разным доменам.
В процессе работы ldapcmp устанавливает соединения с двумя источниками LDAP-данных (подключение к удаленным серверам по протоколу LDAP или прямое подключение к локальной базе данных «Эллес») и формирует списки DN в стандартных разделах каталога (Domain, Configuration, Schema), а также в DNS-разделах (DomainDnsZones, ForestDnsZones). Для каждого общего DN выполняется извлечение LDAP-атрибутов соответствующего объекта и их поэлементное сравнение. Подкоманда проверяет наличие атрибутов с обеих сторон и эквивалентность их содержимого, фиксируя любые различия, включая отсутствие атрибута и несовпадение значений.
Подкоманда автоматически исключает атрибуты, не реплицируемые между контроллерами домена или зависящие от локального состояния конкретного контроллера (список таких атрибутов предопределен в исходном коде), и позволяет дополнительно указать пользовательские списки атрибутов для корректировки результирующего перечня для сравнения (см. описание логики формирования списка игнорируемых атрибутов в подразделе «Алгоритм формирования списка атрибутов, игнорируемых при сравнении»).
При сравнении данных контроллеров, принадлежащих разным доменам, дополнительно игнорируются атрибуты, которые уникальны для каждого домена. При этом в процесс обработки атрибутов выполняется нормализация значений, содержащих DN, DNS-имя домена, NetBIOS-имена и имена серверов, что позволяет сопоставлять логически эквивалентные объекты в разных средах.
Отдельно поддерживается режим сравнения только дескрипторов безопасности (атрибут nTSecurityDescriptor), в рамках которого ldapcmp сопоставляет записи управления доступом (ACE) в формате SDDL с возможностью сортировки и выбора способа представления различий.
Результаты сравнения предоставляются в виде детального отчета о различиях, включающего список объектов, которые присутствуют только на одном сервере, перечень атрибутов с различающими значениями, детализацию различий в дескрипторах безопасности и итоговую сводку по каждому разделу.
При обнаружении различия хотя бы в одном из сравниваемых разделов подкоманда возвращает в итоговой сводке ошибку "Compare failed" с кодом статуса -1.
Алгоритм формирования списка атрибутов, игнорируемых при сравнении
В процессе работы подкоманда ldapcmp формирует список атрибутов LDAP-объектов, которые должны игнорироваться при сравнении.
При формировании списка выполняется следующая последовательность шагов:
-
Используется предопределенный список, преимущественно состоящий из атрибутов, которые не подлежат репликации согласно схеме каталога (установлен флаг
FLAG_ATTR_NOT_REPLICATED):badPasswordTime badPwdCount dSCorePropagationData lastLogoff lastLogon logonCount modifiedCount msDS-Cached-Membership msDS-Cached-Membership-Time-Stamp msDS-EnabledFeatureBL msDS-ExecuteScriptPassword msDS-NcType msDS-ReplicationEpoch msDS-RetiredReplNCSignatures msDS-USNLastSyncSuccess partialAttributeDeletionList partialAttributeSet pekList prefixMap replPropertyMetaData replUpToDateVector repsFrom repsTo rIDNextRID rIDPreviousAllocationPool schemaUpdate serverState subRefs uSNChanged uSNCreated uSNLastObjRem whenChanged
-
К списку добавляются атрибуты, переданные при вызове подкоманды с помощью параметра
--filter. -
К списку добавляются атрибуты, перечисленные в файле, имя которого передано при вызове подкоманды с помощью параметра
--ignore-attributes. -
Из списка удаляются атрибуты, перечисленные в файле, имя которого передано при вызове подкоманды с помощью параметра
--force-cmp-attributes. -
Если участвующие в сравнении контроллеры находятся в разных доменах (при вызове подкоманды передан параметр
-w|--two), то в список добавляются следующие атрибуты:objectCategory objectGUID objectSid whenCreated whenChanged pwdLastSet uSNCreated creationTime modifiedCount priorSetTime rIDManagerReference gPLink ipsecNFAReference fRSPrimaryMember fSMORoleOwner masteredBy ipsecOwnersReference wellKnownObjects otherWellKnownObjects badPwdCount ipsecISAKMPReference ipsecFilterReference msDs-masteredBy lastSetTime ipsecNegotiationPolicyReference subRefs gPCFileSysPath accountExpires invocationId operatingSystem operatingSystemVersion oEMInformation schemaInfo targetAddress msExchMailboxGuid siteFolderGUID
Включенные в итоговый перечень атрибуты игнорируются при формировании списков различающихся значений атрибутов и атрибутов, присутствующих только на одном из участвующих в сравнении контроллеров домена.
|
Атрибуты обратных ссылок (Back Link) не реплицируются, но восстанавливаются по прямым ссылкам (Forward Link) исходных объектов. Подкоманда |
Формат вызова
Для сравнения БД LDAP на контроллерах в одном домене или двух разных доменах используется следующий формат вызова:
samba-tool ldapcmp <URL1> <URL2> (domain|configuration|schema|dnsdomain|dnsforest) [options]
При вызове подкоманды указываются:
-
URL БД LDAP первого контроллера домена в стандартном формате
ldap://<имя или IP-адрес хоста>; -
URL БД LDAP второго контроллера домена в стандартном формате
ldap://<имя или IP-адрес хоста>; -
список разделов каталога (через пробел) для сравнения:
-
domain; -
configuration; -
schema; -
dnsdomain; -
dnsforest.
-
По умолчанию сравниваются все разделы каталога.
Для каждого домена может быть передан свой набор реквизитов для доступа с помощью параметров -U|--username/--password и --username2/--password2.
Для изменения области поиска могут использоваться параметры (см. более подробное описание в подразделе «Параметры»):
-
--baseи--base2для задания адреса корневого объекта в каталоге, с которого должен начинаться поиск; -
--cmp-before=DATEи--cmp-after=DATEдля задания границ временного диапазона выборки объектов для сравнения;При использовании данных параметров следует учитывать следующие ограничения и особенности:
-
корректная работа с временными границами сравниваемого диапазона возможна при функциональном уровне домена и леса Windows Server 2008 R2 и выше;
-
чтобы при задании временных границ для сравнения в выборку попадали объекты, удаленные на первом контроллере домена, должен использоваться параметр
--search-deleted; -
объекты для сравнения выбираются по DN-имени, а не по GUID; таким образом, в сравнение могут попасть два разных объекта с совпадающими DN.
-
-
--ignore-attributes=FILENAMEи--force-cmp-attributes=FILENAMEдля загрузки файлов со списками атрибутов, которые должны быть исключены из выборки или включены в нее; -
--scope— диапазон поиска.
Список атрибутов (через запятую), которые должны быть исключены из сравнения, также может быть передан в параметре --filter.
Порядок следования параметров, изменяющих список игнорируемых при сравнении атрибутов, при вызове подкоманды ldapcmp в командной строке не имеет значения и не влияет на фактический порядок их применения. Параметры применяются строго в соответствии с внутренней логикой подкоманды, описанной в подразделе «Алгоритм формирования списка атрибутов, игнорируемых при сравнении».
|
Параметры
Общие параметры вызова:
-
-w|--two— признак того, что контроллеры находятся в разных доменах; -
--sd— сравнение только атрибутов, содержащих дескрипторы безопасности объектов каталога (nTSecurityDescriptor); -
--sort-aces— сортировка записей ACE в атрибутахnTSecurityDescriptorперед сравнением; -
--view=VIEW— режим отображения результатов сравнения атрибутовnTSecurityDescriptor; возможные значения:-
section— отображаются различия, связанные с отсутствием или несовпадением записей ACE; различия, связанные с несовпадением порядка следования записей, не отображаются, если совпадают значения записей и их количество (значение по умолчанию); -
collision— отображаются различия, связанные с отсутствием или несовпадением записей ACE, а также с несовпадением порядка следования записей, даже если совпадают значения записей и их количество;
-
-
--base=BASE— адрес корневого объекта в каталоге, с которого должен начинаться поиск в БД LDAP на первом контроллере домена; -
--base2=BASE2— адрес корневого объекта в каталоге, с которого должен начинаться поиск в БД LDAP на втором контроллере домена; -
--scope=SCOPE— диапазон поиска; возможные значения:-
SUB— при указании данной опции процесс поиска опускается вниз по иерархии от указанного DN (либо, если DN не указан, базового DN домена) до самого нижнего уровня в информационном дереве каталога; -
ONE— при указании данной опции процесс поиска опускается на один уровень от указанного DN (либо, если DN не указан, базового DN домена); -
BASE— при указании данной опции поиск ведется только для указанного DN (либо, если DN не указан, базового DN домена);
-
-
--filter=FILTER— список игнорируемых атрибутов (через запятую); -
--skip-missing-dn— пропуск отсутствующих DN-имен; -
--cmp-before=DATE— верхняя граница временного диапазона выборки объектов для сравнения в одном из следующих форматов:-
дата и время:
"%Y-%m-%d %H:%M:%S";Например:
--cmp-before="2024-08-21 12:17:45"
-
дата:
"%Y-%m-%d";Например:
--cmp-before="2024-08-21"
-
временной сдвиг влево относительно текущего момента времени:
"%d [d|day|days|h|hrs|hour|hours|m|min|mins|minute|minutes]".Например:
--cmp-before="12 hours" --cmp-before="1 d 6 h 10 m" --cmp-before="1 day 1 hour 10 minutes"
При задании данного параметра при сравнении будут обрабатываться только объекты, которые были изменены на первом контроллере домена (
URL1) до указанной временной границы. -
-
--cmp-after=DATE— нижняя граница временного диапазона выборки объектов для сравнения в одном из следующих форматов:-
дата и время:
"%Y-%m-%d %H:%M:%S";Например:
--cmp-after="2024-08-21 12:17:45"
-
дата:
"%Y-%m-%d";Например:
--cmp-after="2024-08-21"
-
временной сдвиг влево относительно текущего момента времени:
"%d [d|day|days|h|hrs|hour|hours|m|min|mins|minute|minutes]".Например:
--cmp-after="12 hours" --cmp-after="1 d 6 h 10 m" --cmp-after="1 day 1 hour 10 minutes"
При задании данного параметра при сравнении будут обрабатываться только объекты, которые были изменены на первом контроллере домена (
URL1) после указанной временной границы. -
-
--ignore-attributes=FILENAME— имя текстового файла со списком атрибутов (по одному атрибуту на каждой строке), которые должны быть исключены из сравнения (включены в фильтруемый набор атрибутов); -
--force-cmp-attributes=FILENAME— имя текстового файла со списком атрибутов (по одному атрибуту на каждой строке), которые должны быть включены в сравнение (исключены из фильтруемого набора атрибутов); -
--search-deleted— включение в выборку объектов, которые были удалены на первом контроллере домена, при задании границ временного диапазона; -
--json-output=FILENAME— сохранение результатов сравнения в файл в формате JSON с именем, указанным в качестве значения параметра;Формат файла
{ "records":[ (1) { "sourcePresent": true, (2) "destinationPresent": false, "object": { "objectClass": [ "organizationalPerson", "person", "top", "user" ], "cn": "User Name 1", ... } }, { "sourcePresent": false, (3) "destinationPresent": true, "object": { "objectClass": [ "organizationalPerson", "person", "top", "user" ], "cn": "User Name 2", ... } }, { "sourcePresent": true, (4) "destinationPresent": true, "object": { "objectClass": [ "organizationalPerson", "person", "top", "user" ], "cn": "User Name 3", "description": [ (5) [ "Original user" ], [ "Migrated user" ] ], "telephoneNumber": [ "123-45-67", null ], ... } }, {...} ], "sourcePresentDNs":[ (6) "CN=User Name 1,OU=OU1,DC=elles,DC=inno,DC=tech" ], "destinationPresentDNs":[ (7) "CN=User Name 2,OU=OU1,DC=elles,DC=inno,DC=tech" ], "attrDiffDNs":[ (8) "CN=User Name 3,OU=OU1,DC=elles,DC=inno,DC=tech" ] }Описание формата:
1 Блок записей о различиях в составе объектов и значений атрибутов в БД домена-источника и целевого домена в соответствии с переданными параметрами. Каждая запись состоит из трех полей: -
sourcePresent— признак существования объекта в БД домена-источника; -
destinationPresent— признак существования объекта в БД целевого домена; -
object— атрибуты объекта.
2 Пример записи об объекте, существующем в БД домена-источника, но отсутствующем в целевом домене. 3 Пример записи об объекте, существующем в целевом домене, но отсутствующем в БД домена-источника. 4 Пример записи об объекте, который существует и в БД домена-источника, и в БД целевого домена, но имеет различия в значениях атрибутов. Различающиеся атрибуты выводятся в виде массива, где первым элементом является значение атрибута в БД домена-источника, вторым — значение атрибута в БД целевого домена. 5 Различающиеся атрибуты выводятся в виде массива, где первым элементом является значение атрибута в БД домена-источника, вторым — значение атрибута в БД целевого домена. При отсутствии значения атрибута выводится null.6 Массив DN-имен объектов, которые существуют только в БД домена-источника. 7 Массив DN-имен объектов, которые существуют только в БД целевого домена. 8 Массив DN-имен объектов, атрибуты которых различаются в БД домена-источника и целевого домена. -
-
-v|--verbose— вывод детальной информации; -
-q|--quiet— тихий режим (отключает вывод диагностических сообщений во время работы подкоманды).
Порядок следования параметров, изменяющих список игнорируемых при сравнении атрибутов, при вызове подкоманды ldapcmp в командной строке не имеет значения и не влияет на фактический порядок их применения. Параметры применяются строго в соответствии с внутренней логикой подкоманды, описанной в подразделе «Алгоритм формирования списка атрибутов, игнорируемых при сравнении».
|
Дополнительные параметры доступа:
-
--simple-bind-dn2=DN2— DN-имя для использования при простом удаленном подключении к БД LDAP на втором контроллере домена; -
--username2=USERNAME2— имя пользователя для доступа к БД LDAP на втором контроллере домена; -
--password2=PASSWORD2— пароль пользователя для доступа к БД LDAP на втором контроллере домена; -
--workgroup2=WORKGROUP2— значениеWORKGROUPдля доступа к БД LDAP на втором контроллере домена; -
--no-pass2— отсутствие необходимости запрашивать пароль для доступа к БД LDAP на втором контроллере домена; -
--use-kerberos2=desired|required|off— необходимость аутентификации с использованием Kerberos при получении доступа к БД LDAP на втором контроллере домена.
Примеры
Пример сравнения БД LDAP на двух контроллерах в одном домене:
samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator
Пример сравнения отдельного раздела в БД LDAP на двух контроллерах в одном домене:
samba-tool ldapcmp ldap://DC1 ldap://DC2 configuration -UAdministrator
Пример сравнения с указанием игнорируемого атрибута:
samba-tool ldapcmp ldap://DC1 ldap://DC2 --filter=instanceType -UAdministrator
Пример сравнения атрибутов с указанием корневого DN:
samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \
--base='CN=FirstName SecondName,OU=OrgUnit,DC=elles,DC=inno,DC=tech' \
--base2='CN=FirstName SecondName,OU=OrgUnit,DC=elles,DC=inno,DC=tech'
Пример сравнения с указанием файла со списком атрибутов, которые должны быть исключены из обработки:
samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \
--ignore-attributes=attributes-to-ignore.txt
Примеры сравнения с указанием границ временного диапазона для выборки объектов:
-
с указанием даты и времени:
samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \ --cmp-before="2024-08-21 12:17:45" -
с указанием даты:
samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \ --cmp-before="2024-08-21" -
с указанием временного сдвига влево относительно текущего момента:
samba-tool ldapcmp ldap://DC1 ldap://DC2 -UAdministrator \ --cmp-after="1 day 1 hour 10 minutes"
Пример сравнения БД LDAP на контроллерах в разных доменах:
samba-tool ldapcmp ldap://DC1.elles1.inno.tech ldap://DC2.elles2.inno.tech --two -UAdministrator --username2=Administrator --password2=Passw0rd
Пример сохранения результатов сравнения в файл в формате JSON:
samba-tool ldapcmp ldap://DC1.elles.inno.tech ldap://DC1.example.com \
-UAdministrator \
--username2=Administrator \
--password2=Passw0rd
--two \
--base='CN=Group1,OU=OU1,DC=elles,DC=inno,DC=tech' \
--base2='CN=Group1,OU=OU1,DC=example,DC=com' \
--json-output=/tmp/comparison_results.json
В результате работы подкоманды формируется файл следующего вида:
Пример LDIF-файла
{
"records": [
{
"sourcePresent": true,
"destinationPresent": false,
"object": {
"objectClass": [
"organizationalPerson",
"person",
"top",
"user"
],
"cn": "User2",
"instanceType": "4",
"whenCreated": "20250117122503.0Z",
"whenChanged": "20250117122503.0Z",
"uSNCreated": "6236",
"name": "User2",
"objectGUID": "33ad1607-5929-4b99-93b9-b64e1aff1861",
"badPwdCount": "0",
"codePage": "0",
"countryCode": "0",
"badPasswordTime": "0",
"lastLogoff": "0",
"lastLogon": "0",
"primaryGroupID": "513",
"objectSid": "S-1-5-21-207620958-708556064-199204346-1108",
"accountExpires": "9223372036854775807",
"logonCount": "0",
"sAMAccountName": "User2",
"sAMAccountType": "805306368",
"userPrincipalName": "user2@elles.inno.tech",
"objectCategory": "CN=Person,CN=Schema,CN=Configuration,DC=elles,DC=inno,DC=tech",
"pwdLastSet": "133815903036300238",
"userAccountControl": "512",
"uSNChanged": "6238",
"memberOf": [
"CN=Group1,OU=OU1,DC=elles,DC=inno,DC=tech"
],
"distinguishedName": "CN=User2,OU=OU1,DC=elles,DC=inno,DC=tech"
}
},
{
"sourcePresent": true,
"destinationPresent": false,
"object": {
"objectClass": [
"organizationalPerson",
"person",
"top",
"user"
],
"cn": "User4",
"instanceType": "4",
"whenCreated": "20250117135451.0Z",
"whenChanged": "20250117135451.0Z",
"uSNCreated": "6245",
"uSNChanged": "6245",
"name": "User4",
"objectGUID": "ff0bd725-5f69-4377-b0f2-03de397aa55b",
"userAccountControl": "512",
"badPwdCount": "0",
"codePage": "0",
"countryCode": "0",
"badPasswordTime": "0",
"lastLogoff": "0",
"lastLogon": "0",
"pwdLastSet": "0",
"primaryGroupID": "513",
"objectSid": "S-1-5-21-207620958-708556064-199204346-1111",
"accountExpires": "9223372036854775807",
"logonCount": "0",
"sAMAccountName": "User4",
"sAMAccountType": "805306368",
"userPrincipalName": "user4@elles.inno.tech",
"objectCategory": "CN=Person,CN=Schema,CN=Configuration,DC=elles,DC=inno,DC=tech",
"distinguishedName": "CN=User4,OU=OU1,DC=elles,DC=inno,DC=tech"
}
},
{
"sourcePresent": false,
"destinationPresent": true,
"object": {
"objectClass": [
"organizationalPerson",
"person",
"top",
"user"
],
"cn": "User3",
"instanceType": "4",
"whenCreated": "20250117123126.0Z",
"uSNCreated": "98740",
"name": "User3",
"objectGUID": "372e06e9-0d08-4ce6-81b6-fa2b6e44d966",
"badPwdCount": "0",
"codePage": "0",
"countryCode": "0",
"badPasswordTime": "0",
"lastLogoff": "0",
"lastLogon": "0",
"primaryGroupID": "513",
"objectSid": "S-1-5-21-1159061634-2679507100-403793082-2217",
"accountExpires": "9223372036854775807",
"logonCount": "0",
"sAMAccountName": "User3",
"sAMAccountType": "805306368",
"userPrincipalName": "user3@example.com",
"objectCategory": "CN=Person,CN=Schema,CN=Configuration,DC=example,DC=com",
"pwdLastSet": "133815906868119132",
"whenChanged": "20250117123127.0Z",
"userAccountControl": "512",
"uSNChanged": "98742",
"memberOf": [
"CN=Group1,OU=OU1,DC=example,DC=com"
],
"distinguishedName": "CN=User3,OU=OU1,DC=example,DC=com"
}
},
{
"sourcePresent": true,
"destinationPresent": true,
"object": {
"objectClass": [
"group",
"top"
],
"cn": "Group1",
"instanceType": "4",
"name": "Group1",
"sAMAccountName": "Group1",
"sAMAccountType": "268435456",
"groupType": "-2147483646",
"member": [
[
"CN=User1,OU=OU1,DC=elles,DC=inno,DC=tech",
"CN=User2,OU=OU1,DC=elles,DC=inno,DC=tech"
],
[
"CN=User1,OU=OU1,DC=example,DC=com",
"CN=User3,OU=OU1,DC=example,DC=com"
]
],
"distinguishedName": "CN=Group1,OU=OU1,DC=elles,DC=inno,DC=tech"
}
},
{
"sourcePresent": true,
"destinationPresent": true,
"object": {
"objectClass": [
"organizationalPerson",
"person",
"top",
"user"
],
"cn": "User1",
"description": [
[
"Original user"
],
[
"Migrated user"
]
],
"instanceType": "4",
"name": "User1",
"codePage": "0",
"countryCode": "0",
"primaryGroupID": "513",
"sAMAccountName": "User1",
"sAMAccountType": "805306368",
"userPrincipalName": "user1@elles.inno.tech",
"userAccountControl": "512",
"memberOf": [
"CN=Group1,OU=OU1,DC=elles,DC=inno,DC=tech"
],
"telephoneNumber": [
"123-45-67",
null
],
"distinguishedName": "CN=User1,OU=OU1,DC=elles,DC=inno,DC=tech"
}
}
],
"sourcePresentDNs": [
"CN=USER2,OU=OU1,DC=elles,DC=inno,DC=tech",
"CN=USER4,OU=OU1,DC=elles,DC=inno,DC=tech"
],
"destinationPresentDNs": [
"CN=USER3,OU=OU1,DC=EXAMPLE,DC=COM"
],
"attrDiffDNs": [
"CN=GROUP1,OU=OU1,DC=EXAMPLE,DC=COM",
"CN=USER1,OU=OU1,DC=EXAMPLE,DC=COM"
]
}
Рекомендации по настройке состава сравниваемых атрибутов объектов каталога
Для получения оптимальных результатов при использовании подкоманды samba-tool ldapcmp для сравнения конфигураций контроллеров домена рекомендуется:
-
Предварительно сформировать файлы со списками атрибутов, которые:
-
должны игнорироваться при сравнении;
-
являются нереплицируемыми, но при этом должны быть учтены при сравнении.
-
-
При вызове подкоманды указать:
-
файл с игнорируемыми атрибутами в качестве значения ключа
--ignore-attributes; -
файл с учитываемыми атрибутами в качестве значения ключа
--force-cmp-attributes.
-
Далее приводится пример создания списков атрибутов для использования при сравнении:
-
список нереплицируемых атрибутов;
В список включаются все атрибуты, в системных флагах (System Flags) которых установлен бит
0x01(FLAG_ATTR_NOT_REPLICATED). -
список атрибутов, которые не реплицируются на контроллеры RODC;
В список включаются все атрибуты, в флагах поиска (Search Flags) которых установлен бит
0x00000200(fRODCFilteredAttribute). -
список атрибутов, являющихся обратными ссылками (Back Link).
В список включаются все атрибуты с нечетным значением идентификатора ссылки (
linkID).
Для выгрузки атрибутов из схемы каталога используется утилита ldapsearch (пакет ldap-utils), а для работы со списками — gawk (пакет gawk).
Чтобы сформировать списки игнорируемых атрибутов, выполните следующие действия на машине — участнике домена:
-
Если пакеты gawk и ldap-utils отсутствуют, установите их:
sudo apt install ldap-utils gawk
-
Для удобства дальнейшей работы задайте DN домена, имя пользователя с правами на доступ к схеме каталога, а также имена хостов, на которых развернуты сравниваемые БД LDAP, в качестве значений переменных.
Например:
DOMAINDC=DC=elles,DC=inno,DC=tech UserWithSchemaAdminRights=Administrator LDAPHOSTNAME1=dc1.elles.inno.tech LDAPHOSTNAME2=dc2.elles.inno.tech
-
Получите билет Kerberos для доступа к LDAP:
kinit ${UserWithSchemaAdminRights} -
Выгрузите схему каталога в файл (в примере — schema.withflags.raw) в текущем каталоге (у пользователя должны быть права на работу с файлами в каталоге):
ldapsearch -H ldap://${LDAPHOSTNAME1} -E pr=1000/noprompt -LLL \ -b CN=Schema,CN=Configuration,${DOMAINDC} \ -o ldif-wrap=no \ systemFlags searchFlags ldapDisplayName linkID > schema.withflags.rawВ приведенном примере используются следующие параметры
ldapsearch:-
-H— URL БД LDAP участвующего в сравнении контроллера домена; -
-E pr=1000/noprompt— ограничение размера одной страницы, возвращаемой сервером LDAP в ответ на запрос, с указанием на необходимость продолжения обработки запроса без подтверждения; -
-LLL— вывод результатов без комментариев и версии LDIF; -
-b— DN узла для использования в качестве точки начала поиска; -
-o ldif-wrap=no— опция, отключающая перенос строк; -
systemFlags searchFlags ldapDisplayName linkID— список дополнительных атрибутов для вывода в файл.
В результате выполнения команды формируется файл schema.withflags.raw, содержащий строки следующего вида:
... dn: CN=ms-DS-User-AuthN-Policy-BL,CN=Schema,CN=Configuration,DC=elles,DC=inno,DC=tech linkID: 2207 searchFlags: 0 lDAPDisplayName: msDS-UserAuthNPolicyBL systemFlags: 17 dn: CN=MS-TS-ExpireDate,CN=Schema,CN=Configuration,DC=elles,DC=inno,DC=tech searchFlags: 1 lDAPDisplayName: msTSExpireDate systemFlags: 16 dn: CN=ms-WMI-stringValidValues,CN=Schema,CN=Configuration,DC=elles,DC=inno,DC=tech searchFlags: 0 lDAPDisplayName: msWMI-StringValidValues systemFlags: 16 ...
-
-
Поскольку
ldapsearchне гарантирует определенный порядок вывода запрошенных атрибутов, используйтеgawkсо следующими параметрами для сортировки результатов по имени атрибута в рамках одного DN:cat schema.withflags.raw | gawk 'BEGIN{FS=": "}/^dn/{dn=$2}{print dn "#", $0}' |sort > schema.withflagsВ результате выполнения команды формируется файл schema.withflags, содержащий строки следующего вида:
... CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# dn: CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# lDAPDisplayName: accountNameHistory CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# searchFlags: 0 CN=Account-Name-History,CN=Schema,CN=Configuration,DC=gmsa,DC=lan# systemFlags: 16 ...
-
Выберите все нереплицируемые атрибуты (в System Flags установлен бит
0x01,FLAG_ATTR_NOT_REPLICATED) и сохраните их в отдельный файл в текущем каталоге:cat schema.withflags | gawk 'BEGIN{FS=": "}/lDAPDisplayName: /{ldapname=$2}/systemFlags:/{if(and(1,int($2))){print(ldapname)}}' \ > attributes.nonreplicatedВ результате выполнения команды формируется файл attributes.nonreplicated, содержащий строки с именами атрибутов:
badPasswordTime badPwdCount bridgeheadServerListBL dSCorePropagationData frsComputerReferenceBL ...
-
Выберите все атрибуты, которые не реплицируются на контроллеры RODC (в Search Flags установлен бит
0x00000200,fRODCFilteredAttribute), и сохраните их в отдельный файл в текущем каталоге:cat schema.withflags | gawk 'BEGIN{FS=": "}/lDAPDisplayName: /{ldapname=$2}/searchFlags:/{if(and(0x200,int($2))){print(ldapname)}}' \ > attributes.RODCFilteredВ результате выполнения команды формируется файл attributes.RODCFiltered, содержащий строки с именами атрибутов:
msFVE-KeyPackage msFVE-RecoveryPassword msKds-CreateTime msKds-DomainID msKds-KDFAlgorithmID ...
-
Выберите все атрибуты, являющиеся обратными ссылками (
linkIDимеет нечетное значение), и сохраните их в отдельный файл в текущем каталоге:cat schema.withflags | gawk 'BEGIN{FS=": "}/lDAPDisplayName: /{ldapname=$2}/linkID:/{if(0<int($2)%2){print(ldapname)}}' \ > attributes.BackLinksВ результате выполнения команды формируется файл attributes.BackLinks, содержащий строки с именами атрибутов:
bridgeheadServerListBL frsComputerReferenceBL fRSMemberReferenceBL memberOf isPrivilegeHolder ...
-
Объедините файлы любым доступным способом.
Например:
cat attributes.* > attributes.AllIgnored
-
Если в итоговый файл попадают атрибуты, которые не должны реплицироваться и вычисляются, но, тем не менее, должны учитываться при сравнении, отредактируйте файл вручную либо поместите такие атрибуты в отдельный файл (в примере — attributes.ForceComparison).
-
Выполните сравнение с помощью подкоманды
samba-tool ldapcmp(на машине должен быть установлен пакет inno-samba), указав полученные файлы в соответствующих ключах:samba-tool ldapcmp ldap://${LDAPHOSTNAME1} ldap://${LDAPHOSTNAME2} \ -U ${UserWithSchemaAdminRights} \ --ignore-attributes=attributes.AllIgnored \ --force-cmp-attributes=attributes.ForceComparison
Обновлено: