Authenticating Virtual Users without domain

Professa Dementia professa at dementianati.com
Wed Dec 31 03:51:51 UTC 2014


On 12/30/2014 6:49 PM, Leon Kyneur wrote:
> Hi,
>
> I'm trying to migrate a large number of users to a new Dovecot
> cluster. The existing mail system allows a user to authenticate with a
> bare username if they have connected to the correct local IP on the
> server.
>
> e.g.
> imap.somedomain.com = 1.1.1.1
> imap.anotheromain.com = 2.2.2.2
>
> charlie at somedomain can authnenticate as 'charlie' or
> 'charlie at somedomain.com' as long as he is connected to
> imap.somedomain.com (1.1.1.1)
>
> likewise for bare usernames if they connect to imap.anotherdomain.com.
>
> A previous colleague actually achieved this by hacking with the
> Dovecot source code and writing in a lookup table feature. The code is
> very old and won't patch cleanly to the latest 2.2.15 source. Another
> platform we are using (commercial product) also has this feature but
> we also need to migrate these users to Dovecot.
>
> I already have a Dovecot proxy layer for mailbox lookup - so ideally I
> would like to do this on my Dovecot proxies.
>
> I know I can also do this kind of thing if I swapped my dovecot proxy
> for Perdition, however I don't really want to do that.
>
> I've looked into checkpassword scripts and could possibly make
> something work (albeit ugly) - is this the right direction to take
> here?

Using SQL as the user database, set up a table for the mail users.  The 
following example uses the table named "mail_users" with the following 
fields:

user_name = part left of @ in email address (EX: joe)
user_domain = part right of @ in email address( EX: mydomain.com)
domain_ip = the IP they connect to for their domain (EX: 1.1.1.1)
password = hashed password
home = full path to user's home directory
uid = user's uid
gid = user's gid


In dovecot-sql.conf.ext: (line breaks and indenting are added to improve 
readability but your statement should be all one line in the 
dovecot-sql.conf.ext file)

password_query =
   SELECT
     CONCAT(user_name, '@', user_domain) AS user,
     password,
     home AS userdb_home,
     CONCAT('maildir:', home) AS userdb_mail,
     uid AS userdb_uid,
     gid AS userdb_gid
   FROM mail_users
   WHERE user_name = '%Lu'
     AND domain_ip = '%l'

NOTE: %Lu is used on purpose, rather than %Ln.  %Lu will fail the lookup 
if the user provides a full email address, and this is deliberate.  If 
you also want to allow the user to connect to *any* IP with their full 
email address as their login, use:

password_query =
   SELECT
     CONCAT(user_name, '@', user_domain) AS user,
     password,
     home AS userdb_home,
     CONCAT('maildir:', home) AS userdb_mail,
     uid AS userdb_uid,
     gid AS userdb_gid
   FROM mail_users
   WHERE ( user_name = '%Lu' AND domain_ip = '%l' )
      OR ( user_name = '%Ln' AND user_domain = '%Ld' )

With this query, the user can log in as "joe" by connecting to their 
domain's specific IP, or they can log in as joe at mydomain.com by 
connecting to any IP the server is listening on.


This is just a simple example to get started.  You will probably want to 
expand this by adding fields to specify if the account is active and so 
on.  Also, you can put the domain to local IP mapping in another table 
and use a JOIN in your SELECT query, so you can eliminate the 
"domain_ip" field from the "mail_users" table.  This is an exercise left 
to the reader.  The "mail_users" table should have a primary index on 
the combined "user_name" and "user_domain" fields, which should be unique.

In your dovecot-sql.conf.ext file, you will need to create a 
"user_query" statement similar to your finalized "password_query" 
statement, as well as an appropriate "iterate_query" statement.  See the 
Dovecot documentation.

Cheers.

Dem


More information about the dovecot mailing list