We're writing a system that allows a user to change their account password through a web application on our intranet.
At first, everything appeared to be running smoothly. During development passwords for our test accounts could be changed with no problem.
When we made the system live, however, we started running into issues. Here are the symptoms:
- At first, everything is fine. Users can change their passwords.
- At some point, the following error occurs in UserPrincipal.FindByIdentity: "System.Runtime.InteropServices.COMException: The authentication mechanism is unknown. "
- From then on, trying to change a password through the web application results in the error: "System.Runtime.InteropServices.COMException: The server is not operational. "
- If I manually recycle the app pool, everything seems to fix itself until more errors begin happening... i.e., the process starts all over again at phase 1.
Here's the relevant snippet of code:
private static PrincipalContext CreateManagementContext() {
return new PrincipalContext(
ContextType.Domain,
ActiveDirectoryDomain,
ActiveDirectoryManagementAccountName,
ActiveDirectoryManagementAccountPassword);
}
private static void ChangeActiveDirectoryPasword(string username, string password) {
if (username == null) throw new ArgumentNullException("username");
if (password == null) throw new ArgumentNullException("password");
using (var context = CreateManagementContext())
using (var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username)) {
user.SetPassword(password);
}
}
Any clues as to why this is happening? Google searches aren't turning up anything really helpful, and neither are the docs on MSDN.
First thing I notice is that you are using UserPrincipal.FindByIdentity which is inherited from AuthenticablePrincipal which is inherited from Principal. I say all this because the
Principal
class has a known memory leak in theFindByIdentity
. If you have a look at this MSDN entry, you will notice at the bottom that Gary Caldwell from Microsoft said the following:I would guess that this is your issue. The memory leak causes the Application Pool to fill up and finally cause errors, until the Application Pool is reset and the memory is disposed.
When we use any active directory functions, we use the following to accomplish setting of the user's password:
Also, if you're wanting the users to change the passwords directly and you don't want to rely on their honesty, you might want to consider using the
ChangePassword
function of LDAP like this:This forces the user to know the prior password before changing to the new one.
I hope this helps,
Thanks!