Single-UID based POP3 box HOWTO.
By Paul Gregg , 1998
Copyright Paul Gregg, 1998.

This document may be reproduced only in its entirety.

This document will explain how to configure qmail to handle many mail
users (multiple email addresses) with separate POP3 accounts - without
using system accounts.

I've written this document, unapologetically, aimed at the system installer
who doesn't know the ins-and-outs of Qmail - but to get them set up with
a safe, secure and reliable POP3 only (without using system accounts) host.

If you want to use system accounts do not read this document - it may
lead you in the wrong direction.

When configuring Qmail for any system it is advisable to start with
a structure which enables easy maintenance and the ability for you to
add, modify, delete users and/or domains with the minimum of distruption.
On my system, I'm an ISP managing hundreds of domains, so as well as making
the system technically correct, I want it to be easy to manage as well.

Starting:

Assumptions: You have installed Qmail as per DJB instructions and your
qmail is functioning correctly.

Critical files in use are:
  control/rcpthosts
  control/virtualdomains
  users/assign
  users/poppasswd (non-standard password file for checkpasswd - see later)

Note: When modifying either control/rcpthosts or control/virtualhosts you must
      send a HUP signal to qmail-send to cause those files to be re-read.
      Also see the "Managing users/assign" below for what to do when modifying
      users/assign

  [ recipientmap in Qmail 1.01 and before allowed you to map email addresses
    onto other email addresses. I believe in Qmail 1.03 it's use is now
    depreciated - probably because people like me were using it to configure
    aliases and mail forwarding ]

We will also create an additional directory and a 'file per domain'
configuration which will hold details of all email accounts.

So how does it all work?

The users/assign file structure has a very powerful email handling; you can
specify individual email addresses, multiple email address ability for a user
(e.g. user-*@domain.com), complete domain mapping to a single POP3
box.

We will avoid the ~alias user completely (I only use the default djb
~alias/.qmail-(mailer-daemon|postmaster|root) and a single .qmail-uucp-default
define to handle all UUCP delivery to my downstreams (but that is outside
the scope of this document).

How do you define a "domain"?

  When adding a new domain to your mail server you will need to add the
  domain name to the end of control/rcpthosts file (to allow Qmail to accept
  email for this domain).
  You will also need to add an entry for the domain to the
  control/virtualdomains file; however - What format should we use since
  we aren't controlling emails by system users?  As you may be aware qmail
  will convert a domain's periods into "-" minus characters (unless you
  have redefined the character when compiling); thus is becomes reasonable
  to add virtualhosts like this:  domain.com:domain-com

  Note: you should also ensure that the domain is *NOT* listed in
  control/locals  (this catches many people out).

  What does this mean?  It means that all email for the domain will be
  handled by the mail user "domain-com".

How to define the mail user "domain-com" and to accept email addresses for
that domain name.

  This is where the users/assign file comes into play.  This file is a
  powerful way of specifying email addresses which we shall see later.
  To add an email address to the system you need to add a line to this file,
  e.g. joe@domain.com  As we already know domain.com is handles by the 'qmail
  user' domain-com. Qmail will then look in users/assign for "domain-com-joe"
  e.g:
  =domain-com-joe:popuser:888:888:/var/qmail/popboxes/domain-com/joe:::

  What does this mean?

  = - This symbol means "match" the address, using a '+' symbol would allow
      this 'user' to receive email in the form joe-anything@domain.com
  domain-com-joe - This is made up of two parts, the first part is the
                   virtualdomain user specified (in virtualdomain), and
                   the second part is that part of the email address before
                   the @ symbol.
  popuser - This is the userid (in /etc/passwd) you have set up for *all*
            email users.
  888 - This is the UID of popuser
  888 - This is the GID of popuser
  /var/qmail/popboxes/domain-com/joe - This is the directory where qmail
                   will look for .qmail files to figure out how to deliver
                   email for this address (or relay it on).
                 * You must ensure that this directory is created with
                   permissions 0700 and owned by the popuser uid/gid.
                   You should create a .qmail (or .qmail-default) file here
                   to specify how mail is delivered (in this case you'll most
                   likely be delivering to a Maildir - see the "Dot Qmail"
                   section below)

  I find that the best way to manage multiple domains is to keep all
  domain email address specifications in individual files - see Managing
  users/assign below.
  This also applies to the directory structures for the maildrops (see the
  /var/qmail/popboxes/*/* above).
  

So, thats mail delivery sorted out, how do we do POP3 pickup?

  Well as I said, all mail "users" are owned by popuser (uid 888, gid 888).
  I would recommend that if you are new to setting up Qmail that you jump
  straight in to using the Maildir format (it's a little unconventional if
  you are used to more traditional Mailbox formats - but you'll be buying
  me beers for this advice in a year from now).

  When using Qmail with Maildir format, you will need to use qmail-popup ->
  checkpasswd -> qmail-pop3d. So what is this and why not just have a single
  daemon like qpopper?

     Simply Qmail, as you may be aware, is a very modular system and POP3
     is no different.  qmail-popup's job is to collect the username and
     password, once it has done that it runs checkpasswd (and qmail-popup's
     job is done so it exits [pedant note - yes I know it uses execvp() but
     technical functions don't explain it in simple terms] ).
     checkpasswd then takes this username and password and authenticates
     the user (the auth method used is completely up to the type of checkpasswd
     you chose, see below). If the user authenticates ok, then checkpasswd
     sets the environment variables USER, SHELL and HOME, then it runs
     qmail-pop3d which handles the POP3 between the mail client and USER's
     (in our case it is always popuser, but HOME is different) mail directory
     which is $HOME/Maildir.
     The real beauty here is that with Qmail you can use any type of
     authentication you desire - There are checkpasswds which work with
     system passwords, Radius auth, separate password files, PAM, etc.

  So which checkpasswd should I use?

     I started of using Jedi's checkpoppasswd listed on www.qmail.org. This
     allows you to first check a separate password file in the format:
        username:enc_password:realuserid:homedir
     Which is sufficient to specify an email only POP3 user.
     My own hacked version of Jedi's checkpoppasswd is available at:
        http://www.tibus.net/pgregg/projects/qmail/checkpoppasswd.c
        I have added extensive syslog logging to see when people have logged
        in, or when authentication fails for whatever reason.  It also adds
        a 2 second delay on failed authentications so that bruteforce hacking
        attempts are delayed.
        My default logs the failed password, though in the code there is an
        alternative syslog line which you can use which doesn't log the failed
        password.

  Ok, so I've got that setup? Where's the password file?

    In my default the password file is /var/qmail/users/poppasswd
    Simply make file and add a line, e.g:
       testid:DmIMm9e5Hc8ic:popuser:/var/qmail/popboxes/domain-com/joe
    This means we've just added a POP3 user "testid" with a password of
    "testpw" (crypted), with the real (system) id of "popuser" and their
    (home) directory is "/var/qmail/popboxes/domain-com/joe"

FAQ#1: How then can I have two joebloggs users?  I've got joebloggs@domain.com
and joebloggs@bloggs-n-co.com,  I can't have two joebloggs users in the
password file, can I?

A: No you can't have two usernames in the password file.  However who said
that the POP3 usernames should be the same as the "username" bit of the email
address?  Not me...  But most people presume this is what will happen.
Forget trying to do this - my recommendation is to pick an account numbering
scheme,
e.g.1: pop1, pop2, pop3 .... pop###
    2: pop00001, pop00002, pop00003 ... pop99999
or my way of doing it:
    3: ??0001, ??0002, ??0003, ... ??9999
Where ?? is two characters, either random or based upon their real or
company name - this helps to prevent people from randomly attacking your pop
server trying to guess usernames and passwords.


FAQ#2: How can I create the encrypted passwords?

A: They are created using the standard crypt() function (man 3 crypt)
which is available as part of all unix operating systems, and through languages
such as C or perl.  However, if all this is beyond you, you can use a tool
I've provided in my projects directory called mkpasswd.pl
Links: Projects Directory, mkpasswd.pl


Dot Qmail files.

  When you specify and email address in users/assign and their associated
  'home' directory Qmail will look for a .qmail file in this directory to
  instruct qmail how to deliver the email.  You should now read the dot-qmail
  man page.  Simply .qmail contents can be:
    ./Maildir/     - means to deliver the email into the Maildir directory
    ./Mailbox      - means to deliver the email into the standard mailbox
    &otheraddress@otherdomain.com - means to forward the email elsewhere.

Managing users/assign.

  As I have mentioned before I prefer to keep individual domains in separate
  files - there are many reasons for this, none of them technical, all of them
  are that I find it easier to manage (I have over 250 registered domains of
  which 180 have email services).

  users/assign quite simply contains one line per email address (or when
  using the + symbol, potentially many email addresses per user or per domain).
  The last line in users/assign should be a period '.' (or a full stop in UK
  speak).
  When changing this file at all you must run the program qmail-newu to
  rebuild the database (cdb).

  If using separate files to hold all addresses per domain it is a simple
  shell script to create users/assign from this. e.g. say we hold all these
  files in /var/qmail/users/domains/* we can create users/assign with:
	#!/bin/sh
	cat /var/qmail/users/domains/* > /var/qmail/users/assign.new
	echo "." >> /var/qmail/users/assign.new
	mv /var/qmail/users/assign.new /var/qmail/users/assign
	/var/qmail/bin/qmail-newu
  (you can skip the assign.new if you wish but some shells will refuse to
  overwrite a preexisting file without using >! or somesuch, the above
  method should work for everyone).


Ok, I think it's all working, how can I test it?

  telnet mailhost 110
  USER testid
  PASS testpw
  LIST
  RETR 1
  QUIT

If you can do all that then you're working fine, if not then look at your
logfiles and see where it went wrong.  My checkpoppasswd logs to syslog
as auth.warning.