Journal PHP 7.3 apporte la gestion des contrôles dans PHP-LDAP

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
42
19
jan.
2019

Sommaire

PHP 7.3 est sorti le 6 décembre 2018 et apporte la gestion des contrôles dans l’extension LDAP.

La précédente version 7.2 contenait, elle, la prise en charge des opérations étendues.

Étant à l’origine de ces deux ajouts je voulais revenir sur ces fonctionnalités et leur prise en charge dans PHP.

PHP-LDAP

Le gestion de LDAP dans PHP est un peu datée. Il n’y a pas d’interface orientée objet, et la prise en charge de certaines fonctionnalités avancées du protocole LDAP était manquante.

En cherchant un peu, je suis tombé sur des correctifs et des tickets qui dataient de 2005 pour les plus vieux. Ça manquait clairement de mainteneur côté PHP, et la seule fonctionnalité à avoir été fusionnée était la gestion des contrôles dans le cas très spécifique de la pagination : http://php.net/manual/fr/function.ldap-control-paged-result.php.

J’ai donc contacté le projet PHP et j’ai demandé à devenir mainteneur du module LDAP. C’était étonnamment facile d’obtenir le poste (a priori, personne chez PHP ne s’intéressent à LDAP, et c’était juste un truc qu’ils gardaient dans un coin parce que ça marche). Mon employeur a accepté que je fasse ça sur mon temps de travail, vu l’usage avancé que l’on fait de LDAP, et on compte bien utiliser les nouvelles fonctionnalités à terme.

J’ai d’abord naïvement pensé qu’il suffirait de relancer les gens qui s’étaient heurtés à des refus pour être enseveli par les propositions de correctifs et n’avoir plus qu’à faire mon marché. Mais étonnamment, depuis 2005, il semble que les gens concernés aient changé de postes, d’entreprise ou d’intérêts, et je n’ai quasiment pas eu de réponses. J’ai assez vite compris que j’allais devoir développer moi‐même si je voulais faire avancer les choses, en m’inspirant des différents correctifs glanés sur le Web.
Ça a été un peu difficile puisque, comme j’ai toujours contacté les serveurs LDAP au travers de PHP, les choses qui ne sont pas gérées par PHP-LDAP, je ne les ai jamais utilisées. Mais j’y suis parvenu, et l’on arrive enfin au terme de cette trop longue introduction.

PHP 7.2 : les opérations étendues

Les opérations étendues (Extended Operations, souvent abrégées exop), sont des opérations autre que celles de base (add, bind, delete, search, compare et `modify), dont la prise en charge varie d’un serveur LDAP à un autre. Il faut donc d’abord consulter le RootDSE, c’est‐à‐dire faire une recherche LDAP avec un DN (distinguished name) vide et le scope base. Dans le résultat, on regarde l’attribut supportedExtension qui liste les OID des opérations étendues gérées par ce serveur.

PHP 7.2 ajoute donc la fonction suivante pour appeler de telles opérations :

ldap_exop( resource $link , string $reqoid [, string $reqdata = NULL [, array $serverctrls = NULL [, string &$retdata [, string &$retoid ]]]] ) : mixed

Comme $reqdata doit pour la plupart des opérations contenir des données encodées en BER et que c’est pas forcément trivial à faire, il existe aussi des helpers pour les opérations étendues les plus courantes :

  • ldap_​exop_​passwd : opération étendue pour changer un mot de passe (qui laisse le serveur s’occuper du hachage et permet à des overlays comme password policy d’appliquer des politiques de mot de passe) ;
  • ldap_​exop_​refresh : opération pour rafraîchir une entrée dynamique (uniquement disponible dans PHP 7.3, j’ai raté la date butoir) ;
  • ldap_​exop_​whoami : opération pour obtenir le DN utilisé lors du bind.

À noter que des constantes sont aussi définies pour tous les OID des opérations étendues connues, à savoir : LDAP_EXOP_START_TLS, LDAP_EXOP_MODIFY_PASSWD, LDAP_EXOP_REFRESH, LDAP_EXOP_WHO_AM_I et LDAP_EXOP_TURN.

PHP 7.3 : les contrôles

Les contrôles sont un autre moyen d’étendre le protocole LDAP, cette fois‐ci lors d’une opération standard, mais à laquelle on veut rajouter des contraintes ou des fonctionnalités. De la même manière que pour les opérations étendues, on peut connaître les contrôles gérés par le serveur en interrogeant le RootDSE et en regardant l’attribut supportedControl.

Comme il y a beaucoup plus de contrôles et qu’il doivent être passés avec les opérations classiques, je n’ai pas fait une méthode par contrôle pris en charge, mais j’ai convenu d’une façon de représenter chaque contrôle sous forme d’un tableau. Avec la plupart des opérations LDAP il est maintenant possible de passer un tableau contenant pour chaque contrôle à envoyer un tableau contenant les clés suivantes :

  • oid : chaîne contenant l’OID du contrôle ; il est recommandé d’utiliser les constantes prédéfinies ;
  • iscritical : booléen indiquant quoi faire si le serveur ne connaît pas ce contrôle : soit il l’ignore, soit l’opération échoue ; attention, certains contrôles indiquent dans leur RFC que iscritical doit toujours être à vrai ;
  • value : soit une chaîne contenant directement la valeur, soit, pour les contrôles pris en charge, un tableau contenant les données appropriées.

Pour les clés attendues dans value en fonction des contrôles, je vous laisse lire la documentation.

Les contrôles gérés sont les suivants :

  • LDAP_CONTROL_PAGEDRESULTS, qui permet de paginer les résultats d’une recherche ;
  • LDAP_CONTROL_ASSERT, qui permet d’ajouter une assertion nécessaire à l’exécution d’une opération (exemple : s’assurer qu’un entier vaut n dans une modification qui le met à n + 1) ;
  • LDAP_CONTROL_VALUESRETURNFILTER, qui permet de filtrer les valeurs retournées pour un attribut ;
  • LDAP_CONTROL_PRE_READ, qui permet de lire certains attributs avant exécution de l’opération (exemple : sauver la valeur de certains attributs lors d’une suppression) ;
  • LDAP_CONTROL_POST_READ, qui permet de lire certains attributs après opération (exemple : lire la valeur d’un attribut auto‐généré à la création d’une entrée) ;
  • LDAP_CONTROL_SORTREQUEST, qui permet de demander au serveur de trier les résultats d’une requête ;
  • LDAP_CONTROL_VLVREQUEST, qui permet de faire des vues, assez proche de la pagination ;
  • LDAP_CONTROL_PASSWORDPOLICYREQUEST, qui indique qu’on souhaite avoir les informations ppolicy dans la réponse ;
  • LDAP_CONTROL_MANAGEDSAIT, qui indique qu’on veut modifier une référence et pas l’objet qu’elle référence ;
  • LDAP_CONTROL_DONTUSECOPY, qui interdit au serveur de travailler sur une copie des données ;
  • LDAP_CONTROL_PROXY_AUTHZ, qui est l’équivalent LDAP d’un sudo.

Il peut aussi y avoir des contrôles dans les réponses, qui sont récupérables avec ldap_parse_result.
Pour les opérations qui ne donnaient pas accès à l’objet réponse, par exemple ldap_bind qui renvoie directement un booléen, une version avec le suffixe « _ext » a été ajoutée pour obtenir l’objet réponse.

Futur

ldap_sort est déprécié et sera retiré dans PHP 8, ldap_control_paged_result et ldap_control_paged_result_response devraient être bientôt dépréciées et retirées aussi de PHP 8, au profit de la nouvelle API.

Idéalement, il faudrait ajouter à ldap_exop la gestion des exop sous forme de tableau, comme pour les contrôles, pour ne pas avoir à passer par les fonctions spécifiques à chaque exop et pouvoir facilement envoyer des contrôles avec une exop et récupérer les contrôles retournés par le serveur.

À noter que toutes ces fonctionnalités ont encore été peu testées. Donc, n’hésitez pas à ouvrir des rapports de bogue si vous rencontrez des problèmes lors de leur utilisation.

  • # Félicitation !

    Posté par  . Évalué à 8.

    D'abord félicitation pour ton travail c'est cool de voir quelqu'un qui se met à pouvoir contribuer au libre en étant payé !

    J’ai d’abord naïvement pensé qu’il suffirait de relancer les gens qui s’étaient heurtés à des refus pour être enseveli par les propositions de patch et n’avoir plus qu’à faire mon marché. Mais étonnamment depuis 2005 il semble que les gens concernés aient changés de postes, entreprise, intérêts et je n’ai quasiment pas eu de réponses.

    C'est ironique ? S'il n'existe pas, dans le langage que j'utilise une fonctionnalité si je ne peux pas ajouter facilement ma fonctionnalité, il y a de forte chance que je regarde ailleurs…

    ldap_sort est déprécié et sera retiré dans PHP 8

    Il y a des plans pour un PHP8 ?

    • [^] # Re: Félicitation !

      Posté par  (site web personnel) . Évalué à 10.

      D'abord félicitation pour ton travail c'est cool de voir quelqu'un qui se met à pouvoir contribuer au libre en étant payé !

      Mon travail était de toutes façons de faire du logiciel libre, je suis le développeur de FusionDirectory: https://www.fusiondirectory.org/fr/ (L’employeur est OpenSides)
      Mais ça reste chouette de pouvoir contribuer à PHP en parallèle, et j’espère qu’on pourra bientôt lier les deux et utiliser les nouveautés PHP coté FusionDirectory, mais vu qu’on doit supporter Centos et Debian stable c’est pas tout de suite.

      C'est ironique ? S'il n'existe pas, dans le langage que j'utilise une fonctionnalité si je ne peux pas ajouter facilement ma fonctionnalité, il y a de forte chance que je regarde ailleurs…

      C’est à moitié ironique. J’ai réellement cru que les gens allaient revenir avant de me rendre compte qu’ils étaient tous passés à autre chose. Ce n’était en aucun cas une critique de leur comportement par contre, c’est tout à fait normal, le but était plus d’ironiser sur ma naïveté à penser que tout allait se faire tout seul après une inactivité aussi longue du module php-ldap.

      Il y a des plans pour un PHP8 ?

      Il y aura encore PHP 7.4, peut-être 7.5, et ensuite ce sera 8.
      Rien de particulièrement révolutionnaire, c’est juste que numéroter une majeure va leur permettre de retirer ou déprécier des fonctionnalités que les politiques de release interdisent de retirer dans une version mineure. C’est pour faire du ménage.

  • # PHP LDAP objet

    Posté par  (site web personnel) . Évalué à 1.

    Le gestion de LDAP dans PHP est un peu datée. Il n’y a pas d’interface orientée objet,

    Il y a un paquet Pear Net_LDAP2 disponible dans packagist
    https://packagist.org/packages/pear/net_ldap2

    Je le trouve assez agréable d'utilisation mais il commence à dater car plus vraiment maintenu. Pas de recherche paginée par exemple.

    Quelqu'un connait une alternative ? Je crois que le webmail Roundcube a bossé sur son successeur Net_LDAP3 mais je n'ai jamais réussi à mettre la main sur le code.

    http://gregr.fr

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.