Reading the local password policy programmatically

后端 未结 3 555
礼貌的吻别
礼貌的吻别 2021-01-02 16:59

Are there Windows API functions that allows reading what the current password policy is? For instance, minimum length, complexity etc.

If not reading, is there a wa

相关标签:
3条回答
  • 2021-01-02 17:39

    Eugene's answer is helpful, but not quite what I needed. The password complexity filter can actually be customized, and what would be good would be a way of asking Windows, does this password meet the requirements?

    It took me a while to locate it, but the function is NetValidatePasswordPolicy. The MSDN docs for this function are awful; check out this MSDN blog entry instead.

    0 讨论(0)
  • 2021-01-02 17:49

    Querying ActiveDirectory only works for computers joined to a domain; and where the user has the ability to query the domain controller (which is something that can be un-granted).

    @NicholasWilson's answer of using NetValidatePasswordPolicy is a good one; as it can do a lot of heavy lifting for you. It can even perform password quality checks that you would have to re-implement yourself. But NetValidatePasswordPolicy does fail as examining your custom password history when you use salted hashes to store passwords (e.g. BCrypt or Scrypt).

    But the real question is how to query for the current machine's (even an non-domain joined machine's) password policy. You can query that using:

    NetUserModalsGet

    struct USER_MODALS_INFO_0
    {
        DWORD usrmod0_min_passwd_len;
        DWORD usrmod0_max_passwd_age;
        DWORD usrmod0_min_passwd_age
        DWORD usrmod0_force_logoff; 
        DWORD usrmod0_password_hist_len;
    }
    PUSER_MODALS_INFO_0 = ^USER_MODALS_INFO_0;    
    
    PUSER_MODALS_INFO_0 info0;
    
    NET_API_STATUS res = NetUserModalsGet(nil, 0,  out info0);
    
    if (res <> NERR_Success)
       RaiseWin32Error(res);
    try
       //Specifies the minimum allowable password length. 
       //Valid values for this element are zero through PWLEN.
       Log(info0.usrmod0_min_passwd_len);
    
       //Specifies, in seconds, the maximum allowable password age. 
       //A value of TIMEQ_FOREVER indicates that the password never expires. 
       //The minimum valid value for this element is ONE_DAY. 
       //The value specified must be greater than or equal to the value for the usrmod0_min_passwd_age member.
       Log(info0.usrmod0_max_passwd_age);
    
       //Specifies the minimum number of seconds that can elapse between the time
       //a password changes and when it can be changed again. 
       //A value of zero indicates that no delay is required between password updates. 
       //The value specified must be less than or equal to the value for the usrmod0_max_passwd_age member.
       Log(info0.usrmod0_min_passwd_age);
    
       //Specifies, in seconds, the amount of time between the end of the valid
       // logon time and the time when the user is forced to log off the network. 
       //A value of TIMEQ_FOREVER indicates that the user is never forced to log off. 
       //A value of zero indicates that the user will be forced to log off immediately when the valid logon time expires.
       Log(info0.usrmod0_force_logoff);
    
       //Specifies the length of password hi'+'story maintained. 
       //A new password cannot match any of the previous usrmod0_password_hist_len passwords. 
       //Valid values for this element are zero through DEF_MAX_PWHIST
       Log(info0.usrmod0_password_hist_len);
    finally
       NetApiBufferFree(info0);
    end;
    
    0 讨论(0)
  • 2021-01-02 17:52

    See Security Watch Windows Domain Password Policies. You can hit AD using ADSI or its wrappers. I found a VBScript sample. You can translate it to any language you want:

    Sub ListPasswordPolicyInfo( strDomain )
        Dim objComputer
        Set objComputer = GetObject("WinNT://" & strDomain )
        WScript.Echo "MinPasswordAge: " &  ((objComputer.MinPasswordAge) / 86400)
        WScript.Echo "MinPasswordLength: " &  objComputer.MinPasswordLength
        WScript.Echo "PasswordHistoryLength: " &  objComputer.PasswordHistoryLength
        WScript.Echo "AutoUnlockInterval: " &  objComputer.AutoUnlockInterval
        WScript.Echo "LockOutObservationInterval: " &  objComputer.LockOutObservationInterval
    End Sub
    
    Dim strDomain
    Do
        strDomain = inputbox( "Please enter a domainname", "Input" )
    Loop until strDomain <> ""
    
    ListPasswordPolicyInfo( strDomain )
    

    As a bonus, check out LDAP Admin. It's an open source LDAP directory editor, which you can use to test things, and also checkout the code written in Delphi.

    0 讨论(0)
提交回复
热议问题