【问题标题】:How to validate Windows account and password with Perl?如何使用 Perl 验证 Windows 帐户和密码?
【发布时间】:2013-10-09 23:37:47
【问题描述】:

我已经在 Powershell 2.0 中解决了这个问题,但需要移植到 Perl 5.10 才能使用旧版应用程序。

我的 Windows 服务帐户凭据无法以 $Account$Password 的形式交互登录传递给 perl 脚本。 $Account 变量包括域名和 AD 用户帐户名。我的 Powershell 解决方案(单线)是:

PS C:\> New-PsSession -Credential (new-object -typename System.Management.Automation.PSCredential -argumentlist '$Account', (ConvertTo-SecureString '$Password' -AsPlainText -Force)); exit-PsSession;

如果创建了新的 PsSession,则帐户验证通过,我将输出到 STDOUT,如下所示:

 Id Name            ComputerName    State    ConfigurationName     Availability
 -- ----            ------------    -----    -----------------     ------------
  1 Session1        localhost       Opened   Microsoft.PowerShell     Available

如果验证失败,我会得到这样的输出到 STDERR:

[localhost] Connecting to remote server failed with the following error message
 : Access is denied. For more information, see the about_Remote_Troubleshooting
 Help topic.
    + CategoryInfo          : OpenError: (System.Manageme....RemoteRunspace:Re
   moteRunspace) [], PSRemotingTransportException
    + FullyQualifiedErrorId : PSSessionOpenFailed

我可以在我的程序中解析这些结果。我想在 Windows 上的 Perl 5.10 中做类似的事情。我要做的就是测试密码是否适用于帐户,同时记住交互式登录被拒绝。有什么想法吗?

【问题讨论】:

    标签: perl powershell


    【解决方案1】:

    另一种完全不同的方法是使用Net::LDAP 直接联系AD,但是你会遇到很多新的挑战。

    很久以前我也使用过类似以下的东西(调用 win ole)。但我认为不得不放弃win200X-server。如果它可能有任何帮助:(请原谅糟糕的编码)

    但这实际上会检查当前用户是否是组的成员。 我想它也可以用来验证用户名 pwd。

    require Win32::OLE;
    sub GetObject {
        Win32::OLE->GetObject(@_);
    }
    
        my ( $module, $database, $mode ) = @_;
        my $env = {%ENV}; #makes a copy, makes it possible to override $ENV for test etc
        my $oRoot = GetObject("LDAP://rootDSE");
        my $domain_name =  $oRoot && $oRoot->Get("defaultNamingContext");
        my $domain_host =  $oRoot && $oRoot->Get("dnsHostName");
    
        $domain_host .= "/" unless $domain_host =~ /\/$/;
        my $strAttributeName  ="sAMAccountname"; #could be userPrincipalName, cn etc
        my @user_parts = ($user_name); # the last one (i.e. -1) will be the user name
        my $alias = $user_name;
    
        my $group_prefix = $system_info_defs->{adAuthGroupPrefix};
        my $strADsPath        = "LDAP://$domain_host$domain_name";
        my $objConnection = Win32::OLE->new("ADODB.Connection") 
            or do{warn "Cannot create ADODB Connection!";return undef};#die ("Cannot create ADODB object!");
        my $objCommand = Win32::OLE->new("ADODB.Command") 
            or do{warn "Cannot create ADODB command!";return undef};#die ("Cannot create ADODB object!");
    
        $objConnection->{Provider} = ("ADsDSOObject");
        $objConnection->Open();
        $objCommand->{ActiveConnection} = ($objConnection); 
    

    等等。等等

    【讨论】:

      【解决方案2】:

      使用 perl 的系统调用,即反引号

      my $a = `powershell -command "ls;exit;"`;
      if ($a =~ /pl$/) {
          print "folder contains a perl file";
      } else {
          print "folder contains no perl file (strange)";
      }
      

      如果可行,则将简单的 ls-command 替换为更复杂的文本。 可能您可能需要详细说明 \" " ' \' "" 和 '' 才能做到正确。

      【讨论】:

      • 我确实尝试过,但 powershell 进程没有返回。我已经用 Win32::Spawn, Win32:Process:CreateProcess, qw(), system(), ` 花了几天的时间在我的调用进程中都不起作用,所以我想知道它是否可以在本机在 Perl 中无需调用 powershell 进程。
      • 你是否以 ;exit; 结尾? ?
      • 从命令行 c:>perl -e "print '123'.`powershell -command ls;exit`.432"
      • 是的,我以 ;exit 结束。它适用于 cmd.exe 窗口,但不适用于我的调用程序,当我查看任务管理器时,我看到了一个 powershell.exe 进程。
      猜你喜欢
      • 1970-01-01
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多