Authenticating Virtual Users without domain

Professa Dementia
2014-12-31T03:51:51Z

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