Home > Archive > LDAP > March 2005 > AD: partial answer for a multivalue attribute
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
AD: partial answer for a multivalue attribute
|
|
| Hirmke Michael 2005-03-30, 4:08 pm |
| Hi *,
using Net:LDAP 0.31 I wrote a script to retrieve Active Directory data.
Especially I am interested in getting a list of members for all our
groups.
Problem is, a few of these groups have more than 3000 members. If I try
to get the member attribute for one of them, the following attribute name
is returned: "member;range=0-1499"; the according value then consists of
exactly these 1499 members.
I know how to check for an attribute with this range suffix, but I don't
know how if there is an "official" method to handle it and I also don't
know how to retrieve the remaining members with an additional search.
Or perhaps there is some sort of parameter I can add to the first search
to get all the members within one search call.
Can anyone help me with this?
TIA.
Bye.
Michael.
| |
| Durairaj K. Avasi 2005-03-30, 4:08 pm |
|
Hello,
You can use page to get all the members ( i think thats the only option you have
.... page size defined by the directory server.. )
here is the model code .. you can use..
#!/usr/bin/perl -w
use Net::LDAP;
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED );
$ldap = Net::LDAP->new('ldap.dir.webdurai.com' ) or die "$@";
$ldap->bind ('cn=Avasi, cn=Durairaj',
password=>'TestNow123!',
version => '3',
);
ouscan("o=AD");
$ldap->unbind();
#close OUT;
sub ouscan
{
$base = shift @_;
# print "\n$base\n";
$page = Net::LDAP::Control::Paged->new( size => 1000 );
@args = (
base => $base,
scope => "subtree",
filter => 'objectClass=organizationalPerson',
control => [ $page ],
attrs => ["distinguishedName"]
);
my $cookie;
while(1) {
# Perform search
my $mesg = $ldap->search( @args );
# Only continue on LDAP_SUCCESS
if ($mesg->code)
{
warn "ERROR - not LDAP_SUCCESS";
last;
}
# Get cookie from paged control
my($resp) = $mesg->control( LDAP_CONTROL_PAGED ) or last;
$cookie = $resp->cookie or last;
# Set cookie in paged control
$page->cookie($cookie);
foreach $entry ($mesg->all_entries)
{
print " Here he is " . $entry->get_value('distinguishedName');
}
}
if ($cookie) {
$page->cookie($cookie);
$page->size(0);
$ldap->search( @args );
}
}
Have fun with it
Thanks and Kind regards
Durairaj K. Avasi
Quoting Hirmke Michael <Michael.Hirmke@arbeitsagentur.de>:
> Hi *,
>
> using Net:LDAP 0.31 I wrote a script to retrieve Active Directory data.
> Especially I am interested in getting a list of members for all our
> groups.
> Problem is, a few of these groups have more than 3000 members. If I try
> to get the member attribute for one of them, the following attribute name
> is returned: "member;range=0-1499"; the according value then consists of
> exactly these 1499 members.
> I know how to check for an attribute with this range suffix, but I don't
> know how if there is an "official" method to handle it and I also don't
> know how to retrieve the remaining members with an additional search.
> Or perhaps there is some sort of parameter I can add to the first search
> to get all the members within one search call.
>
> Can anyone help me with this?
>
> TIA.
> Bye.
> Michael.
>
--
======================
Catch the mars if you can!!!
| |
| Hirmke Michael 2005-03-30, 4:08 pm |
| Hi,
> Hello,
>
thx for your answer, but AFAIK this is the correct solution for
a different problem ;)
I don't have the problem to get too many hits! The problem is,
that a multivalue attribut within *one* hit has too many values.
To my understanding, paging won't help me in this case.
Btw. - I already use paged requests, too.
[...]
>
> Have fun with it
>
> Thanks and Kind regards
> Durairaj K. Avasi
Bye.
Michael.
| |
| Brian K Johnson 2005-03-30, 4:08 pm |
|
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/d...y/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/...remental-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_nam
e($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,D
C=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 => [@attr],
scope => "sub") or die "search died";
# Some error trapping
$err=$result->code;
if ($err){
if (!($err == 1)){
$errname=Net::LDAP::Util::ldap_error_nam
e($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 (!@$ar[0]){
$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;
}
}
}
| |
| Hirmke Michael 2005-03-30, 4:08 pm |
| Hi,=20
[...]
> Microsoft discusses this issue in the following article. They have a
> code example in C
>=20
> http://msdn.microsoft.com/library/d...=3D/library/en-
> us/ldap/ld
> ap/searching_using_range_retrieval.asp
>=20
> This peculiar behavior is explained in an EXPIRED RFC DRAFT.=20
> This draft
> looks like where Microsoft got the idea. You can find this draft at:
>=20
> http://www.hut.fi/cc/docs/kerberos/...remental-00.txt
good god 8-<
>=20
> 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=20
> 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.
Jepp, that's exactly what I've been looking for.
Thank you very much!
Bye.
Michael.
|
|
|
|
|