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-LDAP p? SourceForge.
- 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:
-
Det at noen s?keresultater returneres betyr ikke at alle resultatene ble returnert. Sjekk om statuskoden som returneres etter s?keresultatene er
success
(LDAP_SUCCESS
) eller ikke. -
Etter enkelte statuskoder vil alle p?f?lgende operasjoner p? samme forbindelse feile, spesielt etter
LDAP_SERVER_DOWN
(en feilkode fra OpenLDAP-biblioteket, ikke fra selve tjeneren).Programmer b?r derfor enten lukke forbindelsen n?r de mottar en statuskode de ikke kjenner igjen, eller spesialbehandle de aktuelle statuskodene. Deretter kan de evt. ?pne en ny forbindelse - men ikke gj?r det i en evig l?kke.
Hvis f?rste operasjon p? en forbindelse f?r
LDAP_SERVER_DOWN
kan det v?re en idé ? sove et sekund eller tre f?r du pr?ver ? ?pne en ny forbindelse, siden tjeneren antakelig er tatt ned og blir restartet. Men du f?r ogs?LDAP_SERVER_DOWN
n?r tjeneren har lukket en forbindelse som har v?rt inaktiv for lenge, eller om du pr?ver en adresse/port hvor det ikke er noen LDAP-tjener. -
<size/time/admin>LimitExceeded
:
Programmer som spesialbehandlersizeLimitExceeded
ogtimeLimitExceeded
b?r ogs? sjekkeadminLimitExceeded
og kanskjeunwillingToPerform
.Det kan v?re noe tilfeldig hvilken av disse som returneres, og om det blir returnert noen s?keresultater f?rst eller ikke.
Ved UiO har vi lagt inn s?kebegrensninger slik at hvis et s?k ville ta for lang tid, vil det som regel feile med
adminLimitExceeded
med det samme - i stedet for ? s?ke i 15+ sekunder (som er v?r max-grense for s?k) og deretter kanskje feile likevel. Men hvis s?ket ikke er fullt s? tungt eller hvis filteret er komplekst og tjeneren ikke ser hvor tungt det er, kan det i stedet returnere noen resultater fulgt av en annen*LimitExceeded
kode.
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.