Index: modules/user/user.install =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.install,v retrieving revision 1.5 diff -u -p -r1.5 user.install --- modules/user/user.install 8 Jan 2008 07:46:41 -0000 1.5 +++ modules/user/user.install 15 Feb 2008 21:26:08 -0000 @@ -149,6 +149,13 @@ function user_schema() { 'default' => '', 'description' => t("User's password (md5 hash)."), ), + 'salt' => array( + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + 'description' => t("Salt for user's password."), + ), 'mail' => array( 'type' => 'varchar', 'length' => 64, @@ -288,3 +295,16 @@ function user_schema() { return $schema; } +function user_update_1() { + $ret = array(); + db_add_field($ret, 'users', 'salt', array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => '', 'description' => t("Salt for user's password."))); + // generate salts for existing users + $result = db_query("SELECT uid FROM {users} WHERE uid <> 0"); + while ($user = db_fetch_object($result)) { + // pgsql only has a two op concat + $ret[] = update_sql("UPDATE {users} SET salt = MD5(CONCAT(CONCAT(init, created), '". mt_rand() ."')) WHERE uid = '$user->uid'"); + } + $ret[] = update_sql('UPDATE {users} SET pass = MD5(CONCAT(pass, salt)) WHERE uid <> 0'); + return $ret; +} + Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.893 diff -u -p -r1.893 user.module --- modules/user/user.module 6 Feb 2008 19:38:28 -0000 1.893 +++ modules/user/user.module 15 Feb 2008 21:26:08 -0000 @@ -156,7 +156,7 @@ function user_load($array = array()) { $params[] = $value; } else if ($key == 'pass') { - $query[] = "pass = '%s'"; + $query[] = "pass = MD5(CONCAT('%s', salt))"; $params[] = md5($value); } else { @@ -213,7 +213,8 @@ function user_save($account, $array = ar if (is_object($account) && $account->uid) { user_module_invoke('update', $array, $account, $category); $query = ''; - $data = unserialize(db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $account->uid))); + $old_account = db_fetch_object(db_query('SELECT data, init, created, salt FROM {users} WHERE uid = %d', $account->uid)); + $data = unserialize($old_account->data); // Consider users edited by an administrator as logged in, if they haven't // already, so anonymous users can view the profile (if allowed). if (empty($array['access']) && empty($account->access) && user_access('administer users')) { @@ -222,7 +223,7 @@ function user_save($account, $array = ar foreach ($array as $key => $value) { if ($key == 'pass' && !empty($value)) { $query .= "$key = '%s', "; - $v[] = md5($value); + $v[$key] = md5($value); } else if ((substr($key, 0, 4) !== 'auth') && ($key != 'pass')) { if (in_array($key, $user_fields)) { @@ -241,6 +242,14 @@ function user_save($account, $array = ar } } } + if (isset($v['pass'])) { + $init = isset($v['init']) ? $v['init'] : $old_account->init; + $created = isset($v['created']) ? $v['created'] : $old_account->created; + // Generate a new salt + $query .= "salt = '%s', "; + $v['salt'] = md5($init . $created . mt_rand()); + $v['pass'] = md5($v['pass'] . $v['salt']); + } $query .= "data = '%s' "; $v[] = serialize($data); @@ -303,25 +312,32 @@ function user_save($account, $array = ar switch ($key) { case 'pass': $fields[] = $key; - $values[] = md5($value); + $values[$key] = md5($value); $s[] = "'%s'"; break; case 'mode': case 'sort': case 'timezone': case 'threshold': case 'created': case 'access': case 'login': case 'status': $fields[] = $key; - $values[] = $value; + $values[$key] = $value; $s[] = "%d"; break; default: if (substr($key, 0, 4) !== 'auth' && in_array($key, $user_fields)) { $fields[] = $key; - $values[] = $value; + $values[$key] = $value; $s[] = "'%s'"; } break; } } + if (isset($values['pass'])) { + // Create a new salt + $fields[] = 'salt'; + $values['salt'] = md5((isset($values['init']) ? $values['init'] : '') . $values['created'] . mt_rand()); + $s[] = "'%s'"; + $values['pass'] = md5($values['pass'] . $values['salt']); + } $success = db_query('INSERT INTO {users} ('. implode(', ', $fields) .') VALUES ('. implode(', ', $s) .')', $values); if (!$success) { // On a failed INSERT some other existing user's uid may be returned.