如何使用Perl验证Windows帐户和密码?

时间:2013-10-09 14:40:44

标签: perl powershell

我已经在Powershell 2.0中解决了这个问题,但需要移植到Perl 5.10以获取遗留应用程序。

我有Windows服务帐户凭据,无法将INTERACTIVELY LOGON作为$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中做类似的事情。我想要做的就是测试密码是否适用于帐户,同时考虑到交互式登录被拒绝。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

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

我很久以前也使用了类似下面的东西(叫做win ole)。但我不得不放弃在win200X服务器上。如果有任何帮助:(请原谅编码不好)

但这实际上会检查当前用户是否是某个组的成员。 我认为它也可能用于以某种方式验证用户名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); 

等。等

答案 1 :(得分:1)

使用来自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替换为更复杂的文本。 Probalby你可能需要详细说明\“”'\'“”和''以使其正确。