OK, I think I've finally been able to come up with steps to duplicate this issue. I don't know if these steps will specifically lead to the root cause, but it at least shows the problem in a consistent manner.
Create an account:
# /usr/local/cpanel/bin/whmapi1 createacct username=%user% domain=%domain% password=%password%
Now it's important in this step to include a password, it can be a simple password with no non-alphanumeric characters, just numbers and letters. In my tests, if you don't include a password and let the system create a password automatically, then this doesn't work. I don't know why - this is puzzle #1.
Now create a database for that user and populate it with some test information
# /usr/local/cpanel/bin/uapi --user=%user% Mysql create_database name=%user%_one
# mysql %user%_one -e "create table one (one int(10), two int(10))"
# mysql %user%_one -e "insert into one (one, two) values (1,2), (3,4)"
This is puzzle #2 - the account has to have at least one database WITH information in it.
Now, note the password hash for %user%'s mysql user:
# mysql mysql -e "select password from user where user=\"%user%\""
+-------------------------------------------+
| password |
+-------------------------------------------+
| *DFA2021762E74350DFBA9AE8E8BC5372F36AF126 |
| *DFA2021762E74350DFBA9AE8E8BC5372F36AF126 |
| *DFA2021762E74350DFBA9AE8E8BC5372F36AF126 |
+-------------------------------------------+
Back up this user:
# /scripts/pkgacct %user% /backup backup --nocompress
Delete this user:
# /scripts/removeacct --force %user%
Restore this user:
# /scripts/restorepkg /backup/%user%.tar
Now look at the user's mysql user password hash:
# mysql mysql -e "select password from user where user=\"%user%\""
+-------------------------------------------+
| password |
+-------------------------------------------+
| *2096C6FEC9ECE4CAA311F45103A0A4A101347C94 |
| *2096C6FEC9ECE4CAA311F45103A0A4A101347C94 |
| *2096C6FEC9ECE4CAA311F45103A0A4A101347C94 |
+-------------------------------------------+
This should be the same as it was above, before you deleted it and restored it - but it's not.
Because this only happens when the %user% has databases with information in them, I have to believe that this is something to do with restoring those databases during the restore process - the restore process creates a random password for the user to run the restore with that user.
But what is REALLY strange, if you don't set a password when you create an account (and thereby let the system create create a random password) then all of this works as it should. The database gets restored and the user's MySQL hash gets restored correctly.
Hoping someone from cPanel can duplicate this and give a bit more information.