OpenDJ – modyfikowanie schematu bez zatrzymywania serwera
Pisałem wcześniej o konwersji schematów do LDIF oraz o dodawaniu schematów offline poprzez wgranie do katalogu config/schema
w OpenDJ i restart serwera. Teraz opiszę jak rozszerzyć schemat w trybie online, czyli bez konieczności restartu serwera LDAP. Większość, jeśli nie wszystkie obecne wersje serwerów LDAP posiadają możliwość dokonywania zmian w konfiguracji i schematach przy użyciu formatu LDIF i narzędzi typu ldapmodify
. Przygotujmy więc odpowiedni plik, najpierw atrybuty:
# cat us-newattrs.ldif
dn: cn=schema changetype: modify add: attributeTypes attributeTypes: ( 1.3.6.1.4.1.XXXX.1.1.11 NAME 'usTypeOfStudies' DESC 'Type of studies' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) - add: attributeTypes attributeTypes: ( 1.3.6.1.4.1.XXXX.1.1.12 NAME 'usSystemOfStudies' DESC 'System of studies' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
Objaśnienie skąd biorą się te cyferki znajdziecie w dokumentacji LDAP i RFC. W miejscu XXXX występuje OID, czyli unikalny numer, który powinien być pozyskany/zarejestrowany dla danej instytucji.
Teraz część, która modyfikuje istniejącą już w schemacie klasę obiektu (najpierw delete
później add
):
# cat us-modclass.ldif
dn: cn=schema changetype: modify delete: objectClasses objectClasses: ( 1.3.6.1.4.1.XXXX.1.2.2 NAME 'useduplStudAccount' DESC 'us.edu.pl account extension for students' SUP useduplAccount AUXILIARY MAY ( usUsosId $ usUsosLogin $ usUsosPass $ usIndexNum $ usAccountActive ) ) - add: objectClasses objectClasses: ( 1.3.6.1.4.1.XXXX.1.2.2 NAME 'useduplStudAccount' DESC 'us.edu.pl account extension for students' SUP useduplAccount AUXILIARY MAY ( usUsosId $ usUsosLogin $ usUsosPass $ usIndexNum $ usAccountActive $ usTypeOfStudies $ usSystemOfStudies ) )
Skoro pliki są już przygotowane, to warto jeszcze zrobić backup przed dokonaniem zmian w katalogu LDAP.
# cd /data/var/OpenDJ
# mkdir ../backup
# ./bin/backup --backUpAll --compress --backupDirectory ../backup
[19/Jun/2012:10:11:18 +0200] category=TOOLS severity=NOTICE msgID=10944792 msg=Starting backup for backend config
[19/Jun/2012:10:11:19 +0200] category=TOOLS severity=NOTICE msgID=10944792 msg=Starting backup for backend userRoot
[19/Jun/2012:10:11:21 +0200] category=JEB severity=NOTICE msgID=8847446 msg=Archived: 00000000.jdb
[19/Jun/2012:10:11:24 +0200] category=JEB severity=NOTICE msgID=8847446 msg=Archived: 00000001.jdb
[19/Jun/2012:10:11:27 +0200] category=JEB severity=NOTICE msgID=8847446 msg=Archived: 00000002.jdb
[19/Jun/2012:10:11:30 +0200] category=JEB severity=NOTICE msgID=8847446 msg=Archived: 00000003.jdb
...
[19/Jun/2012:10:13:01 +0200] category=JEB severity=NOTICE msgID=8847446 msg=Archived: 000004cb.jdb
[19/Jun/2012:10:13:01 +0200] category=TOOLS severity=NOTICE msgID=10944792 msg=Starting backup for backend replicationChanges
[19/Jun/2012:10:13:03 +0200] category=JEB severity=NOTICE msgID=8847446 msg=Archived: 00000005.jdb
[19/Jun/2012:10:13:04 +0200] category=JEB severity=NOTICE msgID=8847446 msg=Archived: 00000006.jdb
[19/Jun/2012:10:13:04 +0200] category=TOOLS severity=NOTICE msgID=10944792 msg=Starting backup for backend schema
[19/Jun/2012:10:13:04 +0200] category=TOOLS severity=NOTICE msgID=10944792 msg=Starting backup for backend tasks
[19/Jun/2012:10:13:04 +0200] category=TOOLS severity=NOTICE msgID=10944795 msg=The backup process completed successfully
Dodajemy nowe atrybuty:
# ./bin/ldapmodify -D cn=dirmgr -h localhost -X -f ../us-newattrs.ldif
Password for user 'cn=dirmgr':
Processing MODIFY request for cn=schema
MODIFY operation successful for DN cn=schema
Sprawdzamy „na sucho” czy modyfikacja objectClass nie spowoduje żadnych błędów, opcja -n
oznacza „dry run”
# ./bin/ldapmodify -D cn=dirmgr -h localhost -X -n -f ../us-newclass.ldif
Password for user 'cn=dirmgr':
Processing MODIFY request for cn=schema
Skoro nie ma żadnych błędów, pomijamy -n
i dokonujemy modyfikacji klasy
# ./bin/ldapmodify -D cn=dirmgr -h localhost -X -f ../us-newclass.ldif
Password for user 'cn=dirmgr':
Processing MODIFY request for cn=schema
MODIFY operation successful for DN cn=schema
Jeśli istnieją odpowiednio skonfigurowane repliki LDAP, to zmiany w schemacie zostaną na nich odwzorowane automatycznie. Można to sprawdzić zaglądając choćby do katalogu config/schema
na innym serwerze:
# less 99-user.ldif
dn: cn=schema
objectClass: top
objectClass: ldapSubentry
objectClass: subschema
cn: schema
attributeTypes: ( 1.3.6.1.4.1.XXXX.1.1.12 NAME 'usSystemOfStudies' DESC 'System of studies' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
attributeTypes: ( 1.3.6.1.4.1.XXXX.1.1.11 NAME 'usTypeOfStudies' DESC 'Type of studies' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
ds-sync-generation-id: 8408
modifiersName: cn=Directory Manager,cn=Root DNs,cn=config
ds-sync-state: 00000132f753ae9a5d4900000001
ds-sync-state: 000001316b1b6be44a1a00000001
ds-sync-state: 0000013803e4be617c7400000004
modifyTimestamp: 20120619083838Z
Uwaga: Pisałem, że da się zmodyfikować schemat bez restartu serwera LDAP, możecie jednak napotkać błąd przy próbie dodania nowych atrybutów do istniejącego wpisu, posiadającego już modyfikowaną klasę obiektu. Wiąże się to z tym, że serwer przechowuje w cache skompresowany schemat, objawia się to błędem o kodzie 65:
Result Code: 65 (Object Class Violation) Additional Information: Entry xxx cannot not be modified because the resulting entry would have violated the server schema: Entry xxx violates the Directory Server schema configuration because it includes attribute testattr which is not allowed by any of the objectclasses defined in that entry
Bug jest zgłoszony i ma być poprawiony w wersji 2.5. W wersjach 2.4.x (zgłoszone w 2.4.2) należy zrestartować serwer aby obejść ten problem. Więcej o tym można poczytać na stronie: https://bugster.forgerock.org/jira/browse/OPENDJ-169