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@somedomain can authnenticate as 'charlie' or 'charlie@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@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