windows 以编程方式读取本地密码策略
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/313859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading the local password policy programmatically
提问by Maltrap
Are there Windows API functions that allows reading what the current password policy is? For instance, minimum length, complexity etc.
是否有允许读取当前密码策略的 Windows API 函数?例如,最小长度、复杂度等。
If not reading, is there a way to verify a password against the policy programmatically?
如果不阅读,有没有办法以编程方式根据策略验证密码?
采纳答案by Eugene Yokota
See Security Watch Windows Domain Password Policies. You can hit AD using ADSIor its wrappers. I found a VBScript sample. You can translate it to any language you want:
请参阅安全监视 Windows 域密码策略。您可以使用ADSI或其包装器命中 AD 。我找到了一个VBScript 示例。您可以将其翻译成您想要的任何语言:
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.
作为奖励,请查看LDAP Admin。它是一个开源的 LDAP 目录编辑器,您可以用它来测试事物,也可以检查用 Delphi 编写的代码。
回答by Nicholas Wilson
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?
尤金的回答很有帮助,但不是我所需要的。密码复杂度过滤器实际上是可以自定义的,请问Windows 的密码是否符合要求?
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 entryinstead.
我花了一段时间才找到它,但功能是NetValidatePasswordPolicy
. 这个功能的 MSDN 文档很糟糕;请查看此MSDN 博客条目。
回答by Ian Boyd
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).
查询 ActiveDirectory 仅适用于加入域的计算机;以及用户可以查询域控制器的地方(这是可以不授予的)。
@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).
@NicholasWilson 的使用答案NetValidatePasswordPolicy
是一个很好的答案;因为它可以为你做很多繁重的工作。它甚至可以执行您必须自己重新实施的密码质量检查。但是NetValidatePasswordPolicy
当您使用加盐哈希来存储密码(例如 BCrypt 或 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:
但真正的问题是如何查询当前机器(甚至是非域加入机器)的密码策略。您可以使用以下方法查询:
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;