OpenDS / OpenDJ - Problème de recherche "Unindexed search"

Suite à l'installation d'une instance OpenDS 2.3 sur une pré-production, sur RHEL 7 et java 1.6, un utilisateur se plaignait de ne plus pouvoir faire fonctionner son application.

Lorsqu'il lançait sa recherche, il n'avait aucun résultat, mais un message d'erreur :

SEARCH operation failed
Result Code:  50 (Insufficient Access Rights)
Additional Information:  You do not have sufficient privileges to perform an unindexed search

La résolution du problème a pris quelques heures, le temps d'écumer le guide d'administration (plutôt complet) et les différents sites internet (dont celui de Ludovic Poitou, toujours très utile).

La requête de base est la suivante :

  • Scope : wholeSubTree
  • Base ou=site,ou=p1,ou=repository,o=rootSuffix
  • Filter : (id=*).

Sachant qu'il y a 9400 objets dans l'ou=site, et que l'attribut id est le RDN de l'objet, tous les objets ont donc un id.

Debug de l'utilisation des requêtes

Le blog de Ludovic Poitou comprenait un article qui parlait des indexes dans OpenDJ (très compatible avec OpenDS), et notamment un attribut opérationnel debugsearchindex qui permet d'avoir les comportement de l'annuaire par rapport aux index.

Exemple :

ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=*)' debugsearchindex
dn: cn=debugsearch
debugsearchindex: filter=(id=*)[NOT-INDEXED] scope=singleLevel[LIMIT-EXCEEDED:94
 17] final=[NOT-INDEXED]

L'attribut n'est pas indexé. On va donc ajouter un index, de type substring.

Création d'un index

dsconfig create-local-db-index --port 4444 --hostname localhost --bindDN "cn=Directory Manager" \
--bindPassword password --backend-name userRoot \
--index-name id  --set index-type:substring \
--trustAll --no-prompt

Puis on lance le rebuild-index

rebuild-index --port 4444 -h localhost -D "cn=directory manager" -w password  --baseDN o=rootSuffix --index id --start 0 --trustAll

A ce stade, si on lance la même requête, on a toujours le même souci.

Par contre, avec un sous-ensemble, ça fonctionne :

ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=ne*)' debugsearchindex
dn: cn=debugsearch
debugsearchindex: filter=(id=ne*)[INDEX:id.substring][COUNT:76] scope=singleLeve
 l[LIMIT-EXCEEDED:9417] final=[COUNT:76]

Note : la recherche en (id=*) nécessite un index de type présence. Il faut donc créer un index de type substring ET presence.

Après avoir faire la création et le rebuilt, on peut vérifier les index :

bin/dbtest list-index-status -b "o=rootSuffix" -n userRoot
Index Name                 Index Type  JE Database Name                     Index Status
----------------------------------------------------------------------------------------
id2children                Index       o_rootSuffix_id2children                true
id2subtree                 Index       o_rootSuffix_id2subtree                 true
uid.equality               Index       o_rootSuffix_uid.equality               true
id.presence                Index       o_rootSuffix_id.presence                true
id.substring               Index       o_rootSuffix_id.substring               true

Cependant, la recherche sur id=* ne fonctionne toujours pas avec un compte "normal"

bin/ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=*)' debugsearchindex
dn: cn=debugsearch
debugsearchindex: filter=(id=*)[INDEX:id.presence][LIMIT-EXCEEDED] scope=singleL
 evel[LIMIT-EXCEEDED:9417] final=[LIMIT-EXCEEDED:9417]

Changement de la limitation sur les index

Il faut alors jouer avec la propriété  index-entry-limit, qui spécifie le nombre maximum des entrées garder dans un index. Dans notre cas, sachant qu'on a actuellement 9400 entrées de type site, et d'autres objets qui ont également un attribut id, on va fixer la valeur à 12 000.

bin/dsconfig set-local-db-index-prop --port 4444 --hostname localhost --bindDN "cn=Directory Manager" \
--bindPassword password --backend-name userRoot \
--trustAll --no-prompt \
--index-name id \
--set index-entry-limit:12000


Après avoir lancé le rebuild,

bin/ldapsearch -p 25389 -D 'cn=directory manager' -w password -s one -b ou=site,ou=p1,ou=repository,o=rootSuffix '(id=*)' debugsearchindex
dn: cn=debugsearch
debugsearchindex: filter=(id=*)[INDEX:id.presence][COUNT:10084] scope=singleLeve
 l[LIMIT-EXCEEDED:9417] final=[COUNT:10084]

 

A ce niveau, la recherche fonctionne, mais on se heurte à une autre limite :

SEARCH operation failed
Result Code:  4 (Size Limit Exceeded)
Additional Information:  This search operation has sent the maximum of 1000 entries to the client

Modification des limites du compte

Par défaut, on a des limites sur le nombre de résultats retournés :

  • ds-rlim-lookthrough-limit : 5000
  • ds-rlim-size-limit : 1000

Il faut donc modifier ces valeurs. Par exemple via un fichier LDIF :

dn: cn=VliPre, ou=account, ou=security, o=rooutSuffix
changetype:modify
add: ds-rlim-size-limit
ds-rlim-size-limit: 15000
-
add: ds-rlim-lookthrough-limit
ds-rlim-lookthrough-limit: 15000


Après toutes ces modifications, le compte peut bien récupérer toutes les entrées.

Par contre, on peut se poser la question sur l'intérêt de récupérer des milliers d'entrées.

Désactivation globale du privilège

En derner recours, il est possible de désactiver globalement le privilège unindexed-search, en passant par ds-config.

On peut voir configuration en cours :

/opt/OpenDS-2.3.0/bin/dsconfig get-global-configuration-prop \
--port 4444 --hostname localhost --trustAll --bindDN "cn=Directory Manager" --bindPassword password --no-prompt

Property                              : Value(s)
--------------------------------------:------------------------
bind-with-dn-requires-password        : true
default-password-policy               : Default Password Policy
disabled-privilege                    : -
entry-cache-preload                   : false
etime-resolution                      : milliseconds
idle-time-limit                       : 0 ms
lookthrough-limit                     : 5000
max-allowed-client-connections        : 0
proxied-authorization-identity-mapper : Exact Match
reject-unauthenticated-requests       : false
return-bind-error-messages            : false
save-config-on-successful-startup     : true
size-limit                            : 1000
smtp-server                           : -
time-limit                            : 1 m
workflow-configuration-mode           : auto
writability-mode                      : enabled


Il est possible de modifier la valeur avec ds-config :

/opt/OpenDS-2.3.0/bin/dsconfig set-global-configuration-prop \
--port 4444 --hostname localhost --trustAll --bindDN "cn=Directory Manager" --bindPassword password --no-prompt \
--set disabled-privilege:unindexed-search


Ceci supprimer les avertissements et erreurs, au détriment des performances, puisque le paramétrage autorise n'importe qui à faire des recherches non indexées.

On peut voir la nouvelle configuration :

/opt/OpenDS-2.3.0/bin/dsconfig get-global-configuration-prop \
--port 4444 --hostname localhost --trustAll --bindDN "cn=Directory Manager" --bindPassword password --no-prompt

Property                              : Value(s)
--------------------------------------:------------------------
bind-with-dn-requires-password        : true
default-password-policy               : Default Password Policy
disabled-privilege                    : unindexed-search
entry-cache-preload                   : false
etime-resolution                      : milliseconds
idle-time-limit                       : 0 ms


 

 

 

 


 

 

 

 

 

Catégorie