Skip to content

Commit

Permalink
Merge pull request #1 from tsibley/search-scope
Browse files Browse the repository at this point in the history
Search scope bug fixes
  • Loading branch information
karpet committed Jul 28, 2012
2 parents b080573 + d559ae4 commit 4da8421
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 8 deletions.
21 changes: 13 additions & 8 deletions lib/Net/LDAP/Server/Test.pm
Expand Up @@ -55,6 +55,7 @@ Only one user-level method is implemented: new().
LDAP_OPERATIONS_ERROR
LDAP_UNWILLING_TO_PERFORM
);
use Net::LDAP::Util qw(ldap_explode_dn);
use Net::LDAP::Entry;
use Net::LDAP::Filter;
use Net::LDAP::FilterMatch;
Expand All @@ -74,6 +75,7 @@ Only one user-level method is implemented: new().
our %Data; # package data lasts as long as $$ does.
our $Cookies = 0;
our %Searches;
my @Scopes = qw(base one sub);

# constructor
sub new {
Expand Down Expand Up @@ -128,17 +130,16 @@ Only one user-level method is implemented: new().

my @results;
my $base = $reqData->{baseObject};
my $scope = $reqData->{scope} || 'sub';
# $reqData->{scope} is a enum but we want a word
my $scope = $Scopes[defined $reqData->{scope} ? $reqData->{scope} : 2];
my @attrs = @{$reqData->{attributes} || []};
my @filters = ();

if ( $scope ne 'base' ) {
if ( exists $reqData->{filter} ) {
if ( exists $reqData->{filter} ) {

push( @filters,
bless( $reqData->{filter}, 'Net::LDAP::Filter' ) );
push( @filters,
bless( $reqData->{filter}, 'Net::LDAP::Filter' ) );

}
}

#warn "stored Data: " . Data::Dump::dump \%Data;
Expand Down Expand Up @@ -197,7 +198,11 @@ Only one user-level method is implemented: new().
next unless $dn eq $base;
}
elsif ( $scope eq 'one' ) {
next unless $dn =~ m/^(\w+=\w+,)?$base$/;
my $dn_depth = scalar @{ ldap_explode_dn($dn) };
my $base_depth = scalar @{ ldap_explode_dn($base) };

# We're guaranteed to be at or under $base thanks to the m// above
next unless $dn_depth == $base_depth + 1;
}

my $entry = $Data{$dn};
Expand All @@ -215,7 +220,7 @@ Only one user-level method is implemented: new().
}

#warn "matched $match";
if ( $match == scalar(@filters) ) { # or $dn eq $base ) {
if ( $match == scalar(@filters) ) {

# clone the entry so that client cannot modify %Data
my $result = $entry->clone;
Expand Down
65 changes: 65 additions & 0 deletions t/05-scope.t
@@ -0,0 +1,65 @@
use strict;
use warnings;

use Test::More;

use Net::LDAP;
use Net::LDAP::Server::Test;

my $port = 1024 + int rand(10000) + $$ % 1024;

ok( my $server = Net::LDAP::Server::Test->new( $port, auto_schema => 1 ), "spawn new server" );
ok( my $ldap = Net::LDAP->new("localhost:$port"), "new LDAP connection" );
ok( my $rc = $ldap->bind(), "LDAP bind()" );

my @scopes = qw(base one sub);

# Add our nested DNs
my $dn = my $base = "dc=example,dc=com";
for my $level (@scopes) {
$dn = "cn=$level group,$dn";
my $result = $ldap->add(
$dn,
attr => [
cn => "$level group",
objectClass => 'Group',
],
);
ok !$result->code, "added $dn: " . $result->error;
}

# Do scopes work?
my %expected = (
'base' => [qw(base)],
'one' => [qw(one)],
'sub' => [qw(base one sub)],
);

for my $scope (@scopes) {
my $cns = $expected{$scope};
my $count = scalar @$cns;
my $msg = $ldap->search(
base => "cn=base group,$base",
scope => $scope,
filter => '(objectClass=group)',
);
ok $msg, "searched with scope $scope";
is $msg->count, $count, "found $count";

my %want = map { ("$_ group" => 1) } @$cns;
my %found = map { ($_->get_value('cn') => 1) } $msg->entries;
is((scalar grep { !$found{$_} } keys %want), 0, "found all expected CNs");
is((scalar grep { !$want{$_} } keys %found), 0, "expected all found CNs");

# test that filters apply correctly on all scopes
$msg = $ldap->search(
base => "cn=base group,$base",
scope => $scope,
filter => '(objectClass=404)',
);
ok $msg, "searched with scope $scope with a non-matching filter";
is $msg->count, 0, "found no entries";
}

ok $ldap->unbind, "unbound";
done_testing;

0 comments on commit 4da8421

Please sign in to comment.