ChangePassword versus SetPassword
Writing a piece of code last night, I was struck by the thought that many developers I've worked with would not know why I use a ChangePassword function, instead of a SetPassword function.
The difference in use is simple - SetPassword requires one password (the new one), whereas ChangePassword requires two passwords (the old one, and the new one).
It would seem as if the obvious easy function to use is SetPassword, because you don't need to prompt the user for the old password on the account.
But I avoid SetPassword unless there's absolutely no alternative - why is that?
Because of all the secrets that a user may own - private keys for EFS encryption, for email identification, for server identification, etc.
Any secret like this is stored in the DPAPI store, which is encrypted using a key derived from the user's current password.
If you use SetPassword, all the information is still in the DPAPI store, but the user no longer has access to it(*).
[The information is still there for a simple reason - if your use of SetPassword was to gain access to an account while its owner is away from work, you'll want to regain that data when the user comes back. You can do this by having him change his password from the new password back to his old password.]
This means that the user loses access to their encrypted files, loses the ability to identify themselves in email (and to decrypt messages sent to them), or if this is a server account, they lose the ability to start up an SSL-based server.
Using ChangePassword, by comparison, because it uses the existing password as a starting point, re-encrypts the DPAPI store with a key derived from the new password.
The other big advantage of a ChangePassword function is that it can be used by anyone, without administrative rights being required (subject to rights and policies, depending on the tool you're using and the OS you're on).
That sounds like a security violation, but isn't - after all, if you know the user's old password, you can log on as that user, and as long as the user is able to change his own password, there's no functional difference between you logging on then changing your password, and changing your password from some other account by providing your old and new passwords.
Depending on the interface you're using, these functions may not be called ChangePassword and SetPassword - for instance, in the Win32 API, the functions to use would be NetUserChangePassword and NetUserSetInfo.
(*)Not quite as simple as this - on a domain at Windows 2000 or later, you will find that a second copy of the DPAPI Master Key is stored in the domain controllers, encrypted using the DC's private key. In the event of a SetPassword operation, the DPAPI Master Key is decrypted and re-encrypted with the new password, so you don't lose any data. The same is sometimes true on workstations, depending on the version. Details are in KB article 309408)