Does anyone else been able to confirm the COM release bug on the PrincipalContext.ValidateCredentials() and come up with a work around? When using a ContextType of Machine to validate a local user's credentials after a computer has been disconnected
from a network, the exception "The network path was not found" is raised.
Specifically, I've been able to identify that this issue only occurs when a computer which was connected to a network and successfully made a ValidateCredentials() call then disconnected and attempts to make a second call will see this error message.
If the machine is booted up disconnected from the network the ValidateCredentials() functionality works as expected (albeit the code under the hood looks like a hack).
var context = new PrincipalContext(ContextType.Machine, "localmachinename");
context.ValidateCredentials("LoginUID", "LoginPassword");
From what I can tell ADsOpenObject() call used the activeds.dll API to call IntADSOpenObject (as ADsOpenObject) which returns a double pointer to the interface IADsOpenDSObject (see blue arrow for double pointer). This is then cast as an
IADs interface on the managed side of the house in order to call the Get("name") method. When the network is connected this will raise a COMException which then throws the GetExceptionFromCOMException() which appears to be squashed as it never
bubbles out of the ValidateCredentials() call (see green arrow). When the network is connected then disconnected the COMException never occurs and the code goes directly to the finally block. When the code attempts to release the COM Object is
when the exception happens (see red arrow).
I was using the .NET Reflector generated PDBs to debug this code so it's possible that the managed code was optimized away and my stack trace is not completely accurate. In anycase, this is definitely a .NET Framework BUG since the logic works without
network connectivity from the get go, just not after the machine has been connected to the network.
I'm using an XBAP application so I'm also trying to stay away from directly using COM and having to marshal back and forth across managed/unmanaged boundaries.
Any suggestions?
![]()
UPDATE:
OK, so I'm completely stupefied. I just took a few huge chunks of the code from the System.DirectoryServices.AccountManagement namespace and created a local class with the key bits for PrincipalContext and ran through the scenarios above so I could
debug some of the internal classes, interfaces, structs, etc. and I can't duplicate the issue AT ALL. I've commented out a few sections that I didn't want to have to resolve (i.e. StringResources for exception messages and objects that have no bearing
on the ValidateCredentials call being tested). In both scenarios where the network is connected and disconnected, the ppObject.Get("name"); call is successful, no COMExceptions are thrown and the Marshal.ReleaseComObject works as expected.
UPDATE 2:
OK, so I may have misspoke on the last update. It appears to be a timing issue and I wasn't waiting long enough. I would hazard a guess that something is being cached and not being released when the network is disconnected but after some arbitrary
amount of time, things start to fail again