Last updated November 26, 2011. Created by mikeryan on November 22, 2011.
Log in to edit this page.

One challenge frequently dealt with in migrations is handling user passwords. Usually the passwords on the old system are encrypted, and cannot be decrypted into a plaintext password which can simply be passed to user_save() and thus encrypted appropriately for Drupal. Here we describe how to handle some of these scenarios.

Plaintext passwords

If the old system stored passwords as plaintext, then you simply need to map the password field in the usual way:

<?php
$this
->addFieldMapping('pass', 'source_password');
?>

Decryptable passwords

If the passwords were not stored directly as plaintext, but can be converted to plaintext, perform the conversion in prepareRow():

<?php
$this
->addFieldMapping('pass', 'source_password');
...
public function
prepareRow($row) {
 
$row->source_password = my_conversion_function($row->source_password);
}
?>

Unsalted MD5 passwords

If the passwords were stored as unsalted md5 hashes, as Drupal itself did up through Drupal 6, you need to short-circuit the fact that user_save() will hash the 'pass' value passed to it.

To Drupal 7

To support upgrading from Drupal 6 installations with md5 passwords, Drupal 7 will hash the md5-hashed password and prepend a 'U' to flag what it's done. If you set the md5_passwords option on MigrateDestinationUser, Migrate will replicate this behavior.

<?php
$this
->destination = new MigrateDestinationUser(array('md5_passwords' => TRUE));
...
$this->addFieldMapping('pass', 'source_password');
?>

To Drupal 6

In this case, the incoming password is exactly what you want to store - but simply mapping the field directly won't work because user_save() will apply an extra serving of hash. What you need to do is manually push the desired password value to the database after user_save():

<?php
$this
->addFieldMapping('pass', 'source_password');
...
public function
complete($account, $row) {
 
db_update('users')
    ->
fields(array('pass' => $row->source_password))
    ->
condition('uid', $account->uid)
    ->
execute();
}
?>

Replicable hashing

In other cases where you can't decrypt the password, but you can replicate the encryption algorithm in PHP, you can implement that algorithm in a password.inc file. You may completely replace the core algorithm, or conditionally apply the appropriate algorithm if you can recognize which form of password exists, resaving the password under the core algorithm at login time and thus slowly over time upgrading the passwords.
@todo: show a concrete example

Non-replicable hashing

@todo

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.