The most recent version of the script is dated 2007-10-02. The script itself contains a list of what changes were made, each time I made a change.
The most common questions I receive about the AUTH_CDB patch involve how to create an "auth.cdb" file in the first place, or how to use the same file on multiple servers. The mkauth script can be a major part of the answer to both questions. This web page will show how I'm using mkauth on my own server.
I should point out that you are not required to use mkauth in order to benefit from the AUTH_CDB patch- any mechanism which produces a list of all valid mailboxes on your system, with their encrypted passwords, will work. As long as you correctly turn this text into a cdb file, qmail-smtpd will be able to use it.
Also, there is no requirement that you use the name "auth.cdb" for the file- you can use any name you like, so long as the file is readable to the userid as which qmail-smtpd runs. This page will use the name "auth.cdb" for example purposes- the filename you use on your own server should match the name you have in the AUTH_CDB variable for your qmail-smtpd service.
Before you install the script, there are a few other packages which need to be installed on the system. The first is djb's cdb library and tools, which contains the cdbmake-12 program, which converts a text file into a cdb file. This package should be installed using the directions on djb's web site. A quick walk-through is shown here:
$ wget
http://cr.yp.to/cdb/cdb-0.75.tar.gz
...
$ tar xvzf cdb-0.75.tar.gz
...
$ cd cdb-0.75
If you are using a system with glibc version 2.3 or later, the original djb source code will cause an error in the file error.h, because the newer versions of glibc implement the errno variable differently than how it has been done in the past. (errno is a global variable which libc uses to tell the caller whether the last I/O function call was successful or not, and if there was an error, it will contain a number identifying the error.)
There is a simple fix, which can actually be done on all systems whether it's necessary or not, without causing any problems. If you know (or suspect) that you need this fix, or if you have tried to compile the code and gotten an error about error.h, or if you just want to do it anyway, here's the fix:
Open the file error.h with a text editor.
$ vi error.h
Find this line:
#ifndef ERROR_H
#define ERROR_H
extern int errno;
extern int error_intr;
extern int error_nomem;
Comment the line out, and add this new line below it:
#ifndef ERROR_H
#define ERROR_H
/* extern int errno; */
#include <errno.h>
extern int error_intr;
extern int error_nomem;
You can also make this change with a one-line sed command, useful for scripts:
$ sed -i '/extern int errno/{s/^/\/* /;s/$/ *\//;G;s/$/#include <errno.h>/;}' error.h
Then finish compiling and installing the package as normal. Note that this same problem can occur, and the same procedure will fix it, in most of djb's programs, including qmail, ucspi-tcp, daemontools, and djbdns.
The mkvalidrcptto script reads several cdb files in order to do its job, which means that you need to install the CDB_File perl module, available through CPAN, the Comprehensive Perl Archive Network, which is an archive of Perl modules which are not included with Perl itself, but which others have decided to share in the hope that they will prove useful.
This is a quick walk-through of how to install the module.
After installing any Perl modules, it's a good idea to run the pfix script, available on the code section of my normal (non-qmail) web site. Some Perl modules don't correctly set the permissions on their files when you install them- the pfix script resets the permissions on all directories in Perl's default library path so that everything is owned by root and is world-readable but only writable to root.
Believe it or not, this is actually the easiest part of the whole process. All you need to do is download it into a directory which is in your PATH and set the permissions.
File: | mkauth |
Size: | 12,521 bytes |
Date: | 2007-10-02 20:45:24 +0000 |
MD5: | 55ab27943db6ebf644fb83dba02fc2d6 |
SHA-1: | d60c35c9ddcf9c29870eb06b9efa575175ee9be9 |
RIPEMD-160: | 9047cfe9d2d477c1d723d09c7e3e8bdb53a069ca |
PGP Signature: | mkauth.asc |
# cd /usr/local/bin
# wget
http://qmail.jms1.net/scripts/mkauth
...
# chmod 755 mkauth
One thing that wouldn't hurt is to make sure that your installation of perl is happy with the script and can find the modules. You can do this by running this command as a non-root user:
$ perl -c /usr/local/bin/mkauth
/usr/local/bin/mkauth syntax OK
You should then run it once as root and make sure the output makes sense for your system. The output should be a list of every valid email address on your system, one on each line.
# mkauth
alan@domain1.xyz $1$dhuMd.kf$UUGFyA3DCaMWU3pFL2QTqk
jms1@domain1.xyz $1$GLKcu17D$TSNDEEt9Gii0oh6WLV2lWx
postmaster@domain1.xyz $1$I/hnPBSk$1QST1iKis22t/cm5pE8pkz
thomas@domain1.xyz $1$r/JKcyUw$RNfIgJ0ZtkpIIOUmoKBYYL
postmaster@domain2.xyz $1$oHXkhAIU$nG1z7gPNd7eBcYB0hCmLX2
postmaster@domain3.xyz $1$iNeEuq4u$I4GHPUKYr9KPuCuK5fD/28
user@domain3.xyz $1$EDjIhtfL$iWwoLY3pBRxc46xy9fTHfW
As shown in the example above, simply running the script as root will produce a list of every mailbox on your system, along with their encrypted passwords. This output can be piped through "cdbmake-12" in order to produce a .cdb file.
# mkauth | cdbmake-12 new.cdb new.tmp
If there are any active qmail-smtpd services using the file, you should not build the file directly- you should build it using a different name, then set the ownership and permissions correctly, and then rename the new file over the old one. This example assumes that qmail-smtpd is running as the "qmaild" user (which is the standard way to do it.)
# chown root:nofiles new.cdb
# chmod 0640 new.cdb
# mv new.cdb auth.cdb
Another option is to use the "-m" option, which produces its output in the format needed by the cdbmake program. I don't see many people using this option, however it's there if you're more comfortable with it.
# mkauth -m
+16,34:alan@domain1.xyz->$1$dhuMd.kf$UUGFyA3DCaMWU3pFL2QTqk
+16,34:jms1@domain1.xyz->$1$GLKcu17D$TSNDEEt9Gii0oh6WLV2lWx
+22,34:postmaster@domain1.xyz->$1$I/hnPBSk$1QST1iKis22t/cm5pE8pkz
+18,34:thomas@domain1.xyz->$1$r/JKcyUw$RNfIgJ0ZtkpIIOUmoKBYYL
+22,34:postmaster@domain2.xyz->$1$oHXkhAIU$nG1z7gPNd7eBcYB0hCmLX2
+22,34:postmaster@domain3.xyz->$1$iNeEuq4u$I4GHPUKYr9KPuCuK5fD/28
+16,34:user@domain3.xyz->$1$EDjIhtfL$iWwoLY3pBRxc46xy9fTHfW
# mkauth -m | cdbmake new.cdb new.tmp
# chown root:nofiles new.cdb
# chmod 0640 new.cdb
# mv new.cdb auth.cdb
Note that the extra blank line between the data and the next command is
part of cdbmake's file format- it needs that blank line to flag the
end of the data.
Probably the easiest option is to use the "-c" option, which generates the .cdb file directly.
# mkauth -c new.cdb
# chown root:nofiles new.cdb
# chmod 0640 new.cdb
# mv new.cdb auth.cdb
The "-n" option causes mkauth to NOT generate output for "local" domains. It will still generate output for virtual domains managed by vpopmail. This was something I used while testing the script, and I didn't see any harm in leaving it there, so if you have a need for it, you have it. Enjoy.
The other option, "-e", specifies a file containing environment variables to be attached to users' entries in the file. Version 7.02 of the combined patch added the ability to specify environment variables, which qmail-smtpd adds to the environment (or changes in the environment) when that particular user authenticates. For now the only use I can see for this is being able to specify per-user DATABYTES limits, however I'm sure others will come up with a use for this mechanism.
The file containing the variables consists of lines. Each line starts with an email address, or in the case of a "local" user, just the userid. After the email address should be one or more spaces or tabs, followed by the variable(s) you wish to set. If you specify multiple variables on a single line, they should be separated with a comma (i.e. ",", ASCII 44, 0x2C.) Note that you can specify an email address on more than one line, and the variables from the various lines will be combined in the output.
Here's an example which shows the relevant pieces of information:
# cat authenv.txt
jms1@domain1.xyz DATABYTES="0"
thomas@domain1.xyz DATABYTES="0" , FNORD="mu"
jms1@domain1.xyz FNORD = " moo "
# mkauth -e authenv.txt
alan@domain1.xyz $1$dhuMd.kf$UUGFyA3DCaMWU3pFL2QTqk
jms1@domain1.xyz $1$GLKcu17D$TSNDEEt9Gii0oh6WLV2lWx,DATABYTES="0",FNORD=" moo "
postmaster@domain1.xyz $1$I/hnPBSk$1QST1iKis22t/cm5pE8pkz
thomas@domain1.xyz $1$r/JKcyUw$RNfIgJ0ZtkpIIOUmoKBYYL,DATABYTES="0",FNORD="mu"
postmaster@domain2.xyz $1$oHXkhAIU$nG1z7gPNd7eBcYB0hCmLX2
postmaster@domain3.xyz $1$iNeEuq4u$I4GHPUKYr9KPuCuK5fD/28
user@domain3.xyz $1$EDjIhtfL$iWwoLY3pBRxc46xy9fTHfW
Of course, this option can be combined with the "-m" or "-c" options as well...
# mkauth -e authenv.txt -c new.cdb
# chown root:nofiles new.cdb
# chmod 0640 new.cdb
# mv new.cdb auth.cdb
# cdbget jms1@domain1.xyz < auth.cdb
$1$GLKcu17D$TSNDEEt9Gii0oh6WLV2lWx,DATABYTES="0",FNORD=" moo "#
Note that "cdbget" does not automatically add a newline to the
end of its output, so the next prompt appears at the end of the output
instead of at the beginning of the next line.
I use a daemontools service called qmail-updater to update my auth.cdb and validrcptto.cdb files on a regular basis. The web page has details about how to set it up.
In addition, I use (and wrote) the vpopmail ONCHANGE patch, so that vpopmail itself can trigger the files to be rebuilt whenever something changes- a mailbox is added or removed, a password is changed, or whatever the case may be. This prevents users from having to wait until a cron job gets around to starting.
One of the biggest advantages of having auth.cdb as a stand-alone file is that it can be copied to other machines. The most common scenario is to have one machine handling the mailboxes, and one or more other machines (which I call "mailhubs") which handle incoming email from the outside world. These mailhubs' only job is to do RBL, virus, and/or spam checking on the incoming email, and only accept messages which are "clean". If a mailhub has an auth.cdb file available, it can validate AUTH commands, and authorized users can relay mail through the mailhubs without involving the mailbox server at all.
The mailhub page explains this scenario in more detail. It also includes scripts to handle automatically replicating certain qmail control files from the mailbox machine to the mailhubs- specifically the rcpthosts and morercpthosts.cdb files, the smtproutes file, the validrcptto.cdb file, and of course the auth.cdb file.