Search code examples
c#credentialswindows-security

How show domain name in credential dialog (using CredUIPromptForWindowsCredentials)?


I use CredUIPromptForWindowsCredentials to get user credentials, but credential dialog don't show domain name if user write login like this mydomain\UserName or UserName@mydomain.local. How to show domain name in in credential dialog as at picture?

credential dialog picture

public static NetworkCredential ShowCredDialog(string caption, string message, NetworkCredential defaultCreds = null)
{
    var credui = new CREDUI_INFO
    {
        pszCaptionText = caption,
        pszMessageText = message,
    };
    credui.cbSize = Marshal.SizeOf(credui);

    uint authPackage = 0;
    var save = false;

    CreateInAuthBuffer(defaultCreds, out var inAuthBuffer, out var inAuthSize);

    var result = CredUIPromptForWindowsCredentials(
        ref credui,
        0,
        ref authPackage,
        inAuthBuffer,
        (uint)inAuthSize,
        out var outCredBuffer,
        out var outCredSize,
        ref save,
        1 /* Generic */);

    if (result != 0)
    {
        return null;
    }

    var maxUserName = 100;
    var maxDomain = 100;
    var maxPassword = 100;
    var usernameBuf = new StringBuilder(maxUserName);
    var domainBuf = new StringBuilder(maxDomain);
    var passwordBuf = new StringBuilder(maxPassword);

    var packAuthRes = CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize,
        usernameBuf, ref maxUserName,
        domainBuf, ref maxDomain,
        passwordBuf, ref maxPassword);

    var userName = usernameBuf.ToString();
    var domain = domainBuf.ToString();
    var password = passwordBuf.ToString();

    CoTaskMemFree(outCredBuffer);

    return new NetworkCredential
    {
        UserName = userName,
        Domain = domain,
        Password = password,
    };
}

[DllImport("credui.dll", CharSet = CharSet.Auto)]
private static extern int CredUIPromptForWindowsCredentials(ref CREDUI_INFO notUsedHere,
    int authError,
    ref uint authPackage,
    IntPtr InAuthBuffer,
    uint InAuthBufferSize,
    out IntPtr refOutAuthBuffer,
    out uint refOutAuthBufferSize,
    ref bool fSave,
    int flags);

Solution

  • I needed to change params: - in CredUIPromptForWindowsCredentials set dwFlags to 0x10 CREDUIWIN_AUTHPACKAGE_ONLY CredUIPromptForWindowsCredentials function disctiption - in CredUnPackAuthenticationBuffer set dwFlags to 0x01 (decrypt) CredUnPackAuthenticationBuffer function disctiption

    ...
    var result = CredUIPromptForWindowsCredentials(
                    ref credui,
                    0,
                    ref authPackage,
                    inAuthBuffer,
                    (uint)inAuthSize,
                    out var outCredBuffer,
                    out var outCredSize,
                    ref save,
                    0x10/*CREDUIWIN_AUTHPACKAGE_ONLY*/);
    ...
    var packAuthRes = CredUnPackAuthenticationBuffer(
                    1, outCredBuffer, outCredSize,
                    usernameBuf, ref maxUserName,
                    domainBuf, ref maxDomain,
                    passwordBuf, ref maxPassword);
    ...