[Vmail-discuss] migrating MD5 hash used in /etc/shadow to vmail-sql

Chris Lightfoot chris@xxxxxxxxxxxxx
Fri, 18 May 2001 01:54:54 +0100


On Thu, May 17, 2001 at 04:57:38PM -0400, Marcin Pacyna wrote:
> I'm trying to migrate my 600+ users from a regular POP3 setup (1 unix system
> account per POP3 mailbox) to vmail-sql (mysql + tpop3d + exim) setup.  One
> of the concerns I have is migrating the passwords which are currently stored
> in /etc/shadow as (AFAIK) MD5 hashes: (this is a RedHat 6.2 box BTW):
> 
> example entry from /etc/shadow:
> 
> domainvm1:$1$dsBlPaKU$OQ45C8IlRjE2GBq1uK.Qi.:11439:0:99999:7:-1:-1:114550524
> 
> however if I put that password hash string
> ($1$dsBlPaKU$OQ45C8IlRjE2GBq1uK.Qi.) into the popbox table - I can't
> authenticate.  If I generate the password using the sample VE-passwd script
> then auth works fine.  The hash strings in /etc/shadow all start with '$1$'
> which I think is the salt but I'm not sure what to do with it.
> 
> In short - does anyone know how can I migrate/convert all the hashes from
> /etc/shadow to something that tpop3d understands?

A brief look at the PAM source code indicates that this
will not be possible directly; unfortunately, the PAM
md5crypt passwords contain a salt (the `$1$' is a magic
number; the salt is separate) and the vmail-sql ones do
not (probably an oversight).

There are three possibilities:

    1. Get your users to change their passwords.

       Evidently you don't want to do this, otherwise you
       wouldn't be asking this question :)

    2. Modify tpop3d and vmail-sql to implement the
       crypt-md5 algorithm.

       mysql_crypt.patch in the distribution would
       probably serve as a starting point; you'll also
       need to link against crypt_md5 from the PAM
       distribution. You'll also need to implement a perl
       version of this to make the vmail-sql admin scripts
       work.

    3. Modify tpop3d to migrate the passwords (with a
       little bit of help).

       (This is the solution I recommend.)

       The basic game here is to alter the auth_pam
       auth_pam_new_user_pass function so that when a user
       is correctly authenticated it emits some line to
       the syslog which you can then grep for, something
       like

        MIGRATE: update popbox set password = '<md5>' where user = '<user>'

       which you can then feed in to the database. This
       way, once all the users have successfully logged in
       once, you will have enough information to migrate
       all their passwords. Observe also that this obeys
       the privacy constraint of never revealing users'
       passwords in plain text.

       The problem here is that if you have users who
       check their mail only infrequently, you may spend a
       long time waiting for all users to be migrated
       across.

       The patch is fairly simple. In v1.3.1, add after
       line 109 of auth_pam.c the following: (untested)

       {
            MD5_CTX ctx;
            unsigned char buf1[16], *p;
            char buf2[33], *q;

            MD5Init(&ctx);
            MD5Update(&ctx, (unsigned char*)pass, strlen(pass);
            MD5Final(buf1, &ctx);
            
            for (p = buf1, q = buf2; p < buf1 + 16; ++p, q += 2)
                sprintf(q, "%02x", (unsigned int)*p);

            print_log(LOG_INFO, "MIGRATE update popbox set password = '%s' where user = '%s'", buf2, user);
        }

        Also insert after line 30:

        #include "md5.h"

        Test this using a known password in /etc/shadow
        to verify that I've got it right!

-- 
Chris Lightfoot -- www.ex-parrot.com/~chris/
 ``The only reason [George W. Bush] gets lost in
   thought is because it is unfamiliar territory.'' (newspaper editorial)