i want to validate a set of credentials against the domain controller. e.g.:
Username: joel
Password: splotchy
Domain: STACKOVERFLOW
In .NET 3.5 and newer you can use PrincipalContext.ValidateCredentials(username, password).
Otherwise you're in trouble.
Following the code in the Microsoft Knowledge Base article How to validate user credentials on Microsoft operating systems, i get to the point where you call AcceptSecurityContext:
ss = AcceptSecurityContext(
@pAS._hcred, //[in]CredHandle structure
phContext, //[in,out]CtxtHandle structure
@InBuffDesc, //[in]SecBufferDesc structure
0, //[in]context requirement flags
SECURITY_NATIVE_DREP, //[in]target data representation
@pAS._hctxt, //[in,out]CtxtHandle strcture
@OutBuffDesc, //[in,out]SecBufferDesc structure
ContextAttributes, //[out]Context attribute flags
@Lifetime); //[out]Timestamp struture
except that the function fails with:
SEC_E_NO_AUTHENTICATING_AUTHORITY(0x80090311)The function failed. No authority could be contacted for authentication. This could be due to the following conditions:
- The domain name of the authenticating party is incorrect.
- The domain is unavailable.
- The trust relationship has failed.
This would be a useful error, except that i can validate the same credentials from .NET 3.5 using:
using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain))
{
valid = context.ValidateCredentials(username, password);
}
What could be happening that allows .NET to validate a set of credentials, while native code cannot?
Update: LogonUser also fails:
LogonUser("joel@stackoverflow.com", null, "splotchy",
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_WINNT50, out token);
with
1311 - There are currently no logon servers available to service the logon request
Update Two: i've tried both the preferred Negotiate provider, as well as the Windows NT4 legacy "NTLM" provider
String package = "Negotiate"; //"NTLM"
QuerySecurityPackageInfo(package, [out] packageInfo);
...
AcquireCredentialsHandle(
null, //[in] principle
package, //[in] package
SECPKG_CRED_OUTBOUND, //[in] credential use
null, //[in] LogonID
pAuthIdentity, //[in] authData
null, //[in] GetKeyFn, not used and should be null
null, //[in] GetKeyArgument, not used and should be null
credHandle, //[out] CredHandle structure
expires); //[out] expiration TimeStamp structure