xinet is an enhanced inetd. It comes with
access controls, resource controls, possibilities to pass environment settings
over to a server, and so on. Unfortunately courier-imap and qmail depend on their own "internet
super servers". So you have the same code three times (xinetd, tcpserver,
couriertcpd). tcpserver and couriertcpd do not support udp, couriertcpd also
performs very badly (I tried to spwan qmail-smtp from couriertcp and opened
one hundred connections: couriertcpd did not kill about 80 connections after
smtp conversation was done). So I was looking for how to use qmail-smtp and
courier-imap with xinetd.
Both servers expect that information about the client like the ip address or
the port number is available in environment variables like
$TCPREMOTEIP or $TCPREMOTEPORT. You could use tcp-env from the
qmail package to do that.
courier-imap reads its configuration from several environment settings which
are defined in /etc/imap/imapd (or whereever you put those
configuration files). You can source them in your xinetd startup script and
pass them to courier-imap by using xinetd's passenv-feature.
qmail-smtp acts as a smtprelay if there is an environment variable called
$RELAYHOST. Normally this is set up by tcpserver if the ip address of
the remote client matches a predefined address range which is allowed to relay
mails. xinetd lacks this feature. So I wrote a small programm called
relaycheck, which is meant to be started from tcp-env. If $TCPREMOTEIP
matches any ip addresses you specified as first argument for relaycheck, then
the program you specified as second argument will be called with the desired
environment variable $RELAYHOST.
Let's have a look at my configuration files and startup scripts. I am running qmail and courier-imap on a dual-homed machine. Access to the imapd should be granted only to the 192.168.0.0/24 subnet. qmail-smtp should be accessible by any host, but should act as a mailrelay for localhost (127.0.0.1) and the 192.168.0.0/24 subnet.
xinetd startup script:
#!/bin/sh
# /sbin/rc.d/init.d/xinetd
PATH=/bin:/sbin:/usr/bin:/usr/sbin
PROG=/usr/sbin/xinetd
MYPIDFILE=/var/run/xinetd.pid
if [ ! -x $PROG ]; then
exit 0
fi
case "$1" in
start)
set -a
. /etc/imap/imapd
$PROG -filelog /var/log/xinetd.log -pidfile $MYPIDFILE
;;
stop)
if [ -f $MYPIDFILE ]; then
if kill -0 `cat $MYPIDFILE`; then
kill `cat $MYPIDFILE`
fi
rm -f $MYPIDFILE
fi
;;
reload)
if [ -f $MYPIDFILE ]; then
if kill -0 `cat $MYPIDFILE`; then
kill -HUP `cat $MYPIDFILE`
else
rm -f $MYPIDFILE
$0 start
fi
else
$0 start
fi
;;
restart)
$0 stop && $0 start
;;
*)
echo "usage: $0 (start|stop|reload|restart)"
esac
xinetd configuration file:
# /etc/xinetd.conf
service smtp
{
flags = NODELAY
socket_type = stream
wait = no
user = qmaild
server = /var/qmail/bin/tcp-env
server_args = -R /usr/bin/relaycheck 127.0.0.1,192.168.0. /var/qmail/bin/qmail-smtpd
log_type = FILE /var/log/smtpd.log
log_on_success = PID HOST EXIT DURATION
log_on_failure = HOST ATTEMPT
passenv =
}
service imap
{
flags = NODELAY
socket_type = stream
wait = no
user = root
server = /var/qmail/bin/tcp-env
server_args = -R /usr/sbin/imaplogin /usr/libexec/authlib/authshadow /usr/bin/imapd Maildir
only_from = 192.168.0.0/24
bind = 192.168.0.1
log_type = FILE /var/log/imapd.log
log_on_success = PID HOST EXIT DURATION
log_on_failure = HOST ATTEMPT
}
relaycheck.c (compile with diet -Os gcc -W -Wall -s -nostdinc -o relaycheck relaycheck.c)