11

Question

I didn't know it would be this difficult to figure out but here I am.

I'm developing a net support client which has to detect if the current logged in user has a password set. I tried it with WMI checking the PasswordRequired property in the Win32_UserAccount class, but it returns false even if my account is password protected. I'm out of ideas...

(Background: I need this info to tell the user he has to set one so I can connect to him via remote desktop, which isn't very happy if the account is "unprotected". If there is a way to get around this I'd also accept a different solution.)

Sincerely yours
Nefarius

Solution

Easier than I thought, I managed it with the WinAPI function LogonUser and provide you this simple wrapper code:

    private bool PasswordRequired
    {
        get
        {
            IntPtr phToken;

            // http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html
            bool loggedIn = LogonUser(Environment.UserName,
                null,
                "",
                (int)LogonType.LOGON32_LOGON_INTERACTIVE,
                (int)LogonProvider.LOGON32_PROVIDER_DEFAULT,
                out phToken);

            int error = Marshal.GetLastWin32Error();

            if (phToken != IntPtr.Zero)
                // http://www.pinvoke.net/default.aspx/kernel32/CloseHandle.html
                CloseHandle(phToken);

            // 1327 = empty password
            if (loggedIn || error == 1327)
                return false;
            else
                return true;
        }
    }

That's exactly what I needed, thank you all for your fast and competent answers, I can always count on you! =)

  • Hi Nefarius, I think this would be a strange way of solving the problem. Perhaps you simply can detect if the account is active (e.g. not disabled) - but determining if the password is set should really not be possible, this would allow others to get password information... You might also want to check any passwords policies in the system... – Anders Jul 02 '11 at 11:05
  • could this help ? http://msdn.microsoft.com/en-us/library/Aa378292 – Keith Beard Jul 02 '11 at 11:09
  • Is this for your own domain/work network? – Lasse V. Karlsen Jul 02 '11 at 11:18
  • Yup, it is. I'll send my tool in an archive file to the person who has a problem and he just has to launch it, it prepares the system for incoming terminal server connection requests. –  Jul 02 '11 at 12:02
  • 1
    1327 is ERROR_ACCOUNT_RESTRICTION, [documented](https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx) as "Account restrictions are preventing this user from signing in. For example: blank passwords aren't allowed, sign-in times are limited, or a policy restriction has been enforced." It seems like there could be situations other than a blank password that would produce this error code, but it is hard to know what they are. – Eric Smith Jul 27 '15 at 20:42

3 Answers3

6

Why not just to try to LogonUser with empty password?

adontz
  • 1,428
  • 16
  • 36
  • I chose this and posted the solution in my first post, thank you again! –  Jul 02 '11 at 11:59
2

Try to Change password with empty password, if succeed, that means user didn't set Password. Suppose domain user and Microsoft account always protected with password. For Microsoft account, it will throw PrincipalOperationException. For local user, if setted password, it will throw PasswordException. VB script reference, c# change password

        try
        {
            using (var context = new PrincipalContext(ContextType.Machine))
            {
                var user = UserPrincipal.FindByIdentity(context, userName);
                if (null == user)
                {
                    //not local user, password required
                    passwordRequired = true;
                }
                else
                {
                    user.ChangePassword("", "");
                }
            }
        }
        catch (PasswordException)
        {
            //local user password required
            passwordRequired = true;
        }
        catch (PrincipalOperationException)
        {
            //for Microsoft account, password required
            passwordRequired = true;
        }
Ling
  • 31
  • 3
1

From what I can find, windows does not store a clear text version of the users password. Windows stores a copy that has been protected with one-way encryption. You can find more information about logging a user into windows in the MSDN documentation on LSALogonUser function. It does not help you get the users password

Keith Beard
  • 1,601
  • 4
  • 18
  • 36
  • I know, I don't want/need the clear-text password, just a check if one is set. –  Jul 02 '11 at 12:03
  • sorry i realized that as i was posting the answer, but i felt it would be good refernce for someone else down the line and LogonUser would probally accomplish what you were looking for. – Keith Beard Jul 02 '11 at 12:13