LDAP-programmering ved UiO

Litt forskjellige råd og tips om LDAP-programmering følger. Se også sidene om bruk og innhold av katalogen.


Verktøy

Det finnes LDAP-biblioteker i flere programmeringsspråk, deriblant:

C (og C++):
OpenLDAPs biblioteker.
Mozillas LDAP C SDK.
Perl:
Modulen Net::LDAP (skrevet i ren Perl). Ved UiO kan den installers fra Store-pakken "Net-LDAP.pm". Det finnes også et enklere grensesnitt til den, Net::LDAP::Express. Begge er fra CPAN (Comprehensive Perl Archive Network).
Mozillas PerLDAP.
Python:
Modulene "ldap" og "ldif" i Python-LDAPSourceForge.
Java:
Mozillas LDAP Java SDK.
USIT har utviklet et Java-bibliotek, no.uio.ldap, som er en overbygning på Mozillas LDAP Java SDK. Biblioteket er tilpasset LDAP-katalogen ved UiO. Det gjør det enkelt å autentisere personer/brukere og å søke/navigere i katalogen. 

Noen av disse trenger også OpenSSL hvis du trenger å kryptere forbindelsen med TLS/SSL, men den bør allerede være installert på din maskin.

Et program som ldapsearch fra OpenLDAP er nyttig til å teste de søkene man utvikler, siden man kan oppgi alle slags søk og det gjør nøyaktig det søket man ber om. Det er installert på en del maskiner.

Vi planlegger å lage Store-pakker og distribuere det over til de som ber om det.

Tegnsett

Tegnsettet til attributtene UiO bruker i katalogen er Unicode kodet som UTF-8. Norske tegn må derfor oversettes mellom UTF-8 og brukerens tegnsett.

Noen attributter godtar imidlertid ikke full Unicode. F.eks:
"gecos" i bruker-objekter godtar bare ASCII, så i det attributtet lagrer UiO "æøå" som "[\]" tilsv. det vi gjør i NIS. (Dette vil antakelig endres en gang.)
"telephoneNumber" godtar bare et subsett av ASCII.

Spesialtegn

I noen situasjoner må en del spesialtegn skrives som \hex (der hex er 2 hexadesimale sifre med ASCII-verdien til tegnet) eller som \tegn. Pass særlig på brukerinput. Tilsvarende må \hex og \tegn i verdier fra katalogen i visse tilfeller dekodes:

I søkefiltre:
Tegnene NUL ( * ) \ skrives som \hex. Andre tegn kan også kodes slik.
I DN-er (objektnavn) og RDN-er når man "bygger" dem fra attributt-verdier, i motsetning til ferdige DN-er man mottar fra katalogen:
Mellomrom og "#" på begynnelsen av attributt-verdier, mellomrom på slutten, samt tegnene NUL " + , ; < > \ må skrives om. Untatt NUL kan disse skrives som \tegn. Dessuten kan alle tegn - også andre enn disse - skrives på \hex-form.
I postadresser (postalAddress) men ikke gateadresser (street):
$ og \ må skrives på \hex-form, siden "$" i dette attributtet betyr linjeskift.
I LDAP-URL-er:
I LDAP-URL-er kodes dessuten noen tegn som %hex slik som i vanlige URL-er. Dette gjøres med resultatet av å kode spesialtegn i URL-ens komponenter (som DN og filter) som beskrevet over. Se RFC 4514.

Format på objekter

Et LDAP-objekt består av et usortert sett av attributter, som hver har et navn (attribute description/type) og et usortert sett med verdier. Objektets navn (dets DN, Distinguished Name) er ikke en del av objektet, men navnets første komponent (RDN, Relative Distinguished Name) er bygd fra en eller flere attributverdier som må finnes i objektet.

Noen programmer (f.eks. ldapsearch) viser objekter i LDIF-format, definert i RFC 2849. I dette formatet vises attributter som inneholder 8-bits tegn, newline og enkelte andre rariteter som "attributtnavn:: base64-kodet verdi", mens andre attributter vises med ett enkelt kolon fulgt av verdien selv. Merk at verdien ikke er base64-kodet når den sendes over LDAP-protokollen. Det er klienten som bruker base64 lokalt. Husk også at en linje i LDIF som starter med mellomrom er en fortsettelse av forrige linje; du setter sammen linjene ved å fjerne newline og ett mellomrom.

Eksempel:

dn: ou=USIT,ou=SADM,ou=Universitetsstyret,cn=organization,dc=uio,dc=no
# Husk at dette er ett attributt med 2 verdier, selv om det
# i LDIF-format ser ut som 2 attributter med 1 verdi hver:
ou: USIT
ou: Universitetets senter for informasjonsteknologi
cn: Universitetets senter for informasjonsteknologi
objectClass: top
objectClass: organizationalUnit
objectClass: norEduOrgUnit
mail: postmottak@usit.uio.no
labeledURI: http://www.usit.uio.no/
telephoneNumber: 22852470
facsimileTelephoneNumber: 22852730
postalAddress: Pb. 1059 - Blindern$0316 OSLO
# Base64-kodet UTF-8 gateadresse:
street:: SW5mb3JtYXRpa2tieWduaW5nZW4sIEdhdXN0YWRhbGzDqWVuIDIzLCAwMzczIE9TTE8=
norEduOrgAcronym: USIT
norEduOrgUniqueNumber: 00000185
norEduOrgUnitUniqueNumber: 330000

Bruk av Bind

Se først Autentisering.

Vår tjener støtter bare Simple Bind, som ikke krypterer passordet. Bind med passord må derfor bare brukes over forbindelser kryptert med TLS/SSL.

LDAP-forbindelser er initielt anonyme. Skal du bruke en anonym forbindelse, er det ikke nødvendig å binde anonymt først. LDAP versjon 2 krevde det, men LDAP versjon 3 gjør ikke.

Hvis du bruker StartTLS-operasjonen til å kryptere forbindelsen, bør du imidlertid binde etterpå - enten anonymt eller med passord. Det er fordi en "Man-in-the-middle" angriper kunne ha lagt inn en Bind-operasjon før StartTLS-operasjonen, så forbindelsen ville få uventete privilegier. på den annen side, hvis du kobler opp mot "ldaps"-porten (LDAP over SSL) i stedet for å bruke StartTLS mot "ldap"-porten, kunne en angriper ikke gjøre det, så du trenger ikke anonym Bind.

Programmer som ber om passord og sjekker om passordet er riktig ved å gjøre Bind, må først sjekke at passordet ikke er tomt. En Bind med DN og tomt passord er lov ifølge standarden, men oppretter en bare anonym forbindelse. Vår tjener avviser slike Bind-operasjoner, men det finnes andre tjenere som godtar dem. Du bør skrive programmer slik at de ikke blir til sikkerhetshull hvis man tar dem i bruk med en annen tjener.

Merk imidlertid at USIT ikke er særlig glad i at folk lager tjenester som ber brukeren om passord. FEIDE er uansett ofte en bedre løsning.

Feilhåndtering

Riktig feilhåndtering er viktig når du programmerer med LDAP. Noen feilsituasjoner å passe på er:

Tjeneren supplerer som regel statuskoden med en tekstlig melding, og noen ganger også et "matchedDN"-felt. Programmer som skriver ut statuskoder fra tjeneren (eller en forklaring av disse) bør også skrive ut disse feltene.