用Perl编写的LDAP查询中的意外行为

用Perl编写的LDAP查询中的意外行为,perl,active-directory,ldap,ldap-query,perlscript,Perl,Active Directory,Ldap,Ldap Query,Perlscript,我试图用Perl实现一个简单的LDAP查询。我想从域中的所有“dnsZone”对象中检索“dc”属性。 我首先使用dsquery编写了它,它工作得非常完美: dsquery * "DC=iii,DC=hogent,DC=be" -attr dc -scope subtree -filter "(objectClass=dnsZone)" 现在,当我尝试在Perl中实现这一点时,我在查询'dc'属性时收到以下错误。当我查询'dc'和'name'属性(看起来相同)时,我没有问题 “ADODB.Fi

我试图用Perl实现一个简单的LDAP查询。我想从域中的所有“dnsZone”对象中检索“dc”属性。 我首先使用dsquery编写了它,它工作得非常完美:

dsquery * "DC=iii,DC=hogent,DC=be" -attr dc -scope subtree -filter "(objectClass=dnsZone)"
现在,当我尝试在Perl中实现这一点时,我在查询'dc'属性时收到以下错误。当我查询'dc'和'name'属性(看起来相同)时,我没有问题

“ADODB.Fields”中的OLE异常:

在与请求的项对应的集合中找不到项 名字或序号

我在考虑财产缓存的方向,也许财产还不可用。但我不知道如何使用LDAP查询刷新属性缓存。也许它有一个getInfoEx([…],0)变体

my$rootDSE=bind_对象('rootDSE');
my$base=bind_对象($rootDSE->Get('defaultNamingContext'))->{ADsPath};
my$filter=“(objectClass=dnsZone)”;
我的$attrs='dc'#将此更改为“dc,name”时没有错误
我的$scope=‘子树’;
我的$connection=Win32::OLE->CreateObject('ADODB.connection');
$connection->{Provider}='ADsDSOObject';
$connection->Open();
我的$command=Win32::OLE->CreateObject('ADODB.command');
$command->{ActiveConnection}=$connection;
$command->{CommandText}=“;$filter;$attrs;$scope;”;
my$resultSet=$command->Execute();
直到($resultSet->{EOF}){
my$fields=$resultSet->{fields};
打印$fields->{dc}->{Value}。“\n”;
$resultSet->MoveNext();
}

有人看到我做错了什么吗?

当查询匹配一个(或多个)不具有任何请求属性的条目时,ldap客户端无法查找结果时,可能会出现这种问题

从查询中删除属性并使用dc作为筛选器可能有助于检查您是否处于这种情况:

  • 从查询中删除
    $attrs
    ,运行查询并检查结果计数
  • 使筛选器仅匹配具有dc:
    “(&(objectClass=dnsZone)(dc=*)”
    )的条目,运行查询(无$attrs)并检查结果计数
  • 比较结果计数
如果第二个查询产生的结果少于前一个查询,则表示原始查询匹配没有
dc
的条目(仅请求
dc
时出错,两个属性均无错误)


这也意味着objectClass
dnsZone
在将其用作读取dc的筛选器时,不会像您预期的那样强制使用
DomainComponent
属性。

当查询匹配一个(或多个)条目时,ldap客户端无法查找结果,可能会出现这种问题没有任何请求的属性

从查询中删除属性并使用dc作为筛选器可能有助于检查您是否处于这种情况:

  • 从查询中删除
    $attrs
    ,运行查询并检查结果计数
  • 使筛选器仅匹配具有dc:
    “(&(objectClass=dnsZone)(dc=*)”
    )的条目,运行查询(无$attrs)并检查结果计数
  • 比较结果计数
如果第二个查询产生的结果少于前一个查询,则表示原始查询匹配没有
dc
的条目(仅请求
dc
时出错,两个属性均无错误)

这也意味着objectClass
dnsZone
不会像您在将其用作读取dc的筛选器时所期望的那样,强制使用
DomainComponent
属性

my $rootDSE = bind_object('RootDSE');

my $base = bind_object($rootDSE->Get('defaultNamingContext'))->{ADsPath};
my $filter = "(objectClass=dnsZone)";
my $attrs = 'dc'; #No error when i change this into 'dc,name'
my $scope = 'subTree';

my $connection = Win32::OLE->CreateObject('ADODB.Connection');
   $connection->{Provider} = 'ADsDSOObject';
   $connection->Open();

my $command = Win32::OLE->CreateObject('ADODB.Command');
   $command->{ActiveConnection} = $connection;
   $command->{CommandText} = "<$base>;$filter;$attrs;$scope;";

my $resultSet = $command->Execute();

until($resultSet->{EOF}) {
    my $fields = $resultSet->{Fields};
    print $fields->{dc}->{Value}."\n";
    $resultSet->MoveNext();
}