Hey all,

First post to the list, so here goes, hope I don't break any rules (I didn't see any rules about not being overly verbose)

I spent a long time looking for anything that would help me migrate from our old IMAP server to our new one without a lot of client-side fuss, multiple e-mail accounts, and so on. I find that a lot of our users get confused by having two 'inboxes' in Outlook (one local, unused, and one IMAP), so I figured the easier I could make it, the better.

I figured there must be some way to do what I was looking for, but I couldn't find it, so I hacked up a little something to do the job. As the saying goes, it's nasty, brutish, and short, but in my tests it's done everything I needed it to.



The problem: Our old mail system is hosted by another company, outsourced before I was hired, so I don't have access to the old user/ passwd database, nor to their e-mail store; thus, I cannot do a clean, simple migration by upgrading in-place as I have done on other servers.



The solution IMAP authentication proxying. The idea is that I don't need to know the password, because the user's mail client knows the password, so all I need is for it to tell me, and then I can create their user. That is what this script is for.



To use, set up your authentication backend (passdb) first, and then after that section, add a 'passdb checkpassword' section containing this script. Thus, the following will happen.

1. Valid users who log into your system will be authenticated as you would expect. 2. Users who could not be authenticated will fall through to the checkpassword section 3. Checkpassword will look for the user in the password database; if they exist, it is assumed that it is a valid user, but incorrect password, and checkpassword fails the user as well. 4. If the user is not currently in the database, it will initiate an IMAP4 connection to the remote host specified. If it succeeds in logging in to the remote host, then we assume that the user is a valid user and can be migrated to the local server. They are added to the database, along with their password. It then **fails the user's login regardless** 5. It /logs the username and password into the database/ so that another process can use that information to migrate their e-mail over to the new server (not yet implemented). 6. If the IMAP connection fails, the login is failed as well, and dovecot continues as normal until it has exhausted all other passdb backends.

Interested? A few things to note about the script:

1. It's a brutal hack. Really, ugly stuff. However, it gets the job done, if your system is similar enough to mine. 2. It only works on MySQL. I only use MySQL in our system, so there's no point for me to add other DBs, nor any way to test. 3. It doesn't support remote servers using SSL. Our current system doesn't use it, so again, it's hard to test. 4. It does not currently migrate mailboxes. I'm working on this (see below). 5. If your schema is at all different from mine, you will likely have to rewrite all of the SQL. There's not much I can do about this. 6. If your backend database doesn't use MySQL, you're largely boned. Exception: rewrite add_user() to do whatever you need to do to add users to your system. 7. The script will **ALWAYS RETURN A FAILED LOGIN TO DOVECOT**. This is because there are too many variables on every configuration, and writing code for all of them is absurd. This way, the user's first login will always fail, and their second login will always succeed. If you want to avoid this, place your normal passdb authentication **both before and after this checkpassword section**. That way, it will check once, fail, pass to checkpassword, and then check again, success.

TODO:
1. Make it not ugly. Break more junk off into functions (e.g. IMAP verification) 2. Send the user an e-mail ('Welcome to the server, sorry your mail is gone, we'll fix that soon') 3. Spawn another process to run imapsync in the background to migrate the user's old mailboxes over. This would be very site-dependent, as there are a lot of variables. It might be best done as a cronjob that polls the database every however often (1 minute? 2 minutes?) or a daemon that sits in the background watching the db for changes, or even accepting the data directly.
4. Stop being so verbose in my first postings to mailing lists.
5. Lots of other things.

URLS

Blah blah blah where's the code. Here you go.

Pretty syntax-highlighted version for browsing before you download, in case I'm an evil hacker:
        http://cdslash.net/temp/python/checkpassword.py
Ugly monochrome version for downloading so you don't get line numbers in your junk:
        http://cdslash.net/temp/python/checkpassword.raw


Questions, comments? I probably won't be on the list very long, so if you want to ask something or have a suggestion, feel free to let me know by e-mail at the address listed in the file's license notification. Alternately, find me on Freenode, occasionally in #dovecot or always in #macosx, as Darien, or some variant thereof.

PS: The code is licensed under a boilerplate MIT license lifted from the OSI license page. If you want it under a different license, let me know. ;)

Thanks,
Dan

Reply via email to