将atime从LDAP转换为Perl

时间:2012-03-19 20:07:36

标签: perl ldap

我在Perl中创建了一个脚本来连接LDAP,检索值并将它们发布到CSV文件中。我通过查询检索的值是d"可分辨名称,userAccountControl&的pwdLastSet。我可以正确地拉出并解析前两个结果并将它们发布到CSV文件,但是pwdLastSet返回WIN32 :: OLE = HASH(0x .......)。我已经厌倦了sprintf,hex(),结果是WIN32值或0.我期待长度为18位。谢谢你的帮助。

#!/usr/bin/perl
use xSV;
use Win32;
use Win32::OLE;
# use strict;
.
.
.
.  
  while ($line = <GROUPS>) {
        chomp($line);
        if ($line =~ m/^  user  .*/) {
            $line =~ s/^  user.\s//;
            my ($objRootDSE, $strDomain, $strUsername, $objConnection, $objCommand, $objRecordSet, $strDN, $arrSplitResponse, $strLName, $strFName, $strUserType);
            use constant ADS_SCOPE_SUBTREE => 2;
            # Get domain components
            $objRootDSE = Win32::OLE->GetObject('LDAP://RootDSE');
            $strDomain = $objRootDSE->Get('DefaultNamingContext');
            # Get username to search for
            $strUsername = $line;
            # Set ADO connection
            $objConnection = Win32::OLE->new('ADODB.Connection');
            $objConnection->{Provider} = 'ADsDSOObject';
            $objConnection->Open('Active Directory Provider');
            # Set ADO command
            $objCommand = Win32::OLE->new('ADODB.Command');
            $objCommand->{ActiveConnection} = $objConnection;
            $objCommand->SetProperty("Properties", 'Searchscope', ADS_SCOPE_SUBTREE);
            $objCommand->{CommandText} = 'SELECT distinguishedName, userAccountControl, pwdLastSet FROM \'LDAP://' . $strDomain . '\' WHERE objectCategory=\'user\' AND samAccountName = \'' . $strUsername . '\'';
            # Set recordset to hold the query result
            $objRecordSet = $objCommand->Execute;
            # If a user was found - Retrieve the distinguishedName
            if (!$objRecordSet->EOF) {
                $strDN = $objRecordSet->Fields('distinguishedName')->Value;
                $strAcctControl = $objRecordSet->Fields('userAccountControl')->Value;
                $strpwdLS = sprintf($objRecordSet->Fields('pwdLastSet')->Value);
                @arrSplitResponse = split(/,/, $strDN);
                $strLName = substr($arrSplitResponse[0],3);
                if ($strLName =~ m/\\$/) {
                    $strLName = substr($strLName,0,-1);
                }
                $strFName = $arrSplitResponse[1];
                if ($strFName =~ m/OU=/) {
                    $strUserType = $strFName;
                    $strFName = "";
                    $strUserType = substr($strUserType,3);
                } else {
                    $strUserType = substr($arrSplitResponse[2],3);
                    }
                if ($strAcctControl == 512) {
                    $strAcctControl = "Active";
                } else {
                    $strAcctControl = "Disabled";
                }
            } else {
                print "No user found";
            }
            &debug("Match!: $line in $group\n");
            $csv->print_data(
                AccountName => $line,
                LastName => $strLName,
                FirstName => $strFName,
                SYSGenericAcct => $strUserType,
                AccessLevel => $group,
                AccessCapability => "User",
                Description => $desc,
                Status => $strAcctControl,
                LastPwdChange => $strpwdLS
            );
        } else {
            $group = $line;
            chomp($desc = <GROUPS>);
            chomp($group2 = <GROUPS>);
            &debug("$group\n$desc\n$group\n");
        }
    }

1 个答案:

答案 0 :(得分:1)

使用Net :: Ldap搜索AD服务器。它速度快,便于携带。可以从其他主机搜索AD服务器,甚至可以从linux搜索。这是一个快速而成熟的模块。

您也可以使用Data :: Dumper进行一些调试。

使用Data :: Dumper; ... print Dumper($ strpwdLS);

我找到了这个帖子:http://code.activestate.com/lists/pdk/3876/

# Calculate password age in days
my $PWage;
my $LastPW  = $item->{pwdLastSet};
my $fRef = ref ($LastPW);
my ($Hval, $Lval);
if ($fRef eq 'Win32::OLE' )
{
   $Hval = $LastPW->HighPart;
   $Lval = $LastPW->LowPart;
   my $Factor = 10000000;   # convert to seconds
   my $uPval = pack("II",$Lval,$Hval);
   my ($bVp, $aVp) = unpack("LL", $uPval);
   $uPval = ($aVp*2**32+$bVp)/$Factor;
   if ($uPval != 0)
   {
      $uPval -= 134774*86400;  #Adjust for perl time!
       my $EpochSeconds = time;
      $PWage = ($EpochSeconds - int($uPval))/(60*60*24) ;
      $PWage =~ s/\..*$//;
   }
}