Servicios de directorio y LDAP

En el contexto de las redes de ordenadores, se denomina directorio a una base de datos especializada que almacena información sobre los recursos, u "objetos", presentes en la red (tales como usuarios, ordenadores, impresoras, etc.) y que pone dicha información a disposición de los usuarios de la red. Por este motivo, esta base de datos suele estar optimizada para operaciones de búsqueda, filtrado y lectura más que para operaciones de inserción o transacciones complejas. Existen diferentes estándares que especifican servicios de directorio, siendo el demominado X.500 tal vez el más conocido.

El estándar X.500 define de forma nativa un protocolo de acceso denominado DAP (Directory Access Protocol) que resulta muy complejo (y computacionalmente pesado) porque está definido sobre la pila completa de niveles OSI. Como alternativa a DAP para acceder a directorios de tipo X.500, LDAP (Lightweight Directory Access Protocol) ofrece un protocolo "ligero" casi equivalente, pero mucho más sencillo y eficiente, diseñado para operar directamente sobre TCP/IP. Actualmente, la mayoría de servidores de directorio X.500 incorporan LDAP como uno de sus protocolo de acceso.

LDAP permite el acceso a la información del directorio mediante un esquema cliente-servidor, donde uno o varios servidores mantienen la misma información de directorio (actualizada mediante réplicas) y los clientes realizan consultas a cualquiera de ellos. Ante una consulta concreta de un cliente, el servidor contesta con la información solicitada y/o con un "puntero" donde conseguir dicha información o datos adicionales (normalmente, el "puntero" es otro servidor de directorio).

Internamente, el modelo de datos de LDAP (derivado de X.500, pero algo restringido) define una estructura jerárquica de objetos o entradas en forma de árbol, donde cada objeto o entrada posee un conjunto de atributos. Cada atributo viene identificado mediante un nombre o acrónimo significativo, pertenece a un cierto tipo y puede tener uno o varios valores asociados. Toda entrada viene identificada unívocamente en la base de datos del directorio mediante un atributo especial denominado nombre distinguido o dn (distinguished name). El resto de atributos de la entrada depende de qué objeto esté describiendo dicha entrada. Por ejemplo, las entradas que describen personas suelen tener, entre otros, atributos como cn (common name) para describir su nombre común, sn (surname) para su apellido, mail para su dirección de correo electrónico, etc. La definición de los posibles tipos de objetos, así como de sus atributos (incluyendo su nombre, tipo, valor(es) admitido(s) y restricciones), que pueden ser utilizados por el directorio de un servidor de LDAP la realiza el propio servidor mediante el denominado esquema del directorio. Es decir, el esquema contiene las definiciones de los objetos que pueden darse de alta en el directorio.

El nombre distinguido de cada entrada del directorio es una cadena de caracteres formada por pares <tipo_atributo>=<valor> separados por comas, que representa la ruta invertida que lleva desde la posición lógica de la entrada en el árbol hasta la raíz del mismo. Puesto que se supone que un directorio almacena información sobre los objetos que existen en una cierta organización, cada directorio posee como raíz (o base, en terminología LDAP) la ubicación de dicha organización, de forma que la base se convierte de forma natural en el sufijo de los nombres distinguidos de todas las entradas que mantiene el directorio. Existen dos formas de nombrar, o estructurar, la raíz de un directorio LDAP:

  1. Nombrado "tradicional": formado por el país y estado donde se ubica la organización, seguida por el nombre de dicha organización. Por ejemplo, la raíz o base de la Universidad Politécnica de Valencia podría ser algo así: "o=UPV, st=Valencia, c=ES".

  2. Nombrado basado en nombres de dominio de Internet (es decir, en DNS): este nombrado utiliza los dominios DNS para nombrar la raíz de la organización. En este caso, la base de la UPV sería: "dc=upv, dc=es". Este es el nombrado que vamos a utilizar puesto que permite localizar a los servidores de LDAP utilizando búsquedas DNS.

A partir de esa base, el árbol se subdivide en los nodos y subnodos que se estime oportuno para estructurar de forma adecuada los objetos de la organización, objetos que se ubican finalmente como las hojas del árbol. De esta forma, el nombre distinguido de cada entrada describe su posición en el árbol de la organización (y vice-versa), de forma análoga a un sistema de archivos típico, en el que el nombre absoluto (unívoco) de cada archivo equivale a su posición en la jerarquía de directorios del sistema, y vice-versa. En la Figura 2.1, “Estructura de directorio del dominio admon.com.” se muestra un ejemplo de un directorio sencillo (dos usuarios y dos equipos) de la organización admon.com.

Figura 2.1. Estructura de directorio del dominio admon.com.

Estructura de directorio del dominio admon.com.

De acuerdo con dicha figura, la entrada correspondiente al usuario "pepe" tendría como nombre distinguido "uid=pepe, ou=People, dc=admon, dc=com". Al margen de ese identificador único, cada entrada u objeto en el directorio puede tener, como hemos dicho, un conjunto de atributos tan descriptivo como se desee. Cada objeto necesita, al margen de su nombre distinguido, su "clase de objeto", que se especifica mediante el atributo ObjectClass (un mismo objeto puede pertenecer a diferentes clases simultáneamente, por lo que pueden existir múltiples atributos de este tipo para un mismo objeto en el directorio). Este atributo especifica implícitamente el resto de atributos de dicho objeto, de acuerdo con la definición establecida en el esquema. Siguiendo con el ejemplo anterior, a continuación se muestra un subconjunto de los atributos del usuario "pepe":

dn: uid=pepe, ou=People, dc=admon, dc=com
objectClass: person
cn: Jose García
sn: García
description: alumno
mail: pepe@admon.com

El formato en el que se han mostrado los atributos del objeto se denomina LDIF (LDAP Data Interchange Format), y resulta útil conocerlo porque es el formato que los servidores LDAP (y OpenLDAP entre ellos) utilizan por defecto para insertar y extraer información del directorio.

Puesto que nosotros vamos a utilizar el directorio con un uso muy específico (centralizar la información administrativa de nuestro dominio para autentificar usuarios de forma global) deberíamos asegurarnos que en el esquema de nuestro directorio existen los tipos de objetos (y atributos) adecuados para ello. Afortunadamente, OpenLDAP posee por defecto un esquema suficientemente rico para cubrir este cometido. Por ejemplo, cada usuario puede definirse mediante un objeto de tipo posixAccount, que posee entre otros atributos para almacenar su UID, GID, contraseña, etc. A título de curiosidad, la entrada en el esquema que define el atributo para la contraseña (userPassword) se muestra a continuación:

attributetype (2.5.5.35 NAME 'userPassword'
     EQUALITY octetStringMatch
     SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128})