[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now


Checking Window accounts with blank passwords using LogonUser in .Net

Posted on 2006-03-29
Medium Priority
Last Modified: 2008-01-09
Hi all

Using VB .NET, I am attempting to see if the current user has logged onto the local system with a password using a call to the LogonUser function in the  Lib "advapi32.dll". My code works fine for accounts that have a password ( I test this by creating a local XP account, assign a non-blank passwd and attempt to logon with the user using the aforementioned command). This is confirmed by auditing on logon events in the event viewer.

My issue is that when I create a user with a Blank passwd (i.e no assigned passwd), the LogonUser function with a blank Passwd does not logon successfully and fails. Again, the logon failure is reflected in Event Viewer.

The call syntax I'm using is

Dim returnValue As Boolean = LogonUser(strUserName, strDomainName, BLANKPASSWD, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle)

Why can't I get LogonUser to accept a blank Passwd (3rd field)? Please respond in VB .NET terms.

Question by:pnicklos
  • 4
  • 3
  • 3
LVL 14

Expert Comment

ID: 16328110
At the command prompt, type the following:

  net accounts

You will see the minimum allowed password length. You can change this setting to allow blank passwords using the command:

  net accounts /minpwlen:0

I guess this solves your problem.


  Nayer Naguib
LVL 41

Expert Comment

ID: 16329014

Did you try the "Nothing" keyword (meaning NULL) instead of an empty (null) string?

Dim returnValue As Boolean = LogonUser(strUserName, strDomainName, Nothing, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle)

Author Comment

ID: 16340834
Hi guys

I have tried all combinations of NULL I can think of including sending Nothing and String.empty etc. No joy unfortunately. Same applies to the Extended version of this command - LogonUserEx

Sorry Nayer, I can logon manually with a blank password on that account - it is when I attempt to programmatically logon using the ADAVPI32.dll LogonUser that I get this issue. I am not attempting to change user account settings on someones system, I am running a security tool that tests to see that the local user doesn't have a blank password and the only way I can do that, as far as I can gather, is by physically trying to logon, via the LogonUser Api, with a blank passwd. Naturally, I did test that I could logon with a blank password manually.

Any other suggestions ?
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

LVL 14

Expert Comment

ID: 16341835
I know that you can log in manually using a blank password. Still, if you check for the MINPWLEN value, you will see that it is greater than zero (default=6).

I think you *must* change this setting before trying to *programmatically* log in to Windows using a blank password. I suggest that you read the stored value first, change it *just* before calling LogonUser() (to zero), and then changing it back after calling LogonUser().


  Nayer Naguib
LVL 41

Expert Comment

ID: 16342748
The fix to this issue is a bit strange...  you'll have to temporarily modify the registry before running the LogonUser function.

The key to change is HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\limitblankpassworduse  it must be set to 0 before you make the API call, and then reset back to 1 afterwards.

Author Comment

ID: 16345546
Thanks Graye, little bit of a bugger this one is - what you suggested is the reason for the LogonUser to fail on a blank password.

My code does work once the RegKey is changed. Unfortunately this leaves me with another issue, I can't guarantee that the logged on user has Local Admin rights and therefore won't be able to guarantee that I can modify the registry in HKLM back and forth as required.

Nayer - thanks for your input however, one of the first things I did was ensure that all password and logon limitations were removed and MinPwd length was set to 0 thus allowing me to change account passwds to any length. So in all my tests, the MinPwdLen was 0. As mentioned above, Graye has discovered the reason for my dilemna.

Is there any other method for a Logged on user to "test" that his account has a blank password programmatically ?
LVL 41

Expert Comment

ID: 16346176
I'd consider using Windows Management Instrumentation (WMI) to pull data about the local accounts (we are just talking about local accounts, right?)
The field in particular is called "PasswordRequired".   If set to false, then the account has a blank password.


Here is an example to demonstrate the concepts

' Remember to add a Reference to System.Management !!!
Imports System
Imports System.Management
Imports System.Windows.Forms

Namespace WMISample

    Public Class MyWMIQuery

        Public Overloads Shared Function Main() As Integer

                Dim searcher As New ManagementObjectSearcher( _
                    "root\CIMV2", _
                    "SELECT * FROM Win32_UserAccount where Domain='Your_PC_Name_Goes_Here'")

                For Each queryObj As ManagementObject in searcher.Get()

                    Console.WriteLine("Win32_UserAccount instance")
                    Console.WriteLine("AccountType: {0}", queryObj("AccountType"))
                    Console.WriteLine("Caption: {0}", queryObj("Caption"))
                    Console.WriteLine("Description: {0}", queryObj("Description"))
                    Console.WriteLine("Disabled: {0}", queryObj("Disabled"))
                    Console.WriteLine("Domain: {0}", queryObj("Domain"))
                    Console.WriteLine("FullName: {0}", queryObj("FullName"))
                    Console.WriteLine("InstallDate: {0}", queryObj("InstallDate"))
                    Console.WriteLine("LocalAccount: {0}", queryObj("LocalAccount"))
                    Console.WriteLine("Lockout: {0}", queryObj("Lockout"))
                    Console.WriteLine("Name: {0}", queryObj("Name"))
                    Console.WriteLine("PasswordChangeable: {0}", queryObj("PasswordChangeable"))
                    Console.WriteLine("PasswordExpires: {0}", queryObj("PasswordExpires"))
                    Console.WriteLine("PasswordRequired: {0}", queryObj("PasswordRequired"))
                    Console.WriteLine("SID: {0}", queryObj("SID"))
                    Console.WriteLine("SIDType: {0}", queryObj("SIDType"))
                    Console.WriteLine("Status: {0}", queryObj("Status"))
            Catch err As ManagementException
                MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
            End Try
        End Function
    End Class
End Namespace
LVL 14

Expert Comment

ID: 16346456
As far as I know, the PasswordRequired field shows whether a password is *required* or not. Having a password required implies that a user cannot have a blank password. However, having a password not required does *not* imply that the user's password is blank. It just means that the user can *choose* whether or not to set a password.


  Nayer Naguib
LVL 41

Accepted Solution

graye earned 1200 total points
ID: 16347377
Nayer, I just did a quick test, and you're right...   The PasswordRequired field does NOT detect a null password.

I think this is gonna be practically impossible to do if the current user is not an administrator.   For example, digging into the SAM database would not be a viable option.

Author Comment

ID: 16347575
Should have mentioned I went through the WMI stuff and have also code around the ADS_UF_PASSWD_NOTREQD in the USERACCOUNTCONTROL cn, which is the AD equivalent of above mentioned WMI control - and unfortunately as you guys have figured out, this only allows a user to select a NULL passwd but doesnt determine whether he has or not.

Just for interest, there is another WMI control - Win32_NetworkLoginProfile that contains FLAGS which is a BIT mask field which, if you do a Binary Anding with Hex 20 (decimal 32) you get the same result as in the Win32_UserAccount instance.

Graye, as you surmised, the SAM database hack won't cut it for me as the users may not be local admins.

As you boys have been really helpful, I'll assign points for this query and open another with the next part.

Sorry Nayer but Graye figured out my initial problem with why the blank doesnt work.


Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
Loops Section Overview

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question