Managing Users With a Database

In a previous post, I added users via the Remote Manager. The default is to store user information on the filesystem. This requires using the Remote Manager to update users. Some people do not like this, since it makes changing user information without logging in very difficult. Someone posted a perl script on the mailing list using a telnet library that could be invoked from a web application.

An easier and more flexible method is to manage user accounts via a relational database. This would allow you to build a web application to manage James users. Searching through the mailing list archives, I found inserting user information into the database seemed to be a common topic. It is not covered very well on the James web site; I was not able to find anything about it. Not to brag, but this may be the first comprehensive explanation with all the info to get you started in one place. A lot of information is scattered in mailing list posts. It is a little frustrating that a common question has not been covered on the James website. Even more frustrating is that the whole procedure is pretty simple.

First I will cover the configuration file. The relevant section is config/users-store/repository, which starts on line 1161. Comment out the filesystem section, and uncomment the database section. You could also set the Remote Manager enabled attribute to “false” at line 778 in the default configuration file (section config/remotemanager). Upload your new config file, and restart James.

The crux of the matter of inserting user accounts is that the database stores the passwords in a one-way hash. The database also stores a string which should contain the name of the hash algorithm. When the user logs in, James hashes the password and compares it to the value in the database. I think a lot of the confusion centers around creating the hash. One post mentioned that you must use the JDK to create the hash, and not the database. Apparently the hashing algorithms are not all compatible. I am not an encryption expert, but I have been able to figure this out.

There is a class in James that can be run on the command line to create the hashes. It is org.apache.james.security.DigestUtil. It can be found in $JAMES_HOME/work/james-$EPOCH_TIMESTAMP/SAR-INF/lib. I assume that it is originally in the SAR file $JAMES_HOME/apps/james.sar, and is expanded when James is first run. To use the class, you need james-2.3.1.jar and the JavaMail jar.

Here is how to use it:

[prompt]

Usage: java org.apache.james.security.DigestUtil [-alg algorithm] [-file] filename|string

[prompt]

Hash is: rVVGgoar2pVf/mIzegYL5mWo

You must do this for each user on your system.

org.apache.james.security.DigestUtil uses the java.security.MessageDigest class to hash the password. The algorithms that it uses are MD2, MD5, SHA-1, SHA-256, SHA-384 and SHA-512. These are listed in the Java Cryptography Architecture API Specification & Reference Appendix A, which itself refers you to the Standard Names Document.

Then log into your database, and do the insert. James gets its SQL statements from the file $JAMES_HOME/apps/james/conf/sqlResources.xml. The statement for inserting a user into the database in the XML file is:

So you would do something like this at the command line:

You would never believe how long it took to get THAT hash.

The hash column can hold up to 50 characters with the default configuration. The MD2 and MD5 algorithms create hashes of 20 characters. The SHA-256 algorithm creates a hash of 40 characters. The SHA-384 algorithm creates a hash of 64 characters. The SHA-512 algorithm creates a hash of 76 characters. You could dig around in $JAMES_HOME/apps/james/conf/sqlResources.xml and change the “create table” statement. Or you could do this:


Updated:

2009-02-16 10:35:39 Monday CST -0600

Image from Gospels of Luke and John, from a late 9th or early 10th century Gospel manuscript housed at Bavarian State Library, webpage information here, image from World Document Library, image assumed allowed under Fair Use.