Sun Java System Messaging Server 6 2005Q4 管理指南

模板替换和重写规则控制序列

替换用于通过将字符串插入到重写的地址中来重写用户名或地址,替换的值由所用的特定替换序列确定。本节包含以下几个部分:

例如,在以下模板中,$U 是一个替换序列。该替换序列将导致被重写地址的用户名部分被替换为模板的输出。因此,如果 jdoe@mailhost.siroe.com 被此模板重写,则结果输出将为 jdoe@siroe.com$U 将在用户名部分替换原始地址的 jdoe

$U@siroe.com

控制序列为给定重写规则的适用性强加了附加条件。不仅重写规则的模式部分必须与要检查的主机或域说明匹配,而且要重写的地址的其他方面也必须满足由控制序列设置的条件。例如,$E 控制序列要求被重写的地址为信封地址,而 $F 控制序列要求其为正向指示地址。以下重写规则仅适用于(重写) 形式的信封 To: user@siroe.com 格式的信封 To: 地址:

siroe.com $U@mail.siroe.com$E$F

如果域或主机说明与某个重写规则的模式部分匹配,但不满足该规则的模板中由控制序列强加的所有条件,则该重写规则将失败,重写程序将继续查找其他适用的规则。

表 11–4 汇总了模板替换和控制序列。

表 11–4 重写规则模板替换和控制序列的摘要

替换序列 

替换 

$D

匹配的域说明的部分。 

$H

不匹配的主机/域说明的部分;模式中的点的左侧。 

$L

不匹配的域文字的部分;模式文字中的点的右侧。 

$U

原始地址中的用户名。 

$nA 

插入从位置 0 开始的当前地址左侧第 n 个字符,如果省略 n,则将插入整个地址。 

$nX 

插入从 0 开始的邮件主机左侧第 n 个组件,如果省略 n,则将插入整个邮件主机。 

$0U 

原始地址中的本地部分(用户名),减去任何子地址。 

$1U 

原始地址的本地部分(用户名)中的子地址(如果存在)。 

$$

插入文字美元符号 ($)。

$%

插入文字百分比符号 (%)。

$@

插入文字 at 符号 (@)。

$\

强制材料为小写。 

$^

强制材料为大写。 

$_

使用原始大小写。 

$=

强制后续替换字符经适当引用插入到 LDAP 搜索过滤器中。 

$W

在随机、唯一的字符串中替换。 

$]...[

LDAP 搜索 URL 查找。 

$(text)

常规数据库替换;如果查找失败则规则失败。 

${...}

将指定的映射应用于提供的字符串。 

$[...] 

调用用户提供的例程;在结果中替换。 

$&n

不匹配的(或通配的)主机的第 n 个部分,由 0 开始从左向右数。

$!n

不匹配的(或通配的)主机的第 n 个部分,由 0 开始从右向左数。

$*n

匹配模式的第 n 个部分,由 0 开始从左向右数。

$#n

匹配模式的第 n 个部分,由 0 开始从右向左数。

$nD

匹配的域说明的部分,保留从 0 开始的第 n 个最左侧部分 

$nH

不匹配的主机/域说明的部分,保留从 0 开始的第 n 个最左侧部分 

控制序列 

对重写规则的作用 

$1M 

只有当通道为内部重新处理通道时才适用。 

$1N 

只有当通道不是内部重新处理通道时才适用。 

$1~ 

执行所有待定通道匹配检查。如果检查失败将会成功地终止当前重写规则模板的处理。 

$A 

如果主机在符号的右侧则适用 

$B 

只适用于标题/主体地址 

$C channel

如果发送到 channel,则将失败

$E 

只适用于信封地址 

$F 

只适用于正向指引的(如 To:)地址 

$M channel

只在 channel 重写地址时适用

$N channel

如果 channel 重写地址,则将失败

$P 

如果主机在百分比符号的右侧则适用 

$Q channel

如果发送到 channel,则适用

$R 

只适用于反向指引的(如 From:)地址 

$S 

如果是源路由的主机则适用 

$Tnewtag

将重写规则标记设置为 newtag 

$Vhost

如果未在 LDAP 目录(在 DC 树中或作为虚拟域)中定义主机名则会失败。如果 LDAP 搜索超时,重写模式的剩余部分(紧跟主机名后面的字符之后)将会被 MTA 选项字符串 DOMAIN_FAILURE 替换。

$X 

如果主机在感叹号的左侧则适用 

$Zhost

如果在 LDAP 目录(在 DC 树中或作为虚拟域)中定义了主机名则会失败。如果 LDAP 搜索超时,重写模式的剩余部分(紧跟主机名后面的字符之后)将会被 MTA 选项字符串 DOMAIN_FAILURE 替换。

$?errmsg

如果重写失败,将返回 errmsg 而不是默认的错误消息。错误消息必须为 US ASCII。

$number?errmsg

如果重写失败,将返回 errmsg 而不是默认的错误消息,并将 SMTP 扩展错误代码设置为 ab.c

  • anumber/1000000(第一个数字)

  • b 为 (number/1000) 除以 1000 的余数(第 2 个到第 4 个数字的值)

  • cnumber 除以 1000 的余数(最后三个数字的值)。

    以下示例将错误代码设置为 3.45.89:

    $3045089?the snark is a boojum

用户名和子地址替换,$U、$0U、$1U

模板中出现的所有 $U 都将被原始地址的用户名(RFC 822 “本地部分”)替换。注意,a."b" 格式的用户名将被 "a.b" 格式的用户名替换,因为 RFC2822 不支持 RFC 822 的前一种语法,并期望后一种用法将来能成为强制性的语法。

模板中出现的所有 $0U 都将被原始地址的用户名替换,减去任何子地址和子地址指示字符 (+)。模板中出现的所有 $1U 都将被原始地址的子地址和子地址指示字符(如果存在)替换。因此请注意,$0U 和 $1U 是用户名的补充部分,$0U$1U 与简单 $U 等效。

主机/域和 IP 文字替换,$D、$H、$nD、$nH、$L

出现的所有 $H 都将被与规则不匹配的主机/域说明部分替换。出现的所有 $D 都将被与重写规则匹配的主机/域说明部分替换。$nH 和 $nD 字符是保留从 0 开始数的第 n 个最左侧部分的标准 $H 或 $D 部分的变体。即 $nH 和 $nD 分别省略了通常为 $H 或 $D 替换的最左侧的 n 部分(从 1 开始数)。特别是,$0H 与 $H 等效,$0D 与 $D 等效。

例如,假设地址 jdoe@host.siroe.com 与以下重写规则匹配:

host.siroe.com    $U%$1D@TCP-DAEMON

结果地址是 jdoe@siroe.comTCP-DAEMON 将用作外发通道。其中 $D 将在匹配的整个域 host.siroe.com 中进行替换,而 $1D 将在从第一部分(第一部分为 siroe)开始匹配的部分中进行替换,因此在 siroe.com 中进行替换。

$L 将替换与重写规则不匹配的域文字部分。

文字字符替换,$$、$%、$@

$、% 和 @ 字符通常是重写规则模板中的元字符。要执行此类字符的文字插入,请为其引上美元字符 $。即,$$ 扩展成单个美元符号 $;$% 扩展成单个百分比 %(这种情况下不将百分比解释为模板字段分隔符);$@ 扩展成单个 at 符号 @(也不解释为字段分隔符)。

LDAP 查询 URL 替换,$]...[

$]ldap-url[ 格式的替换被解释为 LDAP 查询 URL,并且 LDAP 查询的结果将被替换。使用标准 LDAP URL 时省略了主机和端口。而主机和端口在 msg.conf 文件(local.ldaphostlocal.ldapport 属性)中指定。

即,应该按如下所示指定 LDAP URL,其中方括号字符 [ ] 表示 URL 的可选部分:

ldap:///dn[?attributes[?scope?filter]]

dn 是必需的标识名,用于指定搜索基准。URL 的可选属性、范围和过滤器部分进一步完善了要返回的信息内容。对于重写规则,指定返回所需的属性可能是 mailRoutingSystem 属性(或某个类似的属性)。范围可以是任何基准(默认设置)、某个基准或子基准。所需的过滤器可能会要求返回其 mailDomain 值与要被重写的域匹配的对象。

如果 LDAP 目录模式包括属性 mailRoutingSystemmailDomain,则确定要将给定种类地址路由到哪个系统的可能的重写规则可能显示如下,其中 LDAP URL 替换序列 $D 用于将当前域名替换到构建的 LDAP 查询中:


.siroe.com \
  $U%$H$D@$]ldap:///o=siroe.com?mailRoutingSystem?sub? \
  (mailDomain=$D)

         

为了便于阅读,使用了反斜杠字符将单个逻辑重写规则行继续到第二个物理行。表 11–5 列出了 LDAP URL 替换序列。

表 11–5 LDAP URL 替换序列

替换序列 

说明 

$$

文字 $ 字符 

$~ account

用户帐户的主目录 

$A

地址 

$D

域名 

$H

主机名(全限定域名的第一部分) 

$L

用户名减去任何特殊的前导字符,如 ~ 或 _ 

$S

子地址 

$U

用户名 

MTA 现在高速缓存在重写规则和映射中查找到的 URL 结果。这一新的 URL 结果高速缓存由两个新的 MTA 选项控制,URL_RESULT_CACHE_SIZE(默认为 10000 个条目)和 URL_RESULT_CACHE_TIMEOUT(默认为 600 秒)。

常规数据库替换,$(...)

$(text) 格式的替换是经过特殊处理的。文本部分被用作访问特殊的常规数据库的密钥。该数据库包括在 /imta/config/imta_tailor 文件中通过 IMTA_GENERAL_DATABASE 选项指定的文件,此文件通常为 /imta/db/generaldb.db

该数据库通过 imsimta crdb 实用程序生成。如果在数据库中找到了“文本字符串”,则数据库中相应的模板将被替换。如果“文本字符串”与数据库中的任何条目均不匹配,则重写过程失败;这就相当于重写规则从未匹配过。如果替换成功,则从数据库中提取的模板将被重新扫描以进行附加替换。但是,提取的模板中的附加 $(text) 替换会被禁止以防止没完没了的递归引用。

例如,假设地址 jdoe@siroe.siroenet 与以下重写规则匹配:

.SIROENET $($H)

则将在常规数据库中查找文本字符串 siroe, 并且查找的结果(如果有)将用于重写规则的模板。假设查找 siroe 的结果是 $u%eng.siroe.com@siroenet.,则模板的输出将会是 jdoe@eng.siroe.com(即,用户名 = jdoe;主机/域说明 = eng.siroe.com),且路由系统将是 siroenet

如果常规数据库存在,则其应该是全局可读的以确保正常运行。

应用指定的映射,${...}

.SIROENET $($H) ${mapping,argument} 格式的替换用于查找并应用 MTA 映射文件中的映射。mapping 字段指定要使用的映射表的名称,而 argument 指定要传递给映射的字符串。若要重写成功,映射必须存在并必须在其输出中设置 $Y 标志;如果映射不存在或未设置 $Y,则重写将失败。如果重写成功,则映射的结果将合并到当前位置的模板中并重新扩展。

此机制允许 MTA 重写进程以各种复杂的方式进行扩展。例如,可以选择性地分析和修改地址的用户名部分,通常这并不是 MTA 重写过程所具有的功能。

用户提供的例程替换,$[...]

$[image ,routine,argument ] 格式的替换用于查找并调用用户提供的例程。在 UNIX 上运行时,MTA 使用 dlopendlsym 动态地装入并调用从共享库映像中指定的例程。则该例程被称为函数,带有以下变量列表:

status := routine (argument, arglength, result, reslength)

argumentresult 是 252 字节长的字符串缓冲区。在 UNIX 上,argumentresult 将作为指针传递到字符串(例如,在 C 中,作为 char*),arglengthreslength 是由引用传递的有符号型长整数。输入时,argument 包含重写规则模板中的变量字符串,arglength 是该字符串的长度。返回时,结果字符串应放在 result 中,而其长度应放在 reslength 中。然后该结果字符串将替换重写规则模板中的 "$[ image,routine,argument]"。如果重写规则失败则例程将返回 0,如果重写规则成功则例程将返回 -1。

此机制允许重写进程以各种复杂的方式进行扩展。例如,可以执行对某种类型的名称服务的调用并使用调用的结果来按某种方式改变地址。对主机 siroe.com 的正向定位地址(例如 To: 地址)的目录服务查找,可以使用以下重写规则并按如下方式执行。特定于方向和位置的重写规则 ($B, $E, $F, $R)中介绍的 $F 导致此规则仅用于正向定位地址:

siroe.com $F$[LOOKUP_IMAGE,LOOKUP,$U]

正向定位地址 jdoe@siroe.com 与该重写规则匹配时,将导致 LOOKUP_IMAGE(UNIX 上的共享库)被装入内存,并导致例程 LOOKUP 被调用(使用 jdoe 作为变量参数)。然后,例程 LOOKUP 可能会在结果参数中返回一个不同的地址(如 John.Doe%eng.siroe.com)和值 -1,以表示重写规则成功。结果字符串中的百分比符号(请参见重复的重写模板 A%BJohn.Doe@eng.siroe.com 将作为要被重写的地址。

在 UNIX 系统上,站点提供的共享库映像应该是全局可读的。

单个字段替换,$&、$!、$*、$#

单个字段替换从正被重写的主机/域说明中提取单个子域部分。表 11–6 中显示了可用的单个字段替换。

表 11–6 单个字段替换

控制序列 

用法 

$&n 

替换主机说明(不匹配或与某种通配符匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;左侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

$!n 

替换主机说明(不匹配或与某种通配符匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;右侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

$*n 

替换域说明(与模式中的显式文本匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;左侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

$#n 

替换域说明(与模式中的显式文本匹配的部分)中的第 n 个元素,n=0,1,2,...,9,。元素由点分隔;右侧的第一个元素为元素零。如果请求的元素不存在则重写失败。 

假设地址 jdoe@eng.siroe.com 与以下重写规则匹配:

*.SIROE.COM     $U%$&0.siroe.com@mailhub.siroe.com

则从模板得到的结果将会是 jdoe@eng.siroe.com,并将 mailhub.siroe.com 用作路由系统。

唯一字符串替换

每次使用 $W 控制序列时均会插入一个由大写字母和数字组成的文本字符串,这些大写字母和数字都是唯一并且不可重复的。在必须构造非重复的地址信息时,$W 很有用。

特定于源通道的重写规则 ($M, $N)

重写规则可以只与特定的源通道一起使用。这在简短形式的名称具有两种含义时很有用:

  1. 当其在到达某个通道的邮件中显示时。

  2. 当其在到达另一个通道的邮件中显示时。

特定于源通道的重写与使用中的通道程序以及通道关键字 rulesnorules 相关联。如果在与正执行重写的 MTA 组件相关联的通道上指定了 norules,则将不会进行特定于通道的重写检查。如果在通道上指定了规则,则会强制进行特定于通道的规则检查。关键字 rules 是默认设置。

特定于源通道的重写和与给定地址匹配的通道不相关联。该重写仅取决于执行重写的 MTA 组件以及该组件的通道表格条目。

特定于通道的重写检查由规则模板部分中的 $N$M 控制序列触发。$N 或 $M 后面的字符,一直到 at 符号 (@)、百分比符号 (%) 或后面的 $N$M$Q$C$T$? 都被解释为通道名称。

例如,如果 channel 当前没有执行重写,则 $Mchannel 将导致规则失败。如果 channel 正在执行重写,则 $Nchannel 将导致规则失败。可以指定多个 $M$N 子句。如果多个 $M 子句中的任何一个子句匹配,则规则成功。如多个 $N 子句中的任何一个子句匹配,则规则将失败。

特定于目标通道的重写规则 ($C, $Q)

可以具有这样的重写规则,其应用程序取决于邮件要排入的通道。当某个主机有两个名称,一个由一组主机所知晓,一个由另一组主机所知晓时,该重写规则很有用。通过使用不同的通道将邮件发送给每个组,可以对地址进行重写以指代每个组所知晓的名称的主机。

特定于目标通道的重写与要处理邮件并将邮件移出队列的通道,以及该通道上的通道关键字 rulesnorules 关联。如果在目标通道上指定了 norules,则不会执行特定于通道的重写检查。如果在目标通道上指定了 rules,则会强制执行特定于通道的规则检查。关键字 rules 是默认设置。

特定于目标通道的重写和与给定地址匹配的通道不相关联。该重写仅取决于邮件的信封 To: 地址。将邮件加入队列时,首先重写其信封 To: 地址以确定邮件要加入队列的通道。在重写 信封 To: 地址过程中,将忽略所有 $C$Q 控制序列。重写了 信封 To: 地址以及确定了目标通道之后,$C$Q 控制序列才生效,因为与该邮件关联的其他地址已被重写。

特定于目标通道的重写检查由规则模板部分中的 $C$Q 控制序列触发。$C$Q 后面的字符,一直到 at 符号 (@)、百分比符号 (%) 或后面的 $N$M$C$Q$T$? 都被解释为通道名称。

例如,如果 channel 不是目标通道,则 $Qchannel 将会导致规则失败。再如,如果 channel 是目标通道,则 $Cchannel 将会导致规则失败。可以指定多个 $Q$C 子句。如果多个 $Q 子句中的任何一个子句匹配,则规则成功。如果多个 $C 子句中的任何一个子句匹配,则规则失败。

特定于方向和位置的重写规则 ($B, $E, $F, $R)

有时需要指定仅应用于信封地址或仅应用于标题地址的重写规则。如果被重写的地址不是信封地址,控制序列 $E 将强制使重写失败。如果被重写的地址不是来自邮件标题或主体的地址,控制序列 $B 将强制使重写失败。这些序列对重写没有其他作用并且可能会显示在重写规则模板中的任何位置。

地址也可以按方向分类。正向定位地址源自 To:、Cc:Resent-to: 或其他标题,或源自引用了目标的信封行。反向定位地址如 From:Sender:Resent-From:,指的是源。如果地址是正向定位的,则控制序列 $F 将导致应用重写。如果地址是反向指示的,则控制序列 $R 将导致应用重写。

特定于主机位置的重写 ($A, $P, $S, $X)

有时需要重写主机名在地址中出现的敏感位置。主机名可以显示在地址中几个不同的上下文中:

正常情况下,应该以相同的方式处理主机名,而不考虑其显示的位置。有些情况可能需要特殊处理。

四个控制序列用于根据地址中主机的位置来控制匹配。

如果主机的位置不是指定的位置,则规则将失败。这些序列可以组合成一个重写规则。例如,如果指定了 $S$A,规则将与在源路由中或 at 符号右侧指定的主机匹配。不指定这些序列相当于指定了所有序列;规则可以匹配而不考虑位置。

更改当前标记值,$T

$T 控制序列用于更改当前重写规则标记。在配置文件和域数据库中查找重写规则模式之前,所有重写规则模式都前置了重写规则标记。$T 后面的文本,一直到 at 符号、百分比符号、$N、$M、$Q、$C、$T 或 $? 均被视为新标记。

在处理特殊寻址形式(遇到某个组件时更改了地址的整个特征)时,标记很有用。例如,假设在源路由中找到特殊主机名 internet 时,应将其从地址中删除,并强制使结果地址与 TCP-DAEMON 通道匹配。

这可以通过类似以下规则(假定 localhost 为本地主机的正式名称)来实现:

internet               $S$U@localhost$Tmtcp-force|

mtcp-force|.           $U%$H@TCP-DAEMON

如果第一个规则在源路由中显示,则其将与特殊的主机名 internet 匹配。该规则强制 internet 与本地通道匹配,这将确保将 internet 从地址中删除。然后设置重写标记。重写将继续,但由于该标记的原因将不会有常规规则匹配。最后,将通过标记尝试使用默认规则,并且该组的第二个规则将激活,强制地址与 TCP-DAEMON 通道匹配而不考虑任何其他条件。

控制与重写相关联的错误消息 ($?)

重写和通道匹配失败时,MTA 将提供默认错误消息。在某些情况下,更改这些邮件的能力将很有用。例如,如果某人尝试将邮件发送到以太网路由器邮箱,则显示类似“我们的路由器无法接受邮件”的信息可能要比通常的“指定了非法的主机/域”更加明确。

如果规则失败,可以使用特殊控制序列来更改显示的错误消息。序列 $? 用于指定错误消息。如果此次重写的结果与任何通道均不匹配,则 $? 后面的文本,一直到 at 符号 (@)、百分比符号 (%)、$N、$M、$Q、$C、$T 或 $? 均被视为要打印的错误消息的文本。错误消息的设置具有“黏性”并将贯穿重写过程始终。

包含 $? 的规则与其他任何规则的操作方式相同。规则中只包含 $? (而没有任何其他符号)的特殊情况需要特别注意—重写过程将终止,而不更改地址的邮箱或主机部分,并按原样在通道表中查找主机。此查找将要失败,结果将返回错误消息。

例如,假设 MTA 配置文件中的最后一个重写规则如下所示:

. $?Unrecognized address; contact postmaster@siroe.com

此示例中,可能失败的任何不可识别的主机或域说明在失败过程中都会生成错误消息:Unrecognized address; contact postmaster@siroe.com