验证本地Windows用户帐户

时间:2015-05-06 22:27:38

标签: active-directory ldap windows-authentication directoryservices adsi

我编写了这个JScript来验证本地Windows用户帐户:

function ValidateCredentials(strUsername, strPassword) {
  var ADS_SECURE_AUTHENTICATION = 1;
  var objWMISvc = GetObject("winmgmts:\\\\.\\root\\cimv2");
  var colItems = objWMISvc.ExecQuery( "Select * from Win32_ComputerSystem");
  for (var it = new Enumerator(colItems); !it.atEnd(); it.moveNext()) {
    var objItem = it.item();
    if (objItem.PartOfDomain)
      continue;
    var strWorkgroup = objItem.Domain;
    var strComputer  = objItem.Name;
    var strPath = "WinNT://" + strWorkgroup + "/" + strComputer + "/" +
      strUsername + ",user";
    try {
      var objIADS = GetObject("WinNT:").OpenDSObject(strPath, strUsername,
        strPassword, ADS_SECURE_AUTHENTICATION);

      WScript.Echo("OK");
    } catch(e) {
      WScript.Echo("Invalid Username/Password");
    }
  }
}

ValidateCredentials(WScript.Arguments(0), WScript.Arguments(1));

当我从命令提示符运行它时,它既可以作为管理员也可以作为普通用户。当作为 LocalSystem 用户运行的服务进程调用脚本时,它不起作用。而是调用OpenDSObject然后引发异常,错误代码为-2147023584(指定的登录会话不存在。它可能已经被终止)。

问题是什么,我认为LocalSystem帐户实际上比管理员帐户更具特权或信任?

您可以通过将脚本保存到某个.js文件然后从命令提示符运行它来自己试用该脚本,如下所示:

  

cscript.exe validate.js myUsername myPassword

1 个答案:

答案 0 :(得分:1)

如果您只想验证密码,我会避免以上所有情况。有一种不同的方法可以从非特权账户中很好地运作。实际上,您希望确保该帐户实际上无权更改密码。

使用此方法,您可以调用NetUserChangePassword,这需要您指定用户的现有密码,以便在更改之前进行身份验证。

当您从无权更改该用户密码的帐户执行此操作时,它显然会失败(因此密码不会更改)。我们关心的是 它是如何失败的。如果通过返回ERROR_INVALID_PASSWORD失败,那么您就知道密码错误了。如果通过返回ERROR_ACCESS_DENIED失败,则密码正确,并且函数失败,因为您从中调用的帐户无权更改该用户的密码。

因此,这不是要求像LocalSystem或管理员这样的高权限帐户,而是允许您从基本上没有权限的帐户(通过强烈的偏好,甚至不更改自己的密码的权限)来完成工作。