http:// qmail.jms1.net / courier / courier-no-fam.shtml

Building Courier-IMAP RPMs without FAM

Many people, myself included, do not want FAM, the File Alteration Monitor running on their system. I actually don't have anything against FAM, but I don't like the fact that it requires portmapper. To be honest, I can't say I've heard of any security holes with current versions of portmapper, but I spent a long time considering it to be a security hole and I haven't reached the point where I feel comfortable letting it run on a publicly accessible machine (such as my mail server.)

As of the time I'm writing this (2005-03-05) the current version of courier-imap is 4.0.2. It doesn't include a specific option to compile the imap server without requiring fam, but if you compile it on a machine which doesn't have the fam headers installed, it builds an imapd which never tries to talk to fam at all.

The problem is that most of the servers I manage are running Linux distributions which are derivatives of RedHat, and therefore use RPM as the package management system. I like using RPM files to install and upgrade software, but the spec file (which tells "rpmbuild" how to compile the source code and produce binary RPM files) has a hard-coded dependency on the "fam-devel" package- it will refuse to compile the code without this package installed, which makes it impossible to build an RPM file containing an imapd which doesn't rely on fam.

Removing the fam dependencies from the spec file allows "rpmbuild" to compile the code without requiring fam when it runs, and the resulting server does work correctly (I am using it on my own server right now.) The following is a walk-through of building and installing the RPM files needed for a working server, including an explanation of how to modify the spec file.

Note: The following instructions should be completed by a non-root user, except for a few specific commands as noted in the text.

  1. Make sure you have any pre-requisite packages installed already. This will include the mysql-devel, openldap-devel, and postgresql-devel packages (as appropriate for your system- RHEL and friends seem to be making up their own names for this, you may need "rhdb-devel" or "rh-postgresql-devel" instead.)

    Also, a reader emailed me with a good point. courier-authlib and courier-imap are written in C++, which means you need to make sure the C++ compiler and the standard C++ library for your system are installed. The packages will have names like "gcc-c++" and "libstdc++-devel". You will also need the "rpm-build" package as well. Thanks for the tip.

    And, of course, the fam and fam-devel packages should NOT be installed on the machine. The configure script searches for the header files which are in the fam-devel packages, and if it finds them it will build imapd with the requirement for fam, regardless of what the RPM dependency information says.

  2. If you plan to build courier-authlib with support for vpopmail, you must install both qmail and vpopmail before proceeding.

  3. Download the source code for the current Courier authentication library and the Courier-IMAP packages from the official courier-imap download page. For these instructions we will assume that you have stored the files in your home directory.

  4. If you have not already done so, configure your home directory so that you can build RPM files without needing root privileges. This involves two steps:

    1. Create an RPM build directory structure in your home directory. I call mine "rpm", you may want to call yours "rpmbuild" or whatever... but choose a name which doesn't already exist. The example assumes you are using "rpm" as the name:

      % cd
      % mkdir -m 755 rpm
      % mkdir -m 755 rpm/BUILD
      % mkdir -m 755 rpm/RPMS
      % mkdir -m 755 rpm/SOURCES
      % mkdir -m 755 rpm/SPECS
      % mkdir -m 755 rpm/SRPMS

    2. Create a .rpmmacros file in your home directory which contains a pointer to the directory structure you just created. I use a second line which marks any RPM packages I build with my own name and email address- while not strictly required, it is a good idea. My file looks like this:

      %_topdir /home/jms1/rpm
      %packager John Simpson <jms1@spamcop.net>

  5. Build the courier-authlib package without any modifications.

    % rpmbuild -ta courier-authlib-0.58.tar.bz2

    This step will probably be where you find out about any missing dependencies. If you get any error messages, they should indicate which packages are missing. Install them (using yum, apt-get, or rpm) and then try this command again.

    Once it works, you will find the finished binary RPM files in your rpm/RPMS/i386 directory (the "i386" part will be different if you are building on another architecture) and a source RPM in the rpm/SRPMS directory.

  6. AS ROOT, install the courier-authlib and courier-authlib-devel packages. This is necessary in order to build the courier-imap package, even if the machine you're building the packages on is not intended to be a mail server.

    % cd ~/rpm/RPMS/i386
    % su
    Password: (Enter the root password. You should not see it as you type.)
    # rpm -ivh courier-authlib-0.58-1.i386.rpm
    # rpm -ivh courier-authlib-devel-0.58-1.i386.rpm
    # exit
  7. Extract the spec file from the courier-imap source package, and place it (along with the source tarball) into the rpm directory structure, where they will need to be in order to be compiled.

    % cd
    % tar tvjf courier-imap-4.1.1.tar.bz2 | grep spec
    -rw-r--r-- 500/500       7688 2006-02-25 10:16:28 courier-imap-4.1.1/courier-imap.lpspec.in
    -rw-r--r-- 500/500       9451 2006-02-25 10:16:28 courier-imap-4.1.1/courier-imap.spec.in
    -rw-rw-r-- 500/500       9438 2006-05-24 17:21:04 courier-imap-4.1.1/courier-imap.spec
    -rw-rw-r-- 500/500       7683 2006-05-24 17:21:04 courier-imap-4.1.1/courier-imap.lpspec
    % tar xvjf courier-imap-4.1.1.tar.bz2 courier-imap-4.1.1/courier-imap.spec
    courier-imap-4.1.1/courier-imap.spec
    % mv courier-imap-4.1.1/courier-imap.spec rpm/SPECS/
    % rmdir courier-imap-4.1.1
    % mv courier-imap-4.1.1.tar.bz2 rpm/SOURCES/

  8. Modify the spec file. In addition to removing the fam dependencies, we are going to change the release number to indicate that fam has been removed, as well as adding a comment to the RPM file's information block.

    Note: Because different people prefer different text editors, I am going to show the "before and after" of each change, rather than showing commands to run and use any specific editor.

    Note: The changes are shown here in the order in which they appear in the spec file itself. The line numbers refer to the courier-imap.spec file from courier-imap-4.0.2.tar.bz2, your line numbers may be different.

    Edit the file ~/rpm/SPECS/courier-imap.spec as follows:

    1. Change the release number to indicate "nofam".

      Line 31 should be:
      Release: 1%{courier_release}

      Change it to read:
      Release: 1%{courier_release}.nofam
    2. Remove the fam dependencies.

      Lines 43-47 should be:
      %if %suse_version
      BuildPreReq: rpm >= 3.0.5 /usr/bin/sed openldap2 openldap2-devel %([ %{suse_version} -gt 819 ] && echo /usr/include/fam.h)
      %else
      BuildPreReq: rpm >= 4.0.2 sed /usr/include/fam.h openldap-devel openldap-servers
      %endif

      Change them to read:
      BuildPreReq: rpm >= 3.0.5 /usr/bin/sed openldap2 openldap2-devel
      %else
      BuildPreReq: rpm >= 4.0.2 sed openldap-devel openldap-servers
      %endif
    3. Add a note to the package description, telling people that fam support has been removed.

      Lines 72-77 should be:
      %description
      Courier-IMAP is an IMAP server for Maildir mailboxes. This package contains
      the standalone version of the IMAP server that's included in the Courier
      mail server package. This package is a standalone version for use with
      other mail servers. Do not install this package if you intend to install the
      full Courier mail server. Install the Courier package instead.

      Change them to read:
      %description
      Courier-IMAP is an IMAP server for Maildir mailboxes. This package contains
      the standalone version of the IMAP server that's included in the Courier
      mail server package. This package is a standalone version for use with
      other mail servers. Do not install this package if you intend to install the
      full Courier mail server. Install the Courier package instead.

      This package has been modified to remove support for fam.
  9. Build the courier-imap RPM files.

    % rpmbuild -ba ~/rpm/SPECS/courier-imap.spec

    The finished binary RPM files, ready to be installed on the target mail server, are in the ~/rpm/RPMS/i386 directory. The source RPM files, which will simplify the process of rebuilding binary packages on another platform, are in the ~/rpm/SRPMS directory.

  10. Clean up after ourselves. The courier-authlib-devel package can be un-installed, and if the machine you are using to build the RPM files is NOT also going to be your mail server (i.e. where the packages are going to be running) you can remove the courier-authlib package.

    % su -
    Password: (Enter the root password. You should not see it as you type.)
    # rpm -e courier-authlib-devel
    # rpm -e courier-authlib (Skip this one if you're going to be running courier-imap on the machine where you're working.)
    # exit

Installing courier-imap

Once you have built the RPM files, you will need to install them in accordance with the standard instructions (i.e. the README files in the source code packages, which will be installed in /usr/share/doc/courier-* when you install the RPM files.)

Basically, you will need to install the courier-authlib package and any module-specific packages (i.e. courier-authlib-mysql and so forth) needed for your system. You will have to configure the authlib services using the files in /usr/lib/courier-authlib as detailed in the instructions (which basically tell you to edit the authmodulelist line in the /etc/authlib/authdaemonrc file, and then start or restart the courier-authlib service.)

Don't forget to turn the authlib service on after configuring it:

% su -
Password: (Enter the root password. You should not see it as you type.)
# /etc/init.d/courier-authlib start start it now
# chkconfig --level 345 courier-authlib on make it start automatically when the system boots
# exit

You also need to install the courier-imap package itself. If you are using the stock init scripts, you should be able to get it running with these commands:

% su -
Password: (Enter the root password. You should not see it as you type.)
# chkconfig --level 345 courier-imap on
# /etc/init.d/courier-imap start
# exit

You may also be interested in having courier-imap running under daemontools. (I am working on a set of scripts to run courier-authlib under daemontools as well- when I get it working it will be listed on the same page.)