Baah... I figure that I'll just provide my interface for now to let you all see
if this is something that would be useful. I think I've made it general enough
to write anything you want in the authentication/authorization function.
---- begin interface description -----
Here is the relevant data from vpop.h:
vpop__data* vpop__userauthen (char* username, char* password, char*
default_base_username);
typedef struct {
int valid_form;
int valid_user;
char* unix_username;
char* virtual_username;
char* black_box_home;
int authenticated;
char* log_error;
} vpop__data;
The function vpop__userauthen is called whenever a user is trying to
authenticate with the system. It is called _before_ any unix usernames are
checked. Depending on the values in the returned vpop__data structure, the
username and password will or will not be checked as a valid UNIX username.
Here are the details...
vpop__useauthen is called with, of course, the username and the password of the
user trying to connect. However "default_base_username" is a little weird. If
c-client is trying to login a user and it is not running as root it will
provide the username of the current user in default_base_username here. If
c-client is running as root, and can switch to any user then this will e NULL.
(You will not get a non-NULL value from imapd but rather from tools like dmail
in the imap-utils package. These tools are used for things like local delivery
and are already running as the correct UNIX user.)
vpop__userauthen then gets to control what c-client does by the structure it
returns... here are what the values mean
* valid_form specifies if the username looks like a virtual username. If this
is returned as true, c-client does not try to check the username and password
as a UNIX user. If valid_form is false, vpop__userauthen should set it false
and just return there.
* valid_user specifies if this username is a valid username. This can only be
true if valid_form is true.
* unix_username specifies the UNIX username that we should switch uid/gid to
when accessing the mail of the virtual user.
* virtual_username specifies the virtual username of the virtual e-mail
account. Does not have to be a valid login user or anything. Not currently used
for anything. :-)
* black_box_home specifies the directory where the e-mail for this user will
be stored. unix_username should have write permission here. The user is locked
down into this directory and now allowed to get mail from anywhere else in the
system.
* authenticated specifies if the password was correct. Even if the supplied
password was incorrect vpop__userauthen is required to set the unix_username,
virtual_username, and black_box_home values. This is because sometimes this
information is needed without password authentication outside of imapd, such as
when dmail is used to deliver to a virtual e-mail user.
* log_error is a string to log as an error. If this is not NULL, it will be
written to the standard c-client error reporting device. Inside of imapd this
will work its way into syslog.
---- end interface description -----
I figure that someone could just write a vpop__userauthen function to run a
little external program, such as interfacing to one of the currently existing
virtual user packages. Other hackers could just write their own site specific
vpop__userauthen functions like I have done.
Oh, one note. This is really an imapd and ipop3d server together. The c-client
library is modified which is used by imapd, ipop3d, and imap-utils. This way
you write this once function and it works for all your mail server programs.
- David Harris
Principal Engineer, DRH Internet Services