Upgrade to Moodle 2.5: Cannot Login as Guest

I recently upgraded our Moodle site from version 2.4 to 2.5. They main problem I had after the upgrade was that I couldn't login as my admin user (and later also discovered guest user). When I first came across this for the admin user I was impatient and looked for a fix without understanding the reason. The fix was to reset the password using the command line tool as described in Moodle documentation.

Later when I discovered guest could not login I investigated further. First, I made sure Guest access was allowed. Then I read about the updates from 2.4 to 2.5, especially related to passwords. In version 2.4 and before, MD5 was the hash function used and a site-wide salt was stored in the Moodle config.php file. In version 2.5, the hash function was updated to bcrypt and a user-specific salt. However for existing users, MD5 and the site-wide salt were still used for their first login, and then their password was hashed with bcrypt and salt and stored in the database.

My problem was that I didn't copy the site-wide salt from my version 2.4 config.php to the new config.php in version 2.5. So I returned to my config.php from version 2.4 and copied the line similar to that below into by 2.5 config.php (where the RANDOMLOOKINGSTRING was a set of random characters):

$CFG->passwordsaltmain = 'RANDOMLOOKINGSTRING';

Now I could login as guest. And in fact, the first login as guest updated the password entry in the Moodle database for the guest user to use a specific salt and bcrypt. The actual password for guest user is guest. The Moodle database stores a hash of that password combined with a salt.

mysql> select username,password from mdl_user where username="guest";
+----------+--------------------------------------------------------------+
| username | password                                                     |
+----------+--------------------------------------------------------------+
| guest    | $2y$10$FuCuzBz45u3xkLO8AitCIe8.Zcny40dL6b7RsfEHcgm0w4J6OEAra |
+----------+--------------------------------------------------------------+
1 row in set (0.00 sec)

The format of the password field indicates the new hash function is used. In the example below we can see that student1 still uses the old hash function/salt. When student1 logins in, then the new hash function will be used.

mysql> select username,password from mdl_user;
+--------------------------+--------------------------------------------------------------+
| username                 | password                                                     |
+--------------------------+--------------------------------------------------------------+
| guest                    | $2y$10$FuCuzBz45u3xkLO8AitCIe8.Zcny40dL6b7RsfEHcgm0w4J6OEAra |
| student1                 | 28c25dd175514ad09143937510fd4ab7                             |
| student2                 | not cached                                                   |
...

Once all users have logged into version 2.5, there password hashes will be updated to the new ones (bcrypt, user-specific salt). At that point, the site-wide salt in config.php is no longer needed. However since it is difficult to know when all users have logged in at least one, it is recommended to leave the site-wide salt in config.php.

A final note, in our case we use PAM authentication, where users passwords are not actually specific to Moodle, but taken from their Linux account. Hence the above problem didn't arise: most students don't have a hash stored in Moodle database. Instead the entry not cached is stored.

In summary, make sure you copy the site-wide salt value (passwordsaltmain) to your new config.php file when upgrading to Moodle 2.5.