I think you will find that paged controls do not help. This is what I do to deal with this:
Microsoft discusses this issue in the following article. They have a code example in C http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ldap/ld ap/searching_using_range_retrieval.asp This peculiar behavior is explained in an EXPIRED RFC DRAFT. This draft looks like where Microsoft got the idea. You can find this draft at: http://www.hut.fi/cc/docs/kerberos/draft-kashi-incremental-00.txt This perl example shows how to do a search against AD to display group membership where the membership count is greated thaan the AD administrative limit (the limit is 1000 under window2000 and 1500 under windows2003 AD). Oh, the example below is for Windows2000....so one would have to adjust the incrementing range from being 1000 to 1500. use Net::LDAP; use Net::LDAP::Util; # Connect to AD make sure to specify version 3. Some versions of perl-ldap default to version 2 # and this method does not work unless version 3 is used. $yourAdserver="xx.yy.zz"; $ldap = new Net::LDAP("$yourAdserver",port => 3268,debug => 0,version =>3 ) or die "New failed:$@"; # Do an anonymous bind. Depending upon how you AD is setup you May have to do an authenticated bind. $result=$ldap->ldapbind() || die "Bind Failed:$@"; # Some error trapping $err=$result->code; if ($err){ $errname=Net::LDAP::Util::ldap_error_name($err); $errtxt=Net::LDAP::Util::ldap_error_text($err); if ($errtxt){ print "($err) $errtxt\n"; } else { if ($errname){ print "($err) $errname\n"; } else { print "ERR: $err\n"; } } exit; } # The combination of the search base and filter determine which object that you # retrieve # set search filter to groups of objects. This is what you want to enumerate NT groups. $filter="(objectClass=group)"; # Set the search base to the DN of the object that you want to retrieve. BTW, using this method on # groups with less than 1000 members works as well. $base='CN=Mygroup,OU=users,DC=xx,DC=yy,DC=zz'; # Set the initial attribute indexes and name $found=1; $startr=0; $endr=-1; $startattr="member"; while($found){ # Create the attribute range specification $startr=$endr+1; $endr=$startr+999; $attr="$startattr;range=$startr-$endr"; $saveattr=$attr; @attr=("$attr"); # Perform the search $result=$mesg = $ldap->search(base => "$base",filter => $filter, attrs => [EMAIL PROTECTED], scope => "sub") or die "search died"; # Some error trapping $err=$result->code; if ($err){ if (!($err == 1)){ $errname=Net::LDAP::Util::ldap_error_name($err); $errtxt=Net::LDAP::Util::ldap_error_text($err); if ($errtxt){ print "($err) $errtxt\n"; } else { if ($errname){ print "($err) $errname\n"; } else { print "ERR: $err\n"; } } } else { print "COUNT=$cnt\n"; } exit; } $found=0; # OK, get the attribute range...so we can update the value of the attribute # on the next pass foreach $entry ($mesg->all_entries) { @attr=$entry->attributes; foreach(@attr){ $curattr=$_; } } # Print out the current chunk of members foreach $entry ($mesg->all_entries) { $ar=$entry->get("$curattr"); foreach(@$ar){ $cnt++; print "$_\n"; } $found=1; if ([EMAIL PROTECTED]){ $found=0; } } # Check to see if we got the last chunk. If we did print toe total and set # the found flag so we don't search for anymore members if ($curattr=~/\;range=/){ if ($curattr=~/\-\*/){ print "LASTCOUNT:$cnt\n"; $found=0; } } }
