Haut de page

Configuration de LDAP dans MacOS X
pour Carnet d'adresses et le Mail


Après avoir attendu MacOS X Server v10.4 qui offre une interface un petit peu plus complète pour des attributs du carnet d'adresses (Address Book Attributes), j'ai décidé de mettre plutôt cela en oeuvre sur MacOS X (version cliente) afin de séparer l'annuaire LDAP destiné au carnet d'adresse de l'annaire LDAP d'identification.

Le but de l'opération consiste à créer un annuaire LDAP qui va servir à compléter les adresses électroniques lors de la rédaction des mails et qui va aussi compléter les adresses et numéros de téléphone dans l'application Carnet d'adresses.

LDAP (Lightweight Directory Access Protocol) est un protocole d'accès à un annuaire, dérivé d' X500, au dessus de TCP/IP. C'est une implémentation allégée du protocole ISO DAP. Le port TCP 389 est utilisé en standard par LDAP, démon slapd (Stand-alone LDAP Daemon).

Les bases de données LDAP sont référencées par leur DN (Distinguished Name) en général basé sur le nom de la machine dans le DNS. Au premier niveau se trouvent les DC (Domain Components), ensuite se trouvent les OU (organizational units) et les CN (common name).

La première solution sera de mettre en place l'annuaire LDAP sur sa propre machine (localhost). Il faudra ensuite, pour une utilisation réelle, y accéder en SSL et protéger la lecture par un mot de passe.


Configuration pour serveurs MacOS X Server 10.6

Dans la configuration mise en place, j'ai un serveur d'authentification principal MacOS X Server 10.6 (Maître Open Directory) et un serveur secondaire MacOS X Serveur 10.6 connecté au premier serveur pour le serveur de carnets d'adresses (Address Book).

Connexion LDAPs entre serveurs

Et c'est là que commencent les problèmes car il faut que la connexion SSL se fasse sans erreur. En particulier, si vous avez un certificat d'une autorité de certification non reconnue par défaut dans le système.
Il ne se passe rien et cela part en time out en tentant une connexion non sécurisée.

Si vous choisissez de ne pas cocher Encrypt using SSL, cela semble marcher et vous pouvez cocher après la case SSL sur la fenêtre de dialogue précédente.

Malheureusement, lorsque vous allez tenter de configurer un autre service, cela ne fonctionnera pas. Par exemple, vous allez obtenir les erreurs suivantes :

Le problème de fond est que la connexion SSL ne se fait pas correctement car le certificat paraît auto-signé. On a confirmation de cela avec la commande :

ldapsearch -LLL -d 4 -H ldaps://ip_authentification_server:636 -b "dc=lip6,dc=fr" "uid=one_user_login" ldap_build_search_req ATTRS: supportedSASLMechanisms TLS certificate verification: Error, self signed certificate in certificate chain

La note technique d'Apple Mac OS X Server v10.5, 10.6: Enabling SSL for Open Directory binding est une bonne piste mais elle n'est pas suffisante.
Au lieu d'ajouter la ligne TLS_CACERT, il faut indiquer un répertoire contenant tous les certificats de la chaîne de certification : TLS_CACERTDIR /private/etc/openldap/ldapssl/

Je crée donc le répertoire /etc/openldap/ldapssl/ et j'y mets

-rw-r--r-- 1 root wheel 1521 22 jan 2010 3c58f906.0 -rw-r--r-- 1 root wheel 1655 22 jan 2010 9df51c42.0 -rw-r--r-- 1 root wheel 1529 22 jan 2010 ff783690.0

Voir ici comment créer les fichiers et à quoi ils correspondent.

Il faut relancer ldap sur la machine (le plus facile est de redémarrer le serveur)

Lancement du serveur Address Book

Dans le répertoire /Library/AddressBookServer/, sont créés des répertoire au nom et groupe _carddav. Un répertoire Data ne contenant rien, un répertoire Documents contenant un fichier .server-uuid (contenu : 5C807CE3-A717-4C34-B1E4-842CB7A9C0C6) et un répertoire directory vide.

Configuration pour les photos

CardDav

Si on met une photo, le fichier .vcf contient un PHOTO;BASE64: qui, une fois décodée donne un JPEG image data, JFIF standard 1.01.

LDAP

Il est aussi possible de mettre une photo la rubrique jpegPhoto du serveur LDAP. Voici un exemple de code php qui permet de le faire à partir d'une photo stockée en png sur un serveur web.

$newinfo=array(); $jpeg_filename="http://www.xxx.fr/photos/128x128/nom_photo.png"; if ($sData=file_get_contents($jpeg_filename)) $newinfo["jpegPhoto"][0]=$sData; if (count($newinfo) != 0) {  $result=ldap_modify($link_identifier, $valid_dn , $newinfo);  if ($result==false) { echo "Erreur (ldap_modify) : " . ldap_error($link_identifier); echo "\n\n\n"; exit(); } }


Configuration pour clients MacOS X 10.5 et 10.6

Configuration du client Carnet d'adresses

Carnet d'adresses 5.0.3 (MacOS v10.6)

Après avoir connecté un client (dont le GeneratedUID est 4F970F8F-2D92-41F6-9E50-6E29ACE89BBD), le répertoire /Library/AddressBookServer/Documents contient un nouveau répertoire addressbooks contenant trois répertoires __uids__, groups et users. Seul le répertoire __uids__ n'est pas vide et contient : /4F/97/4F970F8F-2D92-41F6-9E50-6E29ACE89BBD/addressbook/.db.sqlite.

Après avoir ajouter des contacts et des groupes de contacts sur le compte serveur, le répertoire qui contient .db.sqlite, contient maintenant des fichiers .vcf : 1E0A4E59-C09A-4C16-8E3A-C32099CA3E95-ABSPlugin.vcf et 97BFC6AE-609B-433B-865E-9D32415F5F7D-ABSPlugin.vcf.

Carnet d'adresses 4.1.2 (MacOS v10.5)

Configuration du client iChat


7 novembre 2007

ATTENTION : L'utilisation avec Mail et Carnet d'adresses ne marche plus avec MacOS X 10.5 (Leopard) une erreur

Binding to server did not complete successfully: '-1:Can't contact LDAP server'

apparait dans system.log. Quelques pistes de recherche


Activation du serveur LDAP

Sur la version cliente de MacOS X, OpenLDAP est configuré pour s'interfacer avec NetInfo (la base de données locale d'informations système des premières version de MacOS X) comme le montre le fichier /etc/openldap/slapd.conf

## # slapd.conf file for NetInfo bridge ## include /etc/openldap/schema/core.schema include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/nis.schema include /etc/openldap/schema/inetorgperson.schema include /etc/openldap/schema/misc.schema include /etc/openldap/schema/samba.schema include /etc/openldap/schema/apple.schema pidfile /var/run/slapd.pid argsfile /var/run/slapd.args allows bind_v2 schemacheck off database netinfo suffix "" flags DSENGINE_FLAGS_NATIVE_AUTHORIZATION DSSTORE_FLAGS_ACCESS_READWRITE datasource /var/db/netinfo/network.nidb include /etc/openldap/schema/netinfo.schema

Un première étape va consister à changer ce fichier pour l'interfacer avec berkeley DB. Avant cela il faut créer un mot de passe d'administration pour l'utilisateur diradmin. Ensuite nous créerons une base LDAP pour le domaine dc=lip6,dc=fr.

Mise en place d'un mot de passe pour l'accès en écriture sur LDAP

Nous allons utiliser la commande slappasswd pour générer un mot de passe SMD5. Dans la suite de l'exemple nous prendrons passtest comme mot de passe.

slappasswd -c -v -h "{SMD5}"

cela va donner : {SMD5}WGSuH+O73Q6elc1e10k/bDKvK9Y=

Interface avec Berkeley DB

Dans le fichier /etc/openldap/slapd.conf, remplacer les lignes à partir de database netinfo par :

#################### # bdb database definitions #################### database bdb suffix "dc=lip6,dc=fr" rootdn "cn=diradmin,dc=lip6,dc=fr" rootpw {SMD5}WGSuH+O73Q6elc1e10k/bDKvK9Y= directory /var/db/openldap/openldap-data

Avant lancement, le répertoire /var/db/openldap/openldap-data est vide et n'est accessible qu'en lecture/écriture par root.

Activation manuelle

On active LDAP en lançant le démon slapd.

sudo /usr/libexec/slapd

Pour l'arrêter faire un kill sur le processus dont le numéro se trouve dans le fichier /var/run/slapd.pid.

ou en mode debug par :

sudo /usr/libexec/slapd -d 1

Activation automatique au démarrage de la machine

A mettre dans les StartupItems comme dans MacOS X Server :

#!/bin/sh ## # LDAP server ## . /etc/rc.common StartService () { ## # Start up LDAP server ## if [ "${LDAPSERVER:=-NO-}" = "-YES-" ]; then if ! pid=$(GetPID slapd); then ConsoleMessage "Starting LDAP server" if [ "${LDAPSSL:=-NO-}" = "-YES-" ]; then slapd -h "ldap:// ldaps:///" else slapd fi fi fi ## # Start up LDAP replicator ## if [ "${LDAPREPLICATOR:=-NO-}" = "-YES-" ]; then if ! pid=$(GetPID slurpd); then ConsoleMessage "Starting LDAP replicator" mkdir -p /var/run/openldap-slurp/replica slurpd fi fi } StopService () { if pid=$(GetPID slapd); then ConsoleMessage "Stopping LDAP server" kill -INT "${pid}" else ConsoleMessage "LDAP server is not running." fi if pid=$(GetPID slurpd); then ConsoleMessage "Stopping LDAP replicator" kill -INT "${pid}" fi } RestartService () { tries=10 StopService while [ -e /var/run/slapd.pid ] && (( tries-- > 0 )); do ConsoleMessage "Waiting for LDAP server to quit." sleep 1 done if pid=$(GetPID slapd); then kill -9 "${pid}" /bin/rm -f /var/run/slapd.pid fi while [ -e /var/run/slurpd.pid ] && (( tries-- > 0 )); do ConsoleMessage "Waiting for LDAP replicator to quit." sleep 1 done if pid=$(GetPID slurpd); then kill -9 "${pid}" /bin/rm -f /var/run/slurpd.pid fi StartService } RunService "$1"


Création et modifications de la base LDAP

Initialisation de la base

Nous créeons une base dc=lip6,dc=fr avec la commande :

ldapadd -x -D "cn=diradmin,dc=lip6,dc=fr" -w passtest -f start.txt

le fichier start.txt contenant :

# start.txt dn: dc=lip6,dc=fr objectclass: top objectclass: organization o: lip6 description: Annuaire LIP6

Ajout et supressions des entrées dans la base

Nous créeons toutes les entrées sous la rubrique contact avec la commande :

ldapadd -x -D "cn=diradmin,dc=lip6,dc=fr" -w passtest -f LIP6-ldif.txt

le fichier LIP6-ldif.txt contenant par exemple :

dn: cn=contacts, dc=lip6,dc=fr objectClass: container cn: contacts # Mounier Jean-Luc dn: uid=PE120, cn=contacts, dc=lip6,dc=fr objectClass: inetOrgPerson uid: PE120 givenName: Jean-Luc sn: Mounier street:: OCBydWUgZHUgQ2FwaXRhaW5lIFNjb3R0CkJ1cmVhdSBDLjExNDM= postalCode: 75015 l: Paris c: France mail: Jean-Luc.Mounier[@]lip6.fr labeledURI: http://www-src.lip6.fr/homepages/Jean-Luc.Mounier/ telephoneNumber: 01 44 27 61 89 # Personne Suivante

La supression de toutes les entrées se fait avec la commande :

ldapdelete -r -x -D "cn=diradmin,dc=lip6,dc=fr" -w passtest "cn=contacts,dc=lip6,dc=fr"

A propos du format LDIF accepté

L'encodage de caractères est en UTF-8 et si on veut mettre plusieurs lignes il faut uuencoder le texte comme ici la rubrique street.

Dans mon cas, j'utilise un script php sur un serveur pour produire le fichier, cela me donne un début de script comme ceci :

#!/bin/sh # Jean-Luc Mounier # ImportLDAP.sh extration du fichier LDIF par requete https et remplacement dans la base LDAP curl -k --user utilisateur:mot_de_passe "https://localhost/LDAP.php" -o LIP6-ldif.txt #curl --user utilisateur:mot_de_passe "http://localhost/LDAP.php" -o LIP6-ldif.txt if [ $? != 0 ] then echo erreur dans curl exit 1 fi ldapdelete -r -x -D "cn=diradmin,dc=lip6,dc=fr" -w passtest "cn=contacts,dc=lip6,dc=fr" ~/bin/recode latin1..UTF8 LIP6-ldif.txt ldapadd -x -D "cn=diradmin,dc=lip6,dc=fr" -w passtest -f LIP6-ldif.txt > /dev/null if [ $? != 0 ] then echo erreur dans ldapadd exit 1 fi


Utilisation de la base LDAP dans le Carnet d'adresses et Mail MacOS 10.4

Dans l'application Carnet d'adresses, choisir Préférences... du menu Carnet d'adresses puis LDAP.

Cliquer le l'icône "+". Remplir les rubriques Nom, Server et Base de recherche.

Ensuite dans le carnet d'adresse, choisir le Groupe Répertoire et taper au moins deux caractères dans zone de recherche en haut à gauche de la fenêtre. La liste des fiches correspondantes s'affiche. Vous pouvez les consulter ou les déplacer dans un autre groupe afin d'en garder une copie. Si vous avez coché Mise à jour automatique des fiches LDAP, elle seront mises à jour dans votre carnet d'adresse si elle changent sur le serveur (je n'ai pas testé).

Dans l'application Mail, choisir Préférences... du menu Mail puis Rédaction. Dans la rubrique Adressage, sélectionner Compléter automatiquement les adresses et cliquer sur le bouton Configurer LDAP... Il n'y a rien à faire c'est déjà configuré :)


Limiter l'accès à la base LDAP

Jusque là, il est possible de se connecter à la base LDAP en utilisateur anonyme et consulter les fiches de l'annuaire. Nous allons protéger l'accès en créant un utilisateur nommé annuaire avec un mot de passe. Ensuite nous indiquerons que seuls les utilisateurs authentifiés peuvent lire la base.

Pour faire correctement les choses nous commençons par faire en sorte que personne ne puisse aller lire les informations concernant l'utilisateur annuaire. Pour cela nous mettons l'utilisateur annuaire dans un sous-répertoire nommé acces auquel nous interdisons la lecture à tous.

Dans le fichier /etc/openldap/slapd.conf, ajouter :

# Interdire la lecture sous le repertoire acces access to dn.subtree="ou=acces,dc=lip6,dc=fr" by users none by anonymous auth

cn=annuaire,ou=acces,dc=lip6,dc=fr

Dans le fichier /etc/openldap/slapd.conf, ajouter :

# Acces en lecture aux utilisateurs authentifies access to * by users read by anonymous auth

Fabriquer un mot de passe pour l'utilisateur annuaire

slappasswd -c -v -h "{SMD5}"

et mettre le résultat à la place du mot de passe dans le fichier le fichier start.txt contenant :

# ou pour l'utilisateur annuaire dn: ou=acces,dc=lip6,dc=fr objectClass: top objectClass: organizationalunit ou: acces # Utilisateur annuaire dn: cn=annuaire,ou=acces,dc=lip6,dc=fr cn: annuaire objectClass: top objectClass: person userPassword: sn: utilisateur annuaire permettant les recherches

Configuration client

Dans la configuration de l'Application Carnet d'adresses (Préférences LDAP), il faut compléter les rubriques Nom d'utilisateur, Mot de passe et choisir le type d'authentification simplifiée.


Activation en SSL

Si vous vous créer un certificat auto-signé :

openssl genrsa -des3 -out server.key 2048 openssl req -new -key server.key -out server.crt openssl x509 -req -days 365 -set_serial 1 -in server.crt -signkey server.key -out ca.crt

Ou bien composez les trois certificats sur le modèle de qu'il faut faire pour MacOS X Server. (/etc/openldap/ssl/server.crt, /etc/openldap/ssl/server.key, /etc/openldap/ssl/ca.crt).

mkdir -p /etc/openldap/ssl cd /etc/openldap/ssl chown -R ldap:ldap /etc/openldap/ssl chown root:wheel /etc/openldap/ssl chmod 700 /etc/openldap/ssl

Dans le fichier /etc/openldap/slapd.conf, ajouter :

# SSL TLSCertificateFile /etc/openldap/ssl/server.crt TLSCertificateKeyFile /etc/openldap/ssl/server.key TLSCACertificateFile /etc/openldap/ssl/ca.crt TLSCipherSuite HIGH

Lancement

# J'ai rajouté 'ldap:/// ldaps:///' afin de faire fonctionne le TLS et je n'écoute qu'en IPv4 (-4)
sudo /usr/libexec/slapd -4 -h 'ldap:// ldaps:///'

Eventuellement avec -d 1 et -u ldap -g ldap si si on le lance même au nom de l'utilisateur ldap du groupe ldap.

ldapadd -x -H 'ldaps:///' -D "cn=diradmin,dc=lip6,dc=fr" -w passtest -f start.txt
ldapadd -x -H 'ldaps:///' -D "cn=diradmin,dc=lip6,dc=fr" -w passtest -f LIP6-ldif.txt
ldapdelete -r -x -H 'ldaps:///' -D "cn=diradmin,dc=lip6,dc=fr" -w passtest "cn=contacts,dc=lip6,dc=fr"
# test si ça passe en TLS
ldapsearch -H "ldap:///" -b "dc=lip6,dc=fr" -x -ZZ
# test si ça passe en LDAPS
ldapsearch -H "ldaps:///" -b "dc=lip6,dc=fr" -x
# test si ça passe en LDAP
ldapsearch -H "ldap:///" -b "dc=lip6,dc=fr" -x

Configuration client

Dans la configuration de l'Application Carnet d'adresses (Préférences LDAP), il faut Utiliser SSL et changer le port pour remettre 389 car l'application utilise TLS au lieu de se connecter au port habituel 636.


Problèmes rencontrés...

Si vous obtenez des erreurs comme :


TLS_CACERTDIR


Déplacement d'un carnet d'adresse (ou Contacts depuis OS X 10.9) d'un compte à un autre compte sur la même machine

Le carnet d'adresse se trouvent dans ~/Library/Application\ Support/AddressBook/, penser à un mkdir -p ~/Library/Application\ Support/AddressBook avant.

mkdir -p "/Users/compte_destination/Library/Application Support/AddressBook" cd "/Users/compte_de_depart/Library/Application Support" tar cf AddressBook.tar AddressBook mv AddressBook.tar "/Users/compte_destination/Library/Application Support/". cd "/Users/compte_destination/Library/Application Support/" rm -Rf AddressBook tar xf AddressBook.tar chown -R compte_destination:staff AddressBook rm AddressBook.tar

À tester

Voir aussi

2005-2011



FutureShare

|

Glossaire

|