18.6. Interpretación de las Reglas de Escritura - Reescritura

Es argumentable que la característica más poderosa de sendmail es la regla de reescritura. Las reglas de reescritura son usadas por sendmail para determinar cómo procesar un manseje de correo recibido. sendmail pasa las direcciones desde las cabeceras de un mensaje de correo a través de colecciones de reglas de reescritura llamadas conjuntos de reglas. Las reglas de reescritura transforman una dirección de correo de una forma a otra y puede pensar en ellas como algo similar a una orden en su editor que reemplaza todo el texto que encaje en un patrón especificado con otro.

Cada regla tiene un lado izquierdo y un lado derecho, separados por al menos un carácter de tabulación. Cuando sendmail está procesando correo, busca a través de las reglas de reescritura intentando encontrar una coincidencia con el lado izquierdo. Si una dirección coincide con una de las reglas del lado izquierdo, la dirección es reemplazada por la del lado derecho y es procesada de nuevo.

18.6.1. Las Órdenes R y S de sendmail.cf

En el fichero sendmail.cf, los conjuntos de reglas son definidos usando órdenes codificadas como Sn, donde n especifica el conjunto de reglas que se considera el actual.

Las reglas por sí mismas aparecen en órdenes codificadas como R. Cuando cada orden R es leída , se añade al conjunto de reglas actual.

Si está tratando sólo con el fichero sendmail.mc, no necesita preocuparse acerca de las órdenes S para nada, ya que las macros construirán éstas por usted. Necesitará codificar manualmente las reglas R.

Un conjunto de reglas de sendmail entonces tiene la siguiente apariencia:
    Sn
    Rlhs rhs
    Rlhs2 rhs2

18.6.2. Algunas Definiciones de Macro Útiles

sendmail utiliza internamente unas cuantas definiciones de macro estandarizadas. Las más útiles de éstas en la escritura de conjuntos de reglas son:

Podemos incorporar estas definiciones de macros en nuestras propias reglas de reescritura. Nuestra configuración de la Cervecera Virtual utiliza la macro $m.

18.6.3. El Lado Izquierdo

A la izquierda de una regla de reescritura, hay que especificar un patrón que coincida con una dirección que desee transformar. La mayoría de los caracteres se les hace coincidir literalmente, pero hay un número de caracteres que tienen significado especial; estos se describen en la lista siguiente. Las reglas de reescritura para el lado izquierdo son:

Un símbolo es una tira de caracteres delimitados por espacios. No hay manera de incluir espacios en un símbolo, o no es necesario como los patrones de expresiones son suficientemente flexibles para atajar esta necesidad. Cuando una regla coincide con una dirección, el texto que coincide con cada uno de los patrones en la expresión será asignado a variables especiales que se usarán en la parte derecha. La única excepción a esto es con el literal $@, que no coincide con ningún símbolo y entonces nunca generará texto para ser usado en el lado derecho.

18.6.4. El Lado Derecho

Cuando el lado izquierdo de una regla de reescritura coincide con una direción, el texto original se borra y se reemplaza por lo que haya en el lado derecho de la regla. Todos los símbolos en el lado derecho son copiados literalmente , a no ser que comiencen por el signo del dólar. De la misma manera que en el lado izquierdo, unos cuantos metasímbolos pueden usarse en el lado derecho. Estos son descritos en la siguiente lista. Las reglas de reescritura para el lado derecho son:

$n

Este metasímbolo es reemplazado por la expresión nésima del lado izquierdo.

$[nombre$]

Este metasímbolo resuelve el nombre del anfitrión a nombre canónico. Es reemplazado por la forma canónica del nombre del anfitrión suministrado.

$(map_clave $@argum $:omisión $)

Esta es la forma más general de búsqueda. La salida es un resultado de mirar la clave en el mapa nombrado map pasándole argum como argumentos. El mapa puede ser cualquiera de los mapas que sendmail soporta como el virtusertable que describimos un poco más tarde. Si la búsqueda es infructuosa, por omisión será la salida. Si no se suministra nada por omisión y la búsqueda falla, la entrada no se altera y la clave es la salida.

$>n

Esto hará que el resto de esta lína sea analizada y entonces dada al conjunto de reglas n para ser evaluada. La salida del conjunto de reglas llamado se escribirá como salida a esta regla. Éste es el mecanismo que permite a las reglas invocar otras reglas.

$#mailer

Este metasímbolo hace que la evaluación del conjunto de reglas se detenga y especifica el transporte que deberá usarse para transportar este mensaje en el siguiente paso de su entrega. Este metasímbolo debería ser llamado sólo desde el conjunto de reglas 0 o una de sus subrutinas. Esta es la parte final del análisis de direcciones y debería ser acompañado de los dos siguientes metasímbolos.

$@host

Este metasímbolo especifica el anfitrión al que este mensaje será reenviado. Si el anfitrión destinatario es el anfitrión local, puede omitirse. El host puede ser una lista de anfitriones de destino separada por dos puntos (:) que a los que se intentará entregar el mensaje en secuencia.

$:user

Este metasímbolo especifica el usuario destinatario para el mensaje de correo.

Una regla de reescritura que coincide se intenta repetidamente hasta que falla una coincidencia, entonces el análisis continúa en la sigiente regla. Este comportamiento puede cambiarse precediendo el lado derecho con uno de dos metasímbolos especiales descritos en la siguiente lista. Las reglas de reescritura para el control del bucle del lado derecho son:

18.6.5. Un Ejemplo de Patrón de Reglas Sencillo

Para ver mejor cómo funcionan las macros de sustitución de patrones, considere la siguiente regla de lado izquierdo:
    $* < $+ >

Esta regla coincide con “Cero o más símbolos, seguidos por el carácter <, seguidas a su vez por una o más símbolos, seguidos por el carácter >. ”

Si esta regla fuese aplicada a brewer@vbrew.com o Head Brewer < >, la regla no coincidiría. La primera cadena no coincidiría porque no incluye el carácter <, y la segunda fallaría porque $+ coincide con uno o más símbolos y no hay símbolos entre los caracteres <>. En cualquier caso en que una regla co coincida, el lado derecho de la regla no se usa.

Si la regla fuera aplicada a Head Brewer < brewer@vbrew.com >, la regla coincidiría, y en el lado derecho $1 sería sustituido por Head Brewer y $2 sería sustituido por brewer@vbrew.com.

Si la regla fuese aplicada a < brewer@vbrew.com > la regla coincidiría porque $* coincide con cero o más símbolos, y en el lado derecho $1 podría ser sustituido por la cadena vacía.

18.6.6. Semántica del Conjunto de Reglas

Cada uno de los conjuntos de reglas de sendmail se les llama para realizar una tarea distinta en el procesado del correo. Cuando se están escribiendo reglas, es importante entender qué se espera que cada uno de los conjuntos de reglas haga. Vamos a echar un vistazo a cada uno de los conjuntos de reglas que los guiones de configuración m4 nos permiten modificar:

LOCAL_RULE_3

El conjunto 3 es responsable de convertir una dirección en un formato arbitrario en un formato común quesendmail procesará. El formato de salida esperado es el aspecto familiar parte-local@especificación-anfitrión-dominio.

El conjunto 3 debería poner la parte del nombre del anfitrión de la dirección convertida entre los caracteres < y > para hacer el análisis de las siguientes reglas más fácil. El conjunto de reglas 3 se aplica antes que sendmail haga cualquier otro procesamiento de una dirección de correo, así que si quiere que sendmail haga de pasarela de correo desde algún sistema que utilice algún formato de dirección poco usual, se debería añadir una regla usando la macro LOCAL_RULE_3 para convertir direcciones en el formato común.

LOCAL_RULE_0 y LOCAL_NET_CONFIG

El conjunto 0 se aplica por sendmail a las direcciones del destinatario tras el conjunto de reglas 3. La macro LOCAL_NET_CONFIG provoca que las reglas sean introducidas en la mitad inferior del conjunto 0.

El conjunto 0 se espera que realice la entrega del mensaje al destinatario, así que debe resolver un triplete que especifica el correo, el anfitrión y el usuario. Las reglas serán colocadas antes de cualquier definición de anfitrión inteligente que quiera incluir, así que si añade reglas que resuelvan direcciones apropiadamente cualquier dirección que coincida con una regla no será tratada por el anfitrión inteligente. Así es como tratamos los smtp directos para los usuarios de nuestra red local en nuestro ejemplo.

LOCAL_RULE_1 y LOCAL_RULE_2

El conjunto 1 se aplica a todas las direcciones de remite y el conjunto 2 de aplica a todas las direcciones de destino. Ambos están normalmente vacíos.

18.6.6.1. Interpretación de la regla en nuestro ejemplo

Nuestro ejemplo en Ejemplo 18-3 usa la macro LOCAL_NET_CONFIG para declarar una regla local que asegure que cualquier correo dentro de nuestro dominio se entregue directamente usando el transporte de correo smtp. Ahora que sabe cómo se construyen las reglas de reescritura, es capaz de entender cómo funciona esta regla. Echémosle un vistazo.

Sabemos que la macro LOCAL_NET_CONFIG hará que la regla se introduzca en algún lugar cerca del final del conjunto de reglas 0, pero antes de cualquier definición del anfitrión inteligente. Sabemos también que el conjunto 0 es el último conjunto en ser ejecutado y que debería resolver un triplete especificando transporte de correo, usuario y anfitrión.

Podemos ignorar las dos líneas de comentariso; no hacen nada útil. La regla en sí misma es la línea que comienza con R. Sabemos que la R es una instrucción de sendmail y que añade esta regla al conjunto de reglas actual, en este caso el conjunto 0. Miremos al lado izquierdo y al lado derecho que devuelve.

El lado izquierdo es como éste: $* < @ $* .$m. > $*.

El conjunto 0 espera los caracteres < y > porque es alimentado por el conjunto 3. El conjunto 3 convierte direcciones en una forma común y para hacer el análisis más fácil, coloca la parte del anfitrión de la dirección de correo entre < y >.

Esta regla coincide con cualquier dirección que parecezca como: 'UsuarioDestino < @ cualquieranfitrión.nuestrodominio. > Algún Texto'. Esto es, coincide con el correo de cualquier usuario y de cualquier anfitrión dentro de nuestro dominio.

Recordará que el texto que coincide con los metasímbolos en el lado izquierdo de una regla de reescritura se asigna a definiciones de macro para su uso en el lado derecho. En nuestro ejemplo, el primer $* coincide con todo el texto desde el inicio de la dirección hasta el carácter <. Todo este texto se asigna al $1 para su uso en el lado derecho. Similarmente, el segundo $* en nuestra regla de reescritura se asigna a $2, y el último se asigna a $3.

Ahora tenemos suficiente para entender el lado izquierdo. Esta regla coincide con el correo de cualquier usuario en cualquier anfitrión dentro de nuestro dominio. Asigna el nombre de usuario a $1, el nombre del anfitrión a $2, y cualquier texto subsiguiente a $3. El lado derecho se invoca entonces para procesar éstos.

Echemos un vistazo a aquello que estamos esperando ver a la salida. El lado derecho de nuestra regla de reescritura de ejemplo es semejante a: $#smtp $@ $2.$m. $: $1 < @ $2.$m. > $3.

Cuando la regla del lado derecho de nuestro conjunto de reglas se procesa, se interpreta cada uno de los metasímbolos y se realizan las sustituciones correspondientes.

El metasímbolo $# hace que esta regla resuelva un transporte específico, smtp en nuestro caso.

El $@ resuelve el anfitrión objetivo. En nuestro ejemplo, el anfitrión objetivo se especifica como $2.$m., el cual es el nombre completamente cualificado del anfitrión en nuestro dominio. El NDCC se construye con el componente del nombre del anfitrión asignado a $2 desde nuestro lado izquierdo con nuestro nombre de dominio (.$m.) concatenado.

El metasímbolo $: especifica el usuario objetivo, el cual se captura otra vez del lado izquierdo y se almacena en $1.

Preservamos los contenidos de la sección <> y cualquier texto acompañante, usando los datos que recogimos desde el lado izquierdo de la regla.

Debido a que esta regla resuelve a un transporte de correo, el mensaje es reenviado al transporte para su entrega. En nuestro exemplo, el mensaje sería reenviado al anfitrión de destino usando el protocolo SMTP.