.I qmqpservers \fR(none) \fRqmail-qmqpc
.I queuelifetime \fR604800 \fRqmail-send
.I rcpthosts \fR(none) \fRqmail-smtpd
+.I relayhosts \fR(none) \fRqmail-smtpd
.I smtpgreeting \fIme \fRqmail-smtpd
.I smtproutes \fR(none) \fRqmail-remote
.I timeoutconnect \fR60 \fRqmail-remote
else
substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
+ do_lst("relayhosts","No relayhosts","Relay host: ","");
do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 ");
do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ","");
do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds");
if (str_equal(d->d_name,"qmqpservers")) continue;
if (str_equal(d->d_name,"queuelifetime")) continue;
if (str_equal(d->d_name,"rcpthosts")) continue;
+ if (str_equal(d->d_name,"relayhosts")) continue;
if (str_equal(d->d_name,"smtpgreeting")) continue;
if (str_equal(d->d_name,"smtproutes")) continue;
if (str_equal(d->d_name,"timeoutconnect")) continue;
.B qmail-smtpd
will reject
any envelope recipient address with a domain not listed in
-.IR rcpthosts .
-
-Exception:
-If the environment variable
-.B RELAYCLIENT
-is set,
-.B qmail-smtpd
-will ignore
-.IR rcpthosts ,
-and will append the value of
-.B RELAYCLIENT
-to each incoming recipient address.
+.I rcpthosts
+unless the sending host is a designated relay client (see the
+description of the
+.I relayhosts
+file beow).
.I rcpthosts
may include wildcards:
Envelope recipient addresses without @ signs are
always allowed through.
.TP 5
+.I relayhosts
+Allowed relay clients. Each line is a host-suffix pair, separated by a
+colon. If the client's hostname matches one of the hostnames in the
+file, that client is permitted to send mail to any host (i.e., to use us
+as a relay), and the corresponding suffix is appended to all recipient
+addresses generated by the client.
+
+.I relayhosts
+may include wildcards:
+
+.EX
+ heaven.af.mil:
+ .heaven.af.mil:
+ hell.irs.gov:.irs.virtdomain
+.EE
+
+For historical reasons, the
+.B RELAYCLIENT
+environment variable overrides this table. If
+.B RELAYCLIENT
+is set, it has the same effect as there being a matching entry in the
+.I relayhosts
+file, using the value of
+.B RELAYCLIENT
+as the suffix.
+.TP 5
.I smtpgreeting
SMTP greeting message.
Default:
int liphostok = 0;
stralloc liphost = {0};
+int relayhostsok = 0;
+stralloc relayhosts = {0};
+struct constmap maprelayhosts;
int bmfok = 0;
stralloc bmf = {0};
struct constmap mapbmf;
if (bmfok == -1) die_control();
if (bmfok)
if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
+
+ switch (control_readfile(&relayhosts, "control/relayhosts", 0)) {
+ case -1:
+ die_control();
+ case 1:
+ relayhostsok = 1;
+ if (!constmap_init(&maprelayhosts, relayhosts.s, relayhosts.len, 1))
+ die_nomem();
+ }
+
if (control_readint(&databytes,"control/databytes") == -1) die_control();
x = env_get("DATABYTES");
if (!remotehost) remotehost = "unknown";
remoteinfo = env_get("TCPREMOTEINFO");
relayclient = env_get("RELAYCLIENT");
+ if (!relayclient && relayhostsok) {
+ int j;
+ int l = str_len(remotehost);
+ relayclient = constmap(&maprelayhosts, remotehost, l);
+ if (!relayclient) for (j = 0; j < l; ++j) {
+ if (remotehost[j] == '.' &&
+ (relayclient = constmap(&maprelayhosts,
+ remotehost + j,
+ l - j)) != 0)
+ break;
+ }
+ }
dohelo(remotehost);
}