Résumé

  • Dès les premiers RFC, le MessageID n’était unique que parmi les requêtes encore actives d’une session LDAP. Toutes les entrées et le résultat final d’une recherche reprenaient ce nombre, autorisant l’entrelacement de plusieurs opérations.
  • Abandon emploie deux identifiants : celui de sa propre enveloppe et celui de l’opération visée. Comme aucun accusé de résultat n’est défini, la corrélation reste exacte sans devenir une preuve d’arrêt ; RFC 3909 créa ensuite Cancel pour obtenir une issue explicite.
  • Une recherche paginée change de message ID à chaque page et poursuit son état avec un cookie opaque. L’identifiant reste local à l’opération ; il n’authentifie personne et ne garantit aucun retour arrière.

Un résultat pouvait être toute une série

Accéder à un annuaire X.500 par un protocole « léger » ne rendait pas nécessairement la réponse courte. Une recherche sous un nœud pouvait produire beaucoup d’entrées, éventuellement des références vers des zones non explorées, puis seulement un verdict final. Il fallait reconnaître l’ensemble sans interdire à la connexion de servir autre chose entre-temps.

En juillet 1993, le RFC 1487 plaça chaque opération dans une enveloppe LDAPMessage. Son champ commun était un entier, messageID, distinct de ceux des autres requêtes en attente dans la même session. Chaque enveloppe de réponse correspondant à la requête devait le répéter.

Le choix est plus subtil qu’un numéro de paquet. Toutes les entrées d’une recherche portent le même nombre parce qu’elles alimentent le même état d’opération. Leur objet est nommé par le distinguished name ; leur forme est indiquée par le type d’opération. Le nombre fournit seulement la jointure dont le client a besoin pour ranger le message reçu dans le bon dossier actif.

Sa portée était volontairement petite. Deux sessions pouvaient employer la même valeur. Une session pouvait la réutiliser après la fin certaine du travail précédent. La propriété utile n’était donc pas l’unicité mondiale, mais l’absence d’ambiguïté parmi les opérations simultanées que le destinataire pouvait réellement observer.

L’asynchronisme donna sa valeur au champ

Le RFC 1777, publié en 1995, précisa que clients et serveurs n’étaient pas tenus à un comportement synchrone. Les requêtes et réponses de plusieurs opérations pouvaient circuler dans n’importe quel ordre.

Une recherche 17 pouvait livrer une première entrée ; une comparaison 18, lancée ensuite, pouvait recevoir son résultat avant la deuxième entrée 17. TCP ordonnait les octets, pas leur appartenance à une opération applicative. Le Message ID transformait une suite physique unique en plusieurs suites logiques lisibles.

Avec LDAPv3, le RFC 2251 conserva ce principe, fixa la limite à 2^31−1 et interdit la réutilisation avant la réponse finale. Les clients incrémentaient généralement un compteur, mais la monotonie n’était pas la garantie : l’absence de doublon parmi les travaux en cours l’était.

La recherche distinguait alors SearchResultEntry, SearchResultReference et SearchResultDone. Entrées et références pouvaient alterner ; une seule réponse finale annonçait la réussite ou l’erreur. Recevoir des entrées ne prouvait donc pas l’achèvement. Le message terminal donnait à la fois un résultat et, en temps normal, la preuve que l’identifiant pouvait sortir du registre des opérations actives.

Le zéro fut réservé à une initiative du serveur

En 2006, la spécification LDAPv3 fut réorganisée. Le RFC 4510 décrit cette filiation, tandis que le RFC 4511 porte la règle actuelle du protocole.

Une requête doit y employer un ID non nul. La valeur zéro appartient aux notifications non sollicitées du serveur, notamment l’avis de déconnexion. Cette séparation permet de reconnaître une parole exceptionnelle qui ne répond à aucune requête du client.

Ce zéro n’est ni un privilège d’identité ni une racine d’autorité. Le type extendedResp et l’OID de notification expliquent le message. La valeur sépare seulement deux classes de corrélation : le travail demandé par le client et la notification née hors de ce travail.

La réutilisation dépend de la durée réelle du service. Le client ne reprend un nombre que lorsqu’il peut déterminer que le serveur ne traite plus l’ancienne requête, par exemple après la réponse finale ou après un Bind ultérieur achevé. Un délai local n’est pas automatiquement une clôture distante.

Abandon nommait précisément une cible sans promettre son sort

Une requête Abandon possède son propre MessageID dans l’enveloppe. Son contenu est un second MessageID, celui de l’opération antérieure à abandonner. Les deux rôles restent visibles : identifier le nouvel acte et sélectionner la cible.

Pourtant, Abandon n’a pas de réponse. Selon RFC 4511, le serveur peut abandonner l’opération. Si une recherche émettait déjà des entrées, il cesse d’en envoyer et ne produit pas de SearchResultDone. Le client doit néanmoins accepter que des résultats déjà en transit arrivent encore, et certaines opérations ne peuvent pas être abandonnées.

L’absence de réponse rend le signal économique pour un client qui ne veut plus du résultat. Elle interdit aussi une conclusion confortable : le silence ne distingue pas l’abandon réussi d’un travail non terminé. Un identifiant exact n’accorde aucune connaissance supplémentaire de l’effet.

Le RFC 2251 conseillait donc de ne réutiliser ni l’ID d’Abandon ni celui de la cible avant la réponse d’une requête envoyée plus tard. Cette réponse ultérieure ne certifiait pas l’abandon ; elle apportait seulement un repère prudent dans l’avancement de la session.

Cancel ajouta l’issue qui manquait

Le RFC 3909, en 2004, ne transforma pas rétroactivement Abandon. Il créa une opération étendue Cancel lorsque l’application exige une indication du résultat.

L’enveloppe Cancel reçoit un identifiant propre et son cancelID nomme l’opération cible. En cas de réussite, une réponse Cancel confirme l’acceptation et l’opération visée se termine avec le code canceled. D’autres codes séparent une opération inconnue, impossible à annuler ou déjà trop avancée.

Le cas tooLate fixe la frontière de pouvoir. L’exemple du RFC est une modification déjà inscrite dans le stockage sous-jacent. Le bon identifiant peut sélectionner exactement la bonne modification ; il ne dispose pas pour autant d’une machine à remonter le temps.

Bind, StartTLS, Unbind, Abandon et Cancel ne sont pas annulables. Ils établissent ou démantèlent l’association, l’authentification ou la couche de sécurité dans laquelle les autres identifiants ont un sens. Le protocole refuse ainsi de laisser une simple clé de corrélation commander son propre cadre d’autorité.

La page suivante changeait d’opération

Le RFC 2696 rend la limite encore plus nette. Une réponse paginée place un cookie opaque dans SearchResultDone. Pour obtenir la suite, le client renvoie les paramètres de recherche mais change le messageID, joint le dernier cookie et peut modifier la taille de page.

Chaque page est une nouvelle opération LDAP. Le cookie assure la continuité du jeu de résultats. Une ancienne valeur peut être refusée ; un cookie vide annonce la fin. Abandon peut interrompre la page courante mais risque d’invalider le cookie. Fermer proprement la séquence demande une nouvelle recherche de taille zéro avec la dernière valeur.

Le message ID répond donc à une question locale : quelle opération active a produit ce message ? Le cookie répond à une question temporelle : quel état de pagination le serveur autorise-t-il à reprendre ? Le nom de l’entrée, l’autorisation et la vérité de ses attributs relèvent encore d’autres preuves.

Ce que les RFC ne permettent pas d’affirmer

Le dossier historique se limite aux RFC 1487, RFC 1777, RFC 2251, RFC 2696, RFC 3909, RFC 4510 et RFC 4511. Ces textes prouvent l’évolution et les obligations publiées. Ils ne mesurent pas l’adoption actuelle, ne certifient aucun produit et ne révèlent pas l’issue d’une opération particulière.

La solidité de ce nombre vient précisément de sa modestie. Il relie un message à un état observable. Les preuves d’achèvement, d’annulation, de continuation, d’authentification et d’autorisation restent ailleurs.