none
LogonUser Lib "advapi32.dll" strange on non domain cpu when local exists? RRS feed

  • Question

  • Hi,  not sure of the correct place to post..

    I'm attempting a Login Form for a win form app and it needs to only allow domain users in a certain group.
    On using the API LogonUser for advapi32.dll either I'm not getting the flags right or something else wierd is happening.

    When used on a domain computer the paramaters of login type (INTERACTIVE,NETWORK,BATCH,NEW_CREDENTIALS) all appear to work fine.

    When used on a Workgroup computer eg: in workgroup "WORKGROUP" on the same network as the domain but isn't on the domain, it doesn't work in any combination I try. It also has an glitch (though I believe this is a policy or something) that if the account you use eg: MyDomain\User1 exists as MyComputer\User1 it returns MyComputer\User1 regardless of specifying the Domain in the Call as "MyDomain".
    This computer can communication with the domain shares etc as I can copy and interact with them - therefore I would expect to able to login to the domain if available.  It might seem strange to attempt this, but basically due to support contracts issues.

    Heres some code:

    Public Class WinSecurity Private Declare Auto Function LogonUser Lib "advapi32.dll" ( ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean Public Const LOGON32_LOGON_INTERACTIVE As Long = 2 Public Const LOGON32_LOGON_NETWORK As Long = 3 Public Const LOGON32_LOGON_BATCH As Long = 4 Public Const LOGON32_LOGON_SERVICE As Long = 5 Public Const LOGON32_LOGON_CLEARTEXT As Long = 8 Public Const LOGON32_LOGON_NEW_CREDENTIALS As Long = 9 Public Const LOGON32_PROVIDER_DEFAULT As Long = 0 Public Const LOGON32_PROVIDER_WINNT50 As Long = 3 Public Const LOGON32_PROVIDER_WINNT40 As Long = 2 Public Const LOGON32_PROVIDER_WINNT35 As Long = 1 Public Shared Function checkUserLogin(ByVal LoginCode As String, ByVal Password As String, ByVal Domain As String, Login As Integer, Provider As Integer) As WindowsIdentity

    Dim token As IntPtr
    LoginUser(LoginCode, Domain, Password, Login, Provider, token)

    If (token.ToInt32 > 0) Then Dim newId As New WindowsIdentity(token) Track.LogDEBUG(String.Format("Attempto PASS: {0}, Auth: {1}, method: {2}, Provider: {3}", newId.Name, newId.Token, Login, Provider)) CloseHandle(token) Else Track.LogDEBUG(String.Format("Attempto FAIL: {0}, Auth: {1}, method: {2}, Provider: {3}", LoginCode, Domain, Login, Provider)) End If End Function End Class ''Calling Code

    dim sDomain as string = "MyDomain" WinSecurity.checkUserLogin(txtUserName.Text, txtPassword.Text, sDomain, WinSecurity.LOGON32_LOGON_INTERACTIVE, WinSecurity.LOGON32_PROVIDER_DEFAULT) WinSecurity.checkUserLogin(txtUserName.Text, txtPassword.Text, sDomain, WinSecurity.LOGON32_LOGON_NETWORK, WinSecurity.LOGON32_PROVIDER_DEFAULT) WinSecurity.checkUserLogin(txtUserName.Text, txtPassword.Text, sDomain, WinSecurity.LOGON32_LOGON_BATCH, WinSecurity.LOGON32_PROVIDER_DEFAULT) WinSecurity.checkUserLogin(txtUserName.Text, txtPassword.Text, sDomain, WinSecurity.LOGON32_LOGON_NEW_CREDENTIALS, WinSecurity.LOGON32_PROVIDER_DEFAULT) WinSecurity.checkUserLogin(txtUserName.Text, txtPassword.Text, sDomain, WinSecurity.LOGON32_LOGON_INTERACTIVE, WinSecurity.LOGON32_PROVIDER_DEFAULT)

    Note: I have changed the names for privacy reasons.

    My Results on the WorkGroup Computer - Local User Active:

    Attempto PASS: MyComputer\User1, Auth: 1088, method: 2, Provider: 0
    Attempto PASS: MyComputer\User1, Auth: 1100, method: 3, Provider: 0
    Attempto PASS: MyComputer\User1, Auth: 1060, method: 4, Provider: 0
    Attempto PASS: MyComputer\LoggedOnUser1, Auth: 1108, method: 9, Provider: 0
    Attempto PASS: MyComputer\User1, Auth: 1076, method: 2, Provider: 0

    Results on WorkGroup Computer - Local User Disabled/doesn't exits:

    Attempto FAIL: User1, Auth: MyDomain, method: 2, Provider: 0
    Attempto FAIL: User1, Auth: MyDomain, method: 3, Provider: 0
    Attempto FAIL: User1, Auth: MyDomain, method: 4, Provider: 0
    Attempto FAIL: User1, Auth: MyDomain, method: 9, Provider: 0
    Attempto FAIL: User1, Auth: MyDomain, method: 2, Provider: 0

    Results on Domain Computer

    Attempto PASS: MyDomain\User1, Auth: 1340, method: 2, Provider: 0
    Attempto PASS: MyDomain\User1, Auth: 1724, method: 3, Provider: 0
    Attempto PASS: MyDomain\User1, Auth: 1736, method: 4, Provider: 0
    Attempto PASS: MyDomain\User1, Auth: 1648, method: 9, Provider: 0
    Attempto PASS: MyDomain\User1, Auth: 1744, method: 2, Provider: 0

    Please let me know if this is by design or I'm missing something.
    Obviously I don't have a Trust setup to this Computer, but assuming this should still work if I can browse to network shares?

    Cheers
    Paul




    • Edited by PCzzz Tuesday, July 24, 2018 8:53 AM fix thy code
    Tuesday, July 24, 2018 3:55 AM

All replies

  • Hi

    The following link has a detailed description, I hope it can help you

    https://docs.microsoft.com/en-gb/windows/desktop/api/winbase/nf-winbase-logonusera

    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.



    Wednesday, July 25, 2018 1:55 AM
  • You probably want to use System.DirectoryServices to interface with Active Directory.

    If the computer is not a member of the domain, you can specify a domain account when utilizing the DirectoryServices objects.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Thursday, July 26, 2018 3:34 AM
    Moderator
  • Thanks Reed,

    I was hoping using a WinAPI would be plenty for simple checking of a user account, looking at Directory services looks like the more modern approach for domain only logins.

    For anyone looking at this looks this appears to have some good examples: but still quite a few issues.

    https://stackoverflow.com/questions/290548/validate-a-username-and-password-against-active-directory

    Cheers
    Paul

    Tuesday, August 21, 2018 5:40 AM