Quatre defauts mesures dans l'integration Keycloak/LDAP, meme famille : une
valeur declaree d'un cote, consommee de l'autre, rien qui verifie la jonction.
1. Aucune regle ne s'appliquait sur le chemin d'un vrai utilisateur. Sonde :
« abcd » refuse par l'operation etendue LDAP, accepte par Keycloak (204),
puis actif pour l'authentification. Keycloak ecrivait userPassword en
direct (ppolicy aveugle) et le realm n'avait aucune passwordPolicy.
2. ldap_entry ne fait que CREER : la politique etait figee a sa creation. Le
depot disait pwdMustChange TRUE, le serveur FALSE — une reconstruction
from-zero aurait ressuscite la boucle du 2026-08-07. ldap_attrs state=exact
reconcilie la politique et l'overlay (DN lu, pas devine).
3. syncRegistrations absent : un compte cree dans Keycloak n'atteignait jamais
ou=people — acces web, aucune boite, invisible du modele de groupes.
4. Le prenom pointait sur cn (nom complet) : « Administrateur systeme systeme ».
Ajoute roles/resoudre_politique_mdp : LA declaration, traduite en pwdPolicy,
passwordPolicy et anti-force-brute. Les deux roles la consomment sans la
redeclarer.
usePasswordModifyExtendedOp ET validatePasswordPolicy : la seconde est
porteuse, Keycloak se liant en rootDN et slapd n'appliquant pas ses controles
de qualite au rootDN. La premiere seule aurait paru juste sans tenir.
Verification : abcd -> 400 « minimum length 12 » et absent de LDAP ; mot de
passe conforme -> 204 puis ldapwhoami accepte ; POST users -> 201 ET present
dans ou=people. Second passage des deux playbooks : changed=0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Le realm portait une politique d'acces complete et aucun moyen d'ecrire a qui
que ce soit. Tout oubli remontait donc a l'exploitant, qui n'avait d'autre
choix que de manipuler le mot de passe d'autrui.
- serveur_keycloak/tasks/courriel-realm.yml : reconcilie smtpServer et
resetPasswordAllowed ; hote du relais DERIVE de applications.postfix.hote,
et refus explicite si le plan ne declare pas de MTA.
- passe par l'API d'administration : kcadm.sh accepte les deux formes -s sur
une map, sort en succes et n'ecrit rien (smtpServer reste vide).
- amorcage_acces_courriel redevient a declarer : cette adresse designe une
personne, hors du systeme qu'on amorce ; une boite interne serait illisible
tant qu'on n'a pas l'acces qu'on cherche justement a recuperer.
- autorisation.md §6.6 : le mecanisme, ses deux conditions, et l'ecart
d'adresse laisse par l'ancien mode READ_ONLY de la federation.
Preuve : banniere SMTP lue depuis idm-01, RCPT TO accepte, execute-actions-email
declenche, MTA en starttls -> relay=mx.chezlepro.ca status=sent (250). Second
deploiement changed=0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Cree uid=sysadmin et cn=sysadmin dans LDAP. Prouve sur idm-01 : le compte
s'authentifie, et le second passage ne touche a rien (changed=0, 7 taches
sautees) — idempotence par EXISTENCE, pas par conformite (D-67).
Il suit l'annuaire au lieu de se declarer au plan : il ecrit par `ldapi:///` et
doit tourner sur cet hote. Le declarer comme groupe obligerait chaque instance a
le poser sur le bon hote, et elles ne le nomment pas pareil (idm-01 ici,
id-ldap-01 chez Technolibre) — je l'ai d'abord pose sur infra-pki-01 par erreur.
Trois defauts trouves en le construisant :
1. `pwdReset` n'existe pas dans ce schema (overlay ppolicy non charge) :
l'entree entiere etait rejetee et `no_log` masquait la cause. J'avais suppose
un mecanisme sans verifier. Le role le DETECTE maintenant, et la doctrine ne
promet plus un changement force qui n'a pas lieu.
2. Le mot de passe aurait ete stocke EN CLAIR : `ldap_entry` ecrit userPassword
litteralement. Hache par `slappasswd -h {SSHA}` desormais.
3. `voute.py` ne scannait que roles/<groupe> : un role applique par un playbook
sans etre un groupe echappait au recensement, ce que D-20 interdit. Il suit
maintenant les listes `roles:` des playbooks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>