This document will probably never be as comprehensively helpful as its inspiration, Life With Qmail by Dave Sill, and it won't explain the basics of qmail and ldap. It will explain the basic setup of qmail-ldap, but you must understand qmail and ldap to get qmail-ldap working.

qmail-ldap is a patch to qmail 1.03 to retrieve all user data from a ldap-directory rather then from files on the disk. This allows easier administration, especially in distributed environments. There is also clustering support builtin making qmail-ldap very well suited for big mail installations at ISPs.

This document will attempt to give the Big Picture, which is most of what you need to get going; describe the components of qmail-ldap and how they fit together; provide illustrations of typical installations; and hopefully in the process field some of the more Frequently Asked Questions; but it is not intended to be a replacement for any of the existing qmail and ldap documentation; this is an introductory paper, to be read in sequential order, not a reference.

This fantastic piece of software was developed by Andre Oppermann and Claudio Jeker.

There's also a Mailing list, qmail-ldap@qmail-ldap.org. Subscribe by sending an empty mail to qmail-ldap-subscribe@qmail-ldap.org, unsubscribing works similar by sending an empty mail to qmail-ldap-unsubscribe@qmail-ldap.org.

If you post to the list, please make sure that you have read all available documentation, that you understand LDAP and qmail and to include all necessary information. This is at least your ~/control/* stuff, complete error description, and the logs. If this is really much, consider uploading the infos on a webserver and post the url.

Lightweight Directory Access Protocol, or LDAP, is a very useful tool in administration of large networks and organizations. It is a database that is highly optimized for read operations, up to ten times faster than SQL database systems. One of the best features of LDAP is the ability to store user accounts. A single account entry can be used for logging in to unix workstations, imap servers, access controlled web pages, and email account storage.

With the qmailUser schema and user accounts loaded into an LDAP server, Qmail-LDAP can be configured so that all mail servers in an organization can share this same account data. Qmail-LDAP supports message routing to the mailhost specified in each users account entry, even when all internal email accounts use business card style addresses such as user@company.com. There is no need to use internal addresses like user@mailhost1.company.com and convert them to user@company.com when mail leaves the intranet.

Using LDAP to store Qmail-LDAP email accounts requires either building an LDAP directory, or modifying your existing directory. Since Qmail-LDAP requires the administrator to have a prior understanding of LDAP, this section of the HOWTO does not deal with basic LDAP or unix topics. For those who are completely unfamiliar with LDAP directory construction and administration, there are excellent books available and there are searchable mailing list archives at http://www.openldap.org.

1. The first part of setting up the directory server to work with Qmail-LDAP is to add the schema. This is not required if you have disabled schema checking, however running an LDAP server with schema checking disabled is highly discouraged. How the schema is loaded depends on the server you are using.

Edit slapd.conf and add the following lines, of course to match your file locations:

include /etc/ldap/schema/inetOrgPerson.schema
include /etc/ldap/schema/nis.schema (required by inetOrgPerson.schema)
include /etc/ldap/schema/qmail.schema (found from the qmail-ldap patch,
copy it to your schema directory)

Now that you have the schema loaded, a little system configuration is needed. I am going to discuss virtual user accounts, meaning that there are no home directories or /etc/passwd accounts for users on the mail server. After all, this is a mail server and not a user playground.

qmail-send handles messages placed in the outgoing queue by qmail-queue and uses qmail-lspawn for local deliveries and qmail-rspawn for remote deliveries. qmail-send will reschedule all messages in the queue for immediate delivery.

qmail-todo does the mail preprocessing to reduce the work load in qmail-send. With qmail-todo the overall performance on high throughput mail servers is far better because of the so called "silly qmail syndrom" caused by a over loaded qmail-send process.

qmail-qmqpd receives messages from remote hosts via QMQP, the Quick Message Queuing Protocol. It will relay _every_ message, so you must make sure only preauthorized hosts can connect. QMQP is used for in-cluster deliveries, if you want to use qmail-ldap's clusteriung you must set up qmail-qmqpd.

Daemontools is a companion package, prerequisite to qmail-ldap. It provides some helper programs which assist in launching and managing daemons.

qmail-ldap is delivered with service run scripts in /var/qmail/boot that can often be used without any modification.

svscan does a vaguely similar job to the System V init: it
monitors jobs and ensures that they keep running. It's
normally started with the directory /service, and each
subdirectory of that directory defines a service; they are
normally symlinks.
svc provides an interactive user interface for controlling
svscan; it takes an option like "-u" for up, "-d" for down,
or "-t" to take down and up again, followed by a service
name in the form of a path to a controlled directory.
Commonest case might be
svc -t /service/qmail-send
to restart qmail-send.
svstat tells the status of service. Just pass the path to a
controlled directory. For example
svstat /service/qmail-send
supervise is run by svscan to watch over a specific daemon, and
restart it if it dies.
multilog reads log data from stdin, optionally filters it, and
deposits the results into one or more logfiles, handling
rotation automatically.

UCSPI is the UNIX Client-Server Program Interface. It defines a command-line structure and environment variable specifications for inter-process communications helper programs; these make it easier to write clients and servers.

UCSPI-TCP is the specific variety of UCSPI for TCP applications; it specifies more details about specific environment variables and suchlike details.

tcpserver
like inetd, only for a single service. An invocation
of tcpserver will listen for connections on a port, when one
arrives it will start a client program with args as
specified on the tcpserver cmdline, and with envars as
specified by UCSPI-TCP. tcpserver implements access-control
rules.
tcprules
compiles the access control rules for tcpserver into a cdb
database
tcpclient
A client helper program; does the setup for writing network
clients for TCP protocols, following the UCSPI-TCP
specification.

There is a SSL/TLS extension patch available for ucspi-tcp that is needed to support secure pop3 and imap connections. The patch can be found on the qmail-ldap home page.

Get qmail-1.03.tar.gz from cr.yp.to. Get the patch from www.qmail-ldap.org. Unpack both, chdir to qmail-1-03. Patch the source tree:

patch -p1 < /path/to/qmail-ldap-1.03-xxxxxxxx.patch

Edit the Makefile to reflect your setup. You can change the following values:

ALTQUEUE
Enable the qmail-queue patch that makes it possible to select a different
qmail-queue program on runtime.
BIGBROTHER
For ISP that need to implement some surveillance method because of some
beloved authoroties (like here in switzerland), you can enable a per
address queue extra feature. See also the ~control/bigbrother file.
BIGTODO
Enables the big todo patch. Normaly not needed.
BIND_8_COMPAT
If the compile fails building dns.c because of undeclared defines this
may help. This is necessary on MacOS X 10.3.
CLEARTEXTPASSWORD (really bad idea)
Allows cleartextpasswords in ldap. Normally, passwords without prefix
are treated as crypt passwords.
DASH-EXT
Turns the dash extension mechanism on.
DATA_COMPRESS
Use smtp on the fly DATA compression if available. Needs the ZLIB options.
EXTERNAL_TODO
Run with the external high-performance todo processing. This avoids the
silly qmail syndrome with high mail injection rates.
IGNOREVERISIGN
Disallow dns wildchar matches on gtlds, thanks verisign.
QLDAP_CLUSTER
Compiles the clustering code in. Note: this doesn't mean clustering is
on, it just means you _can_ turn it on.
QMQP_COMPRESS
Use the QMQP on the fly compression for cluster forwards.
QUOTATRASH
Include the Trash in the quota calculation (normaly it is not).
SMTPEXECCHECK
Enable SMTP DOS/Windows executable and bad MIME attachement detection.
LDAPLIBS
Libraries you need for ldap, normally -lldap and -llber. On some systems
-lresolv is needed, too. If you have problems compiling, double check this.
For OpenLDAP, you typically have
LDAPLIBS=-lldap -llber.
For Netscape you'll need something like
LDAPLIBS=-L/usr/local/ldap/lib -lldap50 -llber50 -lpthread
LDAPINCLUDES=-I/usr/local/ldap/include
Don't forget to adjust the pathes.
LDAPINCLUDES
Path to ldap-includefiles, at least ldap.h and lber.h. If you have
problems compiling, double-check this.
ZLIB
ZLIB is needed for for -DDATA_COMPRESS and -DQMQP_COMPRESS.
If the zlib is installed in a non standard localtion ZINCLUDES should also
be set.
TLS
Enables SMTP encryption via SSL. You'll need OpenSSL.
Use -DTLS_REMOTE to enable tls support in qmail-remote
Use -DTLS_SMTPD to enable tls support in qmail-smtpd
TLSINCLUDES
Path to OpenSSL include files. If you have TLS enabled and compilation
problems, double check this.
Typical: /usr/local/include or /usr/local/openssl/include.
TLSLIBS
Path to OpenSSL libs.
Typical: /usr/local/lib or /usr/local/openssl/lib.
OPENSSLBIN
Path to OpenSSL binary, only used for make cert.
Typical: /usr/sbin/openssl or /usr/local/openssl/bin/openssl.
MAKE_NETSCAPE_WORK
Turns on a bugfix for Netscape's download progress bar and qmail-pop3d.
AUTOMAILDIRMAKE
Turns the auto-MAILdirmake-patch on. No external script needed.
AUTOHOMEDIRMAKE
Compiles the auto-HOMEdirmake-patch in. You need to specify an external
script in ~/control/dirmaker which creates the homedir. It gets the dir
as first (and only) parameter. Note: this script runs under the affected
user's permissions, so, if the homedir for a system user "joe" should be
created in /home, joe must have write permissions in /home.
SHADOWLIBS=-lcrypt & SHADOWOPTS=-DPW_SHADOW
is needed on most systems except OpenBSD. On some systems (Linux, Solaris)
-DSHADOWLIBS=-lcrypt -lshadow is needed if you use system users. Also
SHADOWOPTS is needed to support shadowlibs on some systems (Solaris).
DEBUG
compiles some debugging code in. See QLDAPINSTALL for more info.

You can change the ldap attribute names in qmail-ldap.h, this is self explaining. Also check the conf-* files. On some systems, at least OpenBSD up to 3.4, you have to modify either conf-spawn or conf-cc:

After editing Makefile and checking conf-*, you must add the users for qmail. You MUST add them BEFORE compiling, and you can't change their uids afterwards. Please see INSTALL.ids for example scripts.

Now it's time to compile:

make setup check

If you are using TLS (SSL encryption), you must create an certificate. Please refer to OpenSSL's documentation for explanations about certificates.

If enabled (1), qmail-ldap does not try to retrieve the userpassword-attribute from ldap, instead, it tries to bind to the ldap server using the looked up DN and the supplied password (affects auth_pop and auth_imap). This allows your ACL to be more restrictive, nobody except the user himself needs the right to retrieve his password from the ldap directory.

If given, ldap lookups are limited to entries having this objectclass. This is useful if you use your ldap directory for other purposes, too, and only users having a special objectclass (qmailuser for example) should have mail accounts.

The system user id your virtual users are mapped to. You can add as much users as you want to you ldap directory without having system accounts for them, they are all mapped to a single system user id - this one is defined here.

The default maximum amount of disk space the user can use until all further messages get bounced back to the sender. Size is a byte count. Overridden by user's attribute mailquotasize if existant. Default: NULL (no size limit)

echo "1000000" > defaultquotasize

This means: 1000000 bytes (1MB) size.

Don't forget to set quotawarning, otherwise no quota warning messages are issued.

The default maximum amount of messages the user can have until all further messages get bounced back to the sender. Count is a file count. Overridden by user's attribute mailquotacount if existant. Default: NULL (no count limit)

echo "1000" > defaultquotacount

This means: a maximum of 1000 messages.

Don't forget to set quotawarning, otherwise no quota warning messages are issued.

This file contains envelope sender addresses that are allowed to relay through this server. This is a really bad idea as sender addresses are very easy to spoof and you are an open relay then. You should use SMTP after POP instead.

If you compiled the autohomedirmake-feature, this contains the FULL path to your script which creates missing homedirs. The scrpit is executed under the affected user's uid/gid, so if your homedirs are in /home and the homdir for joe (system uid joe) should be created, joe MUST have write permissions to /home. This feature is most usefull in virtual user environments where all users are mapped to an single system uid/gid pair, let's say virtual/virtual. Then only virtual needs write permissions in /home. The script gets the path for the to be created homedir as first parameter and aliasempty as second one. A sample script:

Alternate names for this host for use with clustering. For example, me contains mx1.example.com. ldapclusterhosts contains mx2.example.com. Every mail for users with either mx1.example.com or mx2.example.com in their mailHost attribute will be delivered locally.

dn
Every entry in a LDAP directory has a "distinguished name", dn in short.
For persons it is normally build from the common name (cn), all
organizational units (ou), and the basedn (dc=bsws, dc=de in this case).
userpassword
The userpassword, prefixed by the crypt-method. If no prefix is given,
unix stadard crypt() is assumed (cleartext if you compiled with
CLEARTEXTPASSWORD).
Lots of other crypt methods like MD5 are possible. If you use rebinding
(ldaprebind=1), all crypt methods supported by your ldap server are
possible.
cn
common name - needed, unique
ou
organizational units - used to "group" users.
objectclass
defines the type of the ldap entry. multiple values are possible. Every
entry to be used by qmail-ldap should have qmailuser as objectclass, but
this isn't checked by default. Starting with patch 20010101, it is
possible to check this.
mailhost
when clustering is turned on, the server where the user's mail is stored
is defined here. Note that it MUST match the name given in "me" on the
affected server.
mailmessagestore
where the user's mails should be stored. If you are starting qmail with
qmail-start ./Maildir/
(this is common), this would expand to /realhome/brahe/Maildir/.
uid
The username to be supplied for pop, imap, webmail and so on. unique.
realname
Hmmm... hard to guess what this could mean... ;-))
accountStatus
active: no restrictions
nopop: pop3 access denied
disabled: bounce incoming mails
mailquota
The users mailquota. In this example, 100 MB or 10000 Mails.
mailforwardingaddress
all mail received for this user is forwarded to this address. If
deliverymethod isn't set to "localdelivery",
mail is only forwarded, no local copy stored.
mail
The users mail address. You can only set ONE mail attribute per user,
and addresses must be unique. Use mailalternateaddress for additional
addresses.
mailalternateaddress
additional mail address(es) for this user. Define as much as you want.

There are more possible fields:

qmailUID
The system uid for this user. If not set, the value from the control file
"ldapuid" is taken (virtual user environment).
qmailgid
The system gid for this user, like qmailUID.
homeDirectory
The users home directory.
If LDAP_HOMEDIR is found this field is used as $HOME, using
aliasempty or mailMessagestore if defined as default delivery method.
I recommend not to use this field, mailmessagestore is the cleaner
approach.
If you use this attribute for other purposes (in our case it's taken to
chroot the user in this directory for ftp access), set LDAP_HOMEDIR in
qmail-ldap.h to something different, noHomeDir is common.
deliveryProgramPath
same as |/path/to/someprog in a .qmail file. Only used if qmailDotMode
is set to ldapwithprog or both.
Example: /path/to/prog
The program gets the message on STDIN. All environment variables as
described in qmail-command(8) are set, and the exit code is handled
exactly as described there. If, for example, the program exits 100 the
mail is bounced.
deliveryMode
normal: Maildir/box delivery only if no forwards or prgrams are executed
forwardonly: hmmm... hard to explain... ;-))
nombox: ignore all maildir/mbox deliveries
localdelivery: always deliver locally. In conjunction with forwarding
this means to deliver a local copy.
reply: send also an auto-reply-mail with text from mailReplyText
echo: don't use it, very strange.
It is possible to set more than one value, be carefull.
mailReplyText:
The text for autoresponders. Only used if deliveryMode is set to "reply".

Access control is done by tcpserver. tcpserver checks a cdb file if supplied via the -x parameter for the connection IP address. Cdb is a database format developed by Dan Berstein. If you are using the conf-qmail package the cdb files are in /service/[servicename]/tcp.cdb and are build from the file tcp in the same directory via the tcprules program. Check tcprules' man page for a description of its parameters. A basic tcp file looks like this:

192.168.1.1:allow
192.168.2.:allow
:deny

The first line allows connections from 192.168.1.1, the second from the hole 192.168.2.0/24 subnet. Note that tcpserver does NOT work with subnet masks, the second line means exactly "connections from all IP addresses beginning with 192.168.2. are allowed". The third line denies connections from any other address. It is possible to set environment variables through tcpserver via the tcp file. This is important for qmail-smtpd:

192.168.1.:allow,RELAYCLIENT=""
:allow

This means: for connections from 192.168.1.* the environment variable RELAYCLIENT is set to "", this means relaying is allowed to any destination. All other IPs may connect, but RELAYCLIENT is not set and therefore only RCTP TOs with domains from the control file rcpthosts are accepted. It is also possible to set more than one environment variable:

192.168.1.:allow,RELAYCLIENT="",MYVAR1="value",MYVAR2=""

Let's have a short look at the control files needed for qmail-ldap operation. The most important piece is qmail-smtpd. You need a tcp file where the environment variable RELAYCLIENT is set to "" for all your local IPs. Connections from all other IPs are normally allowed, but RELAYCLIENT isn't set. For roaming clients we need an additional solution - read on ;-)) For qmail-qmtpd the same rules apply, it is common to use the same tcp.cdb for smtp and qmtp. For qmail-qmqpd it is very important to deny connections by default. There's no relay checking for qmqp! For pop3 and imap tcpserver is normally invoked without a tcp.cdb to check as we normally allow access from anywhere.

Ther preferred IMAP server for qmail-ldap is courier imap. Get it from http://www.inter7.com/courierimap/. You can and should start courier imap using tcpserver and auth_imap. Your run file will look like this:

It's quite common to use sqwebmail with qmail-ldap. If there were an award for the fastest webmail program on earth sqwebmail would get it. It accesses Maildirs directly and is written in C. Get it from http://www.inter7.com/sqwebmail/. Right now you cannot use sqwebmail in a cluster in a clean way.

Alternatively you can use any webmail program working over IMAP. squirrelmail gained popularity the last few years. Horde's IMP is another common choice, though not my one.

It unbelievable simple. In a cluster enabled qmail-ldap environment, every host has all domains to be handled by the cluster both in rcpthosts and locals. When a message is received, the user is looked up and his mailHost attribute is compared to the control files "me" and "ldapmailhost". If mailHost doesn't match either, the mail is forwarded to mailHost via qmqp. There is also pop3- and imap-session forwarding, these are handled by auth_pop and auth_imap.

Important note: all hostnames (especially those in mailHost and me) MUST be valid dns names, qmail does NEVER use /etc/hosts.

As in-cluster delivieries are done via qmqp, you'll need to set up qmail-qmqpd on all cluster members. Use qmail-qmqpd-conf from the qmail-conf package for that. Don't forget to add your cluster hosts IP-addresses to /service/qmqpd/tcp on each cluster member, otherwise in-cluster deliveries will fail.

You'll need to decide on which cluster member each user should have his/her mail stored, set mailHost for each user accordingly.

Add all domains to be handled by the cluster to the control files rcpthosts and locals on all cluster members - rsync is your friend ;-))

This should be all. It's now time to enable clustering (echo 1 > /var/qmail/control/ldapcluster) and start qmail-ldap on each cluster member.

Make sure you have set up pop3 (and possibly imap) on all cluster members storing users mail (important: they _must_ listen on the ip address defined by `me`!) , otherwise session forwarding will fail. If you need imap, you have to use courier imap under tcpserver with auth_imap, otherwise imap session forwarding won't work.

Given your eMail addresses are in the form user@domain.com and your mailserver is called mail.domain.com you may wish to have each user reachable as user@mail.domain.com, too. You can of course just add additional mailAlternateAddress attributes to each user record, but this may be lots of work for big directories. another possibility is making mail.domain.com an alias for domain.com. You need to remove mail.domain.com from control/locals and add it to control/virtualdomains like

mail.domain.com:mail.domain.com

Then, add a file alias/.qmail-mail:domain:com-default containing

|/var/qmail/bin/forward $DEFAULT@domain.com

It is important to use the forward program here instead of just writing $DEFAULT@domain.com in the file. The environment variables like $DEFAULT are only available when doing program deliveries. Also make sure you have localdeliveries turned on. In the .qmail-filename all dots must be replaced by : as described in qmail-local's manpage.

Let's hav a look at an example. A mail for joe-average-user-list@domain.com comes in. qmail-ldap will look for mail: and alternateMailAddress: attributes in the following order and taking the first match:

got the logic? we start with looking for a exact match. if that fails, we replace everything in the local part after the last dash with catchall, then everything after the 2nd last dash, and so on until only catchall is left.

You must first have patched your qmail source tree with the QmailLDAP patch (see above) before you attempt in using the QmailLDAP/Control patch. You should also have succeeded in getting QmailLDAP to work and deliver messages. Using another LDAP patch will only introduce yet another point-of-error, so one thing at a time, please :). It will make all of us happier, and makes it easier at helping you at all.

The main reason for this patch was having a centralised configuration of qmail. My point was to have relativly unexperienced qmail/unix personnel in my organisation to do the 'trivial configuration stuff' such as adding domains to the locals and rcpthosts files. This can quite easily made even by a sales-person like Stef :)

Using a simple webinterface and spending some thoughts when setting up multiple qmail servers (either as a cluster, or standalones), you can have all the configuration in one place (under the same Control DN in the LDAP database), thus making it harder for the unexperienced people to forget a host when modifying system-wide information.

Basically the only FILES you still need in the control directory are 'me', 'ldapcontroldn' and 'ldapserver'.

This is because qmail need to know who it is ('me'). This is Fully Qualified Domain Name (or FQDN for short) for the host running qmail. This information is used by QmailLDAP/Controls to find the proper LDAP object for this particular qmail host. qmail also needs to know WHERE to find the information in the database ('ldapcontroldn'). It will search below the Distinguished Name specified in the 'ldapcontroldn' file. And naturally qmail needs to know WHERE the LDAP server is running ('ldapserver').

If you want to limit access to what information is stored in the QmailLDAP/Controls object, you can put the proper ACL's in your LDAP server and have QmailLDAP/Controls bind with a special Bind DN and password. This information is then specified in the files 'ldaplogin' and 'ldappassword'.

REMEMBER: The 'ldaplogin' is a Distinguished Name entry, NOT a user name!

Just in case your LDAP server isn't running on the default port 389 you can specify the port in the file 'ldapport'.

While QmailLDAP/Controls compiles, you can start by modifying your LDAP server. We must tell it what object classes and attributes that have to do with the QmailLDAP/Controls system. The specification about the object class and the attributes can be found at the bottom of the QLDAPINSTALL file. Please look in this file for the latest definition of the object class. If you are using LDAP v3 (that is, OpenLDAP v2.x) you should use the schema supplied as qmailControl.schema. This file goes into your OpenLDAP schema repository (ie, where the other .schema files are located). They you will have to include this file in the slapd.conf file. After the qmail.schema include is a good bet.

When this is done, restart the LDAP server (or make it reread the new configuration).

Now go through each file in the control directory and create a LDIF out of those values. The way the patch works, all you have to do is use the filename as the attribute. For example, if you have a file there by the name 'locals' (a very common file in qmail), the attribute for each line in this file is 'locals'. And likewise, the file refered to as '~controls/ldapuid' in the QLDAPINSTALL file, would have a attribute name of 'ldapuid' etc.

First thing we should do is decide WHERE (ldapcontroldn) we should have our QmailLDAP/Controls object. I have (on my company's system) decided to create my database with the 'location' system. That is, I'm from Sweden, and my company works mostly/currently only in Sweden. I have therefore specified the BaseDN to be 'c=SE'. Our company is called 'Air2Net', so therefore our branch in the tree is 'o=Air2Net'. Under this, I have created a 'organizationUnit' with the name 'ou=QmailLDAP'. And the mail server is called 'donald.air2.net'. The full DN for the QmailLDAP/Controls object for Donald is therefore:

cn=donald.air2.net,ou=QmailLDAP,o=Air2Net,c=SE

So the first lines in the LDIF we are creating is this (we include the object classes at the same time here):

To show the usage of the LDAP database, I will demonstrate how to move the 'locals' file to LDAP. The locals file is, as I said earlier, a very common file in the qmail world, it is why I choose to demonstrate with this file.

This is a genuine example from my own file (before QmailLDAP/Controls):

The information QmailLDAP needs can naturally also be put in the LDAP server. The most common information QmailLDAP uses are ldapbasedn, ldapuid, ldapgid and ldapdefaultquota etc. To add that information to the QmailLDAP/Controls object, we add these lines to the LDIF (remember, the 'ldapbasedn' is where QmailLDAP will search for USERS, and 'ldapcontroldn' is where QmailLDAP/Controls will search for control information):

ldapbasedn: c=SE
ldapuid: 3001
ldapgid: 3000
ldapdefaultquota: 10000

Create the LDIF out of your remaining files, moving the information one by one.

That's it, the rest of the information that QmailLDAP needs, is retreived from the LDAP server instead!

Important Note: you SHOULD keep a rcpthosts file which may contain only yuour own hostname or somesuch, just in case of a misfunction. without a rcphosts file, qmail (specifically, qmail-smtpd's behaviour) is an Open Relay. Should anything wrt the LDAP lookup go nuts, you are only safe if still having the rcpthosts file.

After patching you need to enable SMTP after POP by adding -DSMTP_AFTER_POP to LDAPFLAGS in Makefile.

As we all know, SMTP does not contain any authentification mechanisms by default. So in practice you are allowing realying through your server only for some IP addresses, normally your corporate network. If your users are coming from various, dynamic IP addresses they can't use your mailserver for sending :-((

To overcome this limitation there are 3 possibilities:

relaying based on the envelope sender - a really bad idea, easy to abuse.

SMTP AUTH - great, but your clients need to support it. For a patch see below.

SMTP after POP - when the user gets his mail through pop, his IP address is recorded and the permission to relay is given for this IP for something about half an hour.

SMTP AUTH would be the best solution as username and password are supplied when sending, but as long as too many clients are lacking support for it, this is not an option for most of us.

Therefore I have written a patch for qmail-ldap to allow SMTP after POP. There is another solution without the need for a patch because it parses logfiles - I don't like this approach, and the patch should perform better. It is based on Russel Nelson's open-smtp.

For first, we need to patch auth_pop to call an external script when a user authentificated. tcpserver (under which the pop-daemon runs) sets fortunately some environment variables, one of them contains the remote host's IP. My patch sets an additional environment variable: AUTHUSER. It contains the authentificated username.

Beware that this script will cause serious trouble when used with an IPv6-aware tcpserver and someone connects to your pop3-server over IPv6! Don't forget to modify the pathes if needed! The first line records the IP and abuses TCPREMOTEINFO to store the authentificated username in the mail header. The second line builds the cdb qmail-smtpd uses to decide wether relaying is allowed or not.

Some Notes about AUTHUSER: For basic smtp after pop operation you don't need AUTHUSER at all. Whenever your client authentificates via pop3 his IP is allowed to relay until your cron job removes it. The idea behind setting TCPREMOTEINFO to AUTHUSER is to store the authentificated user name in the header of outgoing mails from him so it is really easy to determine which user has sent a mail in case of abuse reports. If you don't want this, just remove the ,TCPREMOTEINFO="$AUTHUSER" from pop3-record.

TCPREMOTEINFO is normally used to store the username you get by ident, this has no practical relevance any more as nearly no client runs ident. So we are invoking tcpserver with the according option (-R) to not query ident information and abusing the TCPREMOTEINFO to store our authentificated username.

The user's IP is now allowed to relay infinite - this is not what we want. Therefore, run somthing like the following every 15 mins (or whatever you like) by cron:

As described above SMTP AUTH is the cleanest solution for allowing roaming clients to use your smtp-server. David E. Storey <dave@tamos.net> has ported the patch from brush/elysium.pl to qmail-ldap. I have written auth_smtp for authentication. After installing the patch you must modify your qmail-smtpd startup file, qmail-smtpd needs two options now:

qmail-smtpd /var/qmail/bin/auth_smtp /usr/bin/true

The second parameter isn't used but must exist. If you wan't to be able to authenticate system users on a shadow password system auth_smtp must be suid root. Otherwise it runs fine without special permissions.

Read RFC2554. SMTP AUTH is just an OFFER for the client to authenticate itself to get relaying permissions. If he already has relaying permissions (through IP-based selective relaying aka tcpserver for example) he wins nothing through the authentification.

2. permissions on /var/qmail/bin/auth_smtp

qmail-smtpd must be able to run auth_smtp. qmail-smtpd normally runs as user qmaild. auth_smtp should be owned by root and mode 755 (default, but check it - there was an error regarding this in older versions of the patch) or owned by qmaild and mode 700. If you want to auth system users from shadow password files (/etc/shadow typically) auth_smtp must be setuid root. I don't recommend this.

3. permissions on ~/control/ldap*

auth_smtp MUST be able to read the control files containing informations about the ldap server, especially ldapserver, ldapbasedn and ldappassword (if existant). Pay attention to ldappassword! auth_smtp usually runs as user qmaild and must be able to read this file if you aren't using anonymous binds against your ldap server.

Please note that the patch isn't declared stable or so, it is still experimental. It works fine on my production systems since march or so, but I know there are some gotchas and unclear error messages left.

After patching you need to enable the dash-extension by adding -DDASH_EXT to LDAPFLAGS in Makefile.

If you have the address joe@domain.com in stock qmail, you also have joe-[anything]@domain.com. This isn't the case with qmail-ldap. As ezmlm relies on this, I've written a patch based on the work by Cedric Schieli.

After patching you need to enable MXPS and QMTP by adding -DMXPS to LDAPFLAGS in Makefile.

Dan Bernstein describes MXPS, the Mail eXchanger Protocol Switch. This allows the use of alternative protocols like QMTP instead of SMTP. The MX's priority field in DNS is abused for protocol selection. lets have a look at bsws.de for example:

This tells MXPS-capable remote servers (or clients) to send via QMTP to mx01 first, if this fails, via SMTP to mx01 and so on. Non-MXPS-capable clients just send to mx01 with SMTP (therefore it is important that every server understands SMTP and not only QMTP). QMTP has shown to be at least twice as fast as SMTP in most cases.

Russel Nelson has written a patch for qmail-remote to use MXPS and, if QMTP support is announced by MXPS, use QMTP to deliver mail. The QMTP code itself is taken from Dan's serialmail package.

qmail-ldap can block messages from servers listed on various rbl lists by default. Inspired by Maex extension to rblsmtpd I've patched qmail-smtpd and qmail-qmtpd to tag messages from blacklisted servers. Whenever a mail from a blacklisted server is received qmail-smtpd/-qmtpd adds an X-RBL-Check: [blacklistserver] Header. So, if a mail from 1.2.3.4 is received and this server is blacklisted on rbl.domain.com and rbl.otherservice.com, the two lines

X-RBL-Check: rbl.domain.com
X-RBL-Check: rbl.otherservice.com

will be added to the message's header.

To enable this you'll need to apply the patch and create the new control file rbltags, listing the rbl-servers to check against, one per line. Please note that the qmtpd part is nearly untested, I appreciate any feedback.

Maex has 822xrblcheck, a small program to be used in conjunction with bouncesaying allowing users to reject mails with X-RBL-Check headers in their .qmail-files.

qmail-ldap with patch 20010501 and above has a similar functionality, but I don't like the implementation, especially you must decide to either reject connections from blacklisted hosts or tag messages. You cannot, for example, reject messages from hosts listed in really-well-known-spammers.corp.local and tag messages from hosts in dialups.corp.local. My patch allows this.

When I try to start qmail-ldap I'm getting this error: alert: cannot start qmail-lspawn or it had an error! Check if ~control/ldapserver exists.

The control file ldapserver exists and has correct permissions (644). What's the problem?

If the control file ldapserver exists then it seems that qmail-lspawn crashed while starting. This is because of missing shared libraries. Since OpenLDAP has started to compile normally shared libs we see this reports more often on the mailing list.

To see if you have a shared library problem try this: `env - /var/qmail/bin/qmail-lspawn` or even better `env - /var/qmail/bin/qmail-ldaplookup -m someone@somewhere.org` if you get something like: /var/qmail/bin/qmail-ldaplookup: error in loading shared libraries libldap.so.1: cannot open shared object file: No such file or directory you have a shared library problem.

Also a `ldd /var/qmail/bin/qmail-ldaplookup` should mention that problem: (Output of a Linux test box)

How to solve the problem: 1. find your ldap libs, you should know where they are. In my case /opt/OpenLDAP/lib

Super fast hack: ln -s them /usr/lib and probably rerun ldconfig

Fast hack: set the env-var LD_LIBRARY_PATH to "/path/to/OpenLDAP/lib" e.g. in /var/qmail/rc via a "env LD_LIBRARY_PATH=/opt/OpenLDAP/lib"

Better: add it to the ld.cache. On many systems there are tools like ldconfig. You can use them to add /opt/OpenLDAP/lib to the normal runtime library search path. Under linux you can edit /etc/ld.so.conf. Under *BSD you can use ldconfig /opt/OpenLDAP/lib to add it to the cache AFAIK there is also something like /etc/ld.so.conf on Solaris.

Best: recompile qmail-ldap with adding -R/opt/OpenLDAP/lib to LDAPLIBS This works under Solaris and OpenBSD sparc other OS's may also support it. Under Linux you have to use ld as linker (conf-ld) and add a -rpath /opt/OpenLDAP/lib to LDAPLIBS

In order to use ezmlm with qmail-ldap, you need to enable dash-ext adressing in qmail-ldap. Ezmlm uses listname-directive@domain.com for various things, so your mail server must be able to handle this.

Once you have done this, run the ezmlm-make program as usual. Once you have your list, create an ldap entry for the 'main list' address. Set the mail or mailalternateaddress attribute to your mailing list address. The mailMessageStore attribute should point to the directory that your mailing list is pointing to. Also, qmailDotMode should be set to either dotonly or both and you will probably want to make sure that the accountStatus is flagged as nopop.