Some notes on using DBD for Apache's digest authentication

Summary

A few notes on getting Apache digest authentication to work with the DBD driver and PostgreSQL. The first page of its kind. I had to read the source to figure it out.

Setup

You probably need to compile it into apr-util, see my page on DBM authentication. The flag you're after is --with-pgsql.

On FreeBSD it was enough to do this:

cd /usr/ports/www/apache22
make WITH_PGSQL=yes

On Debian/Ubuntu the default Apache 2 packages are enough. You need to make sure you have the proper symlinks in mods-enabled. You will need links to dbd.load, authn_dbd.load and auth_digest.load.

Despite these things, I've had real problems on a FreeBSD 6.2 machine, while an almost identical one worked fine. Whatever I did, I got the dreaded No DBD Authn configured!. The patch at http://www.ausics.net/mod_dbd.c fixed this for me.

httpd.conf

It seems putting the DBDriver directive in <VirtualHost> does not work in release 2.2.4. Put it in the main section. Example:

DBDriver pgsql
DBDParams "dbname=my_database user=my_role"

The database query and such can go into a VirtualHost or Directory section. Example:

AuthType Digest
AuthName "My Site"
AuthDigestDomain /
AuthDigestProvider dbd
AuthDBDUserRealmQuery "select password from users where username = %s and realm = %s"

The password database

Plaintext passwords in the database don't work (but do, see below). It needs to be encrypted as explained in my article on doing digest authentication with DBM files. Basically the password is the concatenation of the user name, the realm and the password, encoded with the MD5 algorithm. Example:

$ echo -n 'myname:My Realm:password' | md5sum
6ab1403730374a17a0f725b0ab98a0d7 *-

Store this md5 checksum in the password field and it should work.

That said, it is actually possible to store plain passwords in the database, at the expensive of a bit of processing when retrieving it. That's because PostgreSQL has an md5() function. This query will return the md5 checksum if the password is stored as plain text:

AuthDBDUserRealmQuery "select md5(username || ':My Site:' || password) from users where username = %s and realm = %s"