Windows – Why doesn’t LogonUser(…) work for domain accounts

active-directoryimpersonationSecuritywinapiwindows

I've been trying to use LogonUser(...) to get an access token for a user account, as in this MSDN sample.

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
    LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
    out safeTokenHandle);

When I run the sample (with Administrator privileges) it works fine when given a domain of . and a local user account name and password, but no matter what I do I get error code 1326 (Logon failure: unknown user name or bad password) if I try to use a domain account. I get the same result if I enter garbage for the domain, which makes me wonder if it's actually contacting the DC at all.

What could be stopping this from working?

Best Answer

In my case the issue, similar to the question asker, was that the account I was trying to authenticate to was in a domain that my current machine did not belong to. Unlike the original poster, my machine should not and could not be part of this other domain. I wanted the login to perform action on a resource on this domain though.

The answer was the following

bool success = LogonUser(
                userName,
                domain,
                password,
                (int)LOGON32_LOGON_NEW_CREDENTIALS, //9
                (int)LOGON32_PROVIDER_DEFAULT, //0
                out userToken);

with the following constants defined:

public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
public const int LOGON32_PROVIDER_DEFAULT = 0;

Hopefully this will help others who are lost in a similar situation.

Edit: As mentioned in the comments below, this logon type allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the same local identifier but uses different credentials for other network connections. As a result of that fact, "success" will return true even if the password is bad. You will need an additional check beyond "success" to confirm that the credentials are actually good.

This was not a concern in my initial use case as we used the current network user's credential in another function to pull the plaintext password from secure storage. So it would have never been wrong unless there was an inconsistency between that system and active directory in which case we had bigger problems.

Related Topic