[RESOLVED] Determine If User Account Has Password
I need to be able to validate the windows password of the account that is currently logged in. I've managed to do this when the unit has a password. But if it does not have a password, passing an empty string does not work. It fails each time.
I've been looking around, but haven't been able to find much on this. Does anyone know how to determine if the user password is empty?
Below is the API I'm using. But I don't think it will be used for this.
VB.NET Code:
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, _
ByVal dwLogonType As LogonType, ByVal dwLogonProvider As Integer, ByRef phToken As IntPtr) As Integer
Re: Determine If User Account Has Password
Re: Determine If User Account Has Password
Normally the Windows Security System does not allow you to dynamically log on to the system if the user lacks a password. If you just want to check if the password the user has entered is correct (and not that you want to use the returned security token) then you can simply check if the System.Runtime.InteropService.Marshal.GetLastWin32Error is equal to ERROR_ACCOUNT_RESTRICTION (=1327) in which case the call to LogonUser failed because the user password is empty.
The only way to make LogonUser work with empty passwords is to set the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa key to 0 which removes the LimitBlankPasswordUse restriction but this will create a huge security hole in the system and I do not recommend it.
Re: Determine If User Account Has Password
Quote:
Originally Posted by
Joacim Andersson
Normally the Windows Security System does not allow you to dynamically log on to the system if the user lacks a password. If you just want to check if the password the user has entered is correct (and not that you want to use the returned security token) then you can simply check if the System.Runtime.InteropService.Marshal.GetLastWin32Error is equal to ERROR_ACCOUNT_RESTRICTION (=1327) in which case the call to LogonUser failed because the user password is empty.
The only way to make LogonUser work with empty passwords is to set the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa key to 0 which removes the LimitBlankPasswordUse restriction but this will create a huge security hole in the system and I do not recommend it.
Hm... that's an interesting idea. So you're saying I should use my process as normal, but if an empty string is passed as the password, check if the GetLastWin32Error returns ERROR_ACCOUNT_RESTRICTION? If it does, then the logon failed.
Which sounds like it would work, but wouldn't that be thrown if the logon failed, regardless whether or not the user has a password? So if I used this method, if the computer had a password but an empty string was passed, it would assume that the password is empty. That would cause a lot of problems. Unless of course I'm understanding this incorrectly.
Re: Determine If User Account Has Password
No, you wouldn't get the account restriction error if you just tried to logon with the wrong password.
Re: Determine If User Account Has Password
Quote:
Originally Posted by
Joacim Andersson
No, you wouldn't get the account restriction error if you just tried to logon with the wrong password.
Gotcha. I won't really get a chance to check it out until Monday. Thanks for the help.
Re: Determine If User Account Has Password
Go ahead and test in on Monday and when it works (which it will :)) make sure to come back and mark this thread as resolved.
Re: Determine If User Account Has Password
Quote:
Originally Posted by
Joacim Andersson
Go ahead and test in on Monday and when it works (which it will :)) make sure to come back and mark this thread as resolved.
Are you sure it's 127? I ran it and consistently got 6.
VB.NET Code:
Private Sub btnTest_Click(sender As System.Object, e As System.EventArgs) Handles btnTest.Click
If Me.IsNTPasswordValid(String.Empty) Then
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
Else
If Marshal.GetLastWin32Error() = 1327 Then
MessageBox.Show("pass")
Else
MessageBox.Show(Marshal.GetLastWin32Error.ToString)
End If
End If
End Sub
Public Function IsNTPasswordValid(ByVal Password As String) As Boolean
Dim Token As New IntPtr
LogonUser(Environment.UserName, Environment.UserDomainName, Password, LogonType.LOGON32_LOGON_INTERACTIVE, 0, Token)
CloseHandle(Token)
If Token.ToInt32 <> 0 Then Return True Else Return False
End Function
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, _
ByVal dwLogonType As LogonType, ByVal dwLogonProvider As Integer, ByRef phToken As IntPtr) As Integer
Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal hObject As IntPtr) As Boolean
Private Enum LogonType As Integer
LOGON32_LOGON_INTERACTIVE = 2
LOGON32_LOGON_NETWORK = 3
LOGON32_LOGON_BATCH = 4
LOGON32_LOGON_SERVICE = 5
LOGON32_LOGON_UNLOCK = 7
LOGON32_LOGON_NETWORK_CLEARTEXT = 8
LOGON32_LOGON_NEW_CREDENTIALS = 9
End Enum
*Edit: Also, that's not good because I get that error code regardless of the computer has a password.
Re: Determine If User Account Has Password
You're doing the error checking a bit late since you call CloseHandle after the call to LogonUser. CloseHandle can very well change the error number, which it most likely do if LogonUser fails you don't get a handle to close and when you try to do that the CloseHandle will fail and set its own error number. You should check the GetLastWin32Error value directly after the call to LogonUser.
Re: Determine If User Account Has Password
Quote:
Originally Posted by
Joacim Andersson
You're doing the error checking a bit late since you call CloseHandle after the call to LogonUser. CloseHandle can very well change the error number, which it most likely do if LogonUser fails you don't get a handle to close and when you try to do that the CloseHandle will fail and set its own error number. You should check the GetLastWin32Error value directly after the call to LogonUser.
Ah. Gotcha.
Thanks, that did it.