Perl LDAP 搜索 - 群组中超过 1500 名成员

标签 perl active-directory ldap

我想使用 Perl 脚本和 ldap 连接搜索成员超过 10.000 的群组的所有成员。

如果我设置了 $first=0$last=1499,我只能找到结果,并且只获得该组的前 1500 名成员。 如果我对 $first$last 使用其他参数,那么我没有结果。

"$ldapsearchresult = $ldapconnect->search (
Sizelimit => 0,
base   => 'any_base',
filter => '(objectClass=*)',
attr => ['member;range=$first-$last'],
);"

感谢您的帮助!

最佳答案

需要一次又一次地搜索属性范围作为子类型,直到最后返回“*”。

这是我正在使用的代码,它也在AD中使用分页搜索。

use Net::LDAP;
use Net::LDAP qw(LDAP_CONTROL_PAGED);
use Net::LDAP::Util qw(ldap_error_name canonical_dn ldap_explode_dn ldap_error_text);
use Net::LDAP::Control::Paged;

my $page_page = Net::LDAP::Control::Paged->new( 'size' => $input{'page'} );
my $finished_search = 0;
my $page_cookie;
my $result;
my @page_search_args = (
    'base'     => $input{"base"},               
    'scope'    => $input{'scope'},                             
    'filter'   => $input{'filter'},  
    'attrs'    => $input{'attrs'},  
    'control'  => [ $page_page ],
    'deref'    => 'never',
    'raw'      => qr!^DO_NOT_MATCH!,
);

while (!$finished_search) {
        my $msg = $ldap->search(@page_search_args);
        if ($msg->is_error()) {
            die "ERROR: ",$msg->error,"\n";
            last;
        } else {
            my ($response) = $msg->control(LDAP_CONTROL_PAGED);
            $page_cookie = $response->cookie();
            $finished_search = 1 if !$page_cookie;
            $page_page->cookie($page_cookie);

            while (my $entry = $msg->pop_entry()){
                $ldap_searches++;
                print_all_attributes($entry);
            }
        }
}

if ($page_cookie) {
        $page_page->cookie($page_cookie);
        $page_page->size(0);
        $ldap->search(@page_search_args);
}   

sub add_result {
    my $dn     = shift;
    my $attr   = shift;
    my $data   = shift;
    my $res    = shift; 

    $attr =~ s!(;range\=\d+\-\d+)!!i;
    #print "removed $1 from $attr" if $1;
    foreach my $subtype (keys %{$data}){
        $attr = $attr.$subtype if $subtype ne '';
        $attr =~ s!(;range\=\d+\-\d+)!!i;
        if (defined $$res->{$dn}->{$attr}){
            push(@{$$res->{$dn}->{$attr}},@{$data->{$subtype}});
        } else {
            push(@{$$res->{$dn}->{$attr}},@{$data->{$subtype}});
        }
    }

    return $res;    
}
sub print_all_attributes {
    my $entry = shift;
    foreach my $attr ($entry->attributes()) {
        if ($attr =~ /;range=/) {   
            my $last = 0;my $first = 0;
            ### $var will look like this --> "member;range=0-1499"
            (my $pure_attr,my $range) = split /;/, $attr,2;
            (my $junk,$range)         = split /=/, $range,2;
            ($first,$last)            = split /-/, $range,2;
            $i++;
            add_result($entry->dn(),$pure_attr,$entry->get_value($attr,alloptions => 1, asref => 1),\$result) if $last eq '*' or $last >= $parms{'attribute_page'}; 
            ### if $last eq "*", indicates this is the last range increment, and
            ### we do not need to perform another supplemental search
            if ($last ne "*") {                                     
                my $range_diff = ($last - $first) + 1;
                my $increment =  $last + $range_diff;
                $last = $last + 1;
                $attr = "$pure_attr;range=$last-$increment";
                $parms{'attrs'} = [$attr];
                search_nonpaged(%parms);            
            }       
        } else {### if $attr matches range pattern                  
            add_result($entry->dn(),$attr,$entry->get_value($attr,alloptions => 1, asref => 1),\$result);
        }
    }
    return 1;
}
sub search_nonpaged{
    my %input = @_;
    my @page_search_args = (
        'base'     => $input{"base"},               
        'scope'    => $input{'scope'},                             
        'filter'   => $input{'filter'},  
        'attrs'    => $input{'attrs'},  
        'deref'    => 'never',
        'raw'      => qr!^DO_NOT_MATCH!,
    );  
    my $msg = $ldap->search(@page_search_args);
    if ($msg->is_error()) {
        die "ERROR: ",$msg->error,"\n"; 
    }
    while (my $entry = $msg->pop_entry()){
        $ldap_searches++;
        print_all_attributes($entry);
    }
}

关于Perl LDAP 搜索 - 群组中超过 1500 名成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19792363/

相关文章:

perl - 为什么在使用 Date::Manip 时出现 "invalid zone in SetDate"错误?

java - 目录上下文 : Active Directory Ldap request: get groups of user with parent groups

linux - 是否可以从 linux 机器查询 windows ldap 服务器

database - 数据创建响应超时的最佳重试策略

linux - apache linux 中的 LDAP 身份验证

linux - 确定哪些文件已更改或创建

perl - 哪些主机支持 Catalyst Framework 应用程序

arrays - 如何在Perl中访问哈希数组?

Azure Active Directory - 访问 token 组信息

mysql - 流错误,同时尝试在 Compress::Raw::Zlib::_deflateInit 中初始化 deflate 对象